nautechsystems/nautilus_trader · error

Currency must be specified

Error message

Currency must be specified

What it means

`base_balance(&self, currency: Option<Currency>)` on the account base resolves the currency as the argument or the account's `base_currency`; if both are `None` (e.g. a margin/multi-currency account without a base currency), `.expect("Currency must be specified")` panics. This panic is explicitly documented on the method, and the derived helpers `base_balance_total`, `base_balance_free`, and `base_balance_locked` inherit it.

Source

Thrown at crates/model/src/accounts/base.rs:113

            base_currency: self.base_currency,
            calculate_account_state: self.calculate_account_state,
            events: Vec::new(),
            commissions: self.commissions.clone(),
            balances: self.balances.clone(),
            balances_starting: self.balances_starting.clone(),
        }
    }

    /// Returns a reference to the `AccountBalance` for the specified currency, or `None` if absent.
    ///
    /// # Panics
    ///
    /// Panics if `currency` is `None` and `self.base_currency` is `None`.
    #[must_use]
    pub fn base_balance(&self, currency: Option<Currency>) -> Option<&AccountBalance> {
        let currency = currency
            .or(self.base_currency)
            .expect("Currency must be specified");
        self.balances.get(&currency)
    }

    /// Returns the total `Money` balance for the specified currency, or `None` if absent.
    ///
    /// # Panics
    ///
    /// Panics if `currency` is `None` and `self.base_currency` is `None`.
    #[must_use]
    pub fn base_balance_total(&self, currency: Option<Currency>) -> Option<Money> {
        self.base_balance(currency).map(|balance| balance.total)
    }

    #[must_use]
    pub fn base_balances_total(&self) -> IndexMap<Currency, Money> {
        self.balances
            .iter()
            .map(|(currency, balance)| (*currency, balance.total))

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Pass an explicit `Some(currency)` instead of `None` when the account may have no base currency
  2. Check `account.base_currency()` first and fall back to per-currency `account_balance(currency)` / iterating `balances()` for multi-currency accounts
  3. For cash accounts, construct the account with its base currency so `base_currency` is `Some`
  4. Wrap the call if you must use it generically, or use the `balances()` map accessor instead

Example fix

// before
let balance = account.base_balance(None); // panics if base_currency is None
// after
let balance = match account.base_currency() {
    Some(base) => account.base_balance(Some(base)),
    None => None, // multi-currency account: iterate account.balances() instead
};
Defensive patterns

Strategy: type-guard

Validate before calling

let currency = currency.or(account.base_currency());
if currency.is_none() {
    // multi-currency account: use account.balances() / account_balance(currency) instead
    return None;
}

Type guard

fn base_currency_or_none(account: &dyn Account) -> Option<Currency> { account.base_currency() }

Try / catch

match account.base_currency() {
    Some(_) => account.base_balance(None),
    None => None, // or iterate account.balances()
}

Prevention

When it happens

Trigger: Calling `base_balance(None)` (or `base_balance_total(None)` / `base_balance_free(None)` / `base_balance_locked(None)`) on an account whose `base_currency` is `None` — typical for margin accounts supporting multiple currencies.

Common situations: Generic reporting code passing `None` assuming every account has a default base currency; querying balances on a `MarginAccount`; using an account before its base currency was set at construction.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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