nautechsystems/nautilus_trader · error

Cannot calculate price impact, the spot price before is not

Error message

Cannot calculate price impact, the spot price before is not set

What it means

SwapTradeInfo::get_price_impact_bps computes price impact as (spot_price - spot_price_before)/spot_price_before * 10_000 bps. The calculation requires the prior spot price to be a positive, set Price; if spot_price_before is zero/unset the library bails instead of dividing by zero or returning a meaningless impact. The caller must supply a valid pre-swap spot price.

Source

Thrown at crates/model/src/defi/data/swap_trade_info.rs:100

    /// excluding fees. This is the percentage change in spot price from
    /// before to after the swap.
    ///
    /// # Returns
    /// Price impact in basis points (10000 = 100%)
    ///
    /// # Errors
    ///
    /// Returns an error if the spot price before the swap is not set or is zero.
    pub fn get_price_impact_bps(&self) -> anyhow::Result<u32> {
        if let Some(spot_price_before) = self.spot_price_before {
            Self::check_spot_price_before(spot_price_before, PriceMetric::Impact)?;
            let price_change = self.spot_price - spot_price_before;
            let price_impact =
                (price_change.as_decimal() / spot_price_before.as_decimal()).abs() * dec!(10_000);

            Ok(price_impact.round().to_u32().unwrap_or(0))
        } else {
            anyhow::bail!("Cannot calculate price impact, the spot price before is not set");
        }
    }

    /// Calculates slippage in basis points (requires token references for decimal adjustment).
    ///
    /// Slippage includes both price impact and fees, representing the total
    /// deviation from the spot price before the swap. This measures the total
    /// cost to the trader.
    ///
    /// # Returns
    /// Total slippage in basis points (10000 = 100%)
    ///
    /// # Errors
    ///
    /// Returns an error if the spot price before the swap is not set or is zero.
    pub fn get_slippage_bps(&self) -> anyhow::Result<u32> {
        if let Some(spot_price_before) = self.spot_price_before {
            Self::check_spot_price_before(spot_price_before, PriceMetric::Slippage)?;

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Compute the pre-swap spot price from the pool's sqrt_price_x96 before the swap and pass it in
  2. Guard the call: only invoke get_price_impact_bps when spot_price_before > 0
  3. If no prior price exists, treat impact as unavailable (skip or record None) rather than passing zero
  4. Verify the SwapTradeInfo builder/construction path sets spot_price_before from actual event data

Example fix

// before
let impact = swap.get_price_impact_bps(Price::zero())?;
// after
if spot_before.is_zero() {
    return Ok(None); // impact not computable
}
let impact = swap.get_price_impact_bps(spot_before)?;
Defensive patterns

Strategy: validation

Validate before calling

if spot_price_before.is_zero() || spot_price_before.as_decimal() <= dec!(0) {
    // cannot compute impact; skip or record None
}

Type guard

fn has_valid_spot_price_before(p: &Price) -> bool { !p.is_zero() && p.as_decimal() > rust_decimal::Decimal::ZERO }

Try / catch

match swap.get_price_impact_bps(spot_before) {
    Ok(impact) => Some(impact),
    Err(e) if e.to_string().contains("spot price before is not set") => None,
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling get_price_impact_bps with a spot_price_before argument equal to zero (e.g. Price::zero or default), typically when the pre-trade price was never captured from the swap's sqrt price data.

Common situations: Backtesting code that constructs SwapTradeInfo without computing the pre-swap price; pools where the previous price was never recorded; default-initialized Price fields passing through; unit tests probing the zero guard.

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/91c1e86a97c9f791. Report an issue: GitHub.