nautechsystems/nautilus_trader · error

Python on_funding_rate failed: {e}

Error message

Python on_funding_rate failed: {e}

What it means

This error wraps any Python exception raised inside the actor's `on_funding_rate` callback when a `FundingRateUpdate` is dispatched to the Python subclass. The Rust `PyDataActor` calls the Python method via `call_method1` and converts the `PyErr` into an anyhow error with this message. The failure originates in the user's Python override or the Rust-to-Python data conversion.

Source

Thrown at crates/common/src/python/actor.rs:1143

    fn on_book(&mut self, order_book: &OrderBook) -> anyhow::Result<()> {
        self.dispatch_on_book(order_book)
            .map_err(|e| anyhow::anyhow!("Python on_book failed: {e}"))
    }

    fn on_mark_price(&mut self, mark_price: &MarkPriceUpdate) -> anyhow::Result<()> {
        self.dispatch_on_mark_price(*mark_price)
            .map_err(|e| anyhow::anyhow!("Python on_mark_price failed: {e}"))
    }

    fn on_index_price(&mut self, index_price: &IndexPriceUpdate) -> anyhow::Result<()> {
        self.dispatch_on_index_price(*index_price)
            .map_err(|e| anyhow::anyhow!("Python on_index_price failed: {e}"))
    }

    fn on_funding_rate(&mut self, funding_rate: &FundingRateUpdate) -> anyhow::Result<()> {
        self.dispatch_on_funding_rate(*funding_rate)
            .map_err(|e| anyhow::anyhow!("Python on_funding_rate failed: {e}"))
    }

    fn on_instrument_status(&mut self, data: &InstrumentStatus) -> anyhow::Result<()> {
        self.dispatch_on_instrument_status(*data)
            .map_err(|e| anyhow::anyhow!("Python on_instrument_status failed: {e}"))
    }

    fn on_instrument_close(&mut self, update: &InstrumentClose) -> anyhow::Result<()> {
        self.dispatch_on_instrument_close(*update)
            .map_err(|e| anyhow::anyhow!("Python on_instrument_close failed: {e}"))
    }

    fn on_option_greeks(&mut self, greeks: &OptionGreeks) -> anyhow::Result<()> {
        self.dispatch_on_option_greeks(*greeks)
            .map_err(|e| anyhow::anyhow!("Python on_option_greeks failed: {e}"))
    }

    fn on_option_chain(&mut self, slice: &OptionChainSlice) -> anyhow::Result<()> {

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Read the appended Python traceback after 'Python on_funding_rate failed:' to find the raising line.
  2. Initialize funding state in on_start so the first update never references uninitialized structures.
  3. Check field names/types of FundingRateUpdate against your installed nautilus_trader version.
  4. Use Decimal consistently for funding arithmetic to avoid type errors.

Example fix

// before
def on_funding_rate(self, funding_rate):
    cost = self.position * funding_rate.rate

// after
def on_funding_rate(self, funding_rate):
    if funding_rate.rate is None or self.position is None:
        return
    cost = Decimal(str(self.position)) * funding_rate.rate
Defensive patterns

Strategy: try-catch

Validate before calling

from decimal import Decimal
if funding_rate.rate is None:
    return
rate = Decimal(str(funding_rate.rate))

Type guard

def is_valid_funding_rate(update):
    r = getattr(update, "rate", None)
    return r is not None and isinstance(r, (int, float, Decimal))

Try / catch

def on_funding_rate(self, funding_rate):
    try:
        self._accrue_funding(funding_rate)
    except Exception as e:
        self.log.error(f"on_funding_rate failed: {e}", exc_info=True)

Prevention

When it happens

Trigger: Any exception raised by the user's `on_funding_rate(self, funding_rate)` override — e.g. Decimal/float mixing when computing funding cost, missing dict entry for the instrument's funding history, or a helper that raises on the first funding-rate update after startup.

Common situations: Perpetual-futures strategies computing carry positions that hit a funding update before the position dict is initialized; version upgrades where FundingRateUpdate field names or types changed; funding rates arriving as Decimal where the handler assumed float.

Related errors


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