feat: 리스크 관리 강화 — 포트폴리오 락, MDD 단기전략 비활성화, 상관관계 필터

- portfolio.py: summary_lock으로 동시성 보호, apply_buy/apply_sell async화
- mdd_manager.py: MDD -10% 시 단기전략 비활성화 (is_short_term_strategy_paused)
- loss_tracker.py: DB 직접 접근 → db_worker 큐 기반 전환
- db_worker.py: upsert_stock_ban 태스크 추가
- correlation_filter.py: 섹터 집중도 + 피어슨 상관관계 검증 (CLAUDE.md 5.4)
- trade_executor.py: 상관관계 필터 통합, await 적용
- mean_reversion_strategy.py: config 값 타입 안전성 (float 변환)
- main.py/day_trading.py: MDD 체크 후 자동매매/데이트레이딩 차단

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-10 17:26:13 +09:00
parent 783e932145
commit a477072bdc
9 changed files with 661 additions and 87 deletions

View File

@@ -18,6 +18,7 @@ class MDDManager:
def __init__(self):
self.peak_balance: float = 0.0
self.is_paused: bool = False
self.is_short_term_strategy_paused: bool = False # MDD -10% 시 단기 전략 중단
self.reduction_applied: Optional[str] = None # None, "10pct", "20pct"
self._lock = asyncio.Lock() # 스케줄러-sync 동시 접근 방지
@@ -32,6 +33,7 @@ class MDDManager:
if current_balance > self.peak_balance:
self.peak_balance = current_balance
self.is_paused = False
self.is_short_term_strategy_paused = False
self.reduction_applied = None
if self.peak_balance <= 0:
@@ -51,15 +53,17 @@ class MDDManager:
"prioritize_leverage": True,
}
# -10% 돌파: 30% 축소 + 신규진입 중단
# -10% 돌파: 30% 축소 + 신규진입 중단 + 단기전략 중단
if drawdown_pct <= -10 and self.reduction_applied is None:
self.is_paused = True
self.is_short_term_strategy_paused = True # CLAUDE.md 5.3: 단기 매매 전략 중단
self.reduction_applied = "10pct"
logger.warning(f"MDD {drawdown_pct:.1f}% - 30% 축소 + 신규진입 중단")
logger.warning(f"MDD {drawdown_pct:.1f}% - 30% 축소 + 신규진입 중단 + 단기전략 중단")
return {
"action": "REDUCE_AND_PAUSE",
"drawdown": drawdown_pct,
"reduce_pct": 0.30,
"short_term_strategy_paused": True,
}
return {"action": "NONE", "drawdown": drawdown_pct}
@@ -69,9 +73,15 @@ class MDDManager:
async with self._lock:
return not self.is_paused
async def is_short_term_strategy_enabled(self) -> bool:
"""단기 전략 활성화 여부 (thread-safe) — MDD -10% 이상일 때만 활성화"""
async with self._lock:
return not self.is_short_term_strategy_paused
def reset(self):
"""MDD 상태 리셋 (수동 복구 시) — 동기 메서드, 단독 호출 시에만 사용"""
self.is_paused = False
self.is_short_term_strategy_paused = False
self.reduction_applied = None
logger.info("MDD 관리자 리셋")