Markets: A Rigorous Course

4.1 Technical analysis as statistical hypotheses

Core about 35 min

Motivation

Technical analysis is the study of price and volume history to time trades. Most of it is stated in pictures and folklore. A researcher's first job is to turn each picture into a function of data and each piece of folklore into a hypothesis that data can reject. Once you do this, two things become obvious: most indicators are reweightings of past returns, and an indicator "works" only if returns are autocorrelated or if the signal sorts assets with different mean returns.

4.1.1Setup#

Let PtP_t be the close of a stock or index on trading day tt, adjusted for splits, bonuses and dividends (a corporate-action adjustment rescales past prices so that returns across the event are correct). Write pt=ln⁡Ptp_t=\ln P_t and the log return rt=pt−pt−1r_t=p_t-p_{t-1}. Each day also has an open OtO_t, high HtH_t, low LtL_t and traded volume VtV_t (shares). Let Ft\mathcal F_t be the information available after the close of day tt: all bars up to and including tt.

Definition 4.1signal

A signal is a process sts_t that is Ft\mathcal F_t-measurable: its value on day tt is a function of bars dated ≤t\le t only. A position rule maps the signal to a target weight wtw_t (fraction of equity), which is first held from the open of day t+1t+1.

Definition 4.2trading hypothesis

For horizon h≥1h\ge 1 let Rt,t+h=∑j=1hrt+jR_{t,t+h}=\sum_{j=1}^{h} r_{t+j} be the forward return. A rule built on a binary signal st∈{0,1}s_t\in\{0,1\} has predictive content if

Δh  =  E[Rt,t+h∣st=1]−E[Rt,t+h∣st=0]≠0.\Delta_h \;=\; \mathbb E[R_{t,t+h}\mid s_t=1]-\mathbb E[R_{t,t+h}\mid s_t=0]\neq 0 .

It is economically useful only if Δh\Delta_h exceeds the round-trip cost of acting on the signal (4.4.4). The null hypothesis of the weak-form efficient market (prices follow a martingale with constant drift; see M13 · 13.1) implies Δh=0\Delta_h=0 for every signal.

Two points follow at once. First, the conditioning must be on Ft\mathcal F_t, never on anything dated later; the most common bug in retail backtests is to compute sts_t with the close of day tt and also earn the return of day tt. Second, the hypothesis is about a conditional mean. A chart pattern that "looks bullish" is not a hypothesis until it says which mean, over which horizon, compared with what.

4.1.2Indicators as functions of the price series#

Definition 4.3core indicators

For a series xx and window nn:

  • Simple moving average: SMAn(x)t=1n∑k=0n−1xt−k\mathrm{SMA}_n(x)_t=\frac1n\sum_{k=0}^{n-1}x_{t-k}.
  • Exponential moving average: EMAn(x)t=αxt+(1−α)EMAn(x)t−1\mathrm{EMA}_n(x)_t=\alpha x_t+(1-\alpha)\mathrm{EMA}_n(x)_{t-1} with α=2/(n+1)\alpha=2/(n+1).
  • Trend: the sign of a smoothed slope. Common choices are sign⁡(pt−pt−n)\operatorname{sign}(p_t-p_{t-n}) (time-series momentum), sign⁡(Pt−SMAn(P)t)\operatorname{sign}(P_t-\mathrm{SMA}_n(P)_t), or sign⁡(SMAm−SMAn)\operatorname{sign}(\mathrm{SMA}_m-\mathrm{SMA}_n) for m<nm<n.
  • Resistance and support (Donchian channel): Utn=max⁡(Ht−n,…,Ht−1)U^n_t=\max(H_{t-n},\dots,H_{t-1}) and Dtn=min⁡(Lt−n,…,Lt−1)D^n_t=\min(L_{t-n},\dots,L_{t-1}). A resistance level is a price where selling has previously stopped advances; the Donchian channel is the simplest objective version. Note that the window excludes day tt.
  • Breakout: Btn=1{Pt>Utn}B^n_t=\mathbf 1\{P_t>U^n_t\}, the close exceeds the highest high of the previous nn days.
  • Relative volume: RVOLtn=Vt/1n∑k=1nVt−k\mathrm{RVOL}^n_t=V_t\big/\frac1n\sum_{k=1}^{n}V_{t-k}. Again the average excludes today.
  • Relative strength (RS) against a benchmark index ItI_t (for example Nifty 500): RSt=Pt/It\mathrm{RS}_t=P_t/I_t. The Mansfield version is 100 (RSt/SMAn(RS)t−1)100\,(\mathrm{RS}_t/\mathrm{SMA}_n(\mathrm{RS})_t-1), positive when the stock is outperforming its own recent relative trend. A cross-sectional RS rank is the percentile of a stock's trailing 12-month return within a universe; IBD's proprietary "RS rating" is of this type.

