docs: define broker uncertainty gap closure

This commit is contained in:
jordan
2026-07-29 17:02:55 +09:00
parent 479cb39a7e
commit 6398ff250c
3 changed files with 135 additions and 0 deletions
@@ -30,3 +30,8 @@ KRX/NXT/SOR다. admission에서 검증한 venue를 pending 슬롯에 저장해
- 신규 venue 흐름 테스트 4건
- 전체 회귀 `837 passed, 47 skipped`
- 별도 worktree `codex/top50-venue-aware-intents`
## Follow-up
- `dcy-041_20260729_broker-uncertainty-and-adapter-retirement`: `AUTO` 실제 거래소
확정, 취소 결과 상태, 짧은 계좌 스냅샷 복구.
@@ -0,0 +1,129 @@
# 0. 문서 상태
- 상태: confirmed
- 문서 ID: dcy-041_20260729_broker-uncertainty-and-adapter-retirement
- 이슈명: Core 브로커 불확실 상태 구분과 로컬 KIS 어댑터 축소
- 작성 시각(KST): 2026-07-29 16:59:16 KST
- 마지막 갱신 시각(KST): 2026-07-29 17:01:50 KST
- 대체됨: 없음
- 선행 Discovery:
- dcy-013_20260608_kis-external-cancel-pending-sell-stuck
- dcy-022_20260610_stuck-pending-order-recovery
- dcy-039_20260727_intent-venue-end-to-end-propagation
- 후속 Discovery 참조: 없음
- GitHub 이슈: #44, #45
# 1. 계획 상태 요약
- 해석:
- Core에는 intent 거래소 전달, 외부 취소 감지, 결과불명 주문 복구가 일부 구현돼 있다.
- 남은 공용 공백은 `AUTO` 거래소의 실제 제출 거래소 확정, 취소 요청 결과의 명시적 상태, 짧은 계좌 스냅샷 복구다.
- 목표:
- 공용 기능을 Core가 소유하고 로컬 KIS 호환 어댑터는 KIS 중계만 남도록 축소한다.
- 호출 실패를 실제 불일치로 오판하거나 결과불명 주문을 재전송하지 않는다.
# 2. 요구사항 판정 결과
- 판정: 신규 운영 후속 Discovery
- 근거:
- 선행 Discovery들은 이미 확정·구현됐지만 2026-07-28~29 실전 운영에서 취소 응답과 계좌조회 불확실 상태가 다시 확인됐다.
- 이번 변경은 기존 기능의 문구 보강이 아니라 Core와 외부 호환 어댑터의 책임 경계를 바꾸므로 독립 추적한다.
# 3. 문제점의 요약
## 현재 상태
- `dcy-039`는 intent의 `KRX|NXT|SOR` 거래소를 슬롯과 주문·취소까지 보존한다.
- 전략이 거래소를 보내지 않으면 기본 KRX이므로, 전략을 바꾸지 않고 08:00 NXT 주문을 보내는 `AUTO` 계약은 없다.
- `BrokerPort.cancel_order()`는 참/거짓만 반환하므로 요청 접수, 명시적 거부, 응답유실을 구분하지 못한다.
- KIS `get_balance()`는 호출 실패를 검증된 빈 잔고와 구분해 예외로 올리지만, 마지막 정상 계좌 스냅샷의 출처·시각·만료 정책은 Core에 없다.
- 로컬 `nxt_adapter`가 주문번호-거래소와 짧은 잔고 스냅샷을 별도 SQLite에 저장한다.
## 기대 상태
- `AUTO` 주문은 KIS 브로커 경계에서 KST 세션에 따라 실제 거래소를 확정하고 슬롯·취소·Core 원장에 보존한다.
- 취소 요청 결과는 `요청 접수`, `명시적 거부`, `결과불명`으로 구분하고 최종 취소·체결은 기존 체결조회로 확정한다.
- 마지막 정상 계좌 스냅샷은 계정 범위와 캡처 시각을 포함해 원자적으로 저장하고 짧은 유효시간 안에서만 사용한다.
- 신규매수와 위험축소 매도의 허용시간을 분리하고 결과불명 주문은 종목·방향 범위에서 재전송을 차단한다.
# 4. 이번에 정의할 변경
1. `AUTO` 거래소를 실제 KRX/NXT로 확정하고 재시작 후에도 원 주문 거래소를 복구한다.
2. 취소 API 결과를 명시적 상태값으로 바꾸고 응답유실 시 재취소·재주문을 자동 반복하지 않는다.
3. 계정별 마지막 정상 잔고 스냅샷과 방향별 만료 정책을 Core/KIS 브로커 계층에 둔다.
# 5. 요구사항 목록
## 기능 요구사항
- FR-1: `AUTO|KRX|NXT|SOR`를 입력받고 `AUTO`는 KST 세션에 따라 실제 KRX/NXT로 결정한다. 결정 불가능 시간은 KRX로 대체하지 않고 거부한다.
- FR-2: 실제 제출 거래소를 슬롯과 Core 체결 전달 대기 원장에 저장하며 취소·재시작 복구에서 재사용한다.
- FR-3: 취소 요청은 `requested|rejected|unknown` 결과를 반환한다. `requested`는 최종 취소가 아니며 체결조회가 `cancelled|filled`를 확정한다.
- FR-4: `unknown` 취소 결과와 결과불명 주문은 자동 재주문하지 않고 기존 주문 조회로만 수렴한다.
- FR-5: 성공한 계좌조회만 계정 해시·캡처 시각·보유수량·주문가능금액과 함께 원자 저장한다.
- FR-6: 일시적 전송 오류에만 미만료 스냅샷을 사용한다. 계정 불일치·만료·응답 오류는 차단한다.
- FR-7: 신규매수와 위험축소 매도의 스냅샷 최대 나이를 분리하며 KIS 복구 후 다음 백그라운드 조회가 정상값으로 교체한다.
## 비기능 요구사항
- NFR-1: 동일 intent와 동일 결과불명 주문의 중복 제출은 0건이어야 한다.
- NFR-2: 기존 KRX 명시 주문, PaperBroker, 전략 wire의 미지정 필드 호환성을 보존한다.
- NFR-3: 토큰·키·계좌번호·원본 KIS 응답은 로그·문서·테스트 산출물에 남기지 않는다.
- NFR-4: DB 마이그레이션은 멱등이고 기존 슬롯·체결 전달 대기 원장을 보존한다.
## 범위 경계
- In Scope:
- TREX Core의 KIS 브로커, 주문·취소 실행, 슬롯·계좌 스냅샷 영속화, 회귀·장애·재시작 테스트.
- Out of Scope:
- Portfolio Hub API·스키마 변경, 전략 자금배분, 계정관리 대시보드, 토큰 갱신, NXT 분봉 수집, 수동 보유수량 분리.
# 6. 리스크/가정 목록
- R-1: 취소 요청 접수를 취소 확정으로 처리하면 체결 경쟁에서 중복매수가 발생할 수 있다.
- 완화: 슬롯은 pending을 유지하고 체결조회만 최종 상태를 전이한다.
- R-2: 오래된 계좌 스냅샷이 신규매수를 허용하면 주문가능금액을 초과할 수 있다.
- 완화: 신규매수 유효시간을 짧게 두고 수량·금액 한도를 기존 전략 intent 이하로 제한한다.
- R-3: `AUTO` 실제 거래소가 영속화되지 않으면 재시작 후 취소가 잘못된 거래소로 갈 수 있다.
- 완화: 브로커 응답 직후 슬롯 저장을 주문 접수의 완료 조건으로 둔다.
- A-1: KST 세션은 NXT 08:00~08:49:59, KRX 09:00:30~15:29:59, NXT 15:30~20:00으로 운영한다.
- A-2: 미확인주문 상태는 기존 슬롯의 broker_order_id와 결과불명 제출 메타데이터가 정본이다.
- 오픈 질문: 없음. 사용자가 2026-07-29 핵심 3개 범위와 순차 구현을 승인했다.
# 7. 초기 성공 기준
- S-1: 거래소 미지정 전략 intent가 08:00 KST에 NXT로 제출되고 재시작 후 NXT로 취소된다.
- S-2: 취소 응답유실은 `unknown`으로 남고 같은 주문의 자동 재취소·재매수가 발생하지 않는다.
- S-3: KIS 계좌조회 전송 실패에서 미만료 동일계정 스냅샷만 사용하며 신규매수·매도 유효시간이 각각 적용된다.
- S-4: 스냅샷 만료 후 신규매수는 차단되고 보유분 매도·체결조회·원장복구는 독립적으로 검증된다.
- S-5: 단위→회귀→가상계약→가상종단간→오류주입→재시작→원장대조가 모두 통과한다.
# 8. REQ로 넘기기 전 확인 체크
- [x] 기존 Core와 로컬 어댑터의 중복 책임을 코드로 확인했다.
- [x] GitHub #44·#45의 완료 기준과 범위를 확인했다.
- [x] 실전 반영 전 가상 검증과 원복 게이트를 고정했다.
- [x] 사용자 결정이 필요한 오픈 질문이 없다.
# 9. 파일 처리 결과
- 처리 결과: 생성
- 생성 경로: `docs/discovery/dcy-041_20260729_broker-uncertainty-and-adapter-retirement.md`
- 참조:
- `trex_core/application/broker_port.py`
- `trex_core/application/execution.py`
- `trex_core/adapters/broker/kis.py`
- `trex_core/application/snapshot_scheduler.py`
- `docker-local/KIS_ADAPTER_REMOVAL_CONTRACT.md`
# 10. 사용자 결정 필요 항목 요약
- 없음. 사용자가 핵심 범위, 기능별 브랜치, Docker 선검증, 서버 차이 검증, 실전 적용 후 어댑터 축소 순서를 승인했다.
# 11. Discovery Freeze
- Handoff Decision: 승인
- Handoff Rationale: Core의 기존 거래소 전달·결과불명 주문 처리와 남은 취소·계좌조회 공백을 재확인했고, 사용자 승인 범위와 충돌하는 오픈 질문이 없다.
- Ready for REQ Drafting: true
- Confirmed By: 형님
- Confirmed At (KST): 2026-07-29 17:01:50 KST
+1
View File
@@ -44,3 +44,4 @@
| dcy-037_20260714_operator-broker-truth-and-managed-slot-divergence-hotfix | 20260714 | HOTFIX — fetched credential 운영자 broker truth 정합 및 managed non-holding divergence 분리 (#39, #40, #41) | [Discovery](./dcy-037_20260714_operator-broker-truth-and-managed-slot-divergence-hotfix.md) | confirmed |
| dcy-038_20260716_cost-basis-response-contract-and-safe-sync-seeding | 20260716 | P1 — portfolio-hub cost-basis response contract 정합 및 안전한 sync 평균가 seed | [Discovery](./dcy-038_20260716_cost-basis-response-contract-and-safe-sync-seeding.md) | confirmed |
| dcy-039_20260727_intent-venue-end-to-end-propagation | 20260727 | 전략 intent venue를 슬롯·주문·취소까지 전달 | [Discovery](./dcy-039_20260727_intent-venue-end-to-end-propagation.md) | confirmed |
| dcy-041_20260729_broker-uncertainty-and-adapter-retirement | 20260729 | Core 브로커 불확실 상태 구분과 로컬 KIS 어댑터 축소 (#44, #45) | [Discovery](./dcy-041_20260729_broker-uncertainty-and-adapter-retirement.md) | confirmed |