Skip to content

Releases: boutquin/Boutquin.Curves

v1.0.0

17 Apr 15:35

Choose a tag to compare

First stable release. All public APIs stamped as shipped; no breaking changes without a major version bump.

Highlights

  • Eleven-package layered architecture across three tiers: domain contracts and conventions (Layer 1), curve construction and analytics (Layer 2), and integration/serialization/delivery (Layer 3).
  • Four-currency proof packs: USD SOFR, CAD CORRA, GBP SONIA, and EUR €STR — complete end-to-end curve construction from free public EOD data sources via Boutquin.MarketData.Adapter.
  • Production-grade data layer integration: StandardCurveRecipes defines node specs against IDataPipeline; CurveBuilder orchestrates data fetch, calibration, and diagnostic collection in a single BuildAsync call.
  • Full bootstrap pipeline: PiecewiseBootstrapCalibrator with three interpolation methods (linear zero-rate, log-linear DF, monotone cubic Fritsch-Carlson), three root solvers (bisection, Brent, Newton-Raphson), convexity adjustments, spreaded curves, and calibration diagnostics.
  • Risk layer: Scenario-based risk reports with bucketed zero-rate shocks, CurveRiskAnalyzer, DV01 stubs, and Jacobian generation.
  • 246 tests across 16 test assemblies — unit, integration, property-based, and golden calibration tests with documented tolerance policy.

Added

Core Contracts (Boutquin.Curves.Abstractions)

  • Curve contracts: ICurve, IDiscountCurve, IForwardCurve, ICurveGroup, CurveReference (currency + role key), CurveRole enum. CurveGroupExtensions convenience methods GetDiscountCurve, TryGetDiscountCurve, GetForwardCurve, and TryGetForwardCurve.
  • Identifiers and value objects: QuoteId (null/whitespace-rejecting), CurveGroupId, NodeLabel, CalibrationResidual, CalibrationDiagnostic.
  • Diagnostics: CurveSnapshot wrapping the calibrated curve group, diagnostic collection, and forwarded DataIssue entries from Boutquin.MarketData. DATE_ROLLBACK node-level issue emitted by CurveBuilder when the actual observation date precedes the valuation date; "Info" severity for expected publication lags (e.g., SOFR T+1), adapter-level "Warning" for unexpected gaps from same-day publishers.
  • IFixingsStore / InMemoryFixingsStore: Keyed historical benchmark fixing storage by BenchmarkName + DateOnly; time-series queries and date-sliced snapshots. Foundation for valuing instruments that reference past fixings (already-accruing swaps).
  • Public API snapshots: All 11 source packages have fully populated PublicAPI.Shipped.txt files enforced by Microsoft.CodeAnalysis.PublicApiAnalyzers. Future additions require explicit PublicAPI.Unshipped.txt entries before merging.
  • MinVer versioning: Switched from manual VersionPrefix/VersionSuffix to tag-driven semantic versioning. Version is derived from the latest v* git tag on the public release repository.

Conventions and Calendars (Boutquin.Curves.Conventions)

  • Day-count, roll, and business-day convention resolution by stable codes (e.g., USD-SOFR-OIS). InstrumentConventionRegistry.CreateDefault() ships OIS, FRA, futures, and swap-leg entries for USD, CAD, GBP, and EUR.
  • Calendar unification: Calendar contracts (IBusinessCalendar, BusinessDayAdjustment) consumed from Boutquin.MarketData.Abstractions.Calendars; implementations (HolidayCalendar, HolidayCalendarFactory) from Boutquin.MarketData.Calendars. No calendar types are defined in Analytics — eliminates the pre-1.0 duplication. Full holiday datasets for USNY, GBLO, TARGET, and CATO covering 2020–2030.
  • BusinessScheduleGenerator: Convention-aware accrual-period generation for OIS, FRA, and swap legs. Pillar dates account for real financial-center holidays.

Benchmark Indices (Boutquin.Curves.Indices)

  • Benchmark identity and catalog surfaces: SOFR, CORRA, SONIA, and €STR as default RFR identities; LIBOR and CDOR modeled as isolated legacy seams, not as primary architecture.

Interpolation (Boutquin.Curves.Interpolation)

  • LogLinearDiscountFactorInterpolator: Log-linear interpolation in discount-factor space; guaranteed non-negative instantaneous forward rates between pillars.
  • LinearZeroRateInterpolator: Linear interpolation in continuously compounded zero-rate space.
  • MonotoneCubicInterpolator: Fritsch-Carlson monotone-preserving cubic Hermite interpolation in log-DF space. Eliminates forward-rate jumps of log-linear without spurious oscillations of unconstrained splines. Registered in InterpolatorFactory for InterpolatorKind.MonotoneCubic.
  • InterpolatorFactory + InterpolatorKind enum for runtime interpolator selection.

