Markets: A Rigorous Course

13A.12 Indian applications, tested

Core about 15 min

All statistics in this section are computed for this course (6 Nov 2026) from Yahoo Finance adjusted daily closes (tickers HDFCBANK.NS, ICICIBANK.NS, ^NSEI, ^NSEBANK), 4 Jan 2010 to 4 Nov 2026, on log prices, using statsmodels (coint with automatic lag selection; coint_johansen with det_order=0, one lagged difference). Yahoo's adjusted series can contain errors; a production study should use exchange data with its own corporate-action adjustments.

13A.12.1HDFC Bank and ICICI Bank#

Sample nn OLS b^\hat b EG stat EG pp Residual AR(1) half-life Johansen trace r=0r=0 (5% cv 15.49)
2010–2026 4,135 0.919 −1.44 0.785 468 days 8.79
2010–2014 1,221 1.018 −1.82 0.622 104 days 5.82
2015–2019 1,222 1.125 −3.10 0.089 69 days 10.25
2020–2026 1,692 0.381 −1.87 0.596 70 days 11.08
2023–2026 946 0.329 −1.50 0.762 107 days 4.27

In rolling two-year windows (504 trading days, stepped by 63 days, 58 windows) the EG test rejected at 5% in 12% of windows, and the OLS hedge ratio ranged from −0.25 to 1.40.

Reading There is no sample in which the two are convincingly cointegrated. The best case, 2015–19, rejects only at 10%, and that is one of five samples tried. The 12% rolling rejection rate is barely above the 5% expected under the null, and overlapping windows make it weaker evidence still. The hedge ratio is unstable to the point of changing sign. "Half-lives" of 70–100 days are computed on residuals that are not demonstrably stationary and should not be quoted. The two banks are strongly correlated in returns (0.54) and not tied in levels.

13A.12.2Nifty Bank and Nifty 50#

Sample b^\hat b EG stat EG pp Half-life Johansen trace r=0r=0 max-eig r=0r=0 (5% cv 14.26)
2010–2026 1.102 −2.97 0.116 193 days 10.87 10.81
2010–2014 1.181 −2.45 0.299 82 days 6.39 6.11
2015–2019 1.458 −4.64 0.001 21 days 22.09 21.92
2020–2026 1.029 −3.65 0.021 65 days 29.05 23.11
2023–2026 0.885 −1.84 0.612 109 days 7.22 4.25

The log ratio ln⁡(Nifty Bank/Nifty)\ln(\text{Nifty Bank}/\text{Nifty}) itself (the known vector (1,−1)(1,-1), so DF critical values apply) has an ADF statistic with constant of −2.80 (p=0.059p = 0.059); the ratio moved from 1.74 to 2.33 over the sample. Rolling two-year EG windows rejected at 5% in 22% of cases; the hedge ratio ranged from 0.63 to 1.64.

Reading This pair has an economic tie (the banks are a large part of Nifty) and the evidence is correspondingly stronger: both EG and Johansen reject in 2015–19 and 2020–26. But the hedge ratio differs between those two samples (1.46 against 1.03), the full sample and the most recent three years do not reject, and the ratio drifted up by a third. A partial accounting link produces cointegration in windows with a drifting vector. A trader using the 2015–19 hedge ratio in 2020–26 would have held a different spread from the one the data then supported. This is the setting where the Kalman filter of 13A.9 earns its keep, with the trap noted there.

13A.12.3MCX gold against COMEX-implied parity#

M10 (10.15) gives the duty-paid rupee price of gold. In logs, for a futures contract,

st=ln⁡FtMCX−[ln⁡FtCOMEX+ln⁡Xtfwd+ln⁡(1+dt)+ln⁡10×0.99531.1034768],(13A.40)s_t = \ln F^{\text{MCX}}_t - \Big[\ln F^{\text{COMEX}}_t + \ln X^{\text{fwd}}_t + \ln(1+d_t) + \ln\frac{10\times0.995}{31.1034768}\Big], \tag{13A.40}

with FCOMEXF^{\text{COMEX}} in USD per troy ounce for the matching month, XfwdX^{\text{fwd}} the USDINR forward to the same date, dtd_t the customs duty (M10 · 10.5.2) and the last term converting a fine troy ounce into 10 g of 995 gold. The cointegrating vector is known: (1,−1,−1)(1,-1,-1) on the three log prices, with dtd_t a known step function. So test sts_t with the DF/ADF critical values (constant case), not Engle–Granger ones; nothing is estimated.

