nautechsystems/nautilus_trader · error · anyhow::Error

Cannot cache futures spread: no reference futures instrument

Error message

Cannot cache futures spread: no reference futures instrument for {futures_instrument_id}

What it means

GreeksCalculator::cache_futures_spread derives a futures spread from a call/put option pair against a reference future. Before doing any math it looks up the reference future instrument in the Cache; if the Cache has no instrument registered under futures_instrument_id it bails with this error. The library requires all three instruments (call, put, reference future) to be loaded into the Cache before spread caching can run.

Source

Thrown at crates/common/src/greeks.rs:1066

    ) -> anyhow::Result<Price> {
        let cache = self.cache.borrow();
        let call_instrument = cache.instrument(&call_instrument_id).cloned();
        let put_instrument = cache.instrument(&put_instrument_id).cloned();
        let reference_future_instrument = cache.instrument(&futures_instrument_id).cloned();
        drop(cache);

        let Some(call_instrument) = call_instrument else {
            anyhow::bail!(
                "Cannot cache futures spread: missing option instrument {call_instrument_id}"
            );
        };
        let Some(put_instrument) = put_instrument else {
            anyhow::bail!(
                "Cannot cache futures spread: missing option instrument {put_instrument_id}"
            );
        };
        let Some(reference_future_instrument) = reference_future_instrument else {
            anyhow::bail!(
                "Cannot cache futures spread: no reference futures instrument for {futures_instrument_id}"
            );
        };

        if call_instrument.instrument_class() != InstrumentClass::Option
            || put_instrument.instrument_class() != InstrumentClass::Option
        {
            anyhow::bail!(
                "Cannot cache futures spread: non-option instruments provided call_instrument_id={call_instrument_id} put_instrument_id={put_instrument_id}"
            );
        }

        if call_instrument.option_kind() != Some(OptionKind::Call)
            || put_instrument.option_kind() != Some(OptionKind::Put)
        {
            anyhow::bail!(
                "Cannot cache futures spread: expected call/put pair call_instrument_id={call_instrument_id} put_instrument_id={put_instrument_id}"
            );

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Ensure the reference future instrument is added to the Cache (cache.add_instrument) before calling cache_futures_spread; wait for the instrument-definition response from the data client.
  2. Verify futures_instrument_id matches an instrument actually defined on the venue (symbol, expiry, venue code all correct).
  3. If the future is intentionally unavailable, derive the underlying ID differently or skip spread caching and handle the Err instead of unwrapping.

Example fix

// before
let price = greeks.cache_futures_spread(call_id, put_id, future_id)?;
// after
if cache.instrument(&future_id).is_none() {
    // request/await the future's instrument definition first
    client.request_instrument(&future_id);
    return Ok(None);
}
let price = greeks.cache_futures_spread(call_id, put_id, future_id)?;
Defensive patterns

Strategy: validation

Validate before calling

// rust
fn have_reference_future(cache: &Cache, future_id: &InstrumentId) -> bool {
    cache.instrument(future_id).is_some()
}
if !have_reference_future(&cache, &future_id) {
    client.request_instrument(&future_id); // load definition first
    return Ok(None);
}

Type guard

fn reference_future(cache: &Cache, id: &InstrumentId) -> Option<&InstrumentAny> {
    cache.instrument(id)
}

Try / catch

match greeks.cache_futures_spread(call_id, put_id, future_id) {
    Ok(price) => use(price),
    Err(e) if e.to_string().contains("no reference futures instrument") => request_future_definition(),
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling cache_futures_spread(call_id, put_id, futures_id) where futures_id was never added to the Cache via add_instrument — e.g. the future definition was not received from the venue/adapter before the options, or the ID is misspelled or belongs to a different venue.

Common situations: Subscribing to option greeks before the data client has downloaded the futures instrument definitions; passing a synthetic or truncated instrument ID (wrong symbol/expiry in the future's ID); switching adapters where only the options were loaded into cache.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/bc6a72b655cb87db. Report an issue: GitHub.