nautechsystems/nautilus_trader · error · anyhow::Error

Cannot cache futures spread: missing option price for {put_i

Error message

Cannot cache futures spread: missing option price for {put_instrument_id}

What it means

Same flow as the call-side error: `cache_futures_spread` fetches the PUT option's price via `get_price`, and bails with this error when the cache holds no price for the put instrument. Both legs (call and put) are required to derive the synthetic futures spread.

Source

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

        if call_instrument.expiration_ns() != put_instrument.expiration_ns() {
            anyhow::bail!(
                "Cannot cache futures spread: expiration dates differ call_instrument_id={call_instrument_id} put_instrument_id={put_instrument_id}"
            );
        }

        let reference_future_price = self.get_price_object(&futures_instrument_id).ok_or_else(|| {
            anyhow::anyhow!(
                "Cannot cache futures spread: no reference futures price for {futures_instrument_id}"
            )
        })?;
        let call_price = self.get_price(&call_instrument_id).ok_or_else(|| {
            anyhow::anyhow!(
                "Cannot cache futures spread: missing option price for {call_instrument_id}"
            )
        })?;
        let put_price = self.get_price(&put_instrument_id).ok_or_else(|| {
            anyhow::anyhow!(
                "Cannot cache futures spread: missing option price for {put_instrument_id}"
            )
        })?;

        let underlying_instrument_id =
            InstrumentId::from(format!("{call_underlying}.{}", call_instrument_id.venue));

        // Reject if the underlying is present in cache but is not a future
        {
            let cache = self.cache.borrow();
            if let Some(underlying) = cache.instrument(&underlying_instrument_id)
                && underlying.instrument_class() != InstrumentClass::Future
            {
                anyhow::bail!(
                    "Cannot cache futures spread: underlying {underlying_instrument_id} is not a futures contract"
                );
            }
        }

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Subscribe to quotes/trades for the put instrument and wait for a price before calling.
  2. Verify the put instrument ID encodes the correct strike/expiry/venue.
  3. Skip strikes lacking put quotes or fall back to a model price; only cache spreads for fully quoted pairs.
  4. Check contract activity status/expiry before calling.

Example fix

// before
engine.cache_futures_spread(&fut_id, &call_id, &put_id, &underlying)?;
// after
match engine.cache_futures_spread(&fut_id, &call_id, &put_id, &underlying) {
    Ok(()) => {}
    Err(e) if e.to_string().contains(&put_id.to_string()) => warn!("no put price for {put_id}; skipping"),
    Err(e) => return Err(e),
}
Defensive patterns

Strategy: fallback

Validate before calling

// Rust: check put leg before computing the spread
if cache.price(&put_instrument_id).is_none() {
    return Ok(()); // skip strikes without put quotes
}

Type guard

fn price_or_skip(cache: &Cache, id: &InstrumentId) -> Option<f64> { cache.price(id) }

Try / catch

match engine.cache_futures_spread(&fut_id, &call_id, &put_id, &u) {
    Err(e) if e.to_string().contains(&put_id.to_string()) => debug!("no put price {put_id}"),
    other => other?,
}

Prevention

When it happens

Trigger: cache_futures_spread called when the put option instrument has no cached price — no subscription for the put, no quotes at that strike, wrong/swap-corrected put ID, or the put contract has expired.

Common situations: Sparse put quotes on far strikes; subscribing only calls for a synthetic-short strategy; instrument-ID construction mistakes (wrong expiry/strike encoded in the put symbol); pre-market hours with empty option books.

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/131634716bca3d0e. Report an issue: GitHub.