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
- Compute the pre-swap spot price from the pool's sqrt_price_x96 before the swap and pass it in
- Guard the call: only invoke get_price_impact_bps when spot_price_before > 0
- If no prior price exists, treat impact as unavailable (skip or record None) rather than passing zero
- 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
- Always capture the pre-swap spot price from the pool's sqrt price before building SwapTradeInfo
- Never pass default/zero Price values into bps calculations
- Return Option/Result for impact when the pre-price may be unavailable
- Unit-test the zero-price path in swap analytics
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
- Cannot calculate slippage, the spot price before is not set
- Cannot calculate execution price with zero amounts
- Cannot decode inverted price from zero sqrt_price_x96
- Price overflow: {price_raw} exceeds maximum valid raw price
- Router allowance {allowance} is below the swap amount {} for
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/91c1e86a97c9f791.
Report an issue: GitHub.