{"record":{"id":"a7a40b2f1bb05d06","repo":"nautechsystems/nautilus_trader","slug":"step-overflows-raw-quantity-units-for-volume-agg","errorCode":null,"errorMessage":"`step` overflows raw quantity units for volume aggregation","messagePattern":"`step` overflows raw quantity units for volume aggregation","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/data/src/aggregation.rs","lineNumber":1903,"sourceCode":"}\n\nfn is_below_min_size_decimal(size: Decimal, precision: u8) -> bool {\n    quantity_from_decimal(size, precision).raw == 0\n}\n\nfn min_size_decimal(precision: u8) -> Decimal {\n    Decimal::new(1, u32::from(precision))\n}\n\nfn quantity_from_decimal(size: Decimal, precision: u8) -> Quantity {\n    Quantity::from_decimal_dp(size, precision).expect(FAILED)\n}\n\n// Converts a bar specification step to raw quantity units with exact integer arithmetic\nfn step_as_quantity_raw(step: usize) -> QuantityRaw {\n    (FIXED_SCALAR as QuantityRaw)\n        .checked_mul(step as QuantityRaw)\n        .expect(\"`step` overflows raw quantity units for volume aggregation\")\n}\n\n/// Provider for vega per leg (option spreads). Returns `None` when greeks are unavailable.\npub trait VegaProvider {\n    /// Returns vega for the given leg instrument, or `None` if not available.\n    fn vega_for_leg(&self, instrument_id: InstrumentId) -> Option<f64>;\n}\n\n/// Rounder for spread bid/ask (e.g. tick scheme). When absent, raw prices are used with instrument precision.\npub trait SpreadPriceRounder {\n    /// Rounds raw bid/ask to valid prices (handles negative prices with mirroring when using tick scheme).\n    fn round_prices(&self, raw_bid: f64, raw_ask: f64, precision: u8) -> (Price, Price);\n}\n\n/// Vega provider that returns leg vegas from a map (e.g. populated from greeks cache).\n#[derive(Debug, Default)]\npub struct MapVegaProvider {\n    vegas: AHashMap<InstrumentId, f64>,","sourceCodeStart":1885,"sourceCodeEnd":1921,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/data/src/aggregation.rs#L1885-L1921","documentation":"`step_as_quantity_raw` converts a `BarAggregation` step (usize) into raw quantity units by multiplying FIXED_SCALAR by the step with `checked_mul`. If the product overflows QuantityRaw the `.expect` panics, because silently truncating an aggregation step would produce wrong bars.","triggerScenarios":"Configuring volume aggregation with an enormous step value (e.g. `BarAggregationSpec` step near usize::MAX or >= QuantityRaw::MAX / FIXED_SCALAR, i.e. above ~1.8e10 at i64 raw and 1e9 scalar).","commonSituations":"Typo or unit confusion in bar spec strings (step given in satoshis/wei-like raw units then multiplied again); automated config generation producing giant steps; passing a duration or nanosecond value where a quantity step is expected.","solutions":["Reduce the aggregation step to a realistic quantity value (step * 1e9 must fit in i64, so keep step below ~9.2e9)","Validate the step upper bound when parsing bar specifications and reject early with a clear message","Check config for double-scaling: don't pass already-raw quantity units as the step"],"exampleFix":"// before\nlet spec = BarAggregationSpec::new(InstrumentId::from(\"...\"), BarAggregation::Volume, step: usize::MAX, ...);\n// after\nassert!(step <= 9_000_000_000, \"volume aggregation step too large: {step}\");\nlet spec = BarAggregationSpec::new(id, BarAggregation::Volume, step, ...);","handlingStrategy":"validation","validationCode":"// Rust: bound the step so FIXED_SCALAR * step fits QuantityRaw\nconst MAX_STEP: usize = (i64::MAX as usize) / 1_000_000_000;\nassert!(step >= 1 && step <= MAX_STEP, \"invalid volume aggregation step: {step}\");","typeGuard":null,"tryCatchPattern":"let result = std::panic::catch_unwind(|| step_as_quantity_raw(step));","preventionTips":["Validate bar-spec steps when parsing configuration strings","Watch for double-scaling: pass quantity steps, not pre-scaled raw units","Limit steps to realistic trade-volume values"],"tags":["rust","panic","integer-overflow","config"],"backgroundTag":"value-out-of-range","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}