Files
kis_trader/docs/정합성.md
Your Name 36a3e2b4a1 feat: Enhance trading system with new permanent subscription features and order book management
Changes:
- Added a new API endpoint for managing permanent subscriptions, allowing users to enable or disable subscriptions dynamically.
- Implemented a function to fill candle data from Kiwoom, ensuring that only relevant data is inserted into the database.
- Introduced a mechanism to handle master subscription states, improving the management of subscription statuses.
- Updated the database schema to include new fields for managing subscription states and order book filtering.

Impact:
- These enhancements improve the flexibility and reliability of the trading system, allowing for better management of subscriptions and order book data, while reducing the risk of data inconsistencies.

히스토리 align 제거 븅신같은 초기설계 아예 제거
진입모드에 구멍메움
호가진입을 켜도 호가가 안들어올때 호가 안보고 그냥 사버림
2026-08-15 23:01:14 +09:00

9.5 KiB
Raw Blame History

정합성

최종안 (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 금지뿐. 파람/아침용 봉 소스를 둘로 나누지 않음.

0.2 증권사별 저장 · 읽기 (2026-08-14)

ws_candles.source = 증권사(kiwoom|kis), channel = ws|rest|rollup.
UNIQUE = (code, timeframe, candle_time, source, channel).

쓰기 규칙
키움/KIS WS 틱 분봉 source=증권사, channel=ws
갭보정 항상 키움 ka10080source=kiwoom, channel=rest. KIS REST 페이지 갭보정 사용 금지
1M→nM 롤업 source=kiwoom, channel=rollup
영구구독 KR LS WS → ls_ws_candles 만. ws_candles에 넣지 않음. 자동 갭보정 제외. 탭 「확정봉 가져오기」=키움 REST → ls_ws_candles INSERT IGNORE

읽기(실매 RAM = Optuna bt_candle_source): 틱 메인 WS 한 칸, 없으면 kiwoom+rest, 그다음 롤업.
CANDLE_SOURCE=kis 여도 구멍은 키움 REST. 키움 REST로 KIS WS 행을 덮지 않음.

영구구독 마스터 PERMANENT_SUBSCRIBE_ENABLED(기본 true): OFF면 행 유지, KR LS / US 해외 WS 구독만 안 함.

0.3 호가필터 구멍 ≠ 봉 ±1 (혼동 금지)

봉 정합(본 문서)과 별개. 진입 호가필터가 저장 TTL로 None이 되면 필터 ON인데 통과한다.
고치는 키: WS_ORDERBOOK_FILTER_MAX_AGE_SEC(기본 0=마지막 RAM). 저장은 WS_ORDERBOOK_TICK_MAX_AGE_SEC.
사진 한 장도 없으면 WS_ORDERBOOK_FILTER_REJECT_IF_EMPTY(기본 true)로 안 삼.
상세 docs/호가.md. ±1봉 보정으로 맞추지 말 것.


1. 잠긴 매매 규칙 (변경 금지)

항목 규칙
신호 봉 T1 확정봉 (live_backtest_align=True)
진입 봉 T 확정봉
유니버스 실매=키움 RAM 푸시/팝. 백테=target_candidates_history 완성 스냅샷 재생 (event_time 마이크로초). 분 슬롯 ±1 해킹 금지
HTS SCAN 후보 참고. *_SKIP_HTS_SCAN_DUPES 기본 false 유지
차트봉 매매·백테·Optuna 경로에 사용하지 않음 (ws_candles + ws_ticks)

2. 근본 원인 (측정, 2026-07-16)

현상 수치/관찰 의미
장중 확정 후 재기록 봉 마감 +5분 이후 updated_at76% 갭보정 REST가 기존 봉 UPDATE(큰 volume 우선)
새벽/매도 후 백필 다음날 updated_at3.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 규칙

  1. 행이 이미 있으면 OHLCV·RSI 덮어쓰기 금지 (RAM merge_confirmed_bars + DB upsert + 매도/보유 백필 동일).
  2. 없을 때만 INSERT — 갭 구멍·웜업 유지.
  3. 진행 중(미확정) 버킷은 기존처럼 confirmed에 넣지 않음 (WS_GAP_FILL_SKIP_INCOMPLETE_BUCKET).
  4. (옵션, 후속) 거래량을 틱 합으로 통일 — 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. 구현 순서 (승인 후)

  1. 존재 시 덮어쓰기 금지
    merge_confirmed_bars / DB upsert / 백필 — 공통 규칙.
  2. 스모크
    확정 직후 volume vs 1시간 뒤 · 다음날 — 동일해야 함.
  3. 7/16 샘표류 대조
    vol 평균·PASS/FAIL이 실매 저널과 같은지 (웹백테 동일 파라미터).

코드 변경 전: 핵심 매매 로직이 아닌 저장/병합 계층 패치.
시그널 T1/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/1516)은 참고만. 정합 합격 기준으로 쓰지 말 것.

3순위 — 이 문서 §5 체크리스트 닫기

위 1·2가 통과하면 §5 미체크 칸을 체크한다.
그때 “정합 검증 완료”라고 말해도 된다.

선택(후속) — 틱 합으로 volume 통일

freeze가 안정된 뒤에만. 지금은 필수 아님.

안 하는 것 (여기선 안내만 — 강제 금지는 .cursorrules)

  • 신호/진입을 ±1분으로 땜빵하지 않는다
  • freeze를 끄거나 *_SKIP_HTS_SCAN_DUPES를 true로 바꾸지 않는다