Esc

    The API is under testing and may change before release.

    Listed futures

    This page lists what you need to read a listed rate future from its template and value a position in it: which period a contract settles on, when it stops trading, its tick, and how a position is priced. A short-term interest rate future is quoted as a price, 100 minus the rate, and settles on the overnight rate over its reference period.

    Quick example

    The example reads its quotes from the desk sheets; load them once and it runs as shown. It reads the March 2027 contract on four templates, the June 2027 tick on three dates, and values ten March contracts bought at 95.60.

    Rust
    use chrono::NaiveDate;
    use helixio_docs_sheets::{SOFR_CLOSE_DATE, USD_SOFR_LADDER};
    use helixrs::FutureTemplate;
    use helixrs::{
        AnyInstrument, AnyTemplate, CollateralSpec, DayOfWeek, MarketContext, QuoteSheet,
        RateFuture, nth_weekday, template,
    };
    
    fn date(year: i32, month: u32, day: u32) -> NaiveDate {
        NaiveDate::from_ymd_opt(year, month, day).expect("a real calendar date")
    }
    
    fn futures(code: &str) -> FutureTemplate {
        match template(code).expect("a registered template") {
            AnyTemplate::Future(t) => t,
            _ => panic!("{code} is not a futures template"),
        }
    }
    
    fn main() -> Result<(), Box<dyn std::error::Error>> {
        let close = date(SOFR_CLOSE_DATE.0, SOFR_CLOSE_DATE.1, SOFR_CLOSE_DATE.2);
    
        // The March 2027 contract on four templates. A quarterly contract's period runs
        // from the third Wednesday of March to that of June; a monthly one is March.
        println!("{:<20} {:<25} last trading day", "template", "reference period");
        let mut periods = Vec::new();
        for code in ["USD-SOFR-3M-FUT", "USD-SOFR-1M-FUT", "GBP-SONIA-3M-FUT", "EUR-EURIBOR-3M-FUT"] {
            let contract = futures(code);
            let (start, end) = contract.reference_period(2027, 3).expect("an IMM month");
            let last = contract.last_trading_day(2027, 3).expect("an IMM month").expect("a sourced rule");
            periods.push((code, start, end, last));
            println!("{code:<20} {start} to {end}  {last}");
        }
    
        // A CME three-month SOFR contract ticks in half a basis point, and in a quarter
        // of one from about four months before its last trading day. The June contract
        // references June to September, so it trades until September.
        let sr3 = futures("USD-SOFR-3M-FUT");
        let june_last = sr3.last_trading_day(2027, 6).expect("an IMM month").expect("a sourced rule");
        println!("June 2027 last trading day {june_last}");
        let tick = |as_of| sr3.tick_size(2027, 6, as_of).expect("an IMM month").expect("a sourced rule");
        for as_of in [date(2026, 10, 1), date(2027, 4, 1), date(2027, 6, 1)] {
            println!("June 2027 tick on {as_of}  {:.4}", tick(as_of));
        }
    
        // Ten March contracts bought at 95.60. The market marked from the ladder quotes
        // March at 95.65, so the futures rate is 4.35% and the position has gained five
        // basis points on each of ten contracts.
        let sheet = QuoteSheet::from_rows(USD_SOFR_LADDER.iter().copied()).expect("a locator");
        let usd = CollateralSpec::Currency("USD".parse().expect("a currency"));
        let market = MarketContext::as_of(close).with_recipe_quotes(&usd, &sheet).expect("the USD recipe");
        let position = AnyInstrument::RateFuture(
            RateFuture::for_contract(&sr3, 2027, 3, 10.0, 95.60).expect("an IMM month"),
        );
        let rate = position.par_rate(&market).expect("a futures rate");
        let npv = position.npv(&market).expect("a value");
        println!("futures rate  {rate:.8}");
        println!("npv           {npv:.2}");
    
        Ok(())
    }
    Python
    import datetime as dt
    
    import helixio as hlx
    from desk_sheets import SOFR_CLOSE_DATE, USD_SOFR_LADDER
    
    # The March 2027 contract on four templates. A quarterly contract's period runs
    # from the third Wednesday of March to that of June; a monthly one is March.
    print(f"{'template':<20} {'reference period':<25} last trading day")
    periods = []
    for code in ("USD-SOFR-3M-FUT", "USD-SOFR-1M-FUT", "GBP-SONIA-3M-FUT", "EUR-EURIBOR-3M-FUT"):
        template = hlx.templates.get(code)
        start, end = template.reference_period(2027, 3)
        last = template.last_trading_day(2027, 3)
        periods.append((code, start, end, last))
        print(f"{code:<20} {start} to {end}  {last}")
    
    # A CME three-month SOFR contract ticks in half a basis point, and in a quarter
    # of one from about four months before its last trading day. The June contract
    # references June to September, so it trades until September.
    sr3 = hlx.templates.get("USD-SOFR-3M-FUT")
    print(f"June 2027 last trading day {sr3.last_trading_day(2027, 6)}")
    for as_of in (dt.date(2026, 10, 1), dt.date(2027, 4, 1), dt.date(2027, 6, 1)):
        tick = sr3.tick_size(2027, 6, as_of)
        print(f"June 2027 tick on {as_of}  {tick:.4f}")
    
    # Ten March contracts bought at 95.60. The market marked from the ladder quotes
    # March at 95.65, so the futures rate is 4.35% and the position has gained five
    # basis points on each of ten contracts.
    market = hlx.MarketContext(SOFR_CLOSE_DATE).with_recipe_quotes("USD", USD_SOFR_LADDER)
    position = sr3.rate_future_contract(2027, 3, contracts=10.0, traded_price=95.60)
    rate = position.par_rate(market)
    npv = position.npv(market)
    print(f"futures rate  {rate:.8f}")
    print(f"npv           {npv:.2f}")
    template             reference period          last trading day
    USD-SOFR-3M-FUT      2027-03-17 to 2027-06-16  2027-06-15
    USD-SOFR-1M-FUT      2027-03-01 to 2027-04-01  2027-03-31
    GBP-SONIA-3M-FUT     2027-03-17 to 2027-06-16  2027-06-15
    EUR-EURIBOR-3M-FUT   2027-03-17 to 2027-06-16  2027-03-15
    June 2027 last trading day 2027-09-14
    June 2027 tick on 2026-10-01  0.0050
    June 2027 tick on 2027-04-01  0.0050
    June 2027 tick on 2027-06-01  0.0025
    futures rate  0.04350000
    npv           1250.00

    How it's priced

    A position of NN contracts bought at price P0P_0, with a point worth VV and the market's futures rate rr over the reference period, is worth

    value=N (100 (1−r)−P0) V.\text{value} = N\,\big(100\,(1 - r) - P_0\big)\,V.

    On a curve marked from the futures themselves, rr is the contract's own quote, read as (100−P)/100(100 - P)/100, so a position bought below the quoted price has gained. A three-month SOFR point is worth 2,500 dollars. How the exchanges set periods and ticks is covered in how dates and conventions work.

    API

    Symbol Meaning Rust Python
    reference period the period a contract settles on FutureTemplate::reference_period Template.reference_period
    last trading day the exchange's rule FutureTemplate::last_trading_day Template.last_trading_day
    tick the minimum price move on a date FutureTemplate::tick_size Template.tick_size
    a position NN contracts at P0P_0 RateFuture::for_contract Template.rate_future_contract
    rr the futures rate AnyInstrument::par_rate Instrument.par_rate
    Argument Type Default Meaning
    year, month int required the delivery month, for every call below
    as_of date required tick_size only: the day whose tick you want
    contracts float required rate_future_contract: the number of contracts, NN; in Rust, the fourth positional argument of RateFuture::for_contract(&template, year, month, contracts, price)
    traded_price float required rate_future_contract: the price you traded at, P0P_0; in Rust, the fifth positional argument
    short bool False rate_future_contract: book the short side
    convexity_adjustment float or None None rate_future_contract: a stated adjustment to the futures rate

    Defaults and limits

    • Periods: a three-month contract (CME SOFR, ICE SONIA, Eurex €STR and EURIBOR) covers the IMM quarter from the delivery month's third Wednesday to the third Wednesday three months later. A one-month contract covers the calendar month.
    • Last trading day and tick: both come from the exchange's rule, with the template's calendar standing in for the exchange's. Where the rule isn't sourced, the call returns None in Python.
    • Ticks narrow near expiry: CME three-month SOFR moves from half a basis point to a quarter of one about four months before its last trading day (from the business day after the Friday before the third Wednesday of the fourth month before the month trading ends). That's why the example's June tick changes between April and June.
    • Templates: the futures templates are listed in the template registry.

    See also

    • Source: crates/helixrs/src/instruments/rates.rs, crates/helixrs/src/statics/templates/registry.rs
    • Related pages:
      • How dates and conventions work, for why contracts are built this way.
      • Rate futures, for the futures rate with its convexity.
      • Dates and periods, for IMM dates.
      • Curve helpers, for a futures rung.

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