Portfolio LabKnowledgeSign inCreate account

Long/short and statistical arbitrage: methodology

Advanced13 min read · updated 24 October 2026 · 13 sources

The long/short backtest on the Long/Short page tests statistical arbitrage strategies on daily prices: one security is bought, another is sold short, and the profit comes when the gap between them closes again. This methodology describes what the code calculates: four methods, the entry and exit rules, the accounting with leverage, costs, borrow fees and interest, and the metrics. The idea, history and research are covered in the article pairs trading.

Four methods, one calculation engine

The four methods (pairs trading with two securities, a portfolio of pairs, factor residuals and rank long/short) differ in how the long and short positions are created. From there on, the accounting is the same for all of them: day by day at closing prices, with a starting capital of 10,000.

Prices: each security is loaded with its own history, as daily prices with distributions reinvested. The short side therefore automatically pays the dividends of the borrowed security. The common calendar is the union of all trading days; the code fills gaps of up to five days with the last price, but never beyond a security's last price. The page rejects weekly and monthly prices as well as asset classes with monthly values; a universe has at most 60 securities. If some securities have more recent prices, it calculates up to the last price of the least up-to-date security.

Currencies: if all securities are quoted in the same currency, the signals come from prices in this trading currency, but the result is in the base currency of the settings, without currency hedging. With different currencies, everything is calculated in the base currency, and exchange rates then feed into the signals. No look-ahead: a signal on day t uses only closing prices up to t. By default, trades are executed at the closing price of the next trading day, or optionally on the signal day itself. That assumes trading shortly before the close.

Templates: classic pairs such as Coca-Cola/PepsiCo and four universes (11 US sector ETFs, 19 country ETFs, 30 large US stocks and 30 stocks from Germany's DAX index, each with today's members).

Pairs trading: hedge ratio, spread and z-score

For two securities A and B, the code estimates on each day t the relationship between the log prices over the W trading days before t (default 120, allowed 30 to 1,000). The price on day t is not part of the estimate; the day's z-score is therefore an out-of-sample test.

ln A_s = α_t + β_t × ln B_s + u_s (s = t − W … t − 1); z_t = (ln A_t − α_t − β_t × ln B_t) / σ_t
β_t
hedge ratio from the ordinary least squares (OLS) regression over the window
α_t
intercept
σ_t
standard deviation of the residuals with W − 2 degrees of freedom
z_t
z-score: distance of today's spread from equilibrium in standard deviations

Alternatively, a Kalman filter after Kalman (1960) updates the hedge ratio, as Chan (2013) describes for pairs: β and α each follow a random walk, started with an OLS over the first W days. The adjustment is controlled by δ, the ratio of state noise to measurement noise (default 0.0001, allowed 10⁻⁸ to 0.1); the memory is about 1/√δ, i.e. 100 days here. The z-score is then the day's forecast error divided by its predicted dispersion, using the previous day's state.

  • Entry: z above +2 (default, allowed 0.1 to 10) means A is expensive relative to B, hence a short spread: sell A short, buy B. z below −2 means a long spread: buy A, sell B short. Entry only takes place with β > 0 and as long as |z| is below the stop.
  • Exit: if z returns to ±0.5 (default, allowed from 0 to just below the entry level), the position is closed. While the position is open, α, β and σ from the entry day apply; the legs are not rebalanced.
  • Stop-loss: if z keeps moving further out in the direction of the entry signal, to ±4 (default; 0 = off, otherwise above the entry level and up to 20), the position is closed. After that, the code only trades again once |z| has fallen below the entry threshold.
  • Maximum holding period: after 60 trading days (default; 0 = off, up to 5,000), the position is closed, with the same lockout as after a stop. There is no new entry on the day of an exit.
  • Weighting: by default by hedge ratio (the notional of B is β times the notional of A), optionally dollar-neutral with equal amounts. Both legs together make up the gross leverage.

The comparison is both securities at half each, reset daily to equal weights. The estimation window plus 60 further common trading days are required.

Cointegration and half-life