Curve Objects (Boutquin.Curves.Core)

  • Discount curves: FlatDiscountCurve, InterpolatedDiscountCurve, ZeroSpreadedDiscountCurve (additive spread on continuously compounded zero rates), MultiplicativeSpreadDiscountCurve (multiplicative hazard-rate-style spread on discount factors), JumpAdjustedDiscountCurve.
  • Forward curves: FlatForwardCurve, ForwardCurveFromDiscountCurves.
  • All curve types implement ICurve.ZeroRate(DateOnly) and IDiscountCurve.DiscountFactor(DateOnly); forward curves additionally implement IForwardCurve.ForwardRate(DateOnly, DateOnly).

Bootstrap (Boutquin.Curves.Bootstrap)

  • PiecewiseBootstrapCalibrator: Core sequential exact-repricing bootstrap engine. Resolves each pillar discount factor by iterating the root solver until the instrument's model price equals its market quote. Pre-calibration validation via CurveGroupDefinitionValidator checks duplicate curve references, duplicate node labels, missing quotes, unresolvable conventions, unsupported interpolators, and invalid extrapolator modes. Returns categorized ValidationResult with errors and warnings; invalid definitions throw InvalidOperationException with a clear error summary. Opt out via CurveCalibrationRequest.SkipValidation = true.
  • Root solvers: IBracketedRootSolver with BisectionSolver (guaranteed convergence), BrentSolver (superlinear production default), and NewtonRaphsonSolver (quadratic with safeguarded fallback); returned RootSolverResult carries convergence diagnostics.
  • Instrument helpers: DepositInstrumentHelper, FraInstrumentHelper, OisInstrumentHelper, OisFutureInstrumentHelper, FixedFloatSwapInstrumentHelper.
  • Convexity adjustments: IConvexityAdjustment interface; ConstantConvexityAdjustment (flat adjustment for short-dated strips) and HullWhiteConvexityAdjustment (Hull-White one-factor formula with automatic Ho-Lee fallback when mean reversion → 0). Applied in OisFutureInstrumentHelper to reduce futures-implied rates by the model-implied convexity bias before the bootstrap node is solved.
  • ResolvedNode: Node with rate attached — no QuoteId/MarketQuoteSet indirection; rates travel directly from ICurveNodeSpec.ExtractRate() to the calibrator.
  • CurveCalibrationInput: Calibrator input with pre-resolved rates; validated before entering the bootstrap loop.

Risk (Boutquin.Curves.Risk)

  • CurveRiskAnalyzer: BuildScenarioRiskReport for actual shocked-vs-base valuation delta reporting across maturity buckets.
  • BucketedZeroRateShock / BucketedShockPoint: Maturity-dependent zero-rate shock scenarios with linear interpolation.
  • Jacobian generation: Finite-difference bumping with deterministic row/column labeling and quality diagnostics (dimension consistency, finite-value checks, condition estimate).
  • DV01 and key-rate duration stubs for downstream sensitivity attribution.

Recipes and MarketData Integration (Boutquin.Curves.Recipes)

  • CurveBuilder: Single-call orchestrator. Fetches market data via IDataPipeline, resolves nodes via ICurveNodeSpec.ExtractRate(), calibrates via PiecewiseBootstrapCalibrator, and returns a CurveSnapshot containing the calibrated curve group and all diagnostic and data-issue entries.
  • ICurveNodeSpec: Describes how to fetch and extract a rate for one curve node. Default method ExtractActualDate returns the observation date when it differs from the valuation date; OvernightFixingNode overrides this for date gap detection on benchmarks with known publication lags (e.g., SOFR T+1).
  • StandardCurveRecipes: Eight pre-built recipes covering USD/CAD/GBP/EUR discount and projection curves. Discount recipes use 10–11 nodes (O/N + short-tenor deposits + long-tenor OIS swaps); projection recipes use 2 nodes (research-grade). See the recipe table in README.md.
  • CurveGroupRecipe: Typed curve definition pairing a CurveGroupId with an ordered list of ICurveNodeSpec entries.
  • FakeDataPipeline / FixtureData (Boutquin.Curves.Recipes.Testing): Deterministic market data for all four currencies. Enables full end-to-end calibration without network access — the foundation for CI golden tests and the Recipes Quick Start example.

Serialization (Boutquin.Curves.Serialization)

  • CalibrationReportExporter: Static utility for exporting a CurveCalibrationResult to an indented JSON calibration report. The report includes schemaVersion: "1.0", valuation date, curve group name, diagnostics (repricing residuals, structural observations, numerical solver metrics), and an optional Jacobian matrix (omitted when null).
  • CsvQuoteLoader: Static utility for loading market quotes from CSV text or streams into a MarketQuoteSet. Required columns: QuoteId, Value, FieldName, AsOfDate (ISO 8601). Optional: Source, Unit, Notes. Throws FormatException on empty input, missing required columns, unparseable values, duplicate quote IDs, or no data rows.
  • CurveGroupDefinitionDto with SchemaVersion = "1.0" for forward-compatible versioning of persisted curve group definitions.

CI / Quality

  • pr-verify.yml: Build, test, coverage, and format checks on all PR...
Read more