ㅇ 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.0 KiB
정합성
최종안 (2026-07-17) — 실매 · 웹백테 · Optuna가 같은 분봉(OHLCV) 진실을 쓰게 하는 규칙.
신호/진입 바 오프셋(±1) 땜빵은 금지. 봉이 확정 후에도 커지는 것이 근본 원인이다.
관련: CANDLE_FLOW.md · SCALP_BACKTEST_VS_LIVE.md · BACKTEST_ALIGNMENT_FINAL.md
0. 한 줄 원칙
실매가 확정한 1분봉(그 순간의 OHLCV) = DB에 동결 = 웹백테/Optuna가 읽는 봉
- 틱 = 체결가(진입/청산 슬리피지)
- 분봉 = 매수 여부(RSI·거래량배수·평균 등)
- EOD = 포지션 장마감 청산(≈15:25). 봉 동결이 아님.
0.1 누가 무엇을 읽나 (오해 방지)
| 곳 | 읽는 것 | 아님 |
|---|---|---|
| 실매(장중) | WS로 막 확정된 봉 → RAM + DB에 첫 INSERT | — |
| 웹백테 · 파람/Optuna | DB ws_candles(+ws_ticks) 과거 재생 |
Optuna가 실시간 WS에 붙지 않음 |
| 아침 기동 | 같은 DB 로드 + 없는 분만 INSERT | “새벽 INSERT만 보는” 전용 분기 없음 |
대화에서 쓰인 “실매가 확정한 실시간 분봉” = 장중 확정 순간의 숫자를 뜻함.
→ 파람을 실시간 피드로 바꾸라는 뜻이 아님.
→ 고칠 코드 = 존재 시 UPDATE 금지뿐. 파람/아침용 봉 소스를 둘로 나누지 않음.
1. 잠긴 매매 규칙 (변경 금지)
| 항목 | 규칙 |
|---|---|
| 신호 봉 | T−1 확정봉 (live_backtest_align=True) |
| 진입 봉 | T 확정봉 |
| 유니버스 | 초 단위 event_time — 분 슬롯 ±1 해킹 금지 |
| HTS | SCAN 후보 참고. *_SKIP_HTS_SCAN_DUPES 기본 false 유지 |
| 차트봉 | 매매·백테·Optuna 경로에 사용하지 않음 (ws_candles + ws_ticks) |
2. 근본 원인 (측정, 2026-07-16)
| 현상 | 수치/관찰 | 의미 |
|---|---|---|
| 장중 확정 후 재기록 | 봉 마감 +5분 이후 updated_at ≈ 76% |
갭보정 REST가 기존 봉 UPDATE(큰 volume 우선) |
| 새벽/매도 후 백필 | 다음날 updated_at ≈ 3.8% (00:48대), 매도 종목과 100% 겹침 |
POST_SELL_CANDLE_BACKFILL이 hold 구간 UPSERT |
| 갭 구멍 INSERT | ENTER 시 결측분 흔함 | 웜업용 — INSERT는 유지, 덮어쓰기만 문제 |
| 샘표류(007540) | 실매 vol_avg≈1328 vs DB≈634 | 같은 공식, lookback 시리즈가 다름 |
정합을 깨는 본체 = 확정 후 UPDATE. INSERT(구멍 메우기)가 아니다.
3. 최종 설계: Freeze-on-confirm
3.1 규칙
- 행이 이미 있으면 OHLCV·RSI 덮어쓰기 금지 (RAM
merge_confirmed_bars+ DB upsert + 매도/보유 백필 동일). - 없을 때만 INSERT — 갭 구멍·웜업 유지.
- 진행 중(미확정) 버킷은 기존처럼 confirmed에 넣지 않음 (
WS_GAP_FILL_SKIP_INCOMPLETE_BUCKET). - (옵션, 후속) 거래량을 틱 합으로 통일 — 1번 안정화 후.
3.2 수정 대상 (구현 시)
| 경로 | 현재 | 목표 |
|---|---|---|
kis_ws.merge_confirmed_bars |
기존 봉 + new_vol > old_vol → upsert |
존재 시 skip |
kis_ws DB batch / _flush_batch |
ON DUPLICATE KEY UPDATE volume 등 덮음 |
존재 시 no-op (또는 INSERT IGNORE / 조건부) |
post_sell_candle_backfill _INSERT_SQL |
volume=IF(VALUES>volume…) |
존재 시 skip, 없는 분만 INSERT |
| 기타 REST/키움 갭보정 → merge | 위 merge 경유 | merge 규칙만 바꿔도 대부분 흡수 |
3.3 하지 않을 것
- 09:05 시작·새벽 수집 전면 중지만으로 “해결” 선언 (보조책은 가능, 본체 아님)
- 신호/유니버스 ±1분 보정
- “EOD 했으니 당일 봉만 보면 된다” (EOD≠봉동결; lookback·전일시가 필요)
- 매수 직전 REST 재조회로 “안정화 체크”를 본치료로 쓰기 (느림·429·나중에 또 덮이면 무의미)
3.4 운영 보조 (선택, 본치료 아님)
| 아이디어 | 기대 | 한계 |
|---|---|---|
| 09:05 기동 (조건식·봉 정리 후) | 장초 혼선 ↓ | 장중 UPDATE·새벽 백필 미해결 |
| 새벽/장전 덮어쓰기 금지 | freeze와 동일 방향 | 수집 자체 금지가 아니라 INSERT only |
| 실시간 “봉 안정” 폴링 | 체감용 | freeze 없으면 DB는 결국 갈라짐 |
4. 구현 순서 (승인 후)
- 존재 시 덮어쓰기 금지
merge_confirmed_bars/ DB upsert / 백필 — 공통 규칙. - 스모크
확정 직후 volume vs 1시간 뒤 · 다음날 — 동일해야 함. - 7/16 샘표류 대조
vol 평균·PASS/FAIL이 실매 저널과 같은지 (웹백테 동일 파라미터).
코드 변경 전: 핵심 매매 로직이 아닌 저장/병합 계층 패치.
시그널 T−1/T·청산식은 이 작업에서 건드리지 않음.
5. 검증 체크리스트
- 확정 봉 DB row: 이후 REST/백필이 volume을 키우지 않음
- 결측 분은 여전히 INSERT로 채워짐 (웜업 0건 폭주 없음)
- 재시작 후 RAM 재로드 → 확정분과 DB 일치
- 갭보정 로그:
update=가 0에 수렴(또는 skip 카운트),insert=만 정상 - 전략 2개 이상 경로 스모크 (예: SCALP + TAIL) — 공유
ws_candles부작용 없음 - 웹백테 / Optuna: 동일
ws_candles→ 실매 저널과 PASS·지표 근접 POST_SELL_CANDLE_BACKFILL켠 상태에서도 hold 구간 구멍만 채움
6. 영향 범위 분류
| 구분 | 영향 |
|---|---|
| 실매 | RAM/DB에 남는 확정봉이 “첫 확정값”으로 고정 → 이후 매수 판정 입력 안정 |
| 웹백테·Optuna | 같은 DB를 읽으므로 실매와 입력 정렬 (엔진식 변경 없음) |
| 과거 DB | 이미 덮여 커진 봉은 자동 복구 안 됨. 필요 시 해당일 재수집·재백테는 별도 |
7. 승인 상태
| 항목 | 상태 |
|---|---|
| 방향: freeze-on-confirm / INSERT only | 사용자 승인·구현 진행 (2026-07-17) |
| env | WS_CANDLE_FREEZE_ON_CONFIRM 기본 true (false=레거시 덮어쓰기) |
| 구현 | kis_ws merge/confirm/DB flush · DB시드 · post_sell_candle_backfill · fill_kiwoom_candles |
| 재시작 | db_seed=N 로그 = DB 확정봉을 RAM에 시드 (REST로 안 덮음) |
첫 패치: 존재 시 UPDATE 금지 (확정행 OHLCV 동결). 미확정→확정 갱신은 허용.
재시작 시 RAM이 비면 REST가 “첫 삽입”처럼 보이므로, DB에 이미 있으면 DB값으로만 RAM 시드.
8. 다음에 할 일 (쉬운 말 · 우선순위)
코드(freeze)는 이미 켜져 있다. 아래는 새 기능이 아니라 “잘 됐는지 확인” 순서다.
1순위 — 깨끗한 장일 하루만 검증
말: 봉이 끝난 직후 적힌 거래량(volume)이, 한 시간 뒤·다음날에도 그대로여야 한다.
중간에 REST·갭보정·매도백필이 숫자를 키우면 실패.
보는 법:
- 확정 직후 volume vs 1시간 뒤 · 다음날 → 같아야 함
- 갭보정 로그:
freeze_skip있고,update≈0,insert만 정상 (구멍 메우기)
2순위 — 웹백테 1회 (같은 날 · 같은 파라미터)
말: 그날 실매가 본 봉으로, 웹 백테도 같은 시험을 한 번 돌려 본다.
PASS/지표가 실매 저널과 크게 안 벌어지면 OK.
주의: 이미 덮여 커진 날(예: 7/15–16)은 참고만. 정합 합격 기준으로 쓰지 말 것.
3순위 — 이 문서 §5 체크리스트 닫기
위 1·2가 통과하면 §5 미체크 칸을 체크한다.
그때 “정합 검증 완료”라고 말해도 된다.
선택(후속) — 틱 합으로 volume 통일
freeze가 안정된 뒤에만. 지금은 필수 아님.
안 하는 것 (여기선 안내만 — 강제 금지는 .cursorrules)
- 신호/진입을 ±1분으로 땜빵하지 않는다
- freeze를 끄거나
*_SKIP_HTS_SCAN_DUPES를 true로 바꾸지 않는다