{"record":{"id":"77ba0e2f98036cd9","repo":"nautechsystems/nautilus_trader","slug":"starting-balances-must-be-provided","errorCode":null,"errorMessage":"Starting balances must be provided","messagePattern":"Starting balances must be provided","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/backtest/src/exchange.rs","lineNumber":219,"sourceCode":"            .finish_non_exhaustive()\n    }\n}\n\nimpl SimulatedExchange {\n    /// Creates a new [`SimulatedExchange`] instance from a venue configuration.\n    ///\n    /// # Errors\n    ///\n    /// Returns an error if:\n    /// - `starting_balances` is empty.\n    /// - `base_currency` is `Some` but `starting_balances` contains multiple currencies.\n    pub fn new(\n        config: SimulatedVenueConfig,\n        cache: Rc<RefCell<Cache>>,\n        clock: Rc<RefCell<dyn Clock>>,\n    ) -> anyhow::Result<Self> {\n        if config.starting_balances.is_empty() {\n            anyhow::bail!(\"Starting balances must be provided\")\n        }\n\n        if config.base_currency.is_some() && config.starting_balances.len() > 1 {\n            anyhow::bail!(\"single-currency account has multiple starting currencies\")\n        }\n\n        let default_leverage = config.default_leverage.unwrap_or_else(|| {\n            if config.account_type == AccountType::Margin {\n                Decimal::from(10)\n            } else {\n                Decimal::from(1)\n            }\n        });\n\n        Ok(Self {\n            id: config.venue,\n            oms_type: config.oms_type,\n            account_type: config.account_type,","sourceCodeStart":201,"sourceCodeEnd":237,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/backtest/src/exchange.rs#L201-L237","documentation":"Constructor guard in SimulatedExchange::new: the venue configuration supplied an empty starting_balances list. A simulated venue cannot initialize accounts without at least one balance, so construction fails.","triggerScenarios":"Constructing an exchange via SimulatedVenueConfig whose starting_balances vec is empty; building config programmatically without pushing balances.","commonSituations":"Forgot to set starting_balances in venue config; parsing config where balances section was omitted; dynamically generated balances filtered to empty.","solutions":["Provide at least one Money balance in SimulatedVenueConfig.starting_balances matching the account base currency","For multi-currency (margin) accounts, include all needed currency balances","Validate the config before constructing the exchange"],"exampleFix":"// before\nlet config = SimulatedVenueConfig { starting_balances: vec![], .. };\n// after\nlet config = SimulatedVenueConfig {\n    starting_balances: vec![Money::from(\"1_000_000 USD\")],\n    ..\n};","handlingStrategy":"validation","validationCode":"anyhow::ensure!(\n    !config.starting_balances.is_empty(),\n    \"SimulatedVenueConfig.starting_balances must contain at least one balance\"\n);\nlet exchange = SimulatedExchange::new(config, cache, clock)?;","typeGuard":null,"tryCatchPattern":"match SimulatedExchange::new(config, cache, clock) {\n    Err(e) if e.to_string().contains(\"Starting balances must be provided\") => {\n        eprintln!(\"set starting_balances in the venue config\");\n    }\n    other => other?,\n}","preventionTips":["Always populate starting_balances in venue configs","Validate configs with a helper before constructing exchanges","For multi-currency margin accounts, include every currency you intend to trade"],"tags":["backtest","exchange","account-balance"],"backgroundTag":"missing-required-config-field","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"}