Futures Pricing — CTD / Convexity / Fair-Value Family Price exchange-traded futures (Treasury, SOFR, equity index, Eris SOFR swap futures) with cheapest-to-deliver, convexity adjustment, and fair-value methodologies.
Family-level model covering futures pricing methodologies: cheapest- to-deliver (CTD) selection and conversion-factor adjustments for Treasury futures; convexity-adjustment for SOFR futures; fair-value basis with dividend yield for equity index futures; Eris standardized SOFR swap futures. Used in ALM portfolio and hedge program execution. Implementations: 4 FinView L1 + 1 Gold Copy L1 challenger.
Inputs, processing, outputs
- data sources
- DS-001 · DS-002 · DS-005 · DS-006 · DS-009 · DS-031 · DS-033
- assumptions
- A-050, A-051, A-052, A-053
- engines
-
finview.L1.treasury_futures_pricer
finview.L1.sofr_futures_pricer
finview.L1.equity_index_futures_pricer
finview.L1.eris_sofr_futures_pricer
goldcopy.L1.futures_pricer
- contracts
- futures_pricing_v1
- upstream
- M-137
- dimensions
- D2
Methodology
M-135 is the Futures Pricing family: FinView-resident engines that price
exchange-traded futures by cost-of-carry / convexity-adjusted forward
construction and report fair value against a quoted market price. All members
live in [redacted] (engine ids finview.L1.*);
none of the source is in InsModel — InsModel consumes them cross-repo by adding
the FinView path to sys.path (the same pattern M-040/CECL uses).
The family has four production engines plus a frozen "gold copy" challenger fixture:
| Member | Engine id | Method | DV01? |
|---|---|---|---|
| SOFR futures (SR1/SR3) | finview.L1.sofr_futures_pricer |
forward rate from SOFR curve + Hull-White convexity adjustment; price = 100 − futures_rate×100 | yes (tick value, $/bp) |
| Treasury futures (ZT/ZF/ZN/ZB/UB) | finview.L1.treasury_futures_pricer |
cash-and-carry on the cheapest-to-deliver (CTD) bond; fair = (CTD cash + financing − coupon income) / conversion_factor | yes (CTD-implied, /CF) |
| Equity-index futures (ES/NQ/RTY/YM + micros) | finview.L1.equity_index_futures_pricer |
classic cost-of-carry F* = S·exp((r−d)·T) | approx (S·T·1bp×mult) |
| Eris SOFR swap futures (2Y–30Y) | finview.L1.eris_sofr_futures_pricer |
wraps IRSPricer; price = 100 + swap-NPV per $100 notional |
yes (from IRS) |
| Gold-copy challenger | goldcopy.L1.futures_pricer |
frozen CME settlement prices + deliverable baskets (ZN=F, ZB=F, ES=F, SR3) for cross-check | reference only |
Note —
credit_index_futures_priceris not an M-135 member. Although it shares the*_futures_pricernaming and lives alongside the family infinlib/derivatives/,finview.L1.credit_index_futures_priceris assignedmodel_membership: [M-133](Credit Derivatives) inengine_registry.yaml(line 348), and the M-135 registry processing-engines list does not include it. It is documented under M-133, not here.
Two pricing modes coexist in the family. Rate futures (SOFR, Treasury) are
priced off a discount curve with an explicit financing/convexity term; the
equity engine is the textbook cost-of-carry forward; the Eris engine is a
swap-future that reuses the existing IRSPricer rather than re-deriving swap
math. The canonical exemplar documented here is the 3-Month SOFR future
(SR3) — it is the cleanest, most self-contained rate-future pricer (depends
only on bootstrap_sofr_curve and interpolate_curve) and it surfaces every
output a rate future needs in one compute_fair_value call: forward rate,
convexity adjustment, futures price, and DV01.
SR3 pricing chain. From the bootstrapped SOFR discount curve, zero rates
are recovered (z = −ln(DF)/t), the forward rate over the contract reference
period [t1, t2] is (DF(t1)/DF(t2) − 1)/(t2−t1), a convexity adjustment
CA ≈ ½·σ²·t1·t2 (simplified Ho-Lee / Hull-White) lifts the forward to the
futures rate (futures rate > forward rate because daily margining is
positively correlated with rates), and the theoretical price is
100 − futures_rate×100. Fair value in dollars is the price gap times the
contract tick value scale; DV01 is the contract tick value ($25.00/bp for SR3).
Key Assumptions and Their Justification
| Assumption | Value (SR3 canonical) | Source / derivation | Justification |
|---|---|---|---|
| Carry / financing | implicit in curve DFs (no separate repo for SOFR) | SOFR discount curve | SOFR futures settle to compounded SOFR; the curve is the financing leg, so no external repo rate is needed (unlike Treasury futures, which take an explicit repo_rate, default 4.3%). |
| Curve | flat 4.50% par yields, 10 tenors → bootstrapped DF curve | bootstrap_sofr_curve test fixture |
Deterministic canonical input matching tests/test_sofr_futures_pricer.py; flat curve makes the forward ≈ the par rate, so outputs are inspectable by hand. |
| Convexity vol (σ) | 0.005 (50 bp) short-rate vol | engine default | Convexity for short-dated SOFR is tiny (≈1.6e-6 here); the adjustment is O(σ²·t1·t2) so it is materially below a tick at the front end and only grows for deferred contracts. |
| Reference period | 91 days (SR3); accrual start 0.25y | CME SR3 spec | Hard-coded to CME 3-Month SOFR contract definition; accrual_start_years selects which forward window the contract references. |
| Convexity bias sign | futures rate ≥ forward rate | Hull-White structure | Daily variation margin on a short-rate future is paid/received when rates move, biasing the futures-implied rate above the forward — the model encodes this as an additive positive CA. |
Prose. The single most important modelling choice is that SOFR futures
require no exogenous carry input: the SOFR discount curve simultaneously
supplies the forward rate and the financing, so the only "carry" the model
adds is the convexity correction. This is the cleanest member of the family
precisely because the curve collapses spot, carry, and forward into one object.
Treasury futures, by contrast, need an explicit repo_rate and a deliverable
basket to find the CTD — more inputs, more failure modes (see Limitations).
The convexity-vol assumption is the only "soft" parameter in SR3 pricing and
its impact is sub-tick at the front of the curve, which is why the test suite
asserts convexity_adjustment < 0.001.
Output Snapshot
Deterministic single-contract run of SOFRFuturesPricer (SR3) — reproducible,
requires no live market data (python scripts/model_snapshots.py M-135 in
InsModel; the engine is asserted by tests/test_sofr_futures_pricer.py in
FinView, 27 tests). BV-032 immune: the curve is a flat 4.50% synthetic par
curve (the exact test fixture), so no FRED/CME live quote is touched.
Input: SR3 (3-Month SOFR) · notional $2,500,000 · futures_price 95.50 (implied rate 4.50%) · accrual start 0.25y · σ 0.005 · flat 4.50% SOFR curve
| output | value | meaning |
|---|---|---|
| market_price (quoted) | 95.5000 | the contract quote being checked |
| implied_rate (100 − price) | 0.045000 | rate the market quote implies (4.500%) |
| forward_rate (from curve) | 0.044499 | curve forward over the 91-day window |
| convexity_adjustment | 1.571e-06 | ½·σ²·t1·t2 — sub-tick at the front end |
| futures_rate (fwd + CA) | 0.044501 | convexity-lifted rate the future references |
| theoretical_price | 95.5499 | 100 − futures_rate×100 |
| price_difference (theo − mkt) | 0.0499 | fair price sits ~5 ticks above the quote |
| dv01 ($/bp) | 25.00 | SR3 tick value, dollar value of 1 bp |
| fair_value ($ vs market) | 124.74 | dollar mispricing of the quoted contract |
The theoretical price (95.5499) is about 5 bp / 5 ticks above the quoted 95.50, so the model flags the quote as cheap and reports a +$124.74 fair value on one contract. The convexity term is 1.6e-6 in rate space — economically negligible at the 3-month point, exactly as expected for a front-month SOFR future — so almost all of the price gap is the forward-vs-quote difference, not convexity. DV01 is the fixed CME tick value ($25.00/bp for SR3; $41.67/bp for SR1).
Captured 2026-06-04 · deterministic, no live data.
Limitations and Known Gaps
-
Convexity is a simplified Ho-Lee / Hull-White closed form, not a calibrated term-structure model.
CA = ½·σ²·t1·t2with a single flat σ. This is accurate for front-month contracts (the documented SR3 case) but understates convexity for deferred contracts where mean-reversion and a term structure of vol matter. No SABR/HJM calibration is wired in. -
Single flat convexity vol. σ is one scalar (default 0.005); there is no vol surface or per-tenor σ. A deferred SR3 strip priced off one σ will carry correlated convexity error across the curve.
-
SOFR financing is curve-implicit; Treasury financing is a single repo scalar. The Treasury member takes one
repo_rate(default 4.3%) and onedays_to_delivery(default 90) for the whole basket — it does not model a term repo curve or special-collateral (squeeze) effects, which can move the real CTD and the net basis. -
CTD selection is static (lowest net basis at valuation). The Treasury engine picks the cheapest-to-deliver by current net basis and does not model the delivery-option / switch optionality (the right to deliver a different bond if rates move through the 6% notional yield). For SR3 this limitation is moot (cash-settled), but it caps accuracy of the Treasury sibling.
-
Equity DV01 is a crude approximation.
S·T·1bp×multiplier— a first-order rate sensitivity that ignores the dividend-yield term and is not a true Greeks computation. Fine for exposure bucketing, not for hedging. -
FinView-resident, cross-repo dependency. The entire family lives in
[redacted]; InsModel reaches it only bysys.path.insert(0, "[redacted]"). There is no packaged interface — a FinView refactor offinlib.derivativeswould silently break the InsModel snapshot. This is the same cross-repo fragility flagged for M-040 (CECL). -
No live-data path exercised here (by design). The gold-copy challenger (registered engine
goldcopy.L1.futures_pricer; frozen-fixture data infinlib/gold_test_derivatives.py) carries frozen CME settlement prices and deliverable baskets for cross-check, but the documented snapshot uses the flat synthetic curve. The live fetchers (CME/yfinance/Eris FTP) exist but are out of scope for the deterministic card and untested for staleness here.
Tracked for ratification (not applied in this documentation pass). The following are output-changing / modeling-code or validation items left for ratification, noted here for transparency: convexity is a single-sigma Ho-Lee / Hull-White closed form under-built for deferred strips, equity-future DV01 is a crude
S·T·1bpapproximation, and Treasury CTD selection is static with no delivery-option modelling (INV-022); independent effective-challenge validation evidence does not yet exist (registrylast_validated_on: null, peer-review pending — INV-029); and the family is FinView-resident, consumed by InsModel viasys.pathwith no packaged interface or drift gate (INV-032).
Validation Packet
| Check | Where | What it asserts |
|---|---|---|
| Implied-rate identity | tests/test_sofr_futures_pricer.py::TestImpliedRate |
rate = (100 − price)/100 exactly (95.75 → 4.25%). |
| Forward ≈ flat rate | TestForwardRate::test_forward_rate_near_flat_rate |
on a flat 4% curve the recovered forward is within 50 bp of 4%. |
| Convexity sign + monotonicity | TestConvexityAdjustment |
CA > 0 and increases with σ; CA < 0.001 (sub-tick) for short-dated. |
| Theoretical price band | TestTheoreticalPrice |
80 < theo < 105; theo ≈ 100 − rate×100 on a flat curve (±0.5). |
| Fair-value contract keys | TestComputeFairValue::test_required_keys |
result exposes fair_value, forward_rate, convexity_adjustment, futures_rate, dv01, contract. |
| DV01 = tick value | test_dv01_equals_tick_value / test_sr1_prices |
SR3 DV01 = $25.00, SR1 DV01 = $41.67. |
| Edge cases | TestEdgeCases |
unknown contract raises; default/custom notional; accrual-end arithmetic. |
| Family regression | tests/test_treasury_futures_pricer.py, test_equity_index_futures_pricer.py, test_eris_sofr_futures_pricer.py |
CTD/basis, cost-of-carry forward, and Eris-as-IRS pricing. |
| Suite result (2026-06-04) | 4 family test files, FinView venv | 91 passed (SR1/SR3 27, treasury 23, equity 21, eris 20). |
| Cross-venv reproducibility | FinView .venv and InsModel Models/.venv |
identical SR3 outputs (theo 95.5499, fair_value 124.74, DV01 25.00) under both interpreters. |
References
Futures-pricing / convexity literature:
- Hull, Options, Futures, and Other Derivatives — cost-of-carry forward
(F = S·e^((r−q)T)) and the futures-vs-forward convexity bias under daily
margining.
- Ho & Lee (1986) / Hull-White (1990) — short-rate term-structure models
underlying the ½·σ²·t1·t2 convexity adjustment for rate futures.
- CME Group SOFR Futures contract specifications (SR1 1-Month, SR3 3-Month);
CME Treasury Futures conversion-factor and cheapest-to-deliver methodology.
- Burghardt, The Treasury Bond Basis — gross/net basis, carry, implied repo,
and CTD analytics (the Treasury sibling's framework).
Engine source (FinView-resident):
- finlib/derivatives/sofr_futures_pricer.py (finview.L1.sofr_futures_pricer)
— documented SR3 exemplar.
- finlib/derivatives/treasury_futures_pricer.py, equity_index_futures_pricer.py,
eris_sofr_futures_pricer.py, credit_index_futures_pricer.py — family members.
- finlib/curve_builder.py — bootstrap_sofr_curve, interpolate_curve.
Gold-copy challenger (registered engine):
- goldcopy.L1.futures_pricer — registered challenger engine (codebase
gold_copy, path instruments/futures_pricer.py, model_membership: [M-135]
in engine_registry.yaml). This is the registry id the Components list
(above) carries. The frozen CME-settlement fixture data is held in the
FinView test file finlib/gold_test_derivatives.py, which the family test
suites read for cross-check; that file is the test fixture, not the
registered engine id.
Tests:
- tests/test_sofr_futures_pricer.py (27), tests/test_treasury_futures_pricer.py
(23), tests/test_equity_index_futures_pricer.py (21),
tests/test_eris_sofr_futures_pricer.py (20).
Internal:
- BV-032 (live-data immunity) — snapshot uses a synthetic flat curve; no live
CME/FRED/yfinance fetch.
- Cross-repo snapshot pattern — ecosystem/InsModel/Models/scripts/model_snapshots.py
(snap_M_040 precedent for a FinView-resident engine on sys.path).
Change Log
Card change history. Code-side change history lives in git log of the component files.
This in-card Change Log is the change-log of record for M-135 (adopted per RAT-135-v1.0.0
COND-003, 2026-06-06); the registry documentation_pack.change_log flag points here.
- 2026-05-08 — stub created from registry data per Decision 023 Phase 5 / B-07.
- 2026-06-04 — Tier-2 hand-authoring of Methodology, Key Assumptions and
Their Justification, Limitations and Known Gaps, Validation Packet, and
References from the FinView
sofr_futures_pricer.pyengine (SR3 canonical exemplar) + the four family test suites (test_sofr_futures_pricer.py,test_treasury_futures_pricer.py,test_equity_index_futures_pricer.py,test_eris_sofr_futures_pricer.py). Stub marker advanced fromto. - 2026-06-04 — captured the deterministic Output Snapshot (SR3 single contract, flat 4.50% synthetic curve, no live data) and recorded the 2026-06-04 family validation-suite run (91 passed across the four test files). No fabricated numbers — all figures are deterministic engine output.
- 2026-06-06 — code-grounded documentation-accuracy pass against
engine_registry.yaml. Removedfinview.L1.credit_index_futures_pricerfrom the Methodology member table (it ismodel_membership: [M-133], registry line 348; the Components/processing list already correctly omitted it) and added a footnote. Reconciled the gold-copy challenger naming to the registered engine idgoldcopy.L1.futures_pricer(codebasegold_copy,instruments/futures_pricer.py) in the Methodology table, References, and Limitation 7, notingfinlib/gold_test_derivatives.pyas the test fixture file. Added a downstream-consumers aggregate-risk view (M-100 ALM, M-110 Hedge Effectiveness, sourced from the Materiality justification) to Dependencies per §10.5 item 8. Added a ratification-tracking note under Limitations for the gated INV-022 / INV-029 / INV-032 items. No model outputs, back-test numbers, or validation results were fabricated or changed. - 2026-06-06 — RAT-135-v1.0.0 remediation (1L, Decision 053 charter §2.2).
Assembled the Tier-2 validation-evidence pack at
modelling/validation_evidence/M-135/v1.0.0/(conceptual-soundness review,sensitivity_suite.pyon convexity sigma / repo rate / days-to-delivery / dividend yield, andreconcile_finview_vs_goldcopy.pyeffective-challenge cross-check vs the registeredgoldcopy.L1.futures_pricer— equity cost-of-carry overlap, max rel diff 0.00e+00 within 0.5%) — discharges COND-002 / INV-029 on the buildable evidence (live-CME-settlement back-test honestly pending). Reconciled the registrydocumentation_packto disk (model_card/validation_evidence/change_log-> present) and stampedlast_validated_on: 2026-06-06(COND-001); adopted this in-card Change Log as the change-log of record (COND-003). No model outputs, back-test numbers, or validation results were fabricated.
Open findings (3)
Independent 2nd-line review (INV-2026-06) — implemented capability vs registered scope. Each carries a recommended fix and is tracked in insightalm-mrm until closed.
Validation evidence + change logs missing across most of the inventory
Only M-001/M-020/M-050 carried full documentation packs before this pass. Most models record validation_evidence: missing and change_log: missing with peer_review: pending. Gold tests freeze behaviour but many assert only structural invariants (e.g. reserve>0), not correctness against external truth. The flagship T0-vs-10-K match is circular (BV-032).
Recommendation: For each Tier-1 model: produce a validation-evidence pack (back-test vs disclosed results once BV-032 re-calibration lands, sensitivity suite, challenger comparison), a change log, and a 2L ratification. Sequence behind BV-032 (firm-data) for anything needing 10-K reconciliation.
Futures convexity is a single-sigma closed form; sibling pricers have crude greeks
The convexity adjustment is a single-sigma Ho-Lee/Hull-White closed form — accurate front- month, under-built for deferred strips (no vol surface). Equity-future DV01 is a crude S*T*1bp approximation; Treasury CTD is static (no delivery-option/switch modelling).
Recommendation: Calibrate convexity to a short-rate vol surface for deferred contracts; model the CTD delivery option and a proper equity-future sensitivity.
FinView-resident pricing/CECL engines reached cross-repo with no drift gate
M-040 (CECL) and M-130-137 (asset pricing) are FinView-resident, consumed by InsModel only via sys.path insertion. No packaged interface or drift gate — a finlib signature change silently breaks the InsModel snapshot harness / consumers.
Recommendation: Define a packaged interface (or a versioned contract) for the FinView pricing library and a CI drift gate, so cross-repo consumers fail loudly on signature change. Tie to D041 ownership.
Per-tier expectations
Per MRM Framework §10.2 + §10.3, this model's regulatory_frameworks tag list activates the following overlays:
| component | tier-2 expectation | status |
|---|---|---|
| Registry entry | required | present |
| Model card (§10.5 doc pack) | required | present |
| Validation evidence | required | present |
| Change log | required | present |
| Independent effective challenge (2L) | required | attested |
Ratified — RAT-135-v1.0.1
Latest ratification on file: RAT-135-v1.0.1. Authored by 2L (mrm-peer-reviewer) per Decision 028 charter §5 Pattern A.