KIS 계좌에서 직접 매도 주문을 취소하면 poll_fill 이 cncl_yn 을 파싱하지 않아 슬롯이 pending_sell 에 영구히 갇히고 죽은 주문을 무한 폴링하던 버그(issue #9) 정정. 거버넌스: 전부 change-req (신규 REQ 없음, dcy-013 OQ-3). - REQ-012: KIS poll_fill cncl_yn 파싱 → 외부 취소 감지. FillStatus.cancelled /is_partial_cancel 추가. 체결 0 취소→cancelled, 부분 체결 후 취소→partial+cancelled - REQ-013: 집행 _on_partial_cancel — 체결분 원장 1회 + qty 차감(매도 잔여/매수 체결분) + holding 복귀 (OQ-1 A안). 전량 취소는 기존 롤백 경로 재사용 - REQ-018: 부분 체결분 원장 1회 기록 (_record_ledger 재사용) - REQ-031: 잔여 포지션 정합 연계 (slot.qty ↔ 실 잔고, 과매도 방지) - REQ-014: pending stale 워치독 Alert-only (TREX_PENDING_STALE_THRESHOLD, WARN+카운터, 상태 미변경) — 취소 감지 누락 backstop - REQ-015: interface-contract/runtime-flows 정합 전량 취소는 holding 자동 복구(limit_price clear→재매도 시장가, dcy-012 연계). KIS cncl_yn 실 규약은 운영 검증(미지 값 보수 처리 + 워치독 backstop). 검증: 단위 294 passed/32 skipped, 인프라 게이트(PG+RabbitMQ) 326 passed, ruff clean. 신규 test_kis_cancel(httpx stub) + test_execution_cancel(programmable broker). BAT-017 release-candidate. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
3.8 KiB
3.8 KiB
BAT-017 Planning
- Status: confirmed
- Batch: BAT-017
- Profile: standard
Included REQ
- REQ-012 (Integration, change-req): KIS
poll_fillcncl_yn파싱 +cancelled/partial-cancel 매핑,FillStatus.cancelled/is_partial_cancel. - REQ-013 (Integration, change-req): 집행 루프
_on_partial_cancel(체결분 원장 + qty 차감 + holding 복귀), 전량 취소 롤백 재사용. - REQ-018 (Integration, change-req): 부분 체결분 원장 1회 기록(
_record_ledger재사용). - REQ-031 (Exception, change-req): 잔여 포지션 정합 연계(슬롯 qty ↔ 실 잔고).
- REQ-014 (Exception, change-req): pending stale 워치독 Alert-only +
TREX_PENDING_STALE_THRESHOLD. - REQ-015 (Documentation, change-req): interface-contract/runtime-flows 정합.
Delivery Plan
- REQ-012:
broker_port.pyFillStatus.cancelled + is_partial_cancel;kis.py::poll_fillcncl_yn 파싱(full cancel/partial cancel 매핑 + execution_id). - REQ-013/018:
execution.py::_pollis_partial_cancel 분기 +_on_partial_cancel(원장 1회 + qty 차감 + holding). 전량 취소는 기존 is_terminal_reject 롤백. - REQ-014:
_check_stale_pending+ ExecutionResult.stale_pending + ExecutionService threshold;config.pypending_stale_threshold_sec/env;daemon.py배선. - REQ-031: 부분 회계가 잔여 qty 정합 유지(연계, reconcile 코드 무변경) 확인.
- REQ-015: interface-contract/runtime-flows 정합.
- 신규 테스트(test_kis_cancel, test_execution_cancel) + 전체 회귀 + ruff + 인프라 게이트.
Dependencies
- Internal:
- dcy-003/BAT-004 broker execution(poll/rollback/REQ-012/013/014) — 변경 대상.
- dcy-004/BAT-006 fill→ledger(REQ-018) — 부분 체결분 기록.
- dcy-005/BAT-008 reconcile_positions(REQ-031) — 잔여 정합 연계.
- dcy-012/BAT-016 — holding 진입 시 limit_price clear(A-1, 재매도 시장가).
- External:
- KIS
inquire-daily-ccldcncl_yn 필드(R-1, 실 응답 확인은 운영/검증).
- KIS
Design Gate
- Design Required Before Implementation: yes
- Reason: (a) 부분 체결 후 취소 회계(A안)는 FillStatus 계약 확장 + 집행 분기 + 원장 기록 + 슬롯 qty/cost basis 정합까지 교차 — 매도/매수 각각의 qty·avg_price 처리 규칙을 설계에서 못박지 않으면 과매도/이중기록(R-3) 위험. (b) 전량 취소 자동 복구가 기존 is_terminal_reject 롤백 재사용으로 성립하는지(A-2) 설계에서 확인. (c) stale 워치독은 Alert-only 경계(상태 미변경)·임계 env·타임스탬프 출처(slot.updated_at)를 설계에서 고정. → design.md 동일 턴 scaffold.
Milestones
- M1 — REQ-012 FillStatus.cancelled + KIS cncl_yn 매핑, test_kis_cancel green
- M2 — REQ-013/018 부분 체결 회계 + 전량 취소 롤백, test_execution_cancel green
- M3 — REQ-014 stale 워치독 + config/daemon 배선
- M4 — REQ-031 잔여 정합 확인 + REQ-015 문서 정합
- M5 — 전체 회귀 + ruff + 인프라 게이트
Risks
- R-1 (High): KIS 실제 취소 표현(cncl_yn 필드/값)이 가정과 다르면 취소를 여전히 accepted 로 오판. 대응: 미지 값 보수 처리 + stale 워치독(FR-3) backstop. 실 응답 확인은 운영/검증 단계.
- R-2 (Medium): 외부 취소→롤백→재매도 반복 시 safety-sell 무한 재매도. 대응: dcy-010(REQ-052) per-slot 쿨다운 확인, 필요 시 cancelled 도 쿨다운 트리거 포함(후속).
- R-3 (Medium): 부분 체결 후 단순 롤백 시 과매도. 대응: A안(체결분 원장 + qty 차감 + 잔여 holding)으로 구조적 차단, cost basis 유지.
Notes
- 1차 게이트: 전체 회귀 green.
- KIS 어댑터 단위는 httpx stub(fixture)로 cncl_yn 매핑 검증; 집행 회계는 programmable broker 로 FillStatus 주입 검증.
- 실 KIS 외부 취소 e2e 는 실계좌 세션 필요로 비차단 이월(운영 검증).