feat(sim): 물타기(애버리징) 토글 — 하락 시 손절 대신 평단↓ 추가매수

- config: AVERAGING_ENTRY·AVERAGING_DROP_PCT(0.10)·CRASH_DROP_PCT(0.10)
- signals.evaluate_holding: market_ok 인자 + 물타기 분기 (직전매수가 -10% 하락 시 ADD-down, 한도/강세장/비급락 조건, 당일 -10%급락은 손절·약세장 금지)
- engine·backtest: add_kind='down'이면 손절선 낮은 평단 기준 재설정(up은 위로 래칫 유지), engine은 market_ok 전달
- 첫 매수는 기존 검증 진입 그대로(우량주만 물타기)
- 백테스트: 즉시매수와 반대로 유리(10/20/60 수익·승률↑) → 라이브 변이 3개(v301/302/303) 등록, 총 223
- 웹 '물타기' 칩 + 설명 토스트

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
hyowons
2026-06-16 14:30:07 +09:00
parent 70f6b9a34d
commit eaa276b26d
233 changed files with 397 additions and 233 deletions
+2 -2
View File
@@ -182,7 +182,7 @@ def run(overrides: dict | None, codes: list[str], date_from: str = '', date_to:
pos['last_add_price'] = fill
cash -= cost
nstop, ntarget = signals.compute_stop_target(pos['entry_price'], od['atr'], od['recent_low'])
pos['stop'] = max(pos['stop'], nstop)
pos['stop'] = nstop if od.get('add_kind') == 'down' else max(pos['stop'], nstop)
pos['target'] = ntarget
elif kind == 'buy':
if code in positions or len(positions) >= config.MAX_POSITIONS or exited.get(code) == day:
@@ -223,7 +223,7 @@ def run(overrides: dict | None, codes: list[str], date_from: str = '', date_to:
if act in ('sell', 'scale_out'):
pending.append({'kind': act, 'code': code, 'frac': dec.get('sell_frac', 1.0)})
elif act == 'add':
pending.append({'kind': 'add', 'code': code,
pending.append({'kind': 'add', 'code': code, 'add_kind': dec.get('add_kind'),
'atr': ind['atr'], 'recent_low': ind['recent_low']})
# ---- 2. 신규 매수 판단 (당일 종가) → 내일 시가 주문 큐잉 ----