First published on Substack

This ORB strategy backtest using Alpaca was originally published on Substack before appearing on the site. Subscribe there to get new quantitative trading research, backtesting studies, and data quality investigations early.

Introduction

This article shows how to run an ORB strategy backtest in Python using Alpaca, using over 10 years of free intraday data.

In our previous article, we published a Python implementation for backtesting the Opening Range Breakout (ORB) strategy from our paper Can Day Trading Really Be Profitable? (Zarattini & Aziz, 2023). That version used Polygon.io as the data source, but Polygon’s free tier only gives access to the last 2 years of history, which limited how far back you could test.

We wanted to fix that. While working on it, we noticed something unexpected: the same strategy, with identical code and parameters, produced materially different results depending on which data provider we used. That finding turned into its own investigation, which we published separately:

Research Insight
Backtesting Data Quality: Can Your Data Provider Be Trusted?
Using the ORB strategy across Polygon, Alpaca, IQFeed, Interactive Brokers, and Databento, we found performance dispersion exceeding a threefold difference under certain configurations, driven by phantom highs and lows, stale bars, early-close leakage, and differences in tick-to-bar assignment. Once these issues were identified and corrected, results across providers converged.
Open Article →

With that resolved, we can now share what we originally set out to build: a complete, free, reproducible backtest covering 10+ years of SIP-quality intraday data using Alpaca.

This ORB strategy backtest in Python using Alpaca is fully reproducible and runs entirely in the browser.

Alpaca
Get Alpaca API Keys
Create a free account, generate your API keys from the dashboard, and paste them into the notebook to run the backtest.
▶ Watch how to get your API keys
Get Keys →
Google Colab
Open Notebook
Run the full backtest in your browser using Google Colab. No setup required. Just paste your API keys and click Run All.
Open →
Disclaimer
This article is provided for educational purposes only. We are not sponsored by, affiliated with, or compensated by any data provider mentioned. All analysis and comparisons are conducted independently.

Why Alpaca?

The previous article used Polygon.io, which works well but limits free-tier users to 2 years of historical data. For a strategy that was originally tested from 2016 to 2023, that’s not enough.

Alpaca solves this:

What Changed from the Polygon Version

If you’re coming from the Polygon article, here’s what’s different:

Polygon VersionAlpaca Version
Data sourcePolygon.ioAlpaca
Free history~2 years10+ years (since 2016)
Dividend adjustmentManual (fetch dividends separately, apply backward adjustment)Built-in (adjustment=all on daily bars)
Date range2024–2026 (free tier)2016–2026
Stop modesH/L onlyBoth H/L and ATR

The core strategy logic is identical. It uses the same entry rules, the same position sizing, and the same risk management. The improvements are in data coverage, adjustment handling, and ATR implementation.

ORB Strategy Backtest Logic

For those new here, the ORB strategy is straightforward:

  1. Determine direction. If the close of the 5th bar is above the open of the 1st bar, go Long. Otherwise, go Short.
  2. Enter at the open of the 6th bar.
  3. Stop loss has two modes:
    • H/L: the low of the opening range for longs or the high for shorts.
    • ATR: a fraction of the previous day’s ATR, reconverted to current-day dollars.
  4. Target: hold until stop or market close. There is no profit target.
  5. Position sizing: risk 1% of equity per trade, capped at 4x leverage.

The parameters match the paper exactly:

ParameterValue
Opening range5 minutes
Stop (H/L mode)High/Low of the range
Stop (ATR mode)5% of 14-day ATR
Profit target (H/L mode)10R
Profit target (ATR mode)None (hold to close)
Risk per trade1% of equity
Max leverage4x
Starting capital$25,000
Commission$0.0005/share per side

Walkthrough of the Notebook

The notebook implements a complete ORB strategy backtest in Python using Alpaca, from data download to performance analysis.

Section 1: Setup & Configuration

This is the only cell you need to edit. It contains your Alpaca API keys, the ticker symbol (TQQQ), the date range, and all strategy parameters.

