Close Navigation
Statistical Arbitrage Using Cointegrated Stock Pairs in Indian Equity Market (2015-2025) | EPAT Project

Statistical Arbitrage Using Cointegrated Stock Pairs in Indian Equity Market (2015-2025) | EPAT Project

Posted April 13, 2026 at 1:45 pm

Shant Tondon
QuantInsti

The article “Statistical Arbitrage Using Cointegrated Stock Pairs in Indian Equity Market (2015-2025) | EPAT Project” was originally published on QuantInsti blog.

About the author

Shant Tondon brings a diverse background blending financial markets analysis, consulting, and entrepreneurship. He holds a Bachelor’s in Commerce with a focus on Financial Markets from Narsee Monjee College of Commerce and Economics, and completed his High School Diploma in Business/Commerce at Mayo College, Ajmer. Professionally, Shant gained early analytical experience as an intern at Teach For India and KPMG in Mumbai, followed by a role as an Analyst at PwC.

Project Abstract

This project builds and evaluates a market-neutral pairs trading strategy focusing on 25 NSE large-cap stocks spanning the Banking, IT, Pharma, Cement, and Auto sectors. The pairs are selected using a residual stationarity test, specifically the ADF(0) with MacKinnon p-value, on a training sample. To ensure statistical robustness and control for false discoveries, the Benjamini–Hochberg False Discovery Rate (FDR) at 5% is applied.

The strategy trades mean-reversion via z-scores of the spread using a walk-forward train/test split. It represents a clean, defendable academic implementation with no look-ahead bias, explicit transaction costs (5 bps per leg per side), equal capital per active pair (₹5,00,000), and comprehensive portfolio-level risk metrics.

Introduction & Project Motivation

Pairs trading is a classic statistical arbitrage strategy that seeks to exploit temporary price divergences between two related assets while maintaining a market-neutral stance. This project applies this concept to the Indian equity market between January 1, 2015, and June 30, 2025.

The primary motivation was to build a rigorous prototype that addresses common algorithmic trading pitfalls, such as look-ahead bias, incomplete Profit and Loss (PnL) calculations, and inadequate multiple testing controls.

Strategy & Implementation Methodology (Technical Breakdown)

The strategy relies on a rolling walk-forward methodology utilizing a 252 trading-day training window and a 21-day test step.

1. Pair Selection & Cointegration: During the training phase, the hedge ratio (β) is estimated using Ordinary Least Squares (OLS). Residual stationarity is then tested using the ADF(0) t-stat to generate a MacKinnon p-value. The Benjamini–Hochberg FDR is applied at 5% to limit false positives. Three highly cointegrated pairs emerged from the framework: HDFCBANK.NS vs KOTAKBANK.NSHEROMOTOCO.NS vs ULTRACEMCO.NS, and HCLTECH.NS vs ICICIBANK.NS.

2. Signal Generation Logic: To prevent look-ahead bias, the rolling variables for standard deviation and mean are strictly shifted by 1 day.

  • Spread Calculation: St = At - β × Bt
  • Z-Score Calculation: zt = (St - μt-1) / σt-1
  • Execution Rules: Enter when |zt| > 1.5 and exit when zt crosses 0.

Python Implementation Code

Below is a conceptual Python snippet demonstrating the core mathematical logic utilized in Shant’s strategy:

import pandas as pd
import statsmodels.api as sm

def calculate_signals(train_data, test_data, stock_a, stock_b):
    # 1. Estimate Hedge Ratio (Beta) using OLS on Training Window
    model = sm.OLS(train_data[stock_a], train_data[stock_b]).fit()
    beta = model.params

    # 2. Calculate Out-of-Sample Spread
    # Spread formula: S_t = A_t - beta * B_t
    spread = test_data[stock_a] - (beta * test_data[stock_b])

    # 3. Calculate Z-Score strictly avoiding look-ahead bias
    # z_t = (S_t - mu_{t-1}) / sigma_{t-1}
    rolling_mean = spread.rolling(window=30).mean().shift(1)
    rolling_std = spread.rolling(window=30).std().shift(1)
    z_score = (spread - rolling_mean) / rolling_std

    # 4. Generate Trading Signals based on Z-Score Thresholds
    # Enter when absolute z-score > 1.5, Exit when it crosses 0
    long_entry = z_score < -1.5
    short_entry = z_score > 1.5
    exit_signal = (z_score.shift(1) * z_score <= 0)

    return z_score, long_entry, short_entry, exit_signal

3. Portfolio & Risk Management:

  • Sizing: Equal-weight capital allocation, assigning ₹5,00,000 per active pair.
  • Costs: Transaction costs are explicitly modeled at 5 bps per leg per side for entry and exit.
  • PnL Calculation: PnL is mapped from both legs. Any open position is force-closed on the final backtest day to ensure complete reporting.

Key Findings & Portfolio Performance

The out-of-sample backtest generated the following portfolio-level performance metrics over the test period:

Strategy Performance Snapshot