Swing traders also use pivot support and resistance: a swing high at day uu is a bar with Hu>Hu±jH_u>H_{u\pm j} for j=1..kj=1..k. A swing high at uu is only known at day u+ku+k. Code that marks it at uu is using the future. This is the single most common source of look-ahead in pattern-recognition code.

Definition 4.4Wilder's RSI

The relative strength index (unrelated to relative strength above) with period nn (usually 14) is built from price changes dt=Pt−Pt−1d_t=P_t-P_{t-1}. Let WW denote Wilder's smoother: Wn=1n∑t=1nxtW_n=\frac1n\sum_{t=1}^{n}x_t, then Wt=(n−1)Wt−1+xtnW_t=\frac{(n-1)W_{t-1}+x_t}{n}, an EMA with α=1/n\alpha=1/n. Define Ut=W(d+)tU_t=W(d^+)_t, Dt=W(d−)tD_t=W(d^-)_t with d+=max⁡(d,0)d^+=\max(d,0), d−=max⁡(−d,0)d^-=\max(-d,0), and

RSIt=100−1001+Ut/Dt=100 UtUt+Dt.\mathrm{RSI}_t=100-\frac{100}{1+U_t/D_t}=100\,\frac{U_t}{U_t+D_t}.

4.1.3What moving averages and RSI really are#

Proposition 4.1moving-average rules are momentum rules

Apply moving averages to log prices. For 1≤m<n1\le m<n,

SMAm(p)t−SMAn(p)t=∑i=0n−2wi rt−i,wi=n−1−in−(m−1−i)+m  ≥0,(4.1)\mathrm{SMA}_m(p)_t-\mathrm{SMA}_n(p)_t=\sum_{i=0}^{n-2} w_i\, r_{t-i},\qquad w_i=\frac{n-1-i}{n}-\frac{(m-1-i)^+}{m}\;\ge 0, \tag{4.1}

with ∑iwi=(n−m)/2\sum_i w_i=(n-m)/2. The weights rise linearly for i<m−1i<m-1, peak at i=m−1i=m-1, and fall linearly to zero at i=n−1i=n-1. The rule "price above its nn-day average" is the case m=1m=1, with linearly declining weights wi=(n−1−i)/nw_i=(n-1-i)/n.

Proof

Write pt−j=pt−∑i=0j−1rt−ip_{t-j}=p_t-\sum_{i=0}^{j-1}r_{t-i}. Then

SMAn(p)t=1n∑j=0n−1(pt−∑i=0j−1rt−i)=pt−1n∑i=0n−2#{j:i<j≤n−1} rt−i=pt−∑i=0n−2n−1−inrt−i.\begin{aligned} \mathrm{SMA}_n(p)_t&=\frac1n\sum_{j=0}^{n-1}\Big(p_t-\sum_{i=0}^{j-1}r_{t-i}\Big)=p_t-\frac1n\sum_{i=0}^{n-2}\#\{j: i<j\le n-1\}\,r_{t-i}\\ &=p_t-\sum_{i=0}^{n-2}\frac{n-1-i}{n}r_{t-i}. \end{aligned}

The same with mm gives pt−∑i=0m−2m−1−imrt−ip_t-\sum_{i=0}^{m-2}\frac{m-1-i}{m}r_{t-i}. Subtract: ptp_t cancels and (4.1) follows. For i≤m−2i\le m-2, wi=(1−i+1n)−(1−i+1m)=(i+1)(1m−1n)>0w_i=\big(1-\frac{i+1}{n}\big)-\big(1-\frac{i+1}{m}\big)=(i+1)\big(\frac1m-\frac1n\big)>0, increasing in ii. For m−1≤i≤n−2m-1\le i\le n-2, wi=(n−1−i)/n>0w_i=(n-1-i)/n>0, decreasing. Finally ∑i=0n−2n−1−in=(n−1)n/2n=n−12\sum_{i=0}^{n-2}\frac{n-1-i}{n}=\frac{(n-1)n/2}{n}=\frac{n-1}{2}, and likewise m−12\frac{m-1}{2}, so ∑wi=n−m2\sum w_i=\frac{n-m}{2}.∎

