nautechsystems/nautilus_trader · error
Continuous-future adjustment exceeds PriceRaw range
Error message
Continuous-future adjustment exceeds PriceRaw range
What it means
After successfully scaling the adjustment to i128 fixed units, `set_adjustment` converts it to `PriceRaw` with `try_into().expect(...)`. On non-high-precision builds PriceRaw is i64, so an adjustment magnitude beyond i64 raw units panics.
Source
Thrown at crates/data/src/aggregation.rs:236
return;
}
// Spread mode: scale the Decimal offset to FIXED_PRECISION once so the hot path
// can add it straight onto `price.raw`. Signed PriceRaw supports negatives, so
// backward-spread offsets that push prices below zero remain representable.
self.adjustment_is_ratio = false;
let exponent = -(adjustment.scale() as i8);
let raw_i128 =
mantissa_exponent_to_fixed_i128(adjustment.mantissa(), exponent, FIXED_PRECISION)
.expect("Failed to scale continuous-future adjustment to fixed precision");
#[allow(
clippy::useless_conversion,
reason = "i128 to PriceRaw is real when not high-precision"
)]
let raw: PriceRaw = raw_i128
.try_into()
.expect("Continuous-future adjustment exceeds PriceRaw range");
self.adjustment_raw = raw;
self.adjustment_active = self.adjustment_raw != 0;
}
fn apply_adjustment_to_price(&self, price: Price) -> Price {
if !self.adjustment_active {
return price;
}
if self.adjustment_is_ratio {
// Multiply in double; `Price::new` rounds to the target precision.
// Float can shift 1 ULP for high-precision raws (spread mode is exact).
return Price::new(price.as_f64() * self.adjustment_ratio, price.precision);
}
// Spread: signed raw addition.
Price::from_raw(price.raw + self.adjustment_raw, price.precision)View on GitHub (pinned to 18893faf8b)
Solutions
- Sanity-check/clamp the adjustment magnitude (e.g. reject |adj| beyond a plausible price bound) before calling `set_adjustment`
- Fix the upstream scaling so the mantissa is in real price units, not scaled by an extra power of ten
- Compile/use the high-precision build if legitimately large values are required
- Add a validation step at ingestion that drops or flags quotes with out-of-range adjustment factors
Example fix
// before
builder.set_adjustment(raw_index_price_scaled); // panics if beyond PriceRaw
// after
let adj_f = raw_index_price_scaled.as_f64();
assert!(adj_f.abs() < 1.0e9, "implausible adjustment: {adj_f}");
builder.set_adjustment(Price::new(adj_f, adjustment_price.precision())); Defensive patterns
Strategy: validation
Validate before calling
// Rust: sanity-bound the adjustment before use
assert!(adj.as_f64().abs() < 1.0e9, "adjustment out of plausible range: {}", adj.as_f64()); Try / catch
let result = std::panic::catch_unwind(|| builder.set_adjustment(adj));
Prevention
- Validate market-data magnitudes at ingestion (drop absurd quotes)
- Verify unit scaling of upstream feeds (extra 10^k factors)
- Use the high-precision build if large values are legitimate
When it happens
Trigger: Calling `set_adjustment` with an adjustment whose fixed-precision i128 value does not fit in PriceRaw (i64), e.g. an adjustment of billions of dollars expressed at 9-decimal fixed precision.
Common situations: Spread adjustments computed from mis-scaled feeds (mantissa multiplied by an extra 10^k); corrupted market data with absurd price levels; accidentally passing a cumulative index level instead of a per-step offset.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- Failed to scale continuous-future adjustment to fixed precis
- DurationNanos overflow in from_micros
- {e}
- MBO delta index overflow
- window index fits u32
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/e33a7101822179b3.
Report an issue: GitHub.