Whether the spread returns to its mean at all is tested by the Engle-Granger test after Engle and Granger (1987): an OLS estimates ln A = α + β × ln B + u, then an augmented Dickey-Fuller test after Said and Dickey (1984), without a constant, checks whether u has a unit root. The number of lagged differences is chosen by the Akaike criterion, at most 12 × (n / 100)^¼, i.e. 12 for 120 days. The p-value comes from the approximation formulas of MacKinnon (1994) for two series; cointegrated means that the statistic is below the critical value for 5%.

The page runs the test in the first estimation window, i.e. before the first possible signal, and in hindsight over the whole period; only the first is free of look-ahead. Without cointegration the rules still trade, and the page points this out.

The half-life measures how quickly a deviation shrinks. The code estimates Δu_t = λ × u_(t−1) + c + e_t by OLS:

Half-life = −ln 2 / ln(1 + λ) in trading days; λ ≥ 0: no reversion
1 + λ
share of the deviation that remains after one day

Portfolio of pairs after Gatev, Goetzmann and Rouwenhorst

The second method follows the design of Gatev et al. (2006): pairs are searched for in a formation period and traded in the following trading period (default 12 and 6 months, allowed 3 to 36 and 1 to 24). A new cohort starts every month (interval allowed 1 to 24 months, at most the trading period), so six run at the same time. Formation periods cover full calendar months; eligible securities are those with a price on every day of the formation and on the first trading day.

  • Smallest distance (default, distance method): prices normalized to 1 on the first formation day, distance = sum of squared differences (SSD). Each security gets its nearest partner, and the 5 pairs with the smallest SSD are taken (allowed 1 to 50). During trading, the z-score is the difference between the prices normalized to the last formation day, divided by σ, the standard deviation of this difference during the formation.
  • Cointegration: pairs pre-sorted by SSD, Engle-Granger on log prices in both directions (taking the direction with the smaller p-value and β > 0); the first pairs with p ≤ 0.05 (allowed 0.001 to 0.2) are taken, with at most max(20; 4 × pairs) tested. The z-score is (ln P_i − β × ln P_j − α) / σ with the values from the formation.

As in the study, a position is opened when |z| is above 2 standard deviations of the formation (allowed 0.5 to 5): short in the more expensive security, long in the cheaper one. It is closed at the next crossing, when z changes sign, and at the latest at the end of the trading period; a pair can open several times. Capital works as with the study's “committed capital”: each of the K concurrent cohorts ties up 1/K of the capital, spread equally across its pairs, including pairs without a trade. A pair opens dollar-neutral (by hedge ratio only with cointegration) with gross leverage / (K × pairs) of the current capital; the rest earns interest in cash.

Factor residuals after Avellaneda and Lee

“the idiosyncratic returns are modelled as mean-reverting processes, which leads naturally to 'contrarian' strategies”
Avellaneda and Lee (2010)

Avellaneda and Lee (2010) trade each stock against a factor. On each day t, the code estimates a regression on a factor ETF (default SPY) or on the equally weighted basket of the universe, using the last 60 daily returns (as in the paper; allowed 20 to 500). It treats the cumulative residuals as an Ornstein-Uhlenbeck process after Uhlenbeck and Ornstein (1930), estimated as an AR(1):

R_i = β_0 + β × R_F + ε; X_k = Σ ε; X_(k+1) = a + b × X_k + ζ; κ = −ln b × 252; m = a / (1 − b); σ_eq = √(Var ζ / (1 − b²)); s = −m / σ_eq
κ
speed of mean reversion per year; half-life = ln 2 / κ × 252 trading days
m
equilibrium; by default centered on the mean across the stocks tradable that day, as in the paper
σ_eq
dispersion in equilibrium; Var ζ with W − 3 degrees of freedom
s
s-score; because of the regression, the cumulative residual is zero on the last day

The estimate is valid only with 0 < b < 1. A stock is tradable only if it reverts quickly: κ above 252/30 ≈ 8.4 (allowed 0 to 252), i.e. b below 0.967. The thresholds are those of the paper: open long at s < −1.25, short at s > +1.25 (allowed 0.1 to 5), close long at s > −0.50, short at s < +0.75 (allowed −5 to 5, closer to equilibrium than the opening level). A position is also closed if κ falls below the limit or prices are missing; a maximum holding period applies only on request.

Each trade buys (sells) one unit of the stock and sells (buys) β units of the factor, with β from the signal day. One unit is gross leverage / number of stocks; the paper's “2+2” leverage with 100 positions each on the long and the short side would correspond to 2/100. The comparison is the factor itself.

