멀티 전략 앙상블 자동매매

왜 단일 전략은 위험한가

아무리 뛰어난 자동매매 전략이라도 모든 시장 환경에서 수익을 내기는 불가능합니다. 추세추종 전략은 횡보장에서 연속 손실을 내고, 평균회귀 전략은 강한 트렌드에서 큰 손실을 봅니다. 이 문제를 해결하는 방법이 바로 멀티 전략 앙상블입니다. 서로 다른 시장 환경에서 강점을 보이는 전략을 조합하여, 전체 포트폴리오의 안정성을 높이는 접근법입니다.

앙상블의 핵심 원리: 상관관계

앙상블의 효과는 전략 간 상관관계가 낮을수록 극대화됩니다. 수익 곡선이 비슷하게 움직이는 전략을 합쳐봐야 리스크 분산 효과가 없습니다. 핵심은 서로 다른 시장 국면에서 각각 빛나는 전략을 조합하는 것입니다.

전략 유형 강점 구간 약점 구간 대표 지표
추세추종 강한 트렌드 횡보·박스권 이동평균, 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%

결론

멀티 전략 앙상블은 자동매매의 안정성을 한 단계 끌어올리는 방법입니다. 핵심은 상관관계가 낮은 전략을 선택하고, 시장 국면에 맞는 가중치를 적용하는 것입니다. 단일 전략의 화려한 수익률에 매몰되지 말고, 여러 전략이 서로의 약점을 보완하는 구조를 만드세요. 시장은 변하지만, 잘 설계된 앙상블은 어떤 환경에서도 꾸준히 작동합니다.

위로 스크롤
WordPress Appliance - Powered by TurnKey Linux