허스트 지수(Hurst Exponent)란?
허스트 지수는 영국의 수문학자 해럴드 허스트(Harold Edwin Hurst)가 나일강 수위 예측을 위해 개발한 통계 지표입니다. 금융 시장에 적용하면 시계열이 추세를 따르는지, 평균으로 회귀하는지, 랜덤워크인지를 객관적으로 판별할 수 있습니다.
- H > 0.5: 지속성(Persistence) — 상승이 상승을, 하락이 하락을 부름. 추세추종 전략에 유리.
- H = 0.5: 랜덤워크 — 과거가 미래를 예측하지 못함. 매매 자제.
- H < 0.5: 반지속성(Anti-persistence) — 상승 후 하락, 하락 후 상승. 평균회귀 전략에 유리.
대부분의 기술적 지표가 “지금 추세인가?”를 사후적으로 판단하는 반면, 허스트 지수는 “이 시장이 추세를 만들 성질인가?”를 사전에 평가한다는 점에서 차별화됩니다.
R/S 분석법으로 허스트 지수 계산
가장 고전적인 계산법인 Rescaled Range(R/S) 분석입니다. 시계열을 다양한 길이의 구간으로 나누어 각 구간의 범위(R)를 표준편차(S)로 정규화한 뒤, 로그-로그 회귀로 허스트 지수를 추정합니다.
import numpy as np
import pandas as pd
import ccxt
# 바이낸스 일봉 데이터 수집
exchange = ccxt.binance()
ohlcv = exchange.fetch_ohlcv('BTC/USDT', '1d', limit=500)
df = pd.DataFrame(ohlcv, columns=['ts','open','high','low','close','volume'])
df['returns'] = df['close'].pct_change().dropna()
returns = df['returns'].dropna().values
def hurst_rs(series):
"""R/S 분석법으로 허스트 지수 계산"""
n = len(series)
if n < 20:
return 0.5
# 다양한 구간 크기
sizes = []
rs_values = []
for size in range(10, n // 2):
n_chunks = n // size
rs_chunk = []
for i in range(n_chunks):
chunk = series[i * size:(i + 1) * size]
mean_chunk = chunk.mean()
deviate = np.cumsum(chunk - mean_chunk)
R = deviate.max() - deviate.min()
S = chunk.std(ddof=1)
if S > 0:
rs_chunk.append(R / S)
if rs_chunk:
sizes.append(size)
rs_values.append(np.mean(rs_chunk))
# 로그-로그 회귀
log_sizes = np.log(sizes)
log_rs = np.log(rs_values)
hurst, _ = np.polyfit(log_sizes, log_rs, 1)
return hurst
H = hurst_rs(returns)
print(f"허스트 지수 (R/S): {H:.4f}")
if H > 0.55:
print("→ 지속성: 추세추종 전략 유리")
elif H < 0.45:
print("→ 반지속성: 평균회귀 전략 유리")
else:
print("→ 랜덤워크 근접: 매매 신중")
DFA 방법: 더 정확한 허스트 추정
Detrended Fluctuation Analysis(DFA)는 R/S 분석의 한계를 보완한 방법으로, 비정상(non-stationary) 시계열에서도 정확한 허스트 지수를 추정할 수 있습니다.
def hurst_dfa(series):
"""DFA(Detrended Fluctuation Analysis)로 허스트 지수 계산"""
n = len(series)
cumsum = np.cumsum(series - series.mean())
scales = np.unique(np.logspace(
np.log10(10), np.log10(n // 4), num=20
).astype(int))
fluctuations = []
for scale in scales:
n_segments = n // scale
if n_segments < 1:
continue
fluct = []
for i in range(n_segments):
segment = cumsum[i * scale:(i + 1) * scale]
x = np.arange(scale)
# 선형 추세 제거
coeffs = np.polyfit(x, segment, 1)
trend = np.polyval(coeffs, x)
detrended = segment - trend
fluct.append(np.sqrt(np.mean(detrended ** 2)))
fluctuations.append(np.mean(fluct))
# 로그-로그 회귀
log_scales = np.log(scales[:len(fluctuations)])
log_fluct = np.log(fluctuations)
hurst, _ = np.polyfit(log_scales, log_fluct, 1)
return hurst
H_dfa = hurst_dfa(returns)
print(f"허스트 지수 (DFA): {H_dfa:.4f}")
롤링 허스트로 실시간 레짐 감지
허스트 지수를 롤링 윈도우로 계산하면, 시장이 추세 국면에서 레인지 국면으로 전환되는 시점을 실시간으로 포착할 수 있습니다.
def rolling_hurst(returns_series, window=100, step=5):
"""롤링 허스트 지수 계산"""
indices = []
hurst_values = []
for i in range(window, len(returns_series), step):
chunk = returns_series[i - window:i]
h = hurst_dfa(chunk)
indices.append(i)
hurst_values.append(h)
return pd.Series(hurst_values, index=indices)
hurst_series = rolling_hurst(returns, window=100, step=5)
# 레짐 전환점 감지
def detect_regime_shift(hurst_series, threshold=0.5):
"""허스트 지수 기반 레짐 전환 감지"""
regimes = []
for h in hurst_series:
if h > 0.6:
regimes.append('STRONG_TREND')
elif h > 0.5:
regimes.append('MILD_TREND')
elif h > 0.4:
regimes.append('MILD_REVERT')
else:
regimes.append('STRONG_REVERT')
return regimes
regimes = detect_regime_shift(hurst_series)
print(f"현재 레짐: {regimes[-1]}")
print(f"현재 허스트: {hurst_series.iloc[-1]:.4f}")
허스트 기반 전략 전환 시스템
핵심 아이디어는 간단합니다: 허스트가 높으면 추세추종, 낮으면 평균회귀. 이 원칙을 자동매매 시스템에 통합합니다.
class HurstAdaptiveStrategy:
def __init__(self, trend_threshold=0.55, revert_threshold=0.45):
self.trend_th = trend_threshold
self.revert_th = revert_threshold
def trend_following(self, df, period=20):
"""추세추종: 이동평균 교차"""
sma_fast = df['close'].rolling(period).mean().iloc[-1]
sma_slow = df['close'].rolling(period * 3).mean().iloc[-1]
if sma_fast > sma_slow:
return 'BUY'
elif sma_fast < sma_slow:
return 'SELL'
return 'HOLD'
def mean_reversion(self, df, period=20, z_entry=1.5):
"""평균회귀: 볼린저 밴드 역추세"""
sma = df['close'].rolling(period).mean().iloc[-1]
std = df['close'].rolling(period).std().iloc[-1]
price = df['close'].iloc[-1]
z = (price - sma) / std if std > 0 else 0
if z < -z_entry:
return 'BUY' # 과매도 → 반등 기대
elif z > z_entry:
return 'SELL' # 과매수 → 하락 기대
return 'HOLD'
def execute(self, df, hurst_value):
"""허스트 값에 따라 전략 자동 전환"""
if hurst_value > self.trend_th:
strategy = 'TREND_FOLLOW'
signal = self.trend_following(df)
confidence = min((hurst_value - 0.5) * 4, 1.0)
elif hurst_value < self.revert_th:
strategy = 'MEAN_REVERT'
signal = self.mean_reversion(df)
confidence = min((0.5 - hurst_value) * 4, 1.0)
else:
strategy = 'NEUTRAL'
signal = 'HOLD'
confidence = 0.0
return {
'hurst': hurst_value,
'strategy': strategy,
'signal': signal,
'confidence': confidence
}
# 사용 예시
adapter = HurstAdaptiveStrategy()
# result = adapter.execute(df, hurst_series.iloc[-1])
멀티 타임프레임 허스트 분석
단일 타임프레임의 허스트만으로는 노이즈에 취약합니다. 여러 타임프레임의 허스트를 종합하면 더 견고한 판단이 가능합니다.
def multi_timeframe_hurst(exchange, symbol='BTC/USDT'):
"""다중 타임프레임 허스트 분석"""
timeframes = {'1h': 168, '4h': 180, '1d': 200}
results = {}
for tf, limit in timeframes.items():
ohlcv = exchange.fetch_ohlcv(symbol, tf, limit=limit)
closes = pd.DataFrame(ohlcv, columns=['ts','o','h','l','c','v'])
rets = closes['c'].pct_change().dropna().values
h = hurst_dfa(rets)
results[tf] = h
# 가중 평균 (긴 타임프레임에 더 높은 가중치)
weights = {'1h': 0.2, '4h': 0.3, '1d': 0.5}
weighted_h = sum(results[tf] * weights[tf] for tf in timeframes)
return results, weighted_h
# results, avg_hurst = multi_timeframe_hurst(exchange)
# print(f"가중 허스트: {avg_hurst:.4f}")
실전 적용 시 주의사항
- 충분한 데이터: 허스트 지수는 최소 100개 이상의 데이터 포인트가 필요합니다. 짧은 윈도우에서는 추정 오차가 커집니다.
- 계산 방법 비교: R/S와 DFA 모두 계산하여 두 값이 일치하는지 교차 검증하세요. 큰 차이가 나면 데이터 특성을 재확인해야 합니다.
- 0.5 근처 주의: H가 0.48~0.52 범위면 랜덤워크와 구별이 어렵습니다. 이 구간에서는 엔트로피 분석을 병행하여 보완하세요.
- 구조적 변화: 허스트 지수 자체가 급변하면 시장 구조가 바뀌고 있다는 신호입니다. 꼬리 위험 헤지를 활성화하는 트리거로 활용할 수 있습니다.
마무리: 추세인가 레인지인가, 허스트가 답한다
많은 트레이더가 겪는 핵심 문제는 "지금 추세추종을 해야 하는가, 평균회귀를 해야 하는가"입니다. 추세장에서 역추세 매매를 하면 손절이 반복되고, 레인지에서 추세추종을 하면 휩소에 당합니다. 허스트 지수는 이 근본적 질문에 수학적 답을 제공합니다.
자동매매 시스템에 허스트 기반 전략 전환을 내장하면, 시장 환경이 바뀔 때마다 수동으로 전략을 교체할 필요 없이 시스템이 스스로 적응합니다. 이것이 진정한 적응형 퀀트 시스템의 출발점입니다.
| 허스트 범위 | 시장 성질 | 최적 전략 | 대표 지표 |
|---|---|---|---|
| 0.7 이상 | 강한 추세 | 모멘텀, 돌파 | 이동평균 교차 |
| 0.5~0.7 | 약한 추세 | 추세추종 (소량) | ADX, MACD |
| 0.3~0.5 | 약한 회귀 | 평균회귀 (소량) | 볼린저 밴드 |
| 0.3 미만 | 강한 회귀 | RSI 역추세 | RSI, 스토캐스틱 |