Periscøpe
// Guide

How to backtest a trading strategy in Python

A practical guide to backtesting a trading strategy in Python, what you need, how to avoid the common traps, and how to read the results honestly.

June 19, 2026

Backtesting is how you find out whether a trading idea would have worked before you risk money on it. Done well, it’s a sharp tool. Done carelessly, it’s a machine for producing false confidence. Here’s how to backtest a strategy in Python without fooling yourself.

What you need

Three things:

  1. Rules. Your strategy as explicit logic, when to enter, when to exit, how much to trade. If you can’t state the rules precisely, you can’t backtest them.
  2. Data. Historical market data for the instruments and period you care about, clean and correctly time-stamped.
  3. An engine. Something that feeds the data to your rules and simulates the resulting orders and fills.

Event-driven or vectorized?

There are two styles. Vectorized backtesting computes signals over whole arrays at once, fast, great for research, but easy to accidentally use future information. Event-driven backtesting feeds your strategy one event at a time and lets it react, which mirrors live trading and is much harder to fool. For anything you intend to run live, prefer event-driven. (More on the trade-offs here.)

Model the costs

The fastest way to a fake equity curve is to assume every order fills at the last printed price. Real orders pay the spread and suffer slippage. A credible backtest adjusts fills for both, ideally tied to the instrument’s typical range. If your edge disappears once you model costs, it wasn’t an edge.

Avoid look-ahead bias

Look-ahead bias is using data your strategy wouldn’t have had at decision time, the single most common way backtests lie. It creeps in through indicators computed over the full series, signals that peek at the same bar’s close, or data joined without respecting timing. Event-driven engines make this structurally harder because the strategy simply hasn’t been handed future events yet.

Respect the calendar

Markets close. There are holidays, half-days, and, for futures, expirations. A backtest that trades when the market was shut, or mishandles an early close, produces results that look like strategy quirks but are really calendar bugs. Use real market calendars.

Read the results honestly

Don’t stop at the headline return. Look at:

  • The orders and fills: did the strategy do what you intended, at plausible prices?
  • The drawdowns: how much pain, and for how long?
  • The number of trades: a great return from five trades is noise, not evidence.
  • Out-of-sample behavior: does it hold up on data you didn’t tune on?

Common mistakes to avoid

Look-ahead bias, survivorship bias, overfitting to the past, ignoring costs, and unrealistic fills are the usual suspects. They each make a strategy look better than it is. (Full list here.)

How Periscøpe does it

Periscøpe gives you an event-driven backtester that models spread and slippage and uses real market calendars, so a whole class of these traps is handled for you. You write the strategy in Python, run the backtest, and inspect every order, fill, position, and log, and because the same code runs in paper and live, a backtest that survives doesn’t need to be rewritten to go further.

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 →