Articles ·

How a Metrand basket backtest adds markets into one account

A basket trades one strategy on several markets at once, from one account. Each market is replayed as an ordinary backtest of the same window, on the same account size and costs, and kept in the ledger with the basket's id. The basket then adds them into one account.

The account, bar by bar

For every bar it replays, the engine gives the account's lowest, highest and closing equity inside that bar, over both ways the bar could have run, and the notional it held. The basket's account at any moment is the starting capital plus what every market had made by then:

account = start + Σ (market equity − start)

A market not listed yet, or finished, holds its last equity. When several markets mark the same bar, they are taken to reach their lows together and their highs together — a candle does not say which came first, so the basket keeps the worse case, as the engine does inside one market.

A basket of two markets: one falls inside a bar to 88 and closes at 99; at closes the account fell 1%, inside the bar 12%
Drawdown counts the lowest point inside every bar, not only the closes.

Drawdown, a year, Sharpe

One balance, one margin

The markets share one balance. Each market's maintenance margin is taken from its own margin schedule at the notional it holds. When the account's equity at a bar's low reaches the sum of them, the account is liquidated: it ends at zero there and stays there, whatever the markets did next.

Two 3,000 USDT longs on 1,000 USDT: the account reaches the maintenance margin of what it holds and is liquidated; the markets' later recovery is not counted
Once the account is liquidated, nothing after counts.

Held at once is the largest notional the markets held together, and when; the result also gives the most markets holding at once. A basket whose markets held more at once than the starting capital times its leverage is marked: on the exchange some of those positions would have been refused.

What a basket does not model

In the API

POST /backtest with "marks": true returns, beside the report, every traded bar's marks:

"marks": {"t": [1735689600000, …], "low": [1000.0, …], "high": [1000.0, …], "close": [1000.0, …], "held": [0.0, …]}

The last close is the account's final equity, after closing what was still held. Adding several backtests' marks this way gives the basket's account; the platform's basket answer returns it as portfolio (net_pnl, return_pct, max_drawdown_quote, max_drawdown_pct, per_year_pct, sharpe, peak_notional, peak_positions, over_margin, ruined_at, years, curve).