Periscøpe
// Guide

How to backtest a futures strategy in Python

Backtesting futures isn't the same as backtesting equities. Contracts, expiration, session calendars, and margin all change the picture. Here's how to do it right.

June 19, 2026

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.

Related
// Access

Run one strategy through Periscøpe.

We onboard in focused cohorts. Tell us what you trade and how you work. Live access is rolled out to select users on request.

We only use your email to contact you about access.

Read the docs →