So the 50/200-day "golden cross" is a bet on a triangular-weighted average of the last 199 daily returns, with peak weight on the return 49 days ago. Every moving-average rule (SMA, EMA, MACD) is a linear filter of past returns followed by a nonlinearity (the sign). Its value depends entirely on the autocorrelation structure of returns.

Proposition 4.2expected return of a linear trend rule

Let rtr_t be covariance-stationary with mean μ\mu and autocovariances γk=Cov⁡(rt,rt−k)\gamma_k=\operatorname{Cov}(r_t,r_{t-k}). Take the position xt=∑i=0L−1wirt−ix_t=\sum_{i=0}^{L-1}w_i r_{t-i}, held over day t+1t+1. Then

E[xtrt+1]=μ2∑i=0L−1wi+∑i=0L−1wiγi+1.(4.2)\mathbb E[x_t r_{t+1}]=\mu^2\sum_{i=0}^{L-1}w_i+\sum_{i=0}^{L-1}w_i\gamma_{i+1}. \tag{4.2}
Proof

E[rt−irt+1]=Cov⁡(rt−i,rt+1)+μ2=γi+1+μ2\mathbb E[r_{t-i}r_{t+1}]=\operatorname{Cov}(r_{t-i},r_{t+1})+\mu^2=\gamma_{i+1}+\mu^2. Sum with weights.∎

The first term is not timing skill: if μ>0\mu>0, a rule with positive weights is long on average and collects part of the drift. The second term is the only source of timing profit, and it is a weighted sum of autocovariances at lags 1..L1..L. Under a random walk (γk=0\gamma_k=0) every MA rule earns only a diluted buy-and-hold return, before costs. The sign function in practical rules changes the constants but not the conclusion; Problem 4.3 asks you to show that for Gaussian returns the sign rule's timing term is still a linear combination of the γk\gamma_k.

Worked example 4.1a one-day momentum rule on an index

Suppose Nifty 50 daily returns have σ=1%\sigma=1\%, μ=0.05%\mu=0.05\% and first-order autocorrelation ρ1=0.05\rho_1=0.05, with γk=0\gamma_k=0 for k≥2k\ge2. These are illustrative numbers of the right order, not estimates; M02 shows how to estimate them. Use the unit-volatility position xt=rt/σx_t=r_t/\sigma (in multiples of capital). By (4.2) with L=1L=1, w0=1/σw_0=1/\sigma:

E[xtrt+1]=μ2+ρ1σ2σ=2.5×10−7+5×10−60.01=5.25×10−4 per day.\mathbb E[x_tr_{t+1}]=\frac{\mu^2+\rho_1\sigma^2}{\sigma}=\frac{2.5\times10^{-7}+5\times10^{-6}}{0.01}=5.25\times10^{-4}\ \text{per day}.

Its daily volatility is about σ⋅1=1%\sigma\cdot 1=1\%, so the gross daily Sharpe ratio is 0.05250.0525, about 0.830.83 annualised. Now the cost. The position changes each day by ∣xt−xt−1∣≈∣Zt−Zt−1∣|x_t-x_{t-1}|\approx|Z_t-Z_{t-1}| with ZZ iid standard normal, whose mean is E∣N(0,2)∣=2/π≈1.128\mathbb E|N(0,2)|=2/\sqrt\pi\approx1.128 times capital. Delivery-equity costs at a discount broker are about 11.9 bp per side (4.4.4). Daily cost ≈1.128×11.9=13.4\approx1.128\times11.9=13.4 bp, against a gross edge of 5.25 bp. The net expected return is about −8-8 bp a day. The predictability is real in this example and the strategy still loses money. Index futures are cheaper (M01), which is why fast trend rules are run on futures, not on delivery equity.

Proposition 4.3RSI is a normalised momentum oscillator

With WW Wilder's smoother,

RSIt=50+50 W(d)tW(∣d∣)t.(4.3)\mathrm{RSI}_t=50+50\,\frac{W(d)_t}{W(|d|)_t}. \tag{4.3}
Proof

WW is linear, d=d+−d−d=d^+-d^- and ∣d∣=d++d−|d|=d^++d^-. So W(d)=U−DW(d)=U-D and W(∣d∣)=U+DW(|d|)=U+D. Then 50+50U−DU+D=50(U+D)+50(U−D)U+D=100UU+D50+50\frac{U-D}{U+D}=\frac{50(U+D)+50(U-D)}{U+D}=100\frac{U}{U+D}.∎

