{"record":{"id":"cd0d638bef63c4eb","repo":"nautechsystems/nautilus_trader","slug":"fill-group-average-price-is-not-representable","errorCode":null,"errorMessage":"fill group average price is not representable","messagePattern":"fill group average price is not representable","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/live/src/execution/manager.rs","lineNumber":1336,"sourceCode":"                    })?;\n\n                let notional = notional.checked_add(fill_notional).ok_or_else(|| {\n                    anyhow::anyhow!(\"fill notional overflow while aggregating fill group\")\n                })?;\n\n                Ok::<_, anyhow::Error>((quantity, notional))\n            },\n        )?;\n\n        anyhow::ensure!(\n            quantity > Decimal::ZERO,\n            \"fill group quantity is not positive\"\n        );\n\n        let order_qty = Quantity::from_decimal_dp(quantity, instrument.size_precision())?;\n        let avg_px = notional\n            .checked_div(quantity)\n            .ok_or_else(|| anyhow::anyhow!(\"fill group average price is not representable\"))?;\n\n        let ts_accepted = fills\n            .iter()\n            .map(|fill| fill.ts_event)\n            .min()\n            .expect(\"non-empty fill group\");\n\n        let ts_last = fills\n            .iter()\n            .map(|fill| fill.ts_event)\n            .max()\n            .expect(\"non-empty fill group\");\n\n        let ts_init = fills\n            .iter()\n            .map(|fill| fill.ts_init)\n            .max()\n            .expect(\"non-empty fill group\");","sourceCodeStart":1318,"sourceCodeEnd":1354,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/live/src/execution/manager.rs#L1318-L1354","documentation":"After computing the aggregate quantity and notional, the manager derives the average price as `notional.checked_div(quantity)` and throws this error if the division fails (overflow or a Decimal arithmetic edge). It means the fill group's average price cannot be represented in the internal fixed-precision Decimal. In practice this follows extreme notional/quantity magnitudes rather than normal trading values.","triggerScenarios":"Aggregating a fill group where notional divided by quantity exceeds Decimal capacity or hits a Decimal arithmetic edge — e.g. extremely small quantity with enormous notional, or near-max notional accumulated in the prior fold steps.","commonSituations":"Downstream symptom of earlier bad fill data: wrongly scaled prices/quantities from an adapter, corrupted fill records, or aggregating fills with astronomically large notional and tiny quantity; precision mismatch in the instrument definition.","solutions":["Check the group's total notional and quantity values — an extreme ratio indicates malformed fills","Fix adapter price/quantity scaling so per-fill values are within realistic instrument bounds","Validate fills before aggregation (reject fills whose qty*px is implausible for the instrument)","If legitimate, compute the average price incrementally with explicit precision handling and report the Decimal limitation upstream"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"fn average_price_representable(fills: &[Fill]) -> bool {\n    fills.iter().try_fold((Decimal::ZERO, Decimal::ZERO), |(q, n), f| {\n        let fq = f.last_qty.as_decimal();\n        let fn_ = fq.checked_mul(f.last_px.as_decimal())?;\n        Some((q.checked_add(fq)?, n.checked_add(fn_)?))\n    })\n    .and_then(|(q, n)| if q > Decimal::ZERO { n.checked_div(q) } else { None })\n    .is_some()\n}\n","typeGuard":"fn avg_px_computable(fills: &[Fill]) -> bool {\n    let qty: Decimal = fills.iter().map(|f| f.last_qty.as_decimal()).sum();\n    qty > Decimal::ZERO\n        && fills.iter().try_fold(Decimal::ZERO, |acc, f| {\n            acc.checked_add(f.last_qty.as_decimal().checked_mul(f.last_px.as_decimal())?)\n        })\n        .and_then(|n| n.checked_div(qty))\n        .is_some()\n}\n","tryCatchPattern":"match manager.aggregate_fill_group(&fills) {\n    Ok(r) => handle(r),\n    Err(e) if e.to_string().contains(\"average price is not representable\") => {\n        log::error!(\"avg px not representable: {e}\");\n        quarantine_fills(&fills);\n    }\n    Err(e) => return Err(e),\n}\n","preventionTips":["Pre-validate that group quantity and notional are within realistic instrument bounds before aggregation","Fix adapter price/quantity scaling so magnitudes stay in normal ranges","Reject fills whose implied notional-to-quantity ratio is implausible for the instrument","Handle upstream overflow errors (4135-4137) first; this error usually follows bad fill data"],"tags":["decimal-overflow","arithmetic","execution","average-price"],"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"}