Files
trex-core/docs/srs/Integration/req-070_slippage-limit-price-execution.md
T
genichinandClaude Opus 4.8 d8d9021260 feat(execution,obs): 호가단위 스냅(dcy-030/#28) + 운영 관측성(dcy-029/#29) + REL-007 환류
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>
2026-06-16 13:19:31 +09:00

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

  1. 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 (상한 준수 내림).
  2. 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 (하한 준수 올림).
  3. Given limit_price=None(시장가), slippage_pct=1.0, When dispatch, Then OrderRequest.limit_price = None(시장가 — slippage·스냅 무시).
  4. Given slippage_pct=None, limit_price=10000, When dispatch, Then OrderRequest.limit_price = 10000(기존 동작, 회귀 없음).
  5. Given slippage_pct=0.0, When dispatch, Then 실효 지정가 = floor_to_tick(limit_price)(0% 슬리피지 = 기준가의 유효 호가).
  6. Given 기존 매수/매도 슬롯(slippage_pct 없음), When dispatch, Then 기존 동작과 동일(전체 회귀 없음).
  7. Given limit_price=147700, slippage_pct=0.5, side=buy, When dispatch, Then floor_to_tick(148438.5) = 148400 (issue #28 케이스, 유효 호가·상한 미초과).
  8. Given limit_price=54500, slippage_pct=0.5, side=buy, When dispatch, Then floor_to_tick(54772.5) = 54700 (issue #28 케이스).
  9. 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 상한 미초과.
  10. 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(_dispatch slippage 계산 + 호가단위 스냅), 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.
  • 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) (상한·하한 미초과).
  • 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 유틸 소비
  • 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 없음.