nautechsystems/nautilus_trader · error

Invalid starting balance: {e}

Error message

Invalid starting balance: {e}

What it means

Each venue's starting balances are parsed from their string form into Money. If any string is not a valid Money representation (wrong format, bad currency code, malformed amount), parsing fails and the error is wrapped as "Invalid starting balance: {e}".

Source

Thrown at crates/backtest/src/node.rs:227

    pub fn dispose(&mut self) {
        for engine in self.engines.values_mut() {
            engine.dispose();
        }
        self.engines.clear();
    }
}

fn build_engine(config: &BacktestRunConfig) -> anyhow::Result<BacktestEngine> {
    let engine_config = config.engine().clone();
    let mut engine = BacktestEngine::new(engine_config)?;

    for venue_config in config.venues() {
        let starting_balances: Vec<Money> = venue_config
            .starting_balances()
            .iter()
            .map(|s| s.parse::<Money>())
            .collect::<Result<Vec<_>, _>>()
            .map_err(|e| anyhow::anyhow!("Invalid starting balance: {e}"))?;

        let default_leverage = venue_config.default_leverage();
        let leverages = venue_config.leverages().cloned().unwrap_or_default();
        let margin_model = venue_config.margin_model().cloned().map(Into::into);
        let modules = venue_config
            .modules()
            .iter()
            .cloned()
            .map(Into::into)
            .collect();
        let fill_model = venue_config
            .fill_model()
            .cloned()
            .unwrap_or_default()
            .into();
        let fee_model = venue_config.fee_model().cloned().unwrap_or_default().into();
        let latency_model = venue_config.latency_model().cloned().map(Into::into);
        let sim_config = SimulatedVenueConfig::builder()

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Use the exact Money string format, e.g. "1000000.00 USD" (amount, space, ISO currency code)
  2. Remove separators/symbols and use a plain decimal amount
  3. Check for currency codes outside the registered currency list
  4. Read the inner parse error after "Invalid starting balance:" for the specific cause

Example fix

// before
venue_config.add_starting_balance("$1,000,000.00");
// after
venue_config.add_starting_balance("1000000.00 USD");
Defensive patterns

Strategy: validation

Validate before calling

let money: Money = s.parse().map_err(|e| anyhow!("bad starting balance '{s}': {e}"))?;

Try / catch

match s.parse::<Money>() {
    Ok(m) => m,
    Err(e) => { eprintln!("balance '{s}' invalid: {e}"); return Err(e.into()); }
}

Prevention

When it happens

Trigger: Providing a venue starting balance string that fails `"...".parse::<Money>()` — e.g. wrong decimal format, missing currency, unknown currency code — in a BacktestVenueConfig passed to BacktestNode::build.

Common situations: Typo in currency code; amounts with thousands separators or symbols; locale-formatted numbers; balance strings copied from a different API with different formatting.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/d33d2bff96f8d8a5. Report an issue: GitHub.