nautechsystems/nautilus_trader · error · anyhow::Error

No price available for {underlying_instrument_id}

Error message

No price available for {underlying_instrument_id}

What it means

`get_underlying_price` could not determine a price for the underlying instrument: there was no cached quote/price for the underlying and no cached futures-spread price either. The greeks calculation (e.g. `calculate_option_greeks`) requires the underlying spot price as input, so it aborts with this bail when no price source yields a value.

Source

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

        }

        // Only fall back to cached futures spread when the underlying is a future
        // (or absent from the cache, since the spread was explicitly cached).
        let is_future_or_absent = {
            let cache = self.cache.borrow();
            cache
                .instrument(underlying_instrument_id)
                .is_none_or(|inst| inst.instrument_class() == InstrumentClass::Future)
        };

        if is_future_or_absent
            && let Some(underlying_price) =
                self.get_cached_futures_spread_price(*underlying_instrument_id)
        {
            return Ok(underlying_price.as_f64());
        }

        anyhow::bail!("No price available for {underlying_instrument_id}")
    }

    /// Modifies delta, gamma, and vega based on beta weighting and percentage calculations.
    ///
    /// The beta weighting of delta and gamma follows this equation linking the returns of a stock x to the ones of an index I:
    /// (x - x0) / x0 = alpha + beta (I - I0) / I0 + epsilon
    ///
    /// beta can be obtained by linear regression of `stock_return` = alpha + beta `index_return`, it's equal to:
    /// beta = Covariance(`stock_returns`, `index_returns`) / Variance(`index_returns`)
    ///
    /// Considering alpha == 0:
    /// x = x0 + beta x0 / I0 (I-I0)
    /// I = I0 + 1 / beta I0 / x0 (x - x0)
    ///
    /// These two last equations explain the beta weighting below, considering the price of an option is V(x) and delta and gamma
    /// are the first and second derivatives respectively of V.
    ///
    /// Vega beta weighting follows the same change of variable with implied volatility and a volatility index.

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Subscribe to quotes for the underlying instrument and wait for at least one price before computing greeks
  2. Call `cache_futures_spread` to populate the spread-based fallback price
  3. Guard the calculation: check the cache for an underlying price and skip/log if absent instead of erroring

Example fix

// before
let greeks = greeks_calc.calculate_option_greeks(&option_id, ...)?;
// after
if let Some(price) = cache.price(&underlying_id, PriceType::Last) {
    let greeks = greeks_calc.calculate_option_greeks(&option_id, ...)?;
} else {
    tracing::warn!("no underlying price for {underlying_id}, skipping greeks");
}
Defensive patterns

Strategy: fallback

Validate before calling

fn underlying_price_available(cache: &Cache, underlying: &InstrumentId) -> bool {
    cache.price(underlying, PriceType::Last).is_some()
        || cache.quote(underlying).is_some()
}

Try / catch

match greeks_calc.calculate_option_greeks(&option_id, ...) {
    Ok(g) => g,
    Err(e) if e.to_string().starts_with("No price available for") => {
        tracing::warn!("{e}; skipping greeks update");
        return Ok(());
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling `calculate_option_greeks` when the underlying instrument has no cached quote/price (market data never subscribed, stale cache, or outside trading hours) and `get_cached_futures_spread_price` also returns None for that underlying.

Common situations: Running greeks calculations before subscribing to market data for the underlying; weekend/holiday sessions with no quotes; cash/margin accounts where the underlying trades on a different venue than cached; futures-spread fallback not yet populated via `cache_futures_spread`.

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/112981d2e9747814. Report an issue: GitHub.