Esc

    The API is under testing and may change before release.

    The mental model

    Once you've priced a first trade, you've used every piece of helixio: a quote sheet, a market solved from it on a date, an instrument drafted from a template, a book holding instruments and their market, and a question you ask the book at a date. This page explains what each piece holds, and why the chain adds nothing of its own to a value.

    How a desk works

    A trading desk works from the same objects whatever it trades. It reads quotes off a sheet at the close. It turns them into curves that discount cashflows and project fixings. It books trades, whose terms come mostly from a market's standard conventions. And it asks its book questions: what is it worth, what is its risk, what would it be worth under a scenario, as of a given day.

    The library keeps those objects separate and gives each one job:

    Object Holds Built by
    sheet quotes by template and locator; plain data the caller
    market curves solved from a sheet, per date; fixings; recipes; a data source MarketContext
    instrument a trade's terms a template's builder
    book instruments with quantities, and one market Book
    verb a question asked at a date the book's methods

    Why the chain adds nothing

    A value is a function of a trade's terms and a market at a date:

    V=f(θ; Mt),Mt=g(Qt; R),V = f(\theta;\ M_t), \qquad M_t = g(Q_t;\ R),

    where θ\theta is the instrument's terms, QtQ_t is the quote sheet at date tt, RR is the recipe that says which curves the quotes build, and gg solves those curves so that every quote reprices.

    A book with trades θi\theta_i held in quantities qiq_i is worth

    Vbook(t)=∑iqi f(θi; Mt).V_{\text{book}}(t) = \sum_i q_i\, f(\theta_i;\ M_t).

    Nothing in the chain adds to this sum. A book's value at its market's date is its trades' values on that market, weighted by quantity, and a book of one trade at quantity one is worth what the trade is worth.

    From formula to API

    Symbol Meaning Rust Python
    QtQ_t the quote sheet at tt QuoteSheet::from_rows over (template, locator, quote) rows a dict {template: {locator: quote}}
    RR the recipe for a collateral key MarketContext::recipe MarketContext.recipe
    Mt=g(Qt;R)M_t = g(Q_t; R) the market solved on tt MarketContext::as_of(t).with_recipe_quotes(&key, &sheet) MarketContext(t).with_recipe_quotes(key, sheet)
    θ\theta an instrument's terms template(code)?.swap(t)?…build() templates.get(code).swap(t)…build()
    f(θ;Mt)f(\theta; M_t) the instrument's value AnyInstrument::npv Instrument.npv
    Vbook(t)V_{\text{book}}(t) the book's value at tt Book::npv(t) after attach_market Book.npv(as_of=t) after Book.attach_market

    The chain in code

    Each line of this program builds one link, and the comment names it. It reads its quotes from the desk sheets. The book's value at the market's date comes out equal to the instrument's value on that market, to the bit.

    Rust
    use chrono::NaiveDate;
    use helixio_docs_sheets::{SOFR_CLOSE_DATE, USD_SOFR_CLOSE};
    use helixrs::{Book, CollateralSpec, 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")
    }
    
    fn main() -> Outcome<()> {
        let close = date(SOFR_CLOSE_DATE);
        let usd = CollateralSpec::Currency("USD".parse()?);
    
        let sheet = QuoteSheet::from_rows(USD_SOFR_CLOSE.iter().copied())?; // data
        let market = MarketContext::as_of(close).with_recipe_quotes(&usd, &sheet)?; // solved on a date
        let swap = template("USD-SOFR-OIS")? // terms from a template
            .swap(close)?
            .with_maturity("10Y".parse::<Termination>()?)?
            .with_notional(1_000_000.0)
            .with_fixed_rate(0.0480)
            .build()?;
        let book = Book::new()
            .add("SOFR-10Y", swap.clone(), 1.0) // instruments
            .attach_market(market.clone()); // ... and their market
        let value = book.npv(close)?; // a question at a date
        println!("book npv        {value:.2}");
    
        let direct = swap.npv(&market)?;
        println!("instrument npv  {direct:.2}");
    
        Ok(())
    }
    Python
    import helixio as hlx
    from desk_sheets import SOFR_CLOSE_DATE, USD_SOFR_CLOSE
    
    sheet = USD_SOFR_CLOSE                                                    # data
    market = hlx.MarketContext(SOFR_CLOSE_DATE).with_recipe_quotes("USD", sheet)  # solved on a date
    swap = (                                                                  # terms from a template
        hlx.templates.get("USD-SOFR-OIS")
        .swap(SOFR_CLOSE_DATE)
        .with_maturity("10Y")
        .with_notional(1_000_000.0)
        .with_fixed_rate(0.0480)
        .build()
    )
    book = hlx.Book().add("SOFR-10Y", swap, 1.0)                              # instruments
    book.attach_market(market)                                          # ... and their market
    value = book.npv(as_of=SOFR_CLOSE_DATE)                                   # a question at a date
    print(f"book npv        {value:.2f}")
    
    direct = swap.npv(market)
    print(f"instrument npv  {direct:.2f}")
    book npv        -2368.93
    instrument npv  -2368.93

    Each link has its own page that shows what's beneath it.

    See also

    • Source: crates/helixrs/src/market/store.rs, crates/helixrs/src/trading.rs
    • Related pages:
      • Quote sheets and recipes, for QtQ_t and RR.
      • The dated market, for MtM_t across several dates.
      • Books carry their market, for Vbook(t)V_{\text{book}}(t).

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