SOFR Curve Construction, Swap Risk & Value-Change Explain

A compact Python study of how SOFR OIS quotes become discount factors, vanilla swap values, quote-rebuilt risk, curve-shock results, and an opening-to-closing value-change explain.

One dated workflow from quote inputs to book explain

The project keeps curve construction, swap cash flows, quote risk, scenario revaluation, and value-change attribution in one reproducible path. The scope is deliberately narrow enough that every convention can be stated and tested.

1W-30Ysynthetic OIS tenors
4,440sample book DV01, USD/bp
24,326explained value change, USD
OKsample validation status
DatasetStatusUse
SOFR and SOFR IndexRealRealized coupon input and independent compounding check
U.S. Treasury par yieldsRealMarket context only; excluded from the SOFR bootstrap
SOFR OIS quote snapshotsSyntheticCurve construction and quote-risk demonstration
Trades, amendments, and cashSyntheticValuation, scenarios, and value-change explain

Sequential OIS calibration in discount-factor space

Each new OIS quote solves one terminal discount factor while earlier pillars remain fixed. Intermediate cash-flow dates use linear interpolation in log discount factors. Requests beyond the final pillar are rejected rather than silently extrapolated.

Calibration conditionqiAi(D) - PVfloat,i(D) = 0
Interpolationlog D(t) = linear interpolation between solved pillars
Synthetic SOFR zero and forward curves with discount factors
Thirteen solved pillars from 1W through 30Y. Treasury yields are not inputs to this curve.
Convention set. T+1 spot, annual fixed and floating frequencies, ACT/360, modified following, two-business-day payment lag, log-DF interpolation, and no extrapolation.

Fixed cash flows and daily compounded SOFR

Fixed and floating legs are generated separately. For a seasoned unpaid coupon, observations before the valuation date use realized SOFR fixings and the remaining interval uses forward discount-factor ratios. Missing required fixings are errors, not projected substitutes.

Daily compoundingC = ∏i(1 + rini/360)
Signed valueV = s(PVfixed - PVfloat)
Par rateKpar = PVfloat / fixed annuity
S001 / Receive fixed$73,717$22m notional; 3.95% fixed
S002 / Pay fixed-$147,491$15m notional; 4.10% fixed
S003 / Receive fixed$18,284$10m notional; 3.90% fixed

Risk is measured through full curve rebuilds

Parallel and key-rate DV01 use central bumps to the synthetic OIS input quotes. Each bump triggers a new bootstrap and complete swap revaluation. The 25 bp steepener ramps linearly from -25 bp at 1W to +25 bp at 30Y; the flattener applies the inverse ramp.

Desk-positive conventionDV01 = [PVdown - PVup] / (2hbp)

A typical receive-fixed position therefore has positive DV01.

Net key-rate DV01 and full-revaluation curve-shock results
The sample book is concentrated around its 5Y and 7Y quote nodes. Scenario values are full-revaluation changes, not DV01 approximations.
Parallel +25 bp-$110,824
Parallel -25 bp+$111,147
Steepener+$110,429
Flattener-$109,534

A value-change bridge, not an economic P&L claim

The book is revalued through carry and fixing realization, the closing curve, amendments, a new trade, and signed cash. The sample has no independent entry consideration for the new trade, so its closing model value is displayed explicitly rather than being treated as verified trading P&L.

Opening-to-closing value-change waterfall
The five components reconcile exactly to the $24,326 explained portfolio value change.

The same rebuild function supports calibration and risk

Curve construction returns solved pillars and repricing diagnostics. Risk functions bump the stored quote set, call the same bootstrap, and pass the rebuilt curve to the swap pricer.

# src/sofr_curve/curve.py
def objective(log_df: float) -> float:
    candidate = DiscountCurve(
        as_of,
        tuple(pillar_dates + [pillar]),
        np.array(dfs + [math.exp(log_df)]),
        curve_name,
    )
    annuity, floating_pv, _ = _ois_leg_values(
        quote, candidate, calendars, conventions
    )
    return quote.rate * annuity - floating_pv

root, result = brentq(
    objective, -20.0, math.log(3.0),
    xtol=1e-14, rtol=1e-14, full_output=True,
)

Checks cover conventions, numerics, and accounting identities

2.21e-11 bpmaximum quote repricing error
0.0value-change identity difference
Index ratioofficial SOFR compounding cross-check
N/Aexternal-mark residual; no mark supplied

Acceptance tests also cover known-discount-factor recovery, calendar separation, realized and projected partial coupons, missing-fixing failures, DV01 signs, quote-bump scale stability, scenario shocks, amendments, cash, and data provenance.

Useful mechanics within a defined boundary

Market data

The OIS quotes and trade book are synthetic. No claim is made that the sample represents executable dealer levels.

Curve

The project is single-curve USD SOFR. Futures calibration, term SOFR, collateral optionality, and basis curves are outside scope.

Conventions

The named calendars are transparent research approximations rather than licensed SIFMA or ISDA calendars.

Use

This is not a live curve service, trade store, accounting platform, independent price-verification process, or production risk system.