nautechsystems/nautilus_trader · error

Invalid quote rate for pair {pair}, was {value}

Error message

Invalid quote rate for pair {pair}, was {value}

What it means

Raised while converting a map of exchange-rate quotes from `f64` to `Decimal` when `Decimal::from_f64(value)` returns None — i.e. the value is NaN, infinity, or otherwise not representable as a finite decimal. The error names the offending currency pair and the invalid value so the bad quote can be identified.

Source

Thrown at crates/common/src/python/xrate.rs:69

    let quotes_bid = f64_quotes_to_decimal(quotes_bid).map_err(to_pyvalue_err)?;
    let quotes_ask = f64_quotes_to_decimal(quotes_ask).map_err(to_pyvalue_err)?;

    get_exchange_rate(
        Ustr::from(from_currency),
        Ustr::from(to_currency),
        price_type,
        quotes_bid,
        quotes_ask,
    )
    .map_err(to_pyvalue_err)
}

fn f64_quotes_to_decimal(quotes: HashMap<String, f64>) -> anyhow::Result<AHashMap<Ustr, Decimal>> {
    quotes
        .into_iter()
        .map(|(pair, value)| {
            let rate = Decimal::from_f64(value).ok_or_else(|| {
                anyhow::anyhow!("Invalid quote rate for pair {pair}, was {value}")
            })?;
            Ok((Ustr::from(&pair), rate))
        })
        .collect()
}

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Identify the pair named in the message and fix the upstream source so it returns a finite number instead of NaN/inf.
  2. Filter or sanitize quotes before the conversion: drop or default any pair whose value is not finite (`math.isfinite`).
  3. Check the rate calculation for division by zero (e.g. inverse-rate computation with a zero base).
  4. Ensure the exchange-rate provider is configured with data covering the requested pairs and session times.

Example fix

# before
quotes = provider.get_quotes(pairs)  # may contain NaN
decimals = f64_quotes_to_decimal(quotes)

# after
import math
quotes = {p: v for p, v in provider.get_quotes(pairs).items() if math.isfinite(v)}
if len(quotes) != len(pairs):
    raise ValueError(f"Missing finite quotes for: {pairs - quotes.keys()}")
decimals = f64_quotes_to_decimal(quotes)
Defensive patterns

Strategy: validation

Validate before calling

import math
assert all(math.isfinite(v) for v in quotes.values()), 'quotes contain NaN/inf'

Type guard

def all_finite(quotes: dict) -> bool:
    return all(isinstance(v, float) and math.isfinite(v) for v in quotes.values())

Try / catch

match py_get_exchange_rate(...).await {
    Err(e) if e.to_string().contains("Invalid quote rate") => {
        // sanitize/refresh quotes for the named pair and retry once
    }
    other => other?,
}

Prevention

When it happens

Trigger: Calling `py_get_exchange_rate`, which passes its quotes dict through `f64_quotes_to_decimal` (crates/common/src/python/xrate.rs:69), when any quote value for a pair is NaN, +inf, or -inf — typically produced upstream by division by zero, missing data encoded as NaN, or a misconfigured rate provider.

Common situations: Currency conversion lookups where an exchange-rate provider returns NaN for a pair with no data (illiquid pairs, weekend gaps), custom rate resolvers computing 0/0, or bad cached/stale quote tables containing infinities.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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