nautechsystems/nautilus_trader · error · anyhow::Error

Python on_historical_index_prices failed: {e}

Error message

Python on_historical_index_prices failed: {e}

What it means

This error wraps any failure while the Rust engine invokes the strategy's Python `on_historical_index_prices` callback with a batch of IndexPriceUpdate objects. A failed Rust→Python conversion or an exception raised inside the user's Python handler is re-raised as `Python on_historical_index_prices failed: {e}`. This is the last of the historical-data callback wrappers before the impl block ends.

Source

Thrown at crates/trading/src/python/strategy.rs:1265

            .map_err(|e| anyhow::anyhow!("Python on_historical_funding_rates failed: {e}"))
    }

    fn on_historical_bars(&mut self, bars: &[Bar]) -> anyhow::Result<()> {
        self.dispatch_on_historical_bars(bars.to_vec())
            .map_err(|e| anyhow::anyhow!("Python on_historical_bars failed: {e}"))
    }

    fn on_historical_mark_prices(&mut self, mark_prices: &[MarkPriceUpdate]) -> anyhow::Result<()> {
        self.dispatch_on_historical_mark_prices(mark_prices.to_vec())
            .map_err(|e| anyhow::anyhow!("Python on_historical_mark_prices failed: {e}"))
    }

    fn on_historical_index_prices(
        &mut self,
        index_prices: &[IndexPriceUpdate],
    ) -> anyhow::Result<()> {
        self.dispatch_on_historical_index_prices(index_prices.to_vec())
            .map_err(|e| anyhow::anyhow!("Python on_historical_index_prices failed: {e}"))
    }
}

fn state_to_pydict(py: Python<'_>, state: &IndexMap<String, Vec<u8>>) -> PyResult<Py<PyDict>> {
    let py_state = PyDict::new(py);
    for (key, value) in state {
        py_state.set_item(key, PyBytes::new(py, value))?;
    }
    Ok(py_state.unbind())
}

fn pydict_to_state(state: &Bound<'_, PyDict>) -> PyResult<IndexMap<String, Vec<u8>>> {
    let mut rust_state = IndexMap::with_capacity(state.len());
    for (key, value) in state.iter() {
        rust_state.insert(key.extract()?, value.extract()?);
    }
    Ok(rust_state)
}

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Inspect `{e}` for the underlying Python exception in your `on_historical_index_prices` override and fix the handler.
  2. Confirm the override signature `def on_historical_index_prices(self, index_prices)` is exact.
  3. Handle empty update lists explicitly.
  4. Ensure any objects used in the handler accept the IndexPriceUpdate values passed.

Example fix

// before
def on_historical_index_prices(self, index_prices):
    avg = sum(ip.index_price for ip in index_prices) / len(index_prices)  # ZeroDivisionError
// after
def on_historical_index_prices(self, index_prices):
    if not index_prices:
        return None
    return sum(ip.index_price for ip in index_prices) / len(index_prices)
Defensive patterns

Strategy: try-catch

Validate before calling

def _safe_on_historical_index_prices(self, index_prices):
    if index_prices is None or len(index_prices) == 0:
        return
    assert all(hasattr(ip, 'index_price') for ip in index_prices)

Type guard

def is_index_price_update_list(obj):
    return isinstance(obj, (list, tuple)) and all(hasattr(ip, 'index_price') for ip in obj)

Try / catch

def on_historical_index_prices(self, index_prices):
    try:
        self._update_index_prices(index_prices)
    except Exception as e:
        self.log.error(f'Failed processing index prices: {e}', exc_info=True)

Prevention

When it happens

Trigger: Historical index-price data is delivered to a Python strategy whose `on_historical_index_prices` override raises an exception, or whose IndexPriceUpdate objects cannot be converted to Python.

Common situations: Handler code referencing wrong attribute names on index price updates; arithmetic on empty lists; mis-typed expectations of the update objects; exceptions from user indicators inside the override.

Understand the failure class

Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.

Related errors


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