fix: ADX 계산 버그 수정 + Crisis 손절 소급 적용
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

1. mean_reversion_strategy.py: ADX 초기값을 sum→mean으로 변경
   — ADX가 252로 0-100 범위를 초과하던 버그 수정
   — SIDEWAYS 국면 감지가 정상 작동하도록 복원
   — _wilder_smooth() 함수는 변경하지 않음 (ATR/DM은 합산이 정상)

2. swing/exit_service.py: 고정비율 손절에 적응형 모드 손절값 반영
   — Crisis 모드 전환 시 기존 포지션에도 -3% 손절이 소급 적용됨
   — min(config값, adaptive값)으로 타이트한 쪽 선택

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-27 11:06:31 +09:00
parent c0ef58ef5e
commit 844ee8944f
2 changed files with 15 additions and 2 deletions

View File

@@ -137,8 +137,12 @@ def calculate_adx(highs: List[float], lows: List[float], closes: List[float], pe
if len(dxs) < period: if len(dxs) < period:
return None return None
adx_s = _wilder_smooth(dxs) # ADX 평활: 초기값은 mean(DX[:period]) — ATR/DM과 달리 합산이 아닌 평균
return round(adx_s[-1], 2) # _wilder_smooth()는 초기값이 sum이므로 ADX에는 인라인 계산 사용
adx_val = sum(dxs[:period]) / period # 초기값 = 평균
for dx_v in dxs[period:]:
adx_val = adx_val - adx_val / period + dx_v
return round(adx_val, 2)
def detect_market_regime(index_closes: List[float], def detect_market_regime(index_closes: List[float],

View File

@@ -251,6 +251,15 @@ async def check_and_execute_exit_v2(db: AsyncSession) -> list[dict]:
# ── 고정 비율 폴백 손절 ─────────────────────────────────── # ── 고정 비율 폴백 손절 ───────────────────────────────────
if exit_signal is None: if exit_signal is None:
stop_loss_pct = abs(float(getattr(settings, "STOP_LOSS_PERCENT", 6.0))) stop_loss_pct = abs(float(getattr(settings, "STOP_LOSS_PERCENT", 6.0)))
# 적응형 모드(Crisis 등)의 손절값과 비교하여 타이트한 쪽 적용
try:
from app.services.adaptive_strategy import get_current_adaptive_params
_adaptive = get_current_adaptive_params()
if not _adaptive.fallback_used:
_adaptive_sl = abs(_adaptive.stop_loss_pct)
stop_loss_pct = min(stop_loss_pct, _adaptive_sl)
except Exception:
pass # 적응형 전략 로드 실패 시 기본값 유지
profit_rate = ((latest_price - avg_price) / avg_price) * 100 profit_rate = ((latest_price - avg_price) / avg_price) * 100
if profit_rate <= -stop_loss_pct: if profit_rate <= -stop_loss_pct:
from app.services.mean_reversion_strategy import ExitSignal from app.services.mean_reversion_strategy import ExitSignal