dcy-030 (issue #28, P0 체결 복구): - REQ-083 KRX 호가단위(tick) 순수 유틸 (domain/pricing.py) - REQ-070 CHG: 슬리피지 실효가 호가단위 스냅 — 상한 준수(매수 floor/매도 ceil) + band<1tick 하한/상한 보장 + 부동소수 epsilon 가드. 147700→148400/54500→54700. - BAT-044 release-candidate dcy-029 (issue #29, 운영 관측성): - REQ-084 구조화 로깅 기반 (runtime/logging_setup.py): ISO8601 KST·레벨·Loki JSON ·correlation id(slot_id) - REQ-085 주문 결과 로깅 (event=order_submit|fill|reject) - REQ-087 거부 ERROR 가시성 (조용한 롤백 제거) - REQ-086 청산 reason+actor 동반 노출 (안전망/전략 구분, 신규 필드 없음) - REQ-088 운영 조회 CLI report (application/operator_report.py, 보유·오늘 체결 ·실현 PnL net·대기, direct-DB) - REQ-089 운영자 런북 docs/operations.md - REQ-090 baseline 정합 (runtime-flows·project-structure·interface-contract) - BAT-045(P0)·BAT-046(P1) release-candidate REL-007: confirmed → feedback-captured (운영 인스턴스 라이브 검증 + #28/#29 환류 정규화). BAT-037~041 released. 검증: 537 passed, 47 skipped, 회귀 0, ruff clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
9.4 KiB
9.4 KiB
req-070: slippage 보호 지정가 집행 — entry_price 기준 실효 지정가 산출
- Status: Implemented
- Type: Integration
- Priority: High
- Owner: project maintainers
Intent
slippage_pct가 지정된 주문을 dispatch 할 때entry_price*(1±pct)실효 지정가로 제출해 과도한 불리 체결을 막는다.entry_price없으면 무시(순수 시장가는 슬리피지 기준 없음). (dcy-022 FR-3)
Requirement
_dispatch가 슬롯의slippage_pct를 읽어 실효 지정가를 산출한 뒤 KRX 호가단위(REQ-083)로 스냅한다. 방향은 상한 준수: 매수 =floor_to_tick(limit_price * (1 + slippage_pct/100))(내림 — slippage 상한 미초과), 매도 =ceil_to_tick(limit_price * (1 - slippage_pct/100))(올림 — 매도 하한 미초과). band<1tick 엣지에서 미체결을 막기 위해 하한/상한을 보장한다: 매수 실효가 =max(floor_to_tick(...), ceil_to_tick(limit_price)), 매도 실효가 =min(ceil_to_tick(...), floor_to_tick(limit_price)).limit_price(=entry_price)가 None 이면slippage_pct를 무시하고 시장가 주문 제출(기존 동작 보존, 스냅 없음).slippage_pct없는 슬롯은 기존limit_price직접 사용(회귀 없음). 주식 전용 — ETF/ETN 비주식 호가체계는 범위 밖(dcy-030 OQ-1).
Acceptance Criteria
- Given 슬롯에
limit_price=10000,slippage_pct=1.0, side=buy, When dispatch, Then OrderRequest.limit_price =floor_to_tick(10000*1.01)=floor_to_tick(10100)= 10100 (상한 준수 내림). - Given 슬롯에
limit_price=10000,slippage_pct=1.0, side=sell, When dispatch, Then OrderRequest.limit_price =ceil_to_tick(10000*0.99)=ceil_to_tick(9900)= 9900 (하한 준수 올림). - Given
limit_price=None(시장가),slippage_pct=1.0, When dispatch, Then OrderRequest.limit_price = None(시장가 — slippage·스냅 무시). - Given
slippage_pct=None,limit_price=10000, When dispatch, Then OrderRequest.limit_price = 10000(기존 동작, 회귀 없음). - Given
slippage_pct=0.0, When dispatch, Then 실효 지정가 =floor_to_tick(limit_price)(0% 슬리피지 = 기준가의 유효 호가). - Given 기존 매수/매도 슬롯(slippage_pct 없음), When dispatch, Then 기존 동작과 동일(전체 회귀 없음).
- Given
limit_price=147700,slippage_pct=0.5, side=buy, When dispatch, Thenfloor_to_tick(148438.5)= 148400 (issue #28 케이스, 유효 호가·상한 미초과). - Given
limit_price=54500,slippage_pct=0.5, side=buy, When dispatch, Thenfloor_to_tick(54772.5)= 54700 (issue #28 케이스). - Given band<1tick (예:
limit_price=147700,slippage_pct=0.01, buy), When dispatch, Then 매수 실효가 =max(floor_to_tick(147714.77), ceil_to_tick(147700))≥ entry 유효 호가 (미체결 방지), 그리고 slippage 상한 미초과. - Given 임의 매수/매도 + slippage, When dispatch, Then 결과는 유효 KRX 호가단위 배수이고 매수 ≤
limit*(1+pct/100)/ 매도 ≥limit*(1-pct/100).
Impacted Area
- Docs: docs/runtime-flows.md(slippage dispatch + 호가단위 스냅 흐름), docs/project-structure.md(신규 tick 유틸 — REQ-083)
- Modules: trex_core/application/execution.py(
_dispatchslippage 계산 + 호가단위 스냅), REQ-083 tick 유틸 소비 - Tests: tests/application/test_execution.py(slippage dispatch + 스냅 방향·경계·band<tick 하한 보장 단위)
Notes
entry_price=limit_price로 슬롯에 저장되는 설계를 그대로 사용(REQ-013 CHG-20260608-01 선례). 슬리피지는 dispatch-time 변환만 — 슬롯의limit_price자체를 덮어쓰지 않는다.- (CHG-20260616-01, dcy-030) KRX 정밀 호가단위 스냅을 REQ-083 유틸로 구현. 반올림 방향 = 상한 준수(매수 내림/매도 올림). 원래 메모의 "체결 보장(매수 상위/매도 하위)" 방향에서 전환 —
slippage_pct를 리스크 상한으로 취급하기 때문(상한 1틱 초과 방지). band<1tick 하한/상한 보장으로 미체결 방지. - 주식 전용. ETF/ETN 비주식 호가체계 및 2,000원 미만 비주식은 미지원(dcy-030 OQ-1, known limitation).
- 출처: dcy-022 FR-3, OQ-2 / dcy-030 FR-2·2b·3·4.
Change Log
CHG-20260610-01
- Date: 2026-06-10
- Author: Justin Ko
Change Summary
- dcy-022 FR-3 로부터 최초 생성(Proposed).
Intent
- slippage 보호 지정가 dispatch 집행을 backlog 로 정규화.
Acceptance Criteria Delta
- Added: AC-1~6 (매수/매도 slippage 계산, 시장가 무시, 없을 때 회귀 6개 기준)
Impacted Area Delta
- Modules: execution.py(_dispatch)
- Tests: test_execution.py slippage 단위
Delivery Trace Delta
- Batches: none
Revalidation Impact
- Reverification Needed: no / Existing Implementation Invalidated: no / Status Recommendation: keep-current
Validation Plan
- slippage 산출 단위 + 시장가/없을 때 회귀.
CHG-20260610-02
- Date: 2026-06-10
- Author: Justin Ko
Change Summary
- Status Proposed → Approved (confirm-req).
Intent
- delivery input 으로 승격.
Acceptance Criteria Delta
- Added: 없음 / Updated: 없음 / Removed: 없음
Impacted Area Delta
- Docs: docs/srs/index.md (Register Approved)
Delivery Trace Delta
- Batches: none
Revalidation Impact
- Reverification Needed: no / Existing Implementation Invalidated: no / Status Recommendation: keep-current / Follow-up Action: BAT-032.
Validation Plan
- 승인 후 batch planning 에서 AC 검증 기준으로 사용.
CHG-20260611-IMPL
- Date: 2026-06-11
- Author: Justin Ko
- Type: status
- Summary: Approved → Implemented (confirm-req-implemented). 근거: BAT-032(release-candidate) verification — 실행 정책(timeout_sec·slippage_pct) 계약·집행·운영자 cancel 백스톱 전 AC acceptance mapping 존재(신규 71 tests), 단위 425 passed 회귀 없음, baseline 2문서 수동 확인(M5). Blocking Issues 없음.
CHG-20260616-01
- Date: 2026-06-16
- Author: Justin Ko
Change Summary
- slippage 실효 지정가에 KRX 호가단위 스냅을 추가하고, 반올림 방향을 원래 메모의 "체결 보장(매수=상위/매도=하위)"에서 "상한 준수(매수=하위/매도=상위)" 로 전환한다. band<1tick 엣지에 하한(매수)/상한(매도) 보장을 추가한다. (dcy-030 FR-2/FR-2b/FR-3/FR-4)
Intent
- 현재 구현은
int(ceil/floor)만 적용하고 KRX 호가단위로 스냅하지 않아, slippage_pct>0인 매수 한계가가 호가단위를 위반해 KIS주식주문호가단위 오류로 전량 거부됨(issue #28). 호가단위 스냅으로 거부를 제거하되,slippage_pct를 리스크 상한으로 취급해 스냅이 상한을 넘기지 않도록 매수=내림/매도=올림으로 정정한다.
Acceptance Criteria Delta
- Updated:
- AC-1: 매수 =
floor_to_tick(limit*(1+pct/100))(상한 준수 내림). 예:limit=10000,pct=1.0→floor_to_tick(10100)=10100. - AC-2: 매도 =
ceil_to_tick(limit*(1-pct/100))(하한 준수 올림). 예:limit=10000,pct=1.0→ceil_to_tick(9900)=9900.
- AC-1: 매수 =
- Added:
- AC-7:
limit=147700,pct=0.5,buy→floor_to_tick(148438.5)=148400(issue #28 케이스). - AC-8:
limit=54500,pct=0.5,buy→floor_to_tick(54772.5)=54700(issue #28 케이스). - AC-9 (band<1tick 하한 보장): 매수 실효가 =
max(floor_to_tick(limit*(1+pct/100)), ceil_to_tick(limit)); 매도 실효가 =min(ceil_to_tick(limit*(1-pct/100)), floor_to_tick(limit)). slippage<1tick이어도 최소 entry 유효 호가 보장. - AC-10: 스냅 결과는 항상 유효 호가단위 배수이고, 매수 ≤
limit*(1+pct/100)/ 매도 ≥limit*(1-pct/100)(상한·하한 미초과).
- AC-7:
- Removed:
- (없음 — AC-3·4·5·6 시장가/무slippage/0% 회귀 기준 유지)
Impacted Area Delta
- Docs:
- docs/runtime-flows.md(주문 집행 슬리피지 dispatch에 호가단위 스냅 단계 추가), docs/project-structure.md(신규 tick 유틸 — REQ-083)
- Modules:
- trex_core/application/execution.py(
_dispatch스냅 적용), REQ-083 tick 유틸 소비
- trex_core/application/execution.py(
- Tests:
- tests/application/test_execution.py(슬리피지 스냅 방향·경계·band<tick 하한 보장), REQ-083 tick 단위 테스트
Delivery Trace Delta
- Batches: BAT-032(REQ-070 최초 구현) — 본 변경은 신규 batch(dcy-030)에서 재구현·재검증.
- Releases: REL-006(BAT-032 released) — 운영 영향(매수 거부 해소)은 dcy-030 batch 배포 시 신규 release로 추적.
Revalidation Impact
- Reverification Needed: yes
- Existing Implementation Invalidated: yes (tick 스냅 부재 → 매수 거부; 반올림 방향도 변경)
- Status Recommendation: revert-to-approved
- Follow-up Action: dcy-030 batch에서 REQ-083 + REQ-070 재구현·검증 후 confirm-req-implemented로 재전환.
Validation Plan
- REQ-083 tick 유틸 단위 + execution.py 슬리피지 스냅 방향/경계/band<tick 하한 보장 단위 + 기존 AC-3~6 회귀.
CHG-20260616-IMPL
- Date: 2026-06-16
- Author: Justin Ko
- Type: status
- Summary: Approved → Implemented (confirm-req-implemented, BAT-044 release-candidate, dcy-030/issue #28). 근거:
execution.py_dispatch호가단위 스냅 구현(상한 준수 매수 floor/매도 ceil + band<tick 보장 + epsilon 가드, REQ-083 소비). AC-1·2·5·7·8·9·10 단위 매핑(issue #28 케이스 147700→148400/54500→54700, 35000@0.7%→35200, band<tick), AC-3·4·6 회귀. 47 passed(pricing+execution_policy), 전체 516 passed/47 skipped 회귀 0, ruff clean. Blocking Issues 없음.