Capital Base₹15,00,000
Pairs Traded3
Backtest PeriodJan 11, 2016 – Jun 27, 2025
Total Trades271
Win Ratio63.47%
Total PnL₹1,65,544.97
PnL / Capital11.04%
Annualized Return0.30%
Annualized Volatility13.34%
Sharpe Ratio0.089
Max Drawdown-34.31%

Challenges & Limitations

  1. Sizing Constraints: The allocation is educational (equal capital per pair); it does not dynamically model capacity limits or real margin constraints.
  2. Transaction Costs: Modeled cleanly at 5 bps per leg per side, but real-world execution slippage and bid-ask spreads can differ.
  3. ADF(0) Approximation: The model uses a lag-0 ADF for computational speed. A full ADF test with optimized lags is recommended for future iterations.
  4. Multiple Testing: While the FDR method reduces false discoveries, it does not completely eliminate them.
  5. Survivorship Bias: The 25-stock universe is fixed and does not dynamically account for historical index reconstitution.

Next steps

Improving Strategy Performance

While the current strategy provides a clean academic baseline, several targeted enhancements can meaningfully improve its risk-adjusted returns and real-world applicability:

1. Optimise the ADF Lag Selection

Replace the current ADF(0) shortcut with an information-criterion-based lag selector (AIC or BIC). This reduces the risk of spurious cointegration signals and improves pair selection quality, leading to more stable and reliable trade entries.

2. Expand the Universe and Diversify Pairs

The current three-pair portfolio is highly concentrated. Extending the stock universe beyond 25 large-caps to include mid-cap NSE stocks across additional sectors (Energy, FMCG, Metals) would yield a broader set of cointegrated candidates, improve diversification, and reduce the impact of any single pair breaking down.

3. Introduce Dynamic Position Sizing

The strategy currently uses a fixed ₹5,00,000 per pair. Replacing this with volatility-scaled sizing (e.g., inverse-volatility or Kelly-criterion weighting) would allocate more capital to pairs showing stronger mean-reversion signals and tighter spreads, improving overall Sharpe ratio and reducing drawdowns.

4. Refine Entry/Exit Thresholds Adaptively

The fixed z-score thresholds of ±1.5 for entry and 0 for exit are static across all market regimes. An adaptive threshold model; where entry and exit levels are calibrated to each pair’s rolling volatility or regime classification (trending vs. mean-reverting), can filter out low-quality signals and improve the win ratio beyond the current 63.47%.

5. Incorporate Stop-Loss Rules to Control Drawdown

The current maximum drawdown of -34.31% is high relative to the annualised return of 0.30%. Adding a pair-level stop-loss (e.g., exit when the z-score breaches ±3.0 or when unrealised loss exceeds a fixed percentage of allocated capital) would cap downside on regime-breaking events and substantially improve the Sharpe ratio.

6. Address Survivorship Bias with a Rolling Universe

The fixed 25-stock universe inflates historical performance by only including companies that survived the full 2015–2025 period. Using a point-in-time NSE Nifty 50 or Nifty 100 constituent list that reflects actual index composition at each training window would eliminate this bias and produce more realistic forward-looking performance estimates.

Visit QuantInsti for more additional information on this topic.

Join The Conversation

For specific platform feedback and suggestions, please submit it directly to our team using these instructions.

If you have an account-specific question or concern, please reach out to Client Services.

We encourage you to look through our FAQs before posting. Your question may already be covered!

Leave a Reply

Disclosure: Interactive Brokers Third Party

Information posted on IBKR Campus that is provided by third-parties does NOT constitute a recommendation that you should contract for the services of that third party. Third-party participants who contribute to IBKR Campus are independent of Interactive Brokers and Interactive Brokers does not make any representations or warranties concerning the services offered, their past or future performance, or the accuracy of the information provided by the third party. Past performance is no guarantee of future results.

This material is from QuantInsti and is being posted with its permission. The views expressed in this material are solely those of the author and/or QuantInsti and Interactive Brokers is not endorsing or recommending any investment or trading discussed in the material. This material is not and should not be construed as an offer to buy or sell any security. It should not be construed as research or investment advice or a recommendation to buy, sell or hold any security or commodity. This material does not and is not intended to take into account the particular financial conditions, investment objectives or requirements of individual customers. Before acting on this material, you should consider whether it is suitable for your particular circumstances and, as necessary, seek professional advice.

Disclosure: Order Types / TWS

The order types available through Interactive Brokers LLC's trading platforms are designed to help you limit your loss and/or lock in a profit. Market conditions and other factors may affect execution. In general, orders guarantee a fill or guarantee a price, but not both. In extreme market conditions, an order may either be executed at a different price than anticipated or may not be filled in the marketplace.

Disclosure: API Examples Discussed

Please keep in mind that the examples discussed in this material are purely for technical demonstration purposes, and do not constitute trading advice. Also, it is important to remember that placing trades in a paper account is recommended before any live trading.

IBKR Campus Newsletters

This website uses cookies to collect usage information in order to offer a better browsing experience. By browsing this site or by clicking on the "ACCEPT COOKIES" button you accept our Cookie Policy.