What sts_t measures is the local premium or discount qq of M10 plus basis and timing noise. Three cautions.

  • Duty changes are known-date level shifts in sts_t if dtd_t is omitted or mis-dated: 24 Jul 2024 (15% to 6%) and 13 May 2026 (6% to 15%) (M10 · 10.5.2). Include dtd_t or add step dummies at those dates. A break test that "discovers" these dates teaches nothing.
  • Who arbitrages. Closing the spread physically requires importing, paying duty and delivering on MCX, which a trader cannot do. The band within which sts_t wanders is set by importers' costs, not by a trader's. Mean reversion is enforced, but slowly and with a wide band.
  • Weak exogeneity. In the VECM for (ln⁡FMCX,ln⁡FCOMEX,ln⁡X)(\ln F^{\text{MCX}}, \ln F^{\text{COMEX}}, \ln X) one expects the COMEX and USDINR loadings to be near zero: MCX adjusts to the world, not the reverse. That is a testable restriction on α\alpha (13A.4.3), and it decides which leg an arbitrageur expects to move.

M10's worked example of 2 Nov 2026 found the crude parity within 0.034% of the MCX December price, with purity and carry corrections nearly cancelling. A daily sts_t series with these corrections applied is a good first project for the methods of this module; MCX historical data are on the exchange's website.

13A.12.4The gold/silver ratio, revisited#

M10 · 10.7.2 tested ln⁡(Gold/Silver)\ln(\text{Gold}/\text{Silver}) with the known vector (1,−1)(1,-1): ADF p=0.055p = 0.055 on 2001–2026 month-end data, not rejecting in either sub-sample, half-life about 13.6 months before bias correction. Two additions from this module.

  • Known versus estimated vector. Imposing (1,−1)(1,-1) is what allows DF critical values. If you estimate the hedge ratio instead, you need EG critical values (−3.34 at 5% for a pair), which are harder to beat: M10's statistic of −2.83 would be further from rejection. Imposing a correct known vector buys power; imposing a wrong one destroys the test.
  • Economics of trading it. Suppose (illustratively) monthly residual s.d. 0.05 around M10's φ^=0.9503\hat\varphi = 0.9503. Then κ=0.612\kappa = 0.612 per year and the stationary s.d. is 0.161. By (13A.28), a cycle between ±1\pm1 stationary s.d. takes 9.8 years on average, and between ±0.5\pm0.5 s.d. 4.3 years (Problem 13A.16). Even if the ratio is stationary, it offers a handful of round trips per career, each estimated from a sample containing only a few half-lives.

Data lab

Pairs on Indian data: Engle–Granger, half-life and a Kalman hedge ratio

The lab aligns daily closes of a pair on common trading days from 2010, takes logs, runs the Engle–Granger step-1 regression (13A.14) and the residual Dickey–Fuller regression (13A.15) without lags, and compares the tt-ratio with the Engle–Granger critical values (−3.34 at 5%, −3.04 at 10%), not the Dickey–Fuller ones. It reports the AR(1) half-life of the residual (13A.7) and plots a Kalman-filter hedge ratio (13A.9) against the static and the 252-day rolling OLS ratios. The sub-samples are those of the tables in 13A.12.

The data are the API's daily closes, which may not be adjusted for corporate actions the way the notes' series were; a split, bonus or merger shows up as a level shift in the spread. Numbers will differ from 13A.12 for that reason and because the test here uses no augmentation lags.

What to look at The R2R^2 and Durbin–Watson of the levels regression (Granger and Newbold's warning sign, 13A.3); whether the residual test rejects in any sub-sample; how far the hedge ratio drifts.

Questions

  1. For HDFC Bank and ICICI Bank, is R2>DWR^2 > \text{DW}? What does 13A.3 conclude from that, and does the EG test agree?
  2. For Nifty Bank and Nifty 50, which sub-samples reject at 5%? Do the hedge ratios in those samples agree, and what does that imply for a trader who fixed the ratio in 2019?
  3. Quote the half-life with an interval using (13A.25). Is it short enough for a holding period you would accept?
  4. Raise δ\delta until the Kalman path tracks every wiggle. Why is the resulting spread a poor trading signal (13A.9.3)?

Create a free account

Reading is open to everyone. An account keeps your progress, answers, notes and code drafts, and gives you the study plan, the journals and the simulator. Running code needs an account approved for it.