RSI is therefore an exponentially weighted mean price change divided by an exponentially weighted mean absolute change, mapped to [0,100][0,100]. "RSI above 70 is overbought, sell" is a short-term reversal hypothesis: it says that a large normalised recent gain predicts a negative return. "RSI above 50 and rising" is a momentum hypothesis. The same indicator supports opposite rules, and both cannot be right on the same horizon. The data must decide, and 4.3 summarises what the data say. The code checks (4.3) to machine precision.

4.1.4Testing one rule honestly#

The simplest test of Definition 4.2 is an event study (M12 builds this in full). Collect the NN days with st=1s_t=1, compute forward returns Rt,t+hR_{t,t+h} in excess of the index, and form t=Rˉ/(σ^R/N)t=\bar R/(\hat\sigma_R/\sqrt N). Two traps make this tt-statistic too large.

Proposition 4.4overlapping horizons inflate tt-statistics

Let daily excess returns be iid with variance σ2\sigma^2, and let Yt=∑j=1hrt+jY_t=\sum_{j=1}^{h}r_{t+j} be sampled on NN consecutive days (N≫hN\gg h). Then

Var⁡(Yˉ)≈h2σ2N,while the naive formula gives Var⁡(Yt)N=hσ2N.(4.4)\operatorname{Var}(\bar Y)\approx\frac{h^2\sigma^2}{N},\qquad\text{while the naive formula gives }\frac{\operatorname{Var}(Y_t)}{N}=\frac{h\sigma^2}{N}. \tag{4.4}

The naive standard error is too small by a factor h\sqrt h.

Proof

Cov⁡(Yt,Yt+k)=(h−∣k∣)σ2\operatorname{Cov}(Y_t,Y_{t+k})=(h-|k|)\sigma^2 for ∣k∣<h|k|<h and zero otherwise, since the two windows share h−∣k∣h-|k| days. Hence Var⁡(Yˉ)=1N2∑t,sCov⁡(Yt,Ys)≈1N∑k=−(h−1)h−1(h−∣k∣)σ2=h2σ2N\operatorname{Var}(\bar Y)=\frac1{N^2}\sum_{t,s}\operatorname{Cov}(Y_t,Y_s)\approx\frac1N\sum_{k=-(h-1)}^{h-1}(h-|k|)\sigma^2=\frac{h^2\sigma^2}{N}, using ∑k=−(h−1)h−1(h−∣k∣)=h2\sum_{k=-(h-1)}^{h-1}(h-|k|)=h^2.∎

Use non-overlapping events, or Newey–West (heteroskedasticity- and autocorrelation-consistent) standard errors with at least h−1h-1 lags. The second trap is cross-sectional: breakouts cluster in time (many stocks break out in the same strong week), so events are not independent across stocks. Cluster standard errors by date, or test the rule as a calendar-time portfolio.

Worked example 4.2a 20-day breakout in Nifty 500 stocks

Suppose a screen finds 60 non-overlapping 20-day breakouts on above-average volume, with mean 20-day return in excess of the Nifty 500 of 1.2% and standard deviation 8%. Then t=0.012/(0.08/60)=1.16t=0.012/(0.08/\sqrt{60})=1.16. The evidence is consistent with no edge. To reach t=2t=2 at the same mean and dispersion you need N=(2×0.08/0.012)2≈178N=(2\times0.08/0.012)^2\approx178 independent events. If the 60 events had come from overlapping daily samples, the naive tt could easily exceed 3, which would be spurious.

Practitioner notes

  • The canonical academic test of chart rules is Brock, Lakonishok and LeBaron (1992). They tested moving-average and trading-range-break rules on the Dow Jones index from 1897 to 1986, reported strong support for the rules, and found returns after buy signals higher and less volatile than after sell signals. They used bootstraps under random-walk, AR(1), GARCH-M and EGARCH nulls. Case study 4.7.3 discusses what happened when Sullivan, Timmermann and White (1999) asked how many rules had been tried before those 26 were chosen.
  • Indicator parameters (14 for RSI, 20/50/200 for moving averages) are conventions, not optimal values. Every parameter you vary is another trial, and 4.6 charges for it.
  • Prefer rules on log prices or returns. A rule on price levels (a fixed ₹ stop, "round number" resistance at ₹1,000) changes meaning when the series is back-adjusted for a later bonus issue. That is a look-ahead in disguise (4.4.2).

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.