M1 │ 스캐너 최소 거래량 100만→10만주 │ kosdaq_scanner.py │
Some checks failed
CI/CD Pipeline / test-backend (push) Has been cancelled
CI/CD Pipeline / test-frontend (push) Has been cancelled
CI/CD Pipeline / build-and-push (push) Has been cancelled

├─────┼─────────────────────────────────────────────────────┼────────────────────────────────┤
  │ M2  │ ADX 히스테리시스 18/22 (플리핑 방지)                │ mean_reversion_strategy.py     │
  ├─────┼─────────────────────────────────────────────────────┼────────────────────────────────┤
  │ M3  │ 분할매도 최소 수익 1.0%→0.5%                        │ mean_reversion_strategy.py     │
  ├─────┼─────────────────────────────────────────────────────┼────────────────────────────────┤
  │ M4  │ ORB 갭 필터 4% + 레인지 폭 0.3% 최소                │ day_trading_strategy.py        │
  ├─────┼─────────────────────────────────────────────────────┼────────────────────────────────┤
  │ M5  │ 쿨다운 스트릭 부분매도 시 미변경                    │ daytrading/position_manager.py │
  ├─────┼─────────────────────────────────────────────────────┼────────────────────────────────┤
  │ M6  │ MDD 강제매도 loss_tracker 기록 제거 (허위 ban 방지) │ mdd_manager.py                 │
  ├─────┼─────────────────────────────────────────────────────┼────────────────────────────────┤
  │ M7  │ RSI Wilder 스무딩으로 통일                          │ mean_reversion_strategy.py
This commit is contained in:
2026-04-03 11:41:52 +09:00
parent eda5d76af9
commit 9d096ddd57
22 changed files with 299 additions and 132 deletions

View File

@@ -217,6 +217,7 @@ class MDDManager:
holdings = sorted(holdings, key=lambda h: (not _is_leverage(h),))
results = []
skipped = 0
for h in holdings:
stock_code = h.get("pdno", "")
stock_name = h.get("prdt_name", stock_code)
@@ -224,6 +225,7 @@ class MDDManager:
current_price = float(h.get("prpr", 0) or 0)
if quantity <= 0 or current_price <= 0:
skipped += 1
continue
sell_qty = max(int(quantity * reduce_pct), 1)
@@ -243,16 +245,9 @@ class MDDManager:
profit_loss = (current_price - avg_price) * sell_qty
profit_loss_rate = ((current_price - avg_price) / avg_price * 100) if avg_price > 0 else 0.0
# [BUG FIX] loss_tracker 기록 — MDD 강제매도도 연속 손실 추적 대상
try:
from app.services.loss_tracker import loss_tracker
is_loss = profit_loss_rate < 0
await loss_tracker.record_trade_result_safe(
stock_code, is_loss
)
await loss_tracker.save_to_db(stock_code=stock_code)
except Exception as lt_err:
logger.warning(f"[MDD] loss_tracker 기록 실패 ({stock_code}): {lt_err}")
# MDD 강제매도는 시스템적(systemic) 리스크 축소이며,
# 개별 종목의 전략 실패가 아니므로 loss_tracker에 기록하지 않음.
# 기록 시 양호한 종목이 MDD 축소로 인해 false ban될 수 있음.
await enqueue_trade_history({
"stock_code": stock_code,
@@ -304,7 +299,7 @@ class MDDManager:
except Exception as e:
logger.error(f"[MDD] 축소 매도 실패 ({stock_code}): {e}")
failed_count = len(holdings) - len(results)
failed_count = len(holdings) - len(results) - skipped
if failed_count > 0 and executed_key is not None:
# 매도 실패 종목이 있으면 플래그 리셋 → 다음 주기에 재시도
async with self._lock: