Files
kis_trader/docs/BREAKOUT_LIVE_BT_QA.md
Your Name 61bec4bd1d feat: Add DART strategy and related configurations
ㅇ
Changes:
- Introduced the DART strategy to the trading system, including its configuration and integration into the existing framework.
- Updated the database schema to include DART-specific tables for disclosures and watchlists.
- Enhanced the backtesting and parameter search functionalities to support the DART strategy.
- Implemented new rules for browser verification and API interactions to ensure compliance with the updated DART strategy.

Impact:
- These additions expand the trading capabilities of the system, allowing for more comprehensive analysis and execution of DART-related strategies, while maintaining system integrity and performance.
2026-07-21 07:50:24 +09:00

8.4 KiB
Raw Blame History

돌파 실매↔백테 괴리 Q&A (2026-07-16 기준)

패치 적용 완료 (2026-07-17). 실매 봇은 재시작하지 않음. 백테 웹만 재시작.


1번 — 웜업 넣으면 되나?

네 → 적용됨.

  • env: BREAKOUT_BACKTEST_CANDLE_WARMUP_BARS (기본 50, DB 시드)
  • prepend_breakout_candle_warmup — 기간 시작 전 1분봉 prepend
  • 포트폴리오 all_times_backtest_period_start_key 이후만 (전일 시계 오염 방지)
  • 모멘텀 MOMENTUM_BACKTEST_CANDLE_WARMUP_BARS와 동일 계열

2번 — 유니버스 sticky/grace

실매 따라가기 → 적용됨.

동작

  • 공통 resolve_universe_exit_debounce_sec() → 기본값 = CONDITION_EXIT_GRACE_SEC(운영 60, 기존 120→2026-07-17 축소)
  • 돌파/꼬리/모멘텀 타임라인 debounce_sec에 연결
  • 전략별 오버라이드: BREAKOUT_UNIVERSE_EXIT_DEBOUNCE_SEC / TAIL_* / MOMENTUM_* (있으면 우선, 0=OFF)

09:07 1종 스냅샷 점검 결과

event_time n
03:16 22
09:07 1 (248170만)
09:11 2
  • history는 effective 유니버스 저장 설계 → 09:07에 1종이면 그 tick의 live effective도 1종으로 보는 게 맞음 (저장이 grace를 빼먹은 버그로 단정하지 않음). 새벽 스냅샷 후 장초 첫 변동·콜드스타트 가능성이 큼.
  • 디바운스 ON 시: 09:07 스냅샷에서도 overnight 종목을 60초 유지 → 이후 신규 스냅샷 기준으로 정리. 실매 EXIT grace와 같은 전환 규칙.

영향 범위

  • 백테 유니버스 재생 (돌파·꼬리·모멘텀 등 타임라인 사용 전략). 실매 주문 로직 자체는 변경 없음.
  • 망가뜨리는 패치가 아니라 실매 grace 정합 쪽. 백테 거래수/PnL은 실매에 가까워지도록 바뀔 수 있음.

3번 — 슬롯 늘려서 테스트

사용자 검증용 (코드 변경 없음). 총한도/동시보유↑로 슬롯 경쟁 효과 확인.


4번 — 미청산 flatten / EOD

적용됨 (돌파·모멘텀·RANGE_BREAK).

  • 공통 flatten_remaining_portfolio_trades — 루프 끝 미청산을 마지막 확정봉 종가로 장부 기록
  • eod_enabledsell_reason=eod, 아니면 bt_flatten
  • skip_stats: bt_flatten_count
  • 모멘텀: 웜업은 기존, flatten은 이번에 추가 (이전 “미완” 해소)

(부수) invest_cap 이중 % 스케일

적용됨 (돌파·RANGE_BREAK).

  • _resolve_breakout_sl_pct_ui: stop_loss_pct(비율) → UI% ; sl_pct만 있으면 UI%/비율 자동 판별
  • breakout_invest_amount_krwUI% 한 번만 전달 (×100 이중 제거)

패치 상태

순위 항목 상태
1 돌파 백테 전일 봉 웜업 완료
2 유니버스 sticky/grace 디바운스 + 09:07 점검 완료
3 슬롯/한도 검증용 백테 사용자
4 백테 종료 미청산 flatten 완료 (돌파·모멘텀·레인지)
부수 invest_cap % 이중 스케일 완료

관련 파일

  • 웜업·디바운스: kis_trader/backtest/breakout_backtest_common.py
  • 공통 디바운스: kis_trader/backtest/universe_timeline.py (resolve_universe_exit_debounce_sec)
  • flatten: kis_trader/backtest/backtest_portfolio_common.py
  • 포트폴리오: breakout_portfolio_backtest.py, momentum_portfolio_backtest.py, range_break_portfolio_backtest.py
  • 꼬리 디바운스: tail_backtest_common.py
  • env 키: database.py (BREAKOUT_BACKTEST_CANDLE_WARMUP_BARS 등)

검증

  • py_compile OK
  • 스모크: debounce(03:16→09:07 유지→09:11 정리) / invest_cap(30만) / flatten(eod) → SMOKE_OK
  • DB: BREAKOUT_BACKTEST_CANDLE_WARMUP_BARS=50 시드, config 컬럼 추가
  • kis_backtest_web.service 재시작 (active + HTTP 200)
  • 브라우저: http://192.168.0.149:5050/돌파매매 백테스트 탭 클릭, 폼·「백테스트 실행」버튼 정상 표시

잔여 / 다음 확인

