자동매매에서 MDD가 중요한 이유
자동매매 시스템을 운영할 때 수익률만큼 중요한 지표가 바로 MDD(Maximum Drawdown, 최대 드로다운)입니다. MDD는 포트폴리오가 고점 대비 최대 얼마나 하락했는지를 나타내는 지표로, 전략의 위험 수준을 직관적으로 보여줍니다. 연 수익률 50%를 달성해도 MDD가 60%라면 실전에서 견디기 어려운 전략이며, 대부분의 투자자는 심리적 압박으로 중도 포기하게 됩니다.
퀀트 트레이딩에서 MDD 제어는 단순한 손절이 아닙니다. 전략 수준, 포트폴리오 수준, 계좌 수준의 다층 방어 체계를 구축해야 실전에서 살아남을 수 있습니다. 이 글에서는 자동매매 봇에 적용할 수 있는 MDD 제어 기법을 체계적으로 정리합니다.
MDD 계산 공식과 파이썬 구현
MDD를 계산하는 기본 공식은 다음과 같습니다:
MDD = (최저점 - 고점) / 고점 × 100%
파이썬으로 구현하면 누적 수익 곡선에서 실시간으로 MDD를 추적할 수 있습니다:
import numpy as np
def calculate_mdd(equity_curve):
"""누적 수익 곡선에서 MDD 계산"""
peak = np.maximum.accumulate(equity_curve)
drawdown = (equity_curve - peak) / peak
mdd = drawdown.min()
return mdd
def rolling_mdd(equity_curve, window=20):
"""롤링 윈도우 MDD - 최근 N일 기준"""
mdds = []
for i in range(window, len(equity_curve)):
segment = equity_curve[i-window:i+1]
mdds.append(calculate_mdd(segment))
return mdds
실시간 자동매매에서는 rolling_mdd 함수를 활용해 최근 구간의 드로다운 추이를 모니터링하는 것이 핵심입니다.
3단계 MDD 방어 체계
실전 자동매매에서 MDD를 효과적으로 제어하려면 3단계 방어 체계를 구축해야 합니다. 각 단계별 트리거 조건과 대응 액션을 명확하게 정의하는 것이 중요합니다.
1단계: 경고(Yellow Zone) — MDD 10~15%
포트폴리오가 고점 대비 10~15% 하락하면 경고 단계에 진입합니다. 이 단계에서는 포지션 크기를 50% 축소하고, 신규 진입 조건을 강화합니다. 텔레그램이나 슬랙으로 알림을 발송하여 수동 모니터링을 병행합니다.
class MddController:
def __init__(self, yellow=0.10, orange=0.20, red=0.30):
self.yellow = yellow # 경고
self.orange = orange # 위험
self.red = red # 긴급 정지
self.peak_equity = 0
self.current_equity = 0
def update(self, equity):
self.current_equity = equity
self.peak_equity = max(self.peak_equity, equity)
@property
def current_dd(self):
if self.peak_equity == 0:
return 0
return (self.peak_equity - self.current_equity) / self.peak_equity
def get_position_scale(self):
dd = self.current_dd
if dd >= self.red:
return 0.0 # 전면 정지
elif dd >= self.orange:
return 0.25 # 75% 축소
elif dd >= self.yellow:
return 0.50 # 50% 축소
return 1.0 # 정상 운영
2단계: 위험(Orange Zone) — MDD 20~25%
드로다운이 20%를 넘기면 포지션을 75% 축소하고, 기존 보유 포지션의 손절 기준을 타이트하게 조정합니다. 동시에 전략 파라미터가 현재 시장 레짐에 맞는지 점검해야 합니다. 이 단계에서는 수동 개입을 권장합니다.
3단계: 긴급 정지(Red Zone) — MDD 30% 이상
MDD 30%를 돌파하면 모든 포지션을 즉시 청산하고 자동매매를 정지합니다. 이 수준의 드로다운은 전략 자체에 구조적 문제가 있거나 시장 환경이 급변했음을 의미합니다. 최소 1~2주간 전략을 재검증한 후 재가동해야 합니다.
전략별 MDD 한도 설정 기준
모든 전략에 동일한 MDD 한도를 적용하면 안 됩니다. 전략의 특성에 따라 허용 MDD를 차등 설정해야 합니다:
| 전략 유형 | 권장 MDD 한도 | 근거 |
|---|---|---|
| 추세추종(Trend Following) | 20~30% | 횡보장에서 연속 손실 발생이 자연스러움 |
| 평균회귀(Mean Reversion) | 10~15% | 급등·급락 시 큰 손실 위험 |
| 차익거래(Arbitrage) | 5~8% | 저위험 전략이므로 이탈 시 즉시 점검 |
| 모멘텀(Momentum) | 15~25% | 반전 구간에서 드로다운 불가피 |
핵심은 백테스트에서 관찰된 MDD의 1.5~2배를 실전 한도로 설정하는 것입니다. 백테스트 MDD가 15%였다면 실전 한도는 22~30%로 설정합니다. 실전은 백테스트보다 항상 더 나쁜 결과가 나오기 때문입니다.
동적 포지션 사이징과 MDD 연동
고정 비율 포지션 사이징 대신, 현재 드로다운 수준에 따라 포지션 크기를 동적으로 조절하면 MDD를 효과적으로 억제할 수 있습니다. 대표적인 방법이 Anti-Martingale 방식입니다:
def dynamic_position_size(base_size, current_dd, max_dd=0.30):
"""드로다운 비율에 따라 포지션 사이즈 동적 조절"""
if current_dd <= 0:
return base_size
# 드로다운이 깊을수록 포지션 축소
scale = max(0, 1 - (current_dd / max_dd) ** 1.5)
return base_size * scale
# 예시: 기본 10만원, 현재 DD 15%, 최대 허용 DD 30%
size = dynamic_position_size(100000, 0.15, 0.30)
# 결과: 약 64,645원 (35% 축소)
이 방식은 손실 구간에서 자동으로 리스크를 줄이고, 수익 구간에서는 원래 포지션을 유지하므로 포지션 사이징 전략과 자연스럽게 연동됩니다.
쿨다운 메커니즘 구현
MDD 임계치를 터치한 후 바로 재진입하면 추가 손실이 발생할 확률이 높습니다. 쿨다운(Cooldown) 기간을 두어 시장이 안정된 후 점진적으로 재가동하는 것이 안전합니다:
from datetime import datetime, timedelta
class CooldownManager:
def __init__(self, cooldown_hours=48, ramp_up_days=5):
self.cooldown_hours = cooldown_hours
self.ramp_up_days = ramp_up_days
self.stop_time = None
def trigger_stop(self):
self.stop_time = datetime.now()
def get_allowed_scale(self):
if self.stop_time is None:
return 1.0
elapsed = datetime.now() - self.stop_time
# 쿨다운 기간 중에는 거래 금지
if elapsed < timedelta(hours=self.cooldown_hours):
return 0.0
# 점진적 재가동 (20%씩 증가)
days_since = (elapsed - timedelta(hours=self.cooldown_hours)).days
scale = min(1.0, 0.2 * (days_since + 1))
return scale
쿨다운 후 즉시 풀 사이즈로 복귀하는 것이 아니라, 5일에 걸쳐 20%씩 단계적으로 복원하는 것이 핵심입니다. 이를 통해 시장 환경이 여전히 불리한 경우 추가 손실을 최소화할 수 있습니다.
멀티 전략 MDD 관리
여러 전략을 동시에 운영하는 경우, 개별 전략 MDD뿐 아니라 포트폴리오 전체 MDD도 관리해야 합니다. 상관관계가 높은 전략들이 동시에 드로다운에 빠지면 합산 손실이 급격히 커질 수 있기 때문입니다.
멀티 전략 MDD 관리의 핵심 원칙:
- 전략 간 상관계수를 주기적으로 계산하여 상관관계가 0.7 이상인 전략 쌍은 자본 배분을 줄임
- 포트폴리오 레벨 MDD 한도를 별도로 설정 (예: 개별 전략 MDD 한도 합계의 60~70%)
- 하나의 전략이 Red Zone에 진입하면 다른 전략의 포지션도 축소하여 시스템 리스크에 대비
- 전략 추가 시 기존 포트폴리오와의 포트폴리오 최적화를 재실행
실전 MDD 모니터링 대시보드
자동매매 봇에 MDD 모니터링을 통합하려면 다음 지표를 실시간으로 추적해야 합니다:
- 현재 드로다운: 최근 고점 대비 현재 하락률
- 최대 드로다운: 운영 시작 이후 최악의 드로다운
- 드로다운 기간: 고점 회복까지 걸린 시간 (Recovery Time)
- Calmar Ratio: 연수익률 ÷ MDD — 1.0 이상이면 양호, 2.0 이상이면 우수
- Ulcer Index: 드로다운의 깊이와 지속시간을 종합한 리스크 지표
이 지표들을 텔레그램 알림이나 Grafana 대시보드에 연동하면 24시간 자동매매 중에도 리스크 상태를 즉시 파악할 수 있습니다.
MDD 제어 체크리스트
자동매매 봇에 MDD 제어를 적용할 때 반드시 확인해야 할 항목들을 정리합니다:
- ✅ 전략별 MDD 한도가 백테스트 결과 기반으로 설정되었는가
- ✅ 3단계 방어 체계(경고 → 위험 → 긴급 정지)가 코드에 구현되었는가
- ✅ 쿨다운 메커니즘이 적용되어 과도한 재진입을 방지하는가
- ✅ 동적 포지션 사이징이 현재 드로다운과 연동되는가
- ✅ 실시간 알림 시스템이 MDD 임계치 도달 시 작동하는가
- ✅ 멀티 전략 운영 시 포트폴리오 레벨 MDD도 별도 관리하는가
- ✅ 월 1회 이상 MDD 한도의 적정성을 재검증하는가
결론
자동매매에서 MDD 제어는 생존의 문제입니다. 아무리 높은 기대수익률을 가진 전략이라도 MDD 관리 없이는 한 번의 급락으로 계좌가 회복 불가능한 수준까지 손상될 수 있습니다. 3단계 방어 체계, 동적 포지션 사이징, 쿨다운 메커니즘을 조합하여 체계적인 MDD 제어 시스템을 구축하세요. 수익을 추구하기 전에 먼저 살아남아야 합니다.