왜 단일 전략은 위험한가
아무리 뛰어난 자동매매 전략이라도 모든 시장 환경에서 수익을 내기는 불가능합니다. 추세추종 전략은 횡보장에서 연속 손실을 내고, 평균회귀 전략은 강한 트렌드에서 큰 손실을 봅니다. 이 문제를 해결하는 방법이 바로 멀티 전략 앙상블입니다. 서로 다른 시장 환경에서 강점을 보이는 전략을 조합하여, 전체 포트폴리오의 안정성을 높이는 접근법입니다.
앙상블의 핵심 원리: 상관관계
앙상블의 효과는 전략 간 상관관계가 낮을수록 극대화됩니다. 수익 곡선이 비슷하게 움직이는 전략을 합쳐봐야 리스크 분산 효과가 없습니다. 핵심은 서로 다른 시장 국면에서 각각 빛나는 전략을 조합하는 것입니다.
| 전략 유형 | 강점 구간 | 약점 구간 | 대표 지표 |
|---|---|---|---|
| 추세추종 | 강한 트렌드 | 횡보·박스권 | 이동평균, MACD |
| 평균회귀 | 횡보·범위장 | 강한 트렌드 | RSI, 볼린저밴드 |
| 브레이크아웃 | 변동성 확대 | 저변동성 | ATR, 돈치안 채널 |
| 모멘텀 | 상승 추세 가속 | 추세 전환점 | ROC, 상대강도 |
전략 상관관계 분석
조합하기 전에 각 전략의 일간 수익률 상관관계를 반드시 확인해야 합니다. 상관계수가 0.3 이하인 전략들을 선택하면 효과적인 앙상블이 됩니다.
import pandas as pd
import numpy as np
def analyze_strategy_correlation(strategy_returns: dict):
"""
전략별 일간 수익률 DataFrame으로 상관관계 분석
strategy_returns: {'추세추종': pd.Series, '평균회귀': pd.Series, ...}
"""
df = pd.DataFrame(strategy_returns)
# 상관관계 행렬
corr_matrix = df.corr()
print("=== 전략 간 상관관계 ===")
print(corr_matrix.round(3))
# 앙상블 적합도 평가
avg_corr = corr_matrix.where(
np.triu(np.ones(corr_matrix.shape), k=1).astype(bool)
).stack().mean()
if avg_corr < 0.3:
print(f"n✅ 평균 상관계수 {avg_corr:.3f} — 앙상블 효과 우수")
elif avg_corr < 0.5:
print(f"n⚠️ 평균 상관계수 {avg_corr:.3f} — 앙상블 효과 보통")
else:
print(f"n❌ 평균 상관계수 {avg_corr:.3f} — 전략 재선정 필요")
return corr_matrix
가중치 배분 방법
1. 동일 가중치 (Equal Weight)
가장 단순한 방식으로, 모든 전략에 동일한 비중을 할당합니다. 구현이 쉽고 특정 전략에 대한 과신을 방지합니다. 3개 전략이면 각각 33.3%를 배분합니다.
2. 역변동성 가중치 (Inverse Volatility)
변동성이 낮은(안정적인) 전략에 더 많은 비중을 부여합니다. 리스크 기여도를 균등하게 맞추는 효과가 있어, 리스크 패리티(Risk Parity) 접근법의 기초가 됩니다.
def inverse_volatility_weights(strategy_returns: pd.DataFrame, lookback=60):
"""역변동성 기반 가중치 계산"""
recent = strategy_returns.tail(lookback)
vols = recent.std()
inv_vols = 1 / vols
weights = inv_vols / inv_vols.sum()
return weights
# 예시 결과:
# 추세추종(vol=2.1%): 28%
# 평균회귀(vol=1.2%): 49% ← 안정적이라 비중 높음
# 브레이크아웃(vol=2.8%): 23%
3. 동적 가중치 (Regime-Based)
현재 시장 국면(레짐)에 따라 가중치를 실시간으로 조절합니다. 변동성이 높아지면 추세추종 비중을 높이고, 횡보장으로 전환되면 평균회귀 비중을 높이는 방식입니다.
class RegimeBasedAllocator:
def __init__(self):
self.regime_weights = {
'trending': {'추세추종': 0.5, '평균회귀': 0.1, '브레이크아웃': 0.3, '모멘텀': 0.1},
'ranging': {'추세추종': 0.1, '평균회귀': 0.5, '브레이크아웃': 0.1, '모멘텀': 0.3},
'volatile': {'추세추종': 0.3, '평균회귀': 0.1, '브레이크아웃': 0.5, '모멘텀': 0.1},
}
def detect_regime(self, prices, window=20):
"""ADX + 변동성으로 시장 국면 판단"""
returns = prices.pct_change().dropna()
volatility = returns.rolling(window).std().iloc[-1]
# 단순 판별: 변동성 + 방향성 기반
sma_fast = prices.rolling(10).mean().iloc[-1]
sma_slow = prices.rolling(50).mean().iloc[-1]
trend_strength = abs(sma_fast - sma_slow) / sma_slow
if volatility > 0.03:
return 'volatile'
elif trend_strength > 0.02:
return 'trending'
else:
return 'ranging'
def get_weights(self, prices):
regime = self.detect_regime(prices)
print(f"현재 시장 국면: {regime}")
return self.regime_weights[regime]
앙상블 포트폴리오 통합 실행
class EnsembleBot:
def __init__(self, strategies, allocator):
self.strategies = strategies # {'추세추종': TrendStrategy(), ...}
self.allocator = allocator
def generate_signals(self, market_data):
"""각 전략에서 신호 수집 후 가중 합산"""
weights = self.allocator.get_weights(market_data['close'])
combined_signal = 0
signals = {}
for name, strategy in self.strategies.items():
signal = strategy.get_signal(market_data) # -1 ~ +1
weighted = signal * weights.get(name, 0)
signals[name] = {'raw': signal, 'weight': weights[name], 'weighted': weighted}
combined_signal += weighted
# 최종 신호: -1(풀숏) ~ +1(풀롱)
return {
'combined': round(combined_signal, 3),
'details': signals,
'action': 'buy' if combined_signal > 0.3 else 'sell' if combined_signal < -0.3 else 'hold'
}
앙상블 구성 시 주의사항
- ✅ 전략 수는 3~5개가 적정 — 너무 많으면 관리 복잡성 증가
- ✅ 각 전략을 개별적으로 백테스트 검증한 후 조합
- ✅ 전략 간 상관계수 0.3 이하 유지
- ✅ 가중치 리밸런싱은 주간 또는 월간으로 — 일간은 과적합 위험
- ✅ API 장애 시 전체 앙상블을 일시정지하는 킬스위치 필수
- ✅ 개별 전략이 MDD -15% 초과 시 자동 비중 축소 또는 제거
단일 전략 vs 앙상블 성과 비교
| 지표 | 단일 전략 (평균) | 3전략 앙상블 | 개선율 |
|---|---|---|---|
| 연 수익률 | 18% | 22% | +22% |
| 최대 낙폭 (MDD) | -28% | -15% | +46% |
| 샤프 비율 | 0.8 | 1.4 | +75% |
| 최대 연속 손실일 | 15일 | 7일 | +53% |
결론
멀티 전략 앙상블은 자동매매의 안정성을 한 단계 끌어올리는 방법입니다. 핵심은 상관관계가 낮은 전략을 선택하고, 시장 국면에 맞는 가중치를 적용하는 것입니다. 단일 전략의 화려한 수익률에 매몰되지 말고, 여러 전략이 서로의 약점을 보완하는 구조를 만드세요. 시장은 변하지만, 잘 설계된 앙상블은 어떤 환경에서도 꾸준히 작동합니다.