nautechsystems/nautilus_trader · error · ValueError
account report contains multiple currencies
Error message
account report contains multiple currencies
What it means
_calculate_account_returns derives an account balance/returns series from an account report DataFrame. When no target_currency is given, the code requires the report to be single-currency; a report containing rows in more than one currency cannot be aggregated into one balance series without exchange-rate conversion, so it raises ValueError.
Solutions
- Pass target_currency explicitly (e.g. target_currency='USD') so the report is filtered to one currency before series extraction.
- Split the tearsheet generation per account/currency, calling it once per currency.
- Configure the backtest with a single-currency account or a currency conversion setup so the account report is single-currency.
Example fix
// before returns = _calculate_account_returns(report, target_currency=None) // after returns = _calculate_account_returns(report, target_currency='USD')
Defensive patterns
Strategy: validation
Validate before calling
currencies = set(report['currency'].dropna())
if len(currencies) > 1 and target_currency is None:
raise ValueError(f'Multi-currency report {currencies}: pass target_currency') Try / catch
try:
acct_returns = _calculate_account_returns(report, target_currency=None)
except ValueError as e:
if 'multiple currencies' in str(e):
acct_returns = _calculate_account_returns(report, target_currency=base_currency)
else:
raise Prevention
- Pass target_currency explicitly whenever the account may hold multiple currencies.
- Check set(report['currency'].dropna()) before generating account-based tearsheets.
- Configure backtests with a single account currency or convert balances to a base currency upstream.
When it happens
Trigger: Calling _calculate_account_returns (via create_tearsheet's account-returns path) with an account report whose 'currency' column has multiple distinct values (e.g. a multi-currency account) and target_currency=None.
Common situations: Multi-currency backtest accounts (USD deposits plus EUR/JPY instruments); producing a tearsheet across a portfolio spanning several account currencies; forgetting to pass target_currency after changing the strategy's instruments.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- BacktestNode state is unavailable when…
- run_config_id is required when a BacktestNode is provided
- A different extractor is already registered for
- Actor is already registered
- BacktestEngineConfig.controller for importable controller
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/0223dce99d3c57f7.
Report an issue: GitHub.
Appendix: source
Thrown at python/nautilus_trader/analysis/tearsheet.py:920
currency_report["total"].iloc[-1],
)
return account_info
def _extract_account_balance_series(
report: pd.DataFrame,
target_currency: str | None,
) -> tuple[pd.Series | None, str | None]:
if report.empty or "currency" not in report or "total" not in report:
return None, None
observed_currency: str | None = None
if target_currency is None:
account_currencies = set(report["currency"].dropna())
if len(account_currencies) != 1:
raise ValueError("account report contains multiple currencies")
observed_currency = next(iter(account_currencies))
else:
report = report[report["currency"] == target_currency]
if report.empty:
return None, observed_currency
totals = pd.to_numeric(report["total"], errors="coerce")
totals.index = report.index
totals = totals.dropna().sort_index()
if totals.empty:
return None, observed_currency
return totals.groupby(level=0).last(), observed_currency
def _calculate_daily_balance_returns(total_balance: pd.Series) -> pd.Series | None:
account_returns = (View on GitHub (pinned to 18893faf8b)