Rank long/short

The fourth method builds a ranking on the last trading day of each complete month: long the k securities with the highest signal, short the k with the lowest (default 3, allowed 1 to 20). The choices are momentum 12-1 after Jegadeesh and Titman (1993) (return from 252 to 21 trading days ago), one-month reversal after Jegadeesh (1990) (long the losers, short the winners of the last 21 trading days) and low volatility after Ang et al. (2006) (long the calmest, short the most volatile securities, measured over 252 daily returns).

Dollar-neutral (default): each security gets ±gross leverage / (2k). Beta-neutral, like the portfolios of Frazzini and Pedersen (2014): the code splits the gross leverage between the sides so that the net beta is zero; it estimates the betas over 252 days (allowed 60 to 756) against a factor ETF or the equally weighted basket. If the beta of one side is not positive, the month stays dollar-neutral. If a security stays on its side, it is only adjusted to the new weight, and costs apply to the change.

Long side L = gross × β_S / (β_L + β_S); short side S = gross × β_L / (β_L + β_S); L × β_L = S × β_S
β_L, β_S
average beta of the long and of the short securities

Accounting: leverage, costs, borrow fee and interest

All methods run through the same daily accounting, built like the profit-and-loss equation in Avellaneda and Lee (2010):

E_t = E_(t−1) + Σ h_i × r_i,t + rc_t × (E_(t−1) − Σ h_i) − f_t × Σ max(−h_i; 0) − c × Σ |Δh_i|
E
capital, starting at 10,000
h_i
position in the base currency from the previous day, long positive, short negative
rc
cash rate: money market rate of the base currency (default) or a fixed rate (default 2% p.a., allowed −5 to 25%)
f
borrow fee 0.5% p.a. (allowed 0 to 50%) × calendar days / 365.25 on the short notional
c
trading costs per amount traded, default 0.05% = 5 basis points as in Avellaneda and Lee (allowed 0 to 2%)

Positions move with prices and are only traded on signals. Short proceeds are held as collateral in cash (capital minus net position); negative cash costs the same interest rate. The gross leverage (long plus short per unit of capital, default 2, allowed 0.1 to 10) applies at opening, measured against the capital before the day's costs. The code closes first, then adjusts and opens last; it calculates costs per position without netting opposing orders, so they tend to be too high. If the capital is used up, the strategy stops.

A trade runs from opening to closing; its result includes costs and borrow fee, but not the interest on the capital. The page does not calculate taxes.

Results and metrics

The page shows the value of the strategy alongside the comparison and cash, plus drawdowns, calendar years and the metrics as in the backtest, with the comparison as the index for beta and alpha. If beta is close to zero (|β| < 0.1), it hides the Treynor ratio, because excess return divided by β then explodes. In addition:

  • Trades and hit rate: closed trades and the share with a profit; with fewer than ten trades, the page points out that the figures mean little.
  • Holding period, result per trade, turnover and exposure: average trading days, average result on the gross notional at opening, turnover per year in multiples of capital, average gross (long + short) and net (long − short) exposure per unit of capital, time in the market.
  • Where the result comes from: cumulative contributions of the long and short sides, interest, costs and borrow fee, as a percentage of capital.
  • Per method: z-score, spread and cointegration test for the pair, cohorts for the portfolio of pairs, s-scores with κ for the residuals, the latest ranking for the rank method; plus the most recent 1,000 trades.

Limitations

  • Surviving securities: the templates contain today's members, a survivorship bias. Bankruptcies and takeovers are missing, so the results tend to look too good.
  • Short selling assumed: the page assumes that every security can be borrowed, at a fixed fee and without recall. In practice, borrow fees fluctuate and securities are recalled, as Engelberg et al. (2018) show.
  • Flat-rate costs: one rate for spread, fees and slippage; in periods of stress, actual costs are higher.
  • Closing prices: signal and trade at the closing price. The default only trades on the next day, like the “wait one day” variant in Gatev et al. (2006); this removes the bid-ask bounce, the jumping of the closing price between the bid and the ask.
  • Trial and error: if you test many pairs, windows and thresholds, you will find good ones by chance (backtest overfitting).
  • No taxes or margin rules: the page does not model taxes, margin calls or forced liquidations by the broker. Not investment advice.

