{"record":{"id":"0ea9e0944c6fc60f","repo":"nautechsystems/nautilus_trader","slug":"trade-info-is-not-initialized-please-call-calcula","errorCode":null,"errorMessage":"Trade info is not initialized. Please call calculate_trade_info() first.","messagePattern":"Trade info is not initialized\\. Please call calculate_trade_info\\(\\) first\\.","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/model/src/defi/pool_analysis/quote.rs","lineNumber":116,"sourceCode":"            instrument_id,\n            amount0,\n            amount1,\n            sqrt_price_before_x96,\n            sqrt_price_after_x96,\n            tick_before,\n            tick_after,\n            liquidity_after,\n            fee_growth_global_after,\n            lp_fee,\n            protocol_fee,\n            crossed_ticks,\n            trade_info: None,\n        }\n    }\n\n    fn check_if_trade_info_initialized(&self) -> anyhow::Result<&SwapTradeInfo> {\n        if self.trade_info.is_none() {\n            anyhow::bail!(\n                \"Trade info is not initialized. Please call calculate_trade_info() first.\"\n            );\n        }\n\n        Ok(self.trade_info.as_ref().unwrap())\n    }\n\n    /// Calculates and populates the `trade_info` field with market-oriented trade data.\n    ///\n    /// This method transforms the raw swap quote data (token0/token1 amounts, sqrt prices)\n    /// into standard trading terminology (base/quote, order side, execution price).\n    /// The computation uses the `sqrt_price_before_x96` to calculate price impact and slippage.\n    ///\n    /// # Errors\n    ///\n    /// Returns an error if trade info computation or price calculations fail.\n    pub fn calculate_trade_info(&mut self, token0: &Token, token1: &Token) -> anyhow::Result<()> {\n        let trade_info_calculator = SwapTradeInfoCalculator::new(","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/model/src/defi/pool_analysis/quote.rs#L98-L134","documentation":"This error is thrown by `check_if_trade_info_initialized` on the quote wrapper when the internal `trade_info: Option<SwapTradeInfo>` is still `None`. Metrics such as price impact and slippage depend on precomputed swap trade info, so the library forces the caller to call `calculate_trade_info()` (which populates the field) before querying any metric.","triggerScenarios":"Calling `get_price_impact_bps()` or `get_slippage_bps()` (and their dependents like `validate_slippage_tolerance`) on a quote created via the constructor that sets `trade_info: None`, without first invoking `calculate_trade_info()`.","commonSituations":"Constructing a quote object and immediately reading metrics in exploratory code; refactoring where a `calculate_trade_info()` call was dropped; conditionally calculating trade info on one code path but unconditionally reading metrics on another.","solutions":["Call `quote.calculate_trade_info()` once after construction, before any metric getter.","Ensure all code paths that read metrics first pass through trade-info initialization.","Consider constructing the quote via an API that computes trade info eagerly, if available.","In async/event-driven code, verify initialization order between quote creation and metric consumption."],"exampleFix":"// before\nlet mut quote = Quote::new(pool, amount_in);\nlet impact = quote.get_price_impact_bps()?;\n// after\nlet mut quote = Quote::new(pool, amount_in);\nquote.calculate_trade_info()?;\nlet impact = quote.get_price_impact_bps()?;","handlingStrategy":"validation","validationCode":"// ensure initialization before reading metrics\nquote.calculate_trade_info()?;\n// now get_price_impact_bps()/get_slippage_bps() are safe to call","typeGuard":"fn trade_info_ready(quote: &Quote) -> bool {\n    !quote.trade_info.is_none() // or expose an is_initialized() helper\n}","tryCatchPattern":"let impact = quote.get_price_impact_bps().map_err(|e| {\n    if e.to_string().contains(\"not initialized\") {\n        // initialize and retry once\n    }\n    e\n})?;","preventionTips":["Treat calculate_trade_info() as a mandatory constructor step; wrap quote creation in a factory that calls it.","Never expose a half-initialized quote to metric-reading code paths.","Add a debug assertion/log when reading metrics on a freshly constructed quote.","Keep a single code path for quote creation so initialization cannot be skipped."],"tags":["defi","state","initialization","quote"],"backgroundTag":"invalid-state-transition","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"}