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:
@@ -286,7 +286,8 @@ def _run_scan(pf, uni, quotes, cmkt, now, execute: bool = True) -> dict:
|
||||
flow = data.flow_net(data.investor_flow(code))
|
||||
anl = data.analyst(code, cur_price)
|
||||
dec = signals.evaluate_holding(pf.positions[code], ind, flow, anl,
|
||||
held_days=_held_days(pf.positions[code], now))
|
||||
held_days=_held_days(pf.positions[code], now),
|
||||
market_ok=mkt_ok.get(cmkt.get(code, ''), True))
|
||||
pf.apply_position_update(code, dec['position_update'])
|
||||
dec.update({k: pf.positions[code].get(k) for k in
|
||||
('entry_price', 'qty', 'stop', 'target', 'trailing_on', 'entry_at')})
|
||||
@@ -305,7 +306,9 @@ def _run_scan(pf, uni, quotes, cmkt, now, execute: bool = True) -> dict:
|
||||
# 새 평단 기준 손절·목표 재산정 (손절은 위로만 래칫)
|
||||
new_entry = pf.positions[code]['entry_price']
|
||||
nstop, ntarget = signals.compute_stop_target(new_entry, ind['atr'], ind['recent_low'])
|
||||
pf.positions[code]['stop'] = max(pf.positions[code]['stop'], nstop)
|
||||
# 추격매수(up)=손절 위로만 래칫 / 물타기(down)=낮아진 평단 기준으로 손절 재설정
|
||||
pf.positions[code]['stop'] = (nstop if dec.get('add_kind') == 'down'
|
||||
else max(pf.positions[code]['stop'], nstop))
|
||||
pf.positions[code]['target'] = ntarget
|
||||
buys.append(rec)
|
||||
dec.update({'fill_price': fill, 'entry_price': new_entry,
|
||||
|
||||
Reference in New Issue
Block a user