Esc

    The API is under testing and may change before release.

    The dated market

    If you value anything over more than one day (P&L, risk over time, a book revalued every close), this page explains how one market holds several dates: a snapshot of curves per date it was marked on, one shared history of fixings, and the reference data that never changes from day to day.

    Why a market keeps every close

    A desk revalues its book every day. Each close brings a new sheet, and each day brings new fixing prints for the trades that reset on it. Keeping each close as its own snapshot means yesterday's valuation can be repeated exactly while today's is made, which is what explaining a day's P&L needs.

    What does not change from day to day lives once, outside the snapshots: the recipes that say how a sheet builds curves, central bank meeting schedules, counterparties, and the data source.

    How a date is read

    Write M\mathcal{M} for the market, t∗t^\ast for the date it is at, and {Mt}\{M_t\} for its snapshots. A valuation reads the snapshot at the date asked:

    V(θ; M,t)=f ⁣(θ; Mt, H≤t),V(\theta;\ \mathcal{M}, t) = f\!\left(\theta;\ M_t,\ H_{\le t}\right),

    where H≤tH_{\le t} is the fixing history as known on tt. Moving the market to another date selects another snapshot and leaves every other snapshot as it was; dropping a date removes its snapshot and changes no other.

    Every print in the history carries the date it became known and whether it was pinned by hand or fetched. A valuation at tt reads only prints known by tt, and a pinned print is read over any fetched version of the same print. Pinning the prints again on a later date keeps what earlier dates knew: a print pinned again with the same value adds no version, a new print is known from the date it is pinned, and a changed value is a restatement known from that date, kept beside the old one. So H≤tH_{\le t} for an earlier tt is the same after a later pin as it was before.

    From formula to API

    Symbol Meaning Rust Python
    t∗t^\ast the date the market is at MarketContext::reference_date MarketContext.as_of
    MtM_t the snapshot at tt MarketContext::on(t) MarketContext.on(t)
    {t}\{t\} the dates with a snapshot MarketContext::dates MarketContext.dates
    drop MtM_t remove one snapshot MarketContext::without(t) MarketContext.without(t)
    HH the fixing history, by version MarketContext::fixing_history then versions MarketContext.fixing_history
    pin into HH pin prints, keeping what earlier dates knew MarketContext::with_fixings MarketContext.with_fixings

    Two closes on one market

    This program marks two closes on one market, pins a new print on the second day, and reads the fixing history. The September prints keep the close as the date they became known, so a swap that accrued over them values on the close exactly as it did before the second pin. Marking a close, moving on, valuing and dropping a date is the how-to Mark a daily close. The program reads its quotes from the desk sheets.

    Rust
    use chrono::NaiveDate;
    use helixio_docs_sheets::{SOFR_CLOSE_DATE, Sheet, USD_SOFR_CLOSE, USD_SOFR_PRINTS};
    use helixrs::{
        CollateralSpec, FixingKey, FixingStore, MarketContext, QuoteSheet, Termination,
        template,
    };
    
    type Outcome<T> = Result<T, Box<dyn std::error::Error>>;
    
    fn date((year, month, day): (i32, u32, u32)) -> NaiveDate {
        NaiveDate::from_ymd_opt(year, month, day).expect("a real calendar date")
    }
    
    /// A sheet with every quote moved by `shift`.
    fn sheet(rows: Sheet, shift: f64) -> Outcome<QuoteSheet> {
        let shifted = rows.iter().map(|&(template, locator, quote)| (template, locator, quote + shift));
        Ok(QuoteSheet::from_rows(shifted)?)
    }
    
    /// The shared September prints, and any published since.
    fn prints(since: &[(&str, (i32, u32, u32), f64)]) -> Outcome<FixingStore> {
        let observations: Vec<(FixingKey, NaiveDate, f64)> = USD_SOFR_PRINTS
            .iter()
            .chain(since)
            .map(|(index, day, value)| (FixingKey::Typed((*index).to_owned()), date(*day), *value))
            .collect();
        Ok(FixingStore::from_observations_checked(&observations)?)
    }
    
    fn joined(dates: &[NaiveDate]) -> String {
        dates.iter().map(NaiveDate::to_string).collect::<Vec<_>>().join(", ")
    }
    
    fn main() -> Outcome<()> {
        let close = date(SOFR_CLOSE_DATE);
        let next_day = date((2026, 10, 2));
        let usd = CollateralSpec::Currency("USD".parse()?);
    
        // Mark the close, then move to the next day and mark it on a sheet one basis
        // point higher. The first day's snapshot is kept.
        let market = MarketContext::as_of(close)
            .with_fixings(prints(&[])?)
            .with_recipe_quotes(&usd, &sheet(USD_SOFR_CLOSE, 0.0)?)?
            .on(next_day)
            .with_recipe_quotes(&usd, &sheet(USD_SOFR_CLOSE, 0.0001)?)?;
        println!("dates   {}", joined(&market.dates()));
        println!("as of   {}", market.reference_date());
    
        // On the second day the 1 October print is published, and the market pins
        // the full set again. Prints live in one history across the dates, each
        // stamped with the date it became known: the September prints keep the close,
        // an unchanged print adds no version, and the new print is known from the
        // second day.
        let pinned = market.clone().with_fixings(prints(&[("USD-SOFR", SOFR_CLOSE_DATE, 0.0391)])?);
        let versions = pinned.fixing_history().versions();
        for (index, day, known, pinned, value) in &versions {
            let source = if *pinned { "pinned" } else { "fetched" };
            println!("{index} {day}  known {known}  {source}  {value:.4}");
        }
    
        // So the close still knows the September prints: a trade that accrued over
        // them values on the first day exactly as it did before the second pin.
        let seasoned = template("USD-SOFR-OIS")?
            .swap(date((2026, 9, 24)))?
            .with_maturity("5Y".parse::<Termination>()?)?
            .with_notional(10_000_000.0)
            .with_fixed_rate(0.0466)
            .build()?;
        let accrued = seasoned.npv(&pinned.clone().on(close))?;
        let before = MarketContext::as_of(close)
            .with_fixings(prints(&[])?)
            .with_recipe_quotes(&usd, &sheet(USD_SOFR_CLOSE, 0.0)?)?;
        println!("seasoned npv on {close}  {accrued:.2}");
        println!("before the second pin       {:.2}", seasoned.npv(&before)?);
    
        Ok(())
    }
    Python
    import datetime as dt
    
    import helixio as hlx
    from desk_sheets import SOFR_CLOSE_DATE, USD_SOFR_CLOSE, USD_SOFR_PRINTS
    
    NEXT_DAY = dt.date(2026, 10, 2)
    
    # Mark the close, then move to the next day and mark it on a sheet one basis
    # point higher. The first day's snapshot is kept.
    monday = USD_SOFR_CLOSE
    tuesday = {t: {k: v + 0.0001 for k, v in q.items()} for t, q in USD_SOFR_CLOSE.items()}
    market = (
        hlx.MarketContext(SOFR_CLOSE_DATE)
        .with_fixings(USD_SOFR_PRINTS)
        .with_recipe_quotes("USD", monday)
        .on(NEXT_DAY)
        .with_recipe_quotes("USD", tuesday)
    )
    print(f"dates   {', '.join(d.isoformat() for d in market.dates())}")
    print(f"as of   {market.as_of()}")
    
    # On the second day the 1 October print is published, and the market pins the
    # full set again. Prints live in one history across the dates, each stamped
    # with the date it became known: the September prints keep the close, an
    # unchanged print adds no version, and the new print is known from the second
    # day.
    pinned = market.with_fixings([*USD_SOFR_PRINTS, ("USD-SOFR", SOFR_CLOSE_DATE, 0.0391)])
    history = pinned.fixing_history().to_dict()
    for index, day, known, source, value in zip(
        history["index"], history["date"], history["known_on"], history["source"], history["value"]
    ):
        print(f"{index} {day}  known {known}  {source}  {value:.4f}")
    
    # So the close still knows the September prints: a trade that accrued over them
    # values on the first day exactly as it did before the second pin.
    seasoned = (
        hlx.templates.get("USD-SOFR-OIS")
        .swap(dt.date(2026, 9, 24))
        .with_maturity("5Y")
        .with_notional(10_000_000.0)
        .with_fixed_rate(0.0466)
        .build()
    )
    accrued = seasoned.npv(pinned.on(SOFR_CLOSE_DATE))
    before = hlx.MarketContext(SOFR_CLOSE_DATE).with_fixings(USD_SOFR_PRINTS).with_recipe_quotes("USD", monday)
    print(f"seasoned npv on {SOFR_CLOSE_DATE}  {accrued:.2f}")
    print(f"before the second pin       {seasoned.npv(before):.2f}")
    dates   2026-10-01, 2026-10-02
    as of   2026-10-02
    USD-SOFR 2026-09-28  known 2026-10-01  pinned  0.0390
    USD-SOFR 2026-09-29  known 2026-10-01  pinned  0.0388
    USD-SOFR 2026-09-30  known 2026-10-01  pinned  0.0390
    USD-SOFR 2026-10-01  known 2026-10-02  pinned  0.0391
    seasoned npv on 2026-10-01  -20632.04
    before the second pin       -20632.04

    See also

    • Source: crates/helixrs/src/market/store.rs, crates/helixrs/src/marketdata/fixings.rs
    • Related pages:
      • Books carry their market, for a book valued on each date.
      • Data sources, for prints learnt by fetching.
      • Mark a daily close, the task step by step.

    From the 0.0 line at revision bf7f2e2. Every printed number is that revision's own output.