순위 항목 상태
다음 2번 검증 — 장초 이노테나·한울 직전봉약세 근본원인 확정 + 갭보정 진행분 제외 적용 (봇 재시작 시 반영)
후보 1번 A — 마지막 봉 경과 시 포트폴리오 루프에서 즉시 슬롯 해제 (전 전략 공통) 대기 — 저유동은 C로도 분 생성 불가 시 필요
진행 1번 C — 판 뒤 1회 REST 백필 적용 (아래)
3번 슬롯 경쟁 패스

1번 C 적용 (2026-07-17)

  • 모듈: kis_trader/engine/post_sell_candle_backfill.py

  • 실매 훅: order_manager._finalize_sell_fill → 매도 후 비동기 1회 (시세=키움 실키)

  • env: POST_SELL_CANDLE_BACKFILL (기본 true), POST_SELL_CANDLE_ROLLUP_3M, sleep 1~3초

  • 즉시 백필 CLI: scripts/backfill_trade_candles.py --like '2026-07-16%'

  • 로그: /tmp/backfill_trade_candles_0716c.log (및 선행 0716b)

  • 한계: 거래 자체가 없는 분(저유동)은 REST에도 없음 → C만으로는 완전 메꿈 불가, A 보완 여지

  • 웹 돌파 2026-07-16 재백테 ↔ 실매 비교는 C 반영 후 / 장초 직전봉 수정과 병행

  • 실매 봇: post-sell 훅 반영하려면 재시작 필요 (백필 CLI는 봇 없이 완료 가능)


장초 직전봉 (이노테나·한울) — 2번 검증 결과 (2026-07-17)

현상

이노테나 333050 한울 320000
실매 매수 09:01:09 @5350 09:01:42 @11590
실매 로그 prevChg 1.34% 0.61%
BT (DB+웜업) 탈락-직전봉약세 0.19% 탈락-직전봉약세 -2.37%
PREV_CHG_MIN 0.3 (실매=BT 동일) 동일

숫자 재현 (스펙: 전전봉 종가 → 직전봉 종가 %)

  • 이노테나 09:00: O=5220 C=5290 / 전일 15:30 C=5280
    • 전일대비 C2C (5290-5280)/5280 = 0.19% ← BT 탈락
    • 당일 몸통 (5290-5220)/5220 = 1.34% ← 실매 prevChg일치
  • 한울: 전일 15:58 C=11810 → 09:00 C=11530 → C2C -2.37%; 몸통 ≈ 0.70% ≈ 실매 0.61%(RAM OHLC 미세차)

실매 journal 타임라인 (결정적)

  1. 09:00:25 333050 갭보정 REST 빈응답 → 09:00:34 500봉 RAM 적재 (진행 중 당일 09:00 포함)
  2. 09:00:34~09:01:01 내내 탈락-직전봉약세 prev=-1.14%
    • (5220-5280)/5280 = -1.14% → 갭보정이 넣은 미완성 09:00(종가≈시가 5220) 이 확정봉으로 잡힌 상태
  3. 09:01:01 봉강제확정 09:00 C=5290
  4. 09:01:02~ 탈락-저항미돌파 (직전봉 게이트 통과) → 09:01:06 BREAKOUT-B ... prevChg=1.34% 매수

한울도 동일 패턴: 장중 prev=-2.96%(갭/전일) → 09:00 확정 후 저항 대기 → prevChg=0.61%로 매수.

근본원인

갭보정(REST ka10080)이 장중에 “아직 진행 중인 당일 1분봉”을 is_confirmed로 RAM에 넣음.

  • 실매 check_buy = get_candles(확정) + get_current_candle(진행) → 같은 09:00이 확정·진행 양쪽에 있거나, 확정 체인이 전일 종가 대신 시가(불완전봉 종가)prev_prev로 물음.
  • 그 결과 직전봉 필터가 문서/코드 스펙(전전봉→직전봉 종가대비)이 아니라 당일 첫 봉 몸통% 에 가깝게 통과.
  • BT는 DB 확정봉(+웜업 전일 종가)만 쓰므로 0.19%/-2.37%로 올바르게 거름 → 장초 실매만 사는 괴리.

코드 위치: kis_ws.merge_confirmed_bars / fill_gap_from_rest (현재 분 제외 없음) + breakout.check_buy (virtual = confirmed + forming).

수정 방향 (승인 후 — 아직 미적용)

  1. 갭보정 시 candle_time >= 현재 진행 분 봉은 confirmed merge 제외 (또는 _current만 갱신). 실매·BT 모두 전일 종가 C2C로 통일.
  2. (선택) 매수 성공 로그에 confirmed[-2/-1] candle_time/close 남겨 재발 추적.
  3. 스펙을 “직전봉 몸통%”로 바꾸려면 실매·웹·Optuna를 한 세트로 바꿔야 함 — 비권장(HTS/주석과 불일치).

권장: 1번(진행분 REST 제외). 핵심 매매 임계값 변경이 아니라 인프라 정합.

수정 적용 (2026-07-17)

  • env: WS_GAP_FILL_SKIP_INCOMPLETE_BUCKET (기본 true, DB 시드)
  • fill_gap_from_rest / merge_confirmed_bars: 진행 중 버킷(>= 현재 봉시작) insert 금지 + RAM purge
  • 스모크: scripts/smoke_candle_upsert_rollup.py (진행분 skip/purge)
  • 실매 반영: kis_trader_main 재시작 필요 (미재시작 시 기존 프로세스 구코드)