Moving averages are just the beginning. Here are more sophisticated time series techniques that can improve your trading analysis.
Exponentially Weighted Statistics
Standard moving averages weight all periods equally. Exponential weighting gives more importance to recent data:
import numpy as np
import pandas as pd
def ewm_volatility(prices, span=20):
returns = np.diff(np.log(prices))
ewm_var = pd.Series(returns).ewm(span=span).var()
return np.sqrt(ewm_var * 252) # Annualized
def ewm_correlation(series1, series2, span=30):
r1 = np.diff(np.log(series1))
r2 = np.diff(np.log(series2))
return pd.Series(r1).ewm(span=span).corr(pd.Series(r2))
Hurst Exponent: Trending or Mean-Reverting?
def hurst_exponent(prices, max_lag=100):
"""
H > 0.5: trending (momentum strategies work)
H = 0.5: random walk (no edge)
H < 0.5: mean-reverting (reversion strategies work)
"""
lags = range(2, max_lag)
tau = []
for lag in lags:
pp = np.subtract(prices[lag:], prices[:-lag])
tau.append(np.std(pp))
log_lags = np.log(lags)
log_tau = np.log(tau)
# Linear regression
coeffs = np.polyfit(log_lags, log_tau, 1)
return coeffs[0] # Hurst exponent
# Example
h = hurst_exponent(price_series)
if h > 0.55:
print("Trending — use momentum strategies")
elif h < 0.45:
print("Mean-reverting — use reversion strategies")
else:
print("Random walk — no clear edge")
Regime Detection with Hidden Markov Models
def simple_regime_detection(returns, window=60):
"""
Detect market regimes using rolling statistics.
"""
rolling_mean = pd.Series(returns).rolling(window).mean()
rolling_std = pd.Series(returns).rolling(window).std()
regimes = []
for m, s in zip(rolling_mean, rolling_std):
if np.isnan(m):
regimes.append('unknown')
elif m > 0 and s < np.median(rolling_std.dropna()):
regimes.append('bull_calm')
elif m > 0 and s >= np.median(rolling_std.dropna()):
regimes.append('bull_volatile')
elif m <= 0 and s < np.median(rolling_std.dropna()):
regimes.append('bear_calm')
else:
regimes.append('bear_volatile')
return regimes
Autocorrelation Analysis
def analyze_autocorrelation(returns, max_lags=20):
"""
Check if past returns predict future returns.
Significant autocorrelation = potential edge.
"""
from statsmodels.stats.diagnostic import acorr_ljungbox
results = {}
for lag in range(1, max_lags + 1):
correlation = np.corrcoef(returns[:-lag], returns[lag:])[0, 1]
results[lag] = correlation
# Ljung-Box test for significance
lb_test = acorr_ljungbox(returns, lags=max_lags)
return {
'correlations': results,
'significant_lags': [i+1 for i, p in enumerate(lb_test['lb_pvalue']) if p < 0.05]
}
Volatility Forecasting
def garch_like_forecast(returns, alpha=0.1, beta=0.85):
"""
Simple GARCH(1,1)-like volatility forecast.
"""
omega = np.var(returns) * (1 - alpha - beta)
forecasts = [np.var(returns)]
for r in returns:
new_var = omega + alpha * r**2 + beta * forecasts[-1]
forecasts.append(new_var)
return np.sqrt(np.array(forecasts) * 252)
Seasonal Patterns
def analyze_seasonality(df):
"""
Find day-of-week and time-of-day patterns.
"""
df['dow'] = df.index.dayofweek
df['hour'] = df.index.hour
# Day of week effect
dow_returns = df.groupby('dow')['return'].agg(['mean', 'std', 'count'])
dow_returns['t_stat'] = dow_returns['mean'] / (dow_returns['std'] / np.sqrt(dow_returns['count']))
# Intraday pattern
hourly = df.groupby('hour')['return'].agg(['mean', 'std', 'count'])
return {
'day_of_week': dow_returns,
'hourly': hourly,
'best_day': dow_returns['mean'].idxmax(),
'worst_day': dow_returns['mean'].idxmin()
}
Practical Workflow
1. Calculate Hurst exponent → determine strategy type
2. Run regime detection → know current market state
3. Check autocorrelation → find predictive lags
4. Forecast volatility → set position sizes
5. Analyze seasonality → optimize entry timing
These tools give you a quantitative view of market behavior that goes far beyond simple chart patterns. Whether you're refining a strategy or preparing for a trading evaluation, data-driven analysis is the foundation. More on matching your analysis approach to the right trading environment at propfirmkey.com.
Which time series techniques have improved your trading the most?
Top comments (0)