ㅇ 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.
8.4 KiB
돌파 실매↔백테 괴리 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_enabled면sell_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_krw에 UI% 한 번만 전달 (×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_compileOK- 스모크: 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와 일치
- 전일대비 C2C
- 한울: 전일 15:58 C=11810 → 09:00 C=11530 → C2C -2.37%; 몸통 ≈ 0.70% ≈ 실매 0.61%(RAM OHLC 미세차)
실매 journal 타임라인 (결정적)
09:00:25333050 갭보정 REST 빈응답 →09:00:34500봉 RAM 적재 (진행 중 당일 09:00 포함)09:00:34~09:01:01내내탈락-직전봉약세 prev=-1.14%(5220-5280)/5280 = -1.14%→ 갭보정이 넣은 미완성 09:00(종가≈시가 5220) 이 확정봉으로 잡힌 상태
09:01:01봉강제확정09:00 C=529009:01:02~탈락-저항미돌파(직전봉 게이트 통과) →09:01:06BREAKOUT-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).
수정 방향 (승인 후 — 아직 미적용)
- 갭보정 시
candle_time >= 현재 진행 분봉은 confirmed merge 제외 (또는_current만 갱신). 실매·BT 모두 전일 종가 C2C로 통일. - (선택) 매수 성공 로그에
confirmed[-2/-1] candle_time/close남겨 재발 추적. - 스펙을 “직전봉 몸통%”로 바꾸려면 실매·웹·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재시작 필요 (미재시작 시 기존 프로세스 구코드)