{"record":{"id":"d70de8ad3640ceb8","repo":"nautechsystems/nautilus_trader","slug":"fx-symbol-must-be-at-least-6-characters-symbol","errorCode":null,"errorMessage":"FX symbol must be at least 6 characters: {symbol}","messagePattern":"FX symbol must be at least 6 characters: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/backtest/src/modules/fx_rollover.rs","lineNumber":163,"sourceCode":"\n        Ok(Self { rates })\n    }\n\n    /// Calculates the overnight interest rate differential for a currency pair.\n    ///\n    /// Returns `(base_rate - quote_rate) / 365 / 100` as a daily decimal rate.\n    ///\n    /// # Errors\n    ///\n    /// Returns an error if rate data is missing for either currency.\n    pub fn calc_overnight_rate(\n        &self,\n        instrument_id: InstrumentId,\n        date: Date,\n    ) -> anyhow::Result<f64> {\n        let symbol = instrument_id.symbol.as_str();\n        if symbol.len() < 6 {\n            anyhow::bail!(\"FX symbol must be at least 6 characters: {symbol}\");\n        }\n\n        let base_currency = &symbol[..3];\n        let quote_currency = &symbol[symbol.len() - 3..];\n\n        let base_rate = self.lookup_rate(base_currency, date)?;\n        let quote_rate = self.lookup_rate(quote_currency, date)?;\n\n        Ok((base_rate - quote_rate) / 365.0 / 100.0)\n    }\n\n    fn lookup_rate(&self, currency: &str, date: Date) -> anyhow::Result<f64> {\n        let currency_rates = self\n            .rates\n            .get(currency)\n            .ok_or_else(|| anyhow::anyhow!(\"No rate data for currency {currency}\"))?;\n\n        // Try monthly key first","sourceCodeStart":145,"sourceCodeEnd":181,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/backtest/src/modules/fx_rollover.rs#L145-L181","documentation":"Format guard in FxRolloverInterestRate::calc_overnight_rate: FX instrument symbols are assumed to be 6-character pairs (e.g. EURUSD) so base/quote currencies can be split; shorter symbols cannot yield two 3-letter currency codes.","triggerScenarios":"Thrown at crates/backtest/src/modules/fx_rollover.rs:163 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Use a standard 6-character FX pair symbol such as EURUSD","Skip FX rollover for instruments that are not plain currency pairs"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}