Choose two different assets.
Spread = A − β × B. Rolling OLS re-estimates β each day from the trailing window only, so the backtest never sees future prices.
Days used for the rolling mean, standard deviation and hedge ratio. Two to four times the half-life usually works well.
Closes any trade still open after this many days, even if neither target nor stop was hit.
Settings, loaded prices and your journal are saved in this browser. The share link restores this exact setup.
Pairs trading signal for any two assets: the spread z-score against its rolling mean, a daily hedge ratio, half-life of mean reversion, Hurst exponent, and Engle–Granger, ADF and Johansen cointegration tests.
Click any cell to analyze that pair.
| Pair | Coint. p | Corr. | β | Half-life | z now |
|---|
Correlation is not the test: two assets can move together every day and still drift apart for years. Cointegration asks the question that matters for a pair: does the gap keep coming back? Remember too that testing many pairs finds a few false positives by chance, so confirm a promising pair on a second period before trading it.
Pairs trading screener: correlation matrix of daily returns (Pearson, Spearman or Kendall) and Engle–Granger cointegration p-values for every combination, ranked with hedge ratio, half-life and current z-score.
Each cell is that month's return after costs; the last column compounds the year.
Rows are entry z, columns exit z, with your stop held fixed. Click a cell to apply it. The single best cell on past data is rarely best going forward, so favour broad strong regions over one bright spot.
| # | Side | Opened | Closed | Days | Entry z | Exit z | P&L | Return | R | Exit reason |
|---|
How honest is this backtest? It uses daily closes, charges costs on both legs in and out, fills the day after each signal and never lets the hedge ratio peek at future prices. It ignores short-borrow fees, dividends on the short leg and gaps beyond the close. Use it to compare rules, not to forecast profits.
Pairs trading backtest with z-score entry, exit and stop rules: equity curve, drawdown, Sharpe and Sortino ratios, win rate, profit factor, monthly returns and a threshold sweep.
Expected growth per trade at every risk level, built from the backtest's own trades. Growth rises, peaks at the Kelly level, then falls: past the peak, more risk means slower growth and deeper drawdowns.
2,000 possible futures built by resampling the backtest's trades at your risk level. The dark band holds the middle half of outcomes, the light band 90% of them.
Pairs trading position size calculator: share or contract counts for both legs from your risk per trade and z-score stop, leverage check, Kelly criterion from backtest trades, and a Monte Carlo drawdown simulation.
Your cumulative P&L curve appears here after your first closed trade.
| Opened | Pair | Side | Qty A @ entry | Qty B @ entry | Exit A / B | P&L | Return | Notes |
|---|
Why keep a journal: the backtest tells you what the rules should do; the journal tells you what you actually did. Comparing the two shows whether slippage, hesitation or skipped signals are costing you. Open trades are marked to the latest loaded prices when the tickers match.
Pairs trading journal: record both legs, entry and exit prices, fees and notes, with realised P&L, win rate and a cumulative P&L chart. Exports to CSV.
The z-score measures how far today's spread sits from its recent average, in standard deviations: z = (spread − rolling mean) ÷ rolling standard deviation. A z of +2 means the spread is unusually wide, so a mean-reversion trader sells A and buys B, expecting it to narrow.
Correlation says two assets move in the same direction day to day. Cointegration says the gap between them keeps returning to a stable level. Two stocks can be 90% correlated and still drift apart for years. The "Correlated, not cointegrated" scenario shows exactly that, so pair selection here is driven by the Engle–Granger test, with correlation as a secondary check.
By default β comes from an ordinary least-squares regression of A on B over the trailing lookback window, re-estimated every day so no future data leaks in. You can switch to a full-sample fit, an orthogonal (total least squares) fit that treats both legs symmetrically, or type your own ratio.
Half-life is how many trading days the spread typically takes to close half of its distance to the mean, estimated from an Ornstein–Uhlenbeck (AR(1)) fit. It sets expectations for holding time and helps pick a lookback window, often 2 to 4 times the half-life.
The Augmented Dickey–Fuller, Engle–Granger and Johansen tests follow the same method as the Python statsmodels library, including AIC lag selection and MacKinnon p-values, and were checked against it to four decimal places.
Yahoo Finance (Historical Data, then Download), Stooq, Nasdaq.com or your broker's export all work. Use daily closes, ideally adjusted for splits and dividends. The analyzer aligns files on matching dates, so different holidays or listing dates are handled.
No. Files and pasted prices are read and analysed in your browser. Your settings, loaded prices and journal are stored only in this browser's local storage so they are there when you come back.
It is a realistic but simplified model: daily closes, costs on both legs, next-day fills and no look-ahead in the hedge ratio. It ignores borrow fees, dividends on the short leg and intraday gaps beyond the close. Treat it as a way to compare rules, not as a forecast. Nothing here is investment advice.
The disclaimer that actually matters: a pair that has reverted for years can stop reverting without warning, usually when a merger, a regulation change or a market shock rewrites the relationship. The stop is what protects you then. This is an educational tool, not investment advice.
How pairs trading works: z-scores, correlation versus cointegration, hedge ratios, half-life, test accuracy, where to get price data, privacy and the limits of backtests.