TSA Time Series Analysis
Financial data has memory — and exploiting that memory is how you make money
Learning Objectives
- •Understand autocorrelation and what it means for trading
- •Learn ARIMA models — when they work and when they don't
- •Use the Hurst exponent for regime classification
- •Test for stationarity and understand why it matters
Explain Like I'm 5
Time series analysis looks for patterns in data that happen over time. If it rained today, is it more likely to rain tomorrow? Same question with prices — if the market went up today, does that tell us anything about tomorrow? Time series tools help answer that.
Think of It This Way
Financial time series are like weather patterns. There are seasons (regimes), trends (climate change), and random noise (daily weather). You can't predict exact weather tomorrow, but you can know winter is coming. Time series analysis separates the predictable patterns from the noise.
1Autocorrelation — Does the Past Predict the Future?
Typical Autocorrelation of Financial Returns by Lag
2Stationarity — The Foundation Nobody Talks About
3The Hurst Exponent — Regime Detection
Rolling Hurst Exponent Over Time (Simulated)
4ARIMA — Classical But Limited
5Practical Regime Detection Workflow
Key Formulas
Autocorrelation at Lag k
Correlation of a series with itself shifted by k periods. |ρ_k| > 2/√T suggests significant autocorrelation at lag k.
Hurst Exponent (R/S Method)
H is estimated from the slope of log(R/S) vs log(n). H > 0.5 = trending, H < 0.5 = mean-reverting. Production systems compute this on rolling windows to detect regime changes in real-time.
Hands-On Code
Computing the Hurst Exponent
import numpy as np
def hurst_exponent(series, max_lag=100):
"""Compute Hurst exponent using R/S analysis."""
lags = range(2, max_lag)
rs_values = []
for lag in lags:
# Split into chunks of size 'lag'
chunks = [series[i:i+lag] for i in range(0, len(series)-lag, lag)]
rs_chunk = []
for chunk in chunks:
if len(chunk) < lag:
continue
mean_val = np.mean(chunk)
cumdev = np.cumsum(chunk - mean_val)
R = max(cumdev) - min(cumdev)
S = np.std(chunk, ddof=1)
if S > 0:
rs_chunk.append(R / S)
if rs_chunk:
rs_values.append(np.mean(rs_chunk))
# Fit log-log relationship
log_lags = np.log(list(lags[:len(rs_values)]))
log_rs = np.log(rs_values)
H = np.polyfit(log_lags, log_rs, 1)[0]
return H
# Example usage
prices = np.cumsum(np.random.randn(5000)) + 100
H = hurst_exponent(np.diff(prices))
print(f"Hurst Exponent: {H:.3f}")
if H > 0.55: print("→ TRENDING regime")
elif H < 0.45: print("→ MEAN-REVERTING regime")
else: print("→ RANDOM WALK (no clear regime)")The Hurst exponent is one of the most important features in quant trading. Values above 0.55 indicate trending markets, below 0.45 mean-reverting. This drives how you manage exits.
Knowledge Check
Q1.A Hurst exponent of 0.7 indicates:
Q2.Why do most modern quant systems skip ARIMA for signal generation?
Assignment
Compute the Hurst exponent on rolling 252-bar windows for any financial instrument. Plot it over time. Can you identify periods where the regime switched from trending to mean-reverting? Do those shifts correspond to market events you can research?