매도(sell) 주문이 현재가가 아닌 매수가(entry_price) 지정가로 나가던 버그(issue #10) 정정. 슬롯의 매수 전용 entry_price 를 side 무관 "현재 pending 주문 지정가" limit_price 로 내부 rename 하고, pending 이탈(→holding/→closed) 시 clear 해 매수 지정가가 매도로 누수되는 경로를 구조적으로 제거. 거버넌스: 전부 change-req (신규 REQ 없음, dcy-012 OQ-3). - REQ-002: Slot entry_price→limit_price rename + clear-on-exit 생애주기 - REQ-006: daily_slot 컬럼 rename 마이그레이션 006 (idempotent) + persistence 매핑 - REQ-013: _dispatch 가 slot.limit_price 단일 필드로 가격/주문유형 결정 - REQ-007: SellIntent/sell payload optional limit_price + _admit_sell 운반 - REQ-036: SlotService.sell optional 가격 → 자율 매도(safety-sell/kill-switch) 시장가 - REQ-003: 컬럼 계약/드리프트 가드 limit_price 반영 - REQ-015: runtime-flows/interface-contract/data-model 정합 매도 정책(OQ-1 하이브리드): 가격 지정→지정가("00"), 미지정→시장가("01"). 자율 매도는 가격 미전달 → 항상 시장가 (손절 미체결 pending_sell 갇힘 방지, issue #9 연계). 검증: 단위 286 passed/32 skipped, 인프라 게이트(PG+RabbitMQ) 318 passed, ruff clean. 신규 test_sell_pricing(recording broker)로 지정가 매수 슬롯의 매도가 매수가 재사용 안 함을 직접 검증. BAT-016 release-candidate. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
4.2 KiB
4.2 KiB
BAT-016 Verification
- Status: verified
- Batch: BAT-016
Acceptance Mapping
REQ-013 (dispatch 단일 필드, change-req)
| AC | Evidence |
|---|---|
| dispatch 가 slot.limit_price 단일 필드로 결정(매수가 재사용 금지) | tests/application/test_sell_pricing.py::test_limit_buy_then_market_sell_does_not_reuse_buy_limit |
| 기존 buy/sell lifecycle 회귀 | tests/application/test_execution.py (전체) |
REQ-007 (sell intent 가격, change-req)
| AC | Evidence |
|---|---|
| sell optional limit_price → 지정가 | test_sell_pricing.py::test_limit_buy_then_limit_sell_uses_intent_price |
| 미지정 → 시장가(호환) | test_sell_pricing.py::test_limit_buy_then_market_sell_does_not_reuse_buy_limit |
| buy entry_price → 슬롯 limit_price 매핑(동작 동일) | test_sell_pricing.py::test_limit_buy_then_market_sell... (buy_req order_type "00"/1000) |
| 멱등/동시성 회귀 | tests/application/test_intent_concurrency.py |
REQ-036 (자동 매도 시장가, change-req)
| AC | Evidence |
|---|---|
| SlotService.sell(가격 없음) → 시장가 + closed | test_sell_pricing.py::test_safety_sell_dispatches_at_market |
| idempotency 회귀 | tests/application/test_auto_sell* / 전체 회귀 |
REQ-002 (도메인 rename + clear-on-exit, change-req)
| AC | Evidence |
|---|---|
| limit_price clear on →HOLDING | tests/domain/slot/test_service.py::test_pending_buy_to_holding (limit_price is None) |
| clear on →CLOSED / →IDLE | test_service.py::test_closed_to_idle_resets_fields_and_bumps_counter + 전체 회귀 |
| 필드셋 계약 | tests/domain/slot/test_contract.py |
REQ-006 (마이그레이션 + persistence, change-req)
| AC | Evidence |
|---|---|
| 컬럼 rename(데이터 보존) | tests/adapters/persistence/test_migration_and_drift.py::test_daily_slot_columns_match_expected_contract (PG 게이트) |
| 마이그레이션 idempotent | ::test_apply_migrations_is_idempotent |
| persistence round-trip | PG 게이트 repository/전이 테스트 전반 |
REQ-003 (컬럼 계약 가드, change-req)
| AC | Evidence |
|---|---|
| 도메인 필드셋 = limit_price | tests/domain/slot/test_contract.py |
| DB 컬럼 드리프트 가드 = limit_price | test_migration_and_drift.py::test_daily_slot_columns_match_expected_contract / ::test_drift_detected_when_contract_extended |
REQ-015 (baseline 문서, change-req)
| AC | Evidence |
|---|---|
| runtime-flows/interface-contract/data-model 정합 | 문서 diff(BAT-016) |
Evidence
- Test:
- 단위 전체 회귀:
286 passed / 32 skipped(신규 sell-pricing 4 + holding clear 단언 포함;::test_sandbox_token_and_submitdeselect). - 인프라 게이트(PG trex_core_test + RabbitMQ):
318 passed(006 rename 마이그레이션 + 컬럼 계약 limit_price + idempotency + 전이 round-trip 포함). ruff check trex_core tests→ All checks passed.
- 단위 전체 회귀:
- Logs:
286 passed, 32 skipped, 1 deselected/318 passed, 1 deselected ~15.8s.
성공 기준(dcy-012) 대응
- S-1(매도가 매수 지정가 재사용 안 함): test_limit_buy_then_market_sell_does_not_reuse_buy_limit(a) + test_limit_buy_then_limit_sell_uses_intent_price(b) + test_market_buy_slot_sells_at_market_regression(c). 지정가 매수 슬롯 케이스 포함(측정 필수 조건 충족).
- S-2(손절 시장가 체결, pending_sell 갇힘 없음): test_safety_sell_dispatches_at_market.
- S-3(rename 마이그레이션 데이터 보존 + 생애주기): test_migration_and_drift(컬럼 계약+idempotency) + test_service(holding clear).
- S-4(코드-문서 정합): runtime-flows/interface-contract/data-model 갱신.
Carried-Over / 비차단
- KIS 시장가 매도(
ORD_DVSN="01")의 paper/실계좌 수용·체결 특성(A-4): paper 검증 완료, 실계좌는 release 단계 운영 검증. - 재량 지정가 미체결 시 pending_sell 잔류(R-2)·issue #9 복구는 본 주기 밖.
- 과거 누락/잘못 체결 데이터 보정은 범위 밖.
Result
- Ready for Release: true
- Blocking Issues:
- 없음. rename 호출부 전환 누락은 전체 회귀(318 passed) green 으로 부재 확인. 외부 payload/read 필드명 유지로 전략 모듈 계약 무파괴. LIVE sandbox 토큰 테스트 deselect 는
.env환경 의존(본 batch 무관).
- 없음. rename 호출부 전환 누락은 전체 회귀(318 passed) green 으로 부재 확인. 외부 payload/read 필드명 유지로 전략 모듈 계약 무파괴. LIVE sandbox 토큰 테스트 deselect 는