nautechsystems/nautilus_trader · error

single-currency account has multiple starting currencies

Error message

single-currency account has multiple starting currencies

What it means

When a base_currency is configured the account is single-currency, so supplying more than one starting balance is contradictory; the constructor bails to prevent an invalid multi-currency account state.

Source

Thrown at crates/backtest/src/exchange.rs:223

impl SimulatedExchange {
    /// Creates a new [`SimulatedExchange`] instance from a venue configuration.
    ///
    /// # Errors
    ///
    /// Returns an error if:
    /// - `starting_balances` is empty.
    /// - `base_currency` is `Some` but `starting_balances` contains multiple currencies.
    pub fn new(
        config: SimulatedVenueConfig,
        cache: Rc<RefCell<Cache>>,
        clock: Rc<RefCell<dyn Clock>>,
    ) -> anyhow::Result<Self> {
        if config.starting_balances.is_empty() {
            anyhow::bail!("Starting balances must be provided")
        }

        if config.base_currency.is_some() && config.starting_balances.len() > 1 {
            anyhow::bail!("single-currency account has multiple starting currencies")
        }

        let default_leverage = config.default_leverage.unwrap_or_else(|| {
            if config.account_type == AccountType::Margin {
                Decimal::from(10)
            } else {
                Decimal::from(1)
            }
        });

        Ok(Self {
            id: config.venue,
            oms_type: config.oms_type,
            account_type: config.account_type,
            base_currency: config.base_currency,
            starting_balances: config.starting_balances,
            book_type: config.book_type,
            default_leverage,

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Remove base_currency (set None) to allow multi-currency starting balances, or
  2. Reduce starting_balances to a single balance in the configured base_currency
  3. Align account_type with balances: use Margin accounts for multi-currency setups

Example fix

// before
SimulatedVenueConfig { base_currency: Some(Currency::USD()), starting_balances: vec![usd, eur], .. }
// after
SimulatedVenueConfig { base_currency: None, starting_balances: vec![usd, eur], .. } // multi-currency margin
Defensive patterns

Strategy: validation

Validate before calling

anyhow::ensure!(
    config.base_currency.is_none() || config.starting_balances.len() <= 1,
    "single-currency account accepts at most one starting balance"
);

Try / catch

match SimulatedExchange::new(config, cache, clock) {
    Err(e) if e.to_string().contains("single-currency account") => {
        eprintln!("drop base_currency for multi-currency, or trim to one balance");
    }
    other => other?,
}

Prevention

When it happens

Trigger: SimulatedVenueConfig with base_currency set (Some) and starting_balances.len() > 1; copying a multi-currency margin config and adding a base_currency.

Common situations: Config mistake when switching between cash single-currency and margin multi-currency setups; leftover balances from a template config.

Related errors


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