API_KEY_ID     = os.environ.get("ALPACA_API_KEY_ID", "")
API_SECRET_KEY = os.environ.get("ALPACA_API_SECRET_KEY", "")
TICKER         = "TQQQ"
START_DATE     = "2016-01-01"
END_DATE       = "2026-04-20"

Everything else, including data download, processing, backtesting, and analysis, runs automatically from here.

Section 2: Data Download

Two datasets are fetched from Alpaca’s REST API:

Both are cached to CSV on first run. Subsequent executions skip the download entirely.

Section 3: Load Data & Compute ATR

The adjusted daily data is used to build a lookup table of ATR% values, defined as the 14-day ATR divided by the daily open and lagged by one day.

First, we compute the 14-day ATR using adjusted daily price data. We then divide this value by the adjusted daily open to obtain ATR%, a normalized volatility measure that is not affected by splits or dividends.

At trade time, this ratio is converted back into current-day dollar terms by multiplying it by the intraday open price.

The stop is defined as a dollar distance from entry (stop width) and is computed as:

$$ \text{stop width} = \text{stop}_{atr} \times ATR\% \times \frac{\text{intraday open}}{\text{entry}} \quad (\text{e.g. } \text{stop}_{atr} = 0.05) $$

The stop is then calculated by taking the chosen ATR scaling factor (stop_atr), multiplying it by the ATR percentage, and adjusting it based on the relationship between the intraday open and the entry price.

This approach is cleaner than the Polygon version, which required fetching dividends separately and applying a manual backward adjustment.

Section 4: Filter Early-Close Days

On days like Black Friday, Christmas Eve, and July 3rd, the NYSE closes at 1:00 PM instead of 4:00 PM. Some data feeds include bars after the real close. We use the exchange_calendars library to identify these half-days and remove any post-close bars.

Data Quality Note
Early-Close Day Leakage Can Distort Backtests
Some data providers include intraday bars after the official early market close. This can lead to trades being simulated outside regular hours and create inconsistencies across datasets. See Issue 3 for a detailed breakdown.
Open →

Sections 5–6: Strategy Logic & Backtest Engine

The backtest loops day by day:

Both stop modes (H/L and ATR) are run back-to-back for comparison.

Section 7: Performance Analysis

Utility functions compute:

Sections 8–9: Run & Results

The backtests execute and the results are displayed: equity curves, performance tables, and monthly breakdowns for both H/L and ATR stop modes. The out-of-sample period is clearly marked. Strategy lines turn green after February 17, 2023 (the paper’s data cutoff), so you can visually assess out-of-sample performance.

How to Run It Yourself

This ORB strategy backtest in Python using Alpaca requires only a free API key and a browser.

  1. Create a free Alpaca account at alpaca.markets.
  2. Get your API keys from the dashboard (Paper trading keys work).
  3. Open the notebookGoogle Colab link
  4. Paste your API keys into Section 1.
  5. Run All, data downloads in ~5 minutes (cached afterward), backtest runs in under a minute.

No paid subscriptions. No local installs. Just a browser and a free API key.

Conclusion

This article extends our original Polygon-based backtest with a significantly longer data history (10+ years vs 2 years), a cleaner data pipeline (no manual dividend adjustments), and a faithful implementation of the ATR stop from the paper.

If you’re interested in how data quality affects backtesting results and why the same code can produce wildly different outcomes depending on the provider, see our companion article: Backtesting Data Quality: Can Your Data Provider Be Trusted?.

The full code is open and reproducible. Fork it, change the ticker, adjust the parameters, and see what you find.

Get research like this before it’s public.

Enter your email to receive our next data-driven analysis.

Live Experiment

Can You Beat a Systematic Strategy?

We’re running a research experiment to test whether day trading skill can improve the performance of a fully systematic intraday strategy.

No trade generation. No guessing.
Just managing exposure using price action — and we are measuring the result.

Join the Experiment →