Frequently asked questions

What does the z-score on the page mean?

It measures how far today's spread is from the estimated equilibrium, in standard deviations of the estimation window. z = 2.5 means: relative to B, A is 2.5 standard deviations more expensive than usual. The estimate uses only days before today.

Why does the page only trade on the next day?

Because the signal needs the closing price, at which you can then no longer trade. By default, trades are therefore executed at the closing price of the next trading day, as in the “wait one day” variant of Gatev, Goetzmann and Rouwenhorst. This also removes the bid-ask bounce.

Why is the hit rate high but the return still weak?

Mean reversion rules often win many small trades and lose rarely, but heavily, for instance when a pair drifts apart for good and the stop kicks in. On top of that come costs and borrow fees. The chart “Where the result comes from” shows what contributes how much.

Does the page account for short-selling costs?

Yes: a borrow fee p.a. on the short notional, by calendar days, 0.5% by default. Dividends on the securities sold short are paid automatically by the short side via the prices with distributions. The page does not model recalls or rising fees.

Literature

  1. Ang, Andrew; Hodrick, Robert J.; Xing, Yuhang; Zhang, Xiaoyan (2006): The Cross-Section of Volatility and Expected Returns. The Journal of Finance 61 (1), pp. 259–299. doi:10.1111/j.1540-6261.2006.00836.x
  2. Avellaneda, Marco; Lee, Jeong-Hyun (2010): Statistical arbitrage in the US equities market. Quantitative Finance 10 (7), pp. 761–782. doi:10.1080/14697680903124632
  3. Chan, Ernest P. (2013): Algorithmic Trading: Winning Strategies and Their Rationale. Wiley. doi:10.1002/9781118676998
  4. Engelberg, Joseph E.; Reed, Adam V.; Ringgenberg, Matthew C. (2018): Short-Selling Risk. The Journal of Finance 73 (2), pp. 755–786. doi:10.1111/jofi.12601
  5. Engle, Robert F.; Granger, C. W. J. (1987): Co-Integration and Error Correction: Representation, Estimation, and Testing. Econometrica 55 (2), pp. 251–276. doi:10.2307/1913236
  6. Frazzini, Andrea; Pedersen, Lasse Heje (2014): Betting against beta. Journal of Financial Economics 111 (1), pp. 1–25. doi:10.1016/j.jfineco.2013.10.005
  7. Gatev, Evan; Goetzmann, William N.; Rouwenhorst, K. Geert (2006): Pairs Trading: Performance of a Relative-Value Arbitrage Rule. Review of Financial Studies 19 (3), pp. 797–827. doi:10.1093/rfs/hhj020
  8. Jegadeesh, Narasimhan (1990): Evidence of Predictable Behavior of Security Returns. The Journal of Finance 45 (3), pp. 881–898. doi:10.1111/j.1540-6261.1990.tb05110.x
  9. Jegadeesh, Narasimhan; Titman, Sheridan (1993): Returns to Buying Winners and Selling Losers: Implications for Stock Market Efficiency. The Journal of Finance 48 (1), pp. 65–91. doi:10.1111/j.1540-6261.1993.tb04702.x
  10. Kalman, R. E. (1960): A New Approach to Linear Filtering and Prediction Problems. Journal of Basic Engineering 82 (1), pp. 35–45. doi:10.1115/1.3662552
  11. MacKinnon, James G. (1994): Approximate Asymptotic Distribution Functions for Unit-Root and Cointegration Tests. Journal of Business & Economic Statistics 12 (2), pp. 167–176. doi:10.1080/07350015.1994.10510005
  12. Said, Said E.; Dickey, David A. (1984): Testing for unit roots in autoregressive-moving average models of unknown order. Biometrika 71 (3), pp. 599–607. doi:10.1093/biomet/71.3.599
  13. Uhlenbeck, G. E.; Ornstein, L. S. (1930): On the Theory of the Brownian Motion. Physical Review 36 (5), pp. 823–841. doi:10.1103/PhysRev.36.823

Full bibliography

This page describes how Portfolio Lab calculates; past results are not a forecast. All terms in the glossary.