Backtesting a futures strategy in Python looks like backtesting equities until it doesn’t. Futures have expiring contracts, their own session calendars, and a margin model that works nothing like cash equities. Skip those and your backtest will be confidently wrong. Here’s what actually matters.
Contracts expire, plan for it
An equity ticker is forever; a futures contract isn’t. Each contract has an expiration, after which it settles and stops trading. A backtest that ignores expiration will happily keep trading a dead contract or misattribute the settlement.
You have two things to get right:
- Expiration handling. The backtest must know when a contract expires and stop trading it accordingly.
- Continuous series / roll. If your strategy trades “the front month” over a long window, you’re really trading a sequence of contracts. How you stitch and roll them affects the price series and the P&L, and there’s no single correct method, just be explicit about the one you use.
Sessions aren’t equity hours
Futures trade on exchange-specific calendars that don’t match NYSE equity hours, different sessions, different holidays. Use the right calendar for the instrument, or you’ll generate bars and trades at times the contract wasn’t trading. This is one of the most common sources of futures backtest bugs, and it’s invisible until you look for it.
Margin is variation margin, not cash-and-shares
Equities use a cash-and-shares model: buy shares, cash goes down. Futures use variation margin, you post margin and your account is settled against the position’s gains and losses. Modeling futures P&L with an equities cash model will misstate your capital usage and your returns. The backtest needs variation-margin accounting to reflect what actually happens to a futures account.
Fills still need modeling
Everything that’s true for equities fills is true here: don’t assume the last printed price. Model spread and slippage so the simulated fills resemble what a real order would get, and be careful with order types, a stop may not fill in a backtest the way it would at the exchange.
A futures backtest checklist
- Does the backtest handle contract expiration?
- If you trade a continuous series, is the roll method explicit?
- Are you using the correct exchange calendar for the instrument?
- Is P&L modeled with variation margin, not an equities cash model?
- Are fills modeled with spread and slippage rather than an ideal price?
How Periscøpe does it
Periscøpe handles the futures-specific parts so you don’t reimplement them. It loads exchange security-master data, uses the relevant exchange calendars, handles contract expiration against the trading calendar, and accounts for variation margin rather than treating futures like equities. The backtest is event-driven and the same code runs in paper and live, so once a futures strategy survives a faithful backtest, taking it forward doesn’t mean rewriting it.