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:
where is the instrument's terms, is the quote sheet at date , is the recipe that says which curves the quotes build, and solves those curves so that every quote reprices.
A book with trades held in quantities is worth
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 |
|---|---|---|---|
| the quote sheet at | QuoteSheet::from_rows over (template, locator, quote) rows |
a dict {template: {locator: quote}} |
|
| the recipe for a collateral key | MarketContext::recipe |
MarketContext.recipe |
|
| the market solved on | MarketContext::as_of(t).with_recipe_quotes(&key, &sheet) |
MarketContext(t).with_recipe_quotes(key, sheet) |
|
| an instrument's terms | template(code)?.swap(t)?…build() |
templates.get(code).swap(t)…build() |
|
| the instrument's value | AnyInstrument::npv |
Instrument.npv |
|
| the book's value at | 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.
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(())
}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 and .
- The dated market, for across several dates.
- Books carry their market, for .
From the 0.0 line at revision bf7f2e2. Every printed number is that revision's own output.