Boutquin.Market is a market-infrastructure library for modern yield-curve construction in .NET 10. It is the market-layer companion to Boutquin.OptionPricing.
If you are building a pricing system, a risk engine, or studying how production curve construction actually works, this is the starting point. The library covers the full pipeline: from raw market quotes and instrument conventions through piecewise bootstrapping and calibration diagnostics to governed data acquisition from free public sources.
The design is deliberately post-LIBOR and RFR-first. SOFR and CORRA are not bolt-ons — they are the default benchmark identities, convention keys, and data source targets. LIBOR transition history and legacy rates are modeled explicitly as isolated seams rather than as the primary architecture.
A complete EOD curve-building pipeline is available without commercial data licenses. Daily fixings and settlement prices from the NY Fed, US Treasury, Bank of Canada, and CME are free and production-quality at end-of-day. Where commercial data is required (full-tenor OIS discount curves, intraday feeds), the library models those gaps as explicit interface seams with warnings — not as synthetic fallback data that silently degrades results.
Working through this codebase gives practical exposure to:
- how modern OIS discount curves are constructed from overnight fixings and futures strips in a post-LIBOR world,
- how bootstrapping works instrument-by-instrument, why pillar order matters, and how repricing residuals tell you whether calibration succeeded,
- how conventions (day count, roll, settlement lag) affect cash-flow schedules and therefore curve nodes — and why they must be resolved from stable codes rather than hardcoded per instrument,
- how market-data acquisition is governed: what production-grade EOD data looks like, which gaps require commercial licenses, and how fallback policy should be explicit rather than silent,
- how a clean layered architecture keeps a pricing library extensible without coupling pricers to data-adapter or bootstrap internals.
The solution is organized into four layers. For per-package descriptions and guidance on where to make changes, see docs/repository-map.md.
Layer 1 — Domain Contracts And Conventions
Stable market semantics that all other layers depend on. Downstream pricing systems typically only need to reference this layer directly.
| Package | Description |
|---|---|
Boutquin.Market.Abstractions |
Contracts, value objects, identifiers, and IFixingsStore/InMemoryFixingsStore for historical benchmark fixing storage |
Boutquin.Market.Conventions |
Day-count, roll, and business-day convention resolution by stable codes (e.g. USD-SOFR-OIS) |
Boutquin.Market.Calendars |
Multi-jurisdiction holiday calendars (USNY, GBLO, TARGET, CATO) with embedded holiday datasets, composite construction, and caching |
Boutquin.Market.Indices |
Benchmark identity and catalog surfaces (SOFR, CORRA, and legacy rates) |
Boutquin.Market.Quotes |
Normalized quote primitives used across both adapter and bootstrap logic |
Layer 2 — Curve Construction And Analytics
Calibrated curve objects and the bootstrap engine that produces them.
| Package | Description |
|---|---|
Boutquin.Market.Curves |
Query-time discount and projection curve objects and curve-group composition |
Boutquin.Market.Curves.Interpolation |
Interpolation/extrapolation strategies — linear zero-rate, log-linear DF, monotone cubic (Fritsch-Carlson) — with explicit left/right extrapolation modes |
Boutquin.Market.Curves.Bootstrap |
Piecewise exact-repricing bootstrap engine with repricing, structural, and numerical diagnostics; pre-calibration validation; root solver abstraction (bisection, Brent, Newton-Raphson) |
Boutquin.Market.Risk |
Scenario and sensitivity seams — bucketed zero-rate shocks, CurveRiskAnalyzer, DV01 and key-rate duration stubs |
Layer 3 — Governed Market Data Ingestion
Every data source carries explicit provenance, licensing category, and fallback policy. Commercial gaps are modeled as warnings, not silence.
| Package | Description |
|---|---|
Boutquin.Market.Data.Abstractions |
Governance vocabulary: DataSourceTier, DataLicenseFlag, DataFrequency, MarketDataMode, FallbackLevel, MarketCompleteness |
Boutquin.Market.Data.Core |
Source registry, aggregation pipeline, fallback evaluation, and snapshot storage |
Boutquin.Market.Data.NewYorkFed |
SOFR fixings from the NY Fed Markets API (EOD production-grade, free) |
Boutquin.Market.Data.UsTreasury |
Treasury bill rates and par yields from treasury.gov (EOD production-grade, free) |
Boutquin.Market.Data.BankOfCanada |
CORRA, GoC benchmark yields, and zero-coupon curve via the BoC Valet API (EOD production-grade, free) |
Boutquin.Market.Data.Cme |
CME EOD futures settlement CSV adapter plus licensed/delayed intraday seams |
Boutquin.Market.Data.BankOfEngland |
SONIA overnight fixings from the Bank of England Statistics API (EOD production-grade, free) |
Boutquin.Market.Data.Ecb |
€STR overnight fixings from the ECB Data Portal SDMX-ML API (EOD production-grade, free) |
Boutquin.Market.Data.Ice |
ICE benchmark rate seam (commercial license required) |
Boutquin.Market.Data.CanDeal |
CanDeal CAD OIS/swap seam (commercial license required) |
Boutquin.Market.Data.OtcQuotes |
OTC OIS quote adapters for full-tenor discount bootstrapping (commercial) |
Boutquin.Market.Data.TermBenchmarks |
Term SOFR and Term CORRA seams |
Boutquin.Market.Data.Legacy |
LIBOR and CDOR history for transition and backfill workflows |
Boutquin.Market.Data.Fixtures |
Deterministic fixture adapters for tests and examples — no network required |
Layer 4 — Integration, Serialization, And Delivery
Pre-wired entry points and examples that compose the lower layers into user-ready workflows.
| Package | Description |
|---|---|
Boutquin.Market.Recipes |
Standard curve definitions and single-call EodCurveSnapshotBuilder |
Boutquin.Market.Serialization |
JSON calibration report export (CalibrationReportExporter), CSV quote ingestion (CsvQuoteLoader), and DTO mapping for curve group definitions |
Boutquin.Market.Examples |
Executable examples for core construction workflows |
Boutquin.Market.Data.Examples |
Executable examples for governed data acquisition and aggregation |
Boutquin.Market.Benchmarks |
BenchmarkDotNet performance suite |
dotnet add package Boutquin.Market.Abstractions
dotnet add package Boutquin.Market.Curves
dotnet add package Boutquin.Market.Curves.Bootstrap
dotnet add package Boutquin.Market.RecipesBoutquin.Market.Recipes handles adapter registration, data fetch, quote normalization, and calibration so consumers get a calibrated ICurveGroup without managing SOFR convention keys or bootstrap pipeline details:
var definition = StandardCurveDefinitions.UsdSofrDiscount(valuationDate);
var snapshot = await new EodCurveSnapshotBuilder()
.WithFixtureAdapters()
.BuildAsync(definition, valuationDate);
var df = ((IDiscountCurve)snapshot.CurveGroup.GetCurve(discountRef)).DiscountFactor(maturity);| Method | Currency | Nodes | Day Count | Use Case |
|---|---|---|---|---|
UsdSofrDiscount |
USD | 11 (O/N + 1M–30Y) | ACT/360 | Collateralized cash-flow discounting |
CadCorraDiscount |
CAD | 10 (O/N + 3M–30Y) | ACT/365F | CAD discounting |
GbpSoniaDiscount |
GBP | 11 (O/N + 1M–30Y) | ACT/365F | GBP discounting (T+0 settlement) |
EurEstrDiscount |
EUR | 11 (O/N + 1M–30Y) | ACT/360 | EUR discounting |
UsdSofrProjection |
USD | 2 (O/N + 30Y) | ACT/360 | Research-grade forward projection |
CadCorraProjection |
CAD | 2 (O/N + 30Y) | ACT/365F | Research-grade forward projection |
GbpSoniaProjection |
GBP | 2 (O/N + 30Y) | ACT/365F | Research-grade forward projection |
EurEstrProjection |
EUR | 2 (O/N + 30Y) | ACT/360 | Research-grade forward projection |
| Mode | Builder call | When to use |
|---|---|---|
| Fixture | .WithFixtureAdapters() |
Tests, CI, and examples — deterministic, no network |
| Live | .WithPublicAdapters() |
EOD workflows using free public sources (NY Fed, US Treasury, Bank of Canada, CME, Bank of England, ECB) |
| Custom | .WithAdapter(myAdapter) |
Any IMarketDataSourceAdapter implementation |
EodCurveSnapshot contains:
- CurveGroup — calibrated
ICurveGroupfor discount factor, zero rate, and forward queries - Diagnostics — repricing residuals, structural warnings (including
TREASURY_PROXYflags for nodes built from Treasury par yields), and numerical quality metrics - DataResult — raw adapter fetch results with provenance tracking
- Coverage — completeness report describing data coverage and fallback usage
For exploring the lower-level API without the data layer:
var flatCurve = new FlatDiscountCurve(
valuationDate: DateOnly.FromDateTime(DateTime.Today),
rate: 0.05m);
var df = flatCurve.DiscountFactor(
DateOnly.FromDateTime(DateTime.Today.AddYears(1)));Boutquin.Market is organized into four layers with explicit boundaries:
- Layer 1 — Domain Contracts And Conventions: stable interfaces, value objects, day-count conventions, calendars, benchmark identity, and normalized quote primitives. The only layer that downstream pricers like
Boutquin.OptionPricingneed to depend on. - Layer 2 — Curve Construction And Analytics: piecewise bootstrap, query-time curve objects, interpolation/extrapolation strategies, calibration diagnostics, and risk seams.
- Layer 3 — Governed Market Data Ingestion: source adapters with explicit governance descriptors (
DataSourceTier,DataLicenseFlag,DataFrequency,MarketDataMode,FallbackLevel,MarketCompleteness), fallback policy evaluation, and snapshot storage. - Layer 4 — Integration, Serialization, And Delivery:
Boutquin.Market.Recipesas the pre-wired consumer entry point, JSON serialization, executable examples, and performance benchmarks.
Dependency flows in one direction: Layer 4 → Layer 2/3 → Layer 1. The bootstrapping layer is separate from curve query objects. Diagnostics are first-class output.
See docs/architecture.md for design rationale, pipeline context, common mistakes per layer, and package placement guidance.
Boutquin.Market/
├── src/ # Source projects (26)
│ ├── Abstractions/ # Core interfaces and value objects
│ ├── Conventions/ # Day-count, business-day, roll conventions
│ ├── Calendars/ # Holiday calendars and composition
│ ├── Indices/ # Benchmark index definitions
│ ├── Quotes/ # Normalized quote records
│ ├── Curves/ # Discount curves and curve groups
│ ├── Curves.Interpolation/ # Interpolation methods
│ ├── Curves.Bootstrap/ # Piecewise bootstrap engine
│ ├── Serialization/ # JSON serialization
│ ├── Risk/ # Scenario and sensitivity
│ ├── Data.Abstractions/ # Data governance vocabulary
│ ├── Data.Core/ # Shared data infrastructure
│ ├── Data.NewYorkFed/ # SOFR, repo rates (NY Fed)
│ ├── Data.UsTreasury/ # US Treasury par yields
│ ├── Data.BankOfCanada/ # CORRA, GoC yields (BoC)
│ ├── Data.BankOfEngland/ # SONIA (Bank of England)
│ ├── Data.Ecb/ # €STR (ECB)
│ ├── Data.Cme/ # Term SOFR (CME)
│ ├── Data.Ice/ # ICE benchmark rates
│ ├── Data.CanDeal/ # Term CORRA (CanDeal)
│ ├── Data.OtcQuotes/ # OTC OIS quote adapters
│ ├── Data.TermBenchmarks/ # Term benchmark adapters
│ ├── Data.Legacy/ # Legacy benchmark history
│ ├── Data.Fixtures/ # Test fixture data
│ ├── Data.Examples/ # Data adapter examples
│ └── Examples/ # Core library examples
├── tests/ # Test projects (15)
│ ├── Abstractions.Tests/ # Abstraction contract tests
│ ├── Conventions.Tests/ # Convention verification
│ ├── Calendars.Tests/ # Calendar logic tests
│ ├── Indices.Tests/ # Index definition tests
│ ├── Quotes.Tests/ # Quote normalization tests
│ ├── Curves.Tests/ # Curve construction tests
│ ├── Curves.Interpolation.Tests/
│ ├── Curves.Bootstrap.Tests/ # Bootstrap verification
│ ├── Risk.Tests/ # Risk scenario tests
│ ├── Serialization.Tests/ # Serialization and export tests
│ ├── Data.Abstractions.Tests/
│ ├── Data.Core.Tests/
│ ├── Data.SourceAdapters.Tests/
│ ├── PropertyTests/ # Property-based tests
│ └── IntegrationTests/ # End-to-end integration
├── benchmarks/
│ └── Benchmarks/ # BenchmarkDotNet suite
├── docs/ # Documentation
├── Resources/ # Shared assets (icon)
├── scripts/ # Utility scripts
└── .github/ # CI/CD workflows
| Document | Description |
|---|---|
| docs/curve-construction-guide.md | Practitioner guide: bootstrapping, multi-curve, querying, diagnostics, fixings, and OptionPricing integration |
| docs/architecture.md | Layer 1–4 design rationale, pipeline context, common mistakes, and placement guide |
| docs/repository-map.md | Per-package descriptions organized by layer with navigation guidance |
| docs/data-layer.md | EOD data strategy, full package map, and data design choices |
| docs/public-data-adapters.md | Adapter endpoints, output formats, and normalization rules |
Contributions are welcome! Please read the contributing guidelines and code of conduct first.
If you find a bug, please report it by opening an issue on the Issues page with:
- A clear and descriptive title
- Steps to reproduce the issue
- Expected and actual behavior
- Screenshots or code snippets, if applicable
- Fork the repository and clone locally
- Create a feature branch:
git checkout -b feature-name - Make your changes following the style guides
- Commit with clear messages:
git commit -m "Add feature X" - Push and open a pull request
Boutquin.Market is open-source software provided under the Apache 2.0 License. It is a general-purpose library intended for educational and research purposes.
This software does not constitute financial advice. The curve construction, market data, and risk analysis tools are provided as-is for research and development. Before using any financial calculations in production, consult with qualified professionals who understand your specific requirements and regulatory obligations.
This project is licensed under the Apache 2.0 License — see the LICENSE file for details.
For inquiries, please open an issue or reach out via GitHub Discussions.