dcy-026 confirm-discovery + REQ-018 change-req(CHG-20260612-01)→구현→ confirm-req-implemented(CHG-20260612-02) 전체 delivery. - broker_port.py: calculate_tax(side, amount) 신규 + fee/tax 율 env 상수화 (TREX_KIS_FEE_BPS=1.5, TREX_KRX_TAX_SELL_BPS=20.0). 매도 0.2%/매수 0. - paper.py / kis.py: tax=0.0 하드코딩 3곳 제거 → 정책 함수 호출. KIS daily-ccld 응답에 fee/tax 필드 부재 → 정책 폴백(향후 정본 우선 훅). - runtime-flows.md: 체결→ledger fee/tax 산출 흐름 갱신. - tests: fee/tax 정책 단위 + issue #24 4건 회귀(fee+tax=1,376.9원). 429 passed (+6), ruff clean. REQ-018 Approved→Implemented, BAT-038 release-candidate. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
4.3 KiB
4.3 KiB
BAT-038 Verification
- Status: confirmed
- Batch: BAT-038
Acceptance Mapping
-
REQ-018 AC-1 (매수 체결 → holding + buy 원장 1건):
- 이번 배치 변경 범위 밖(기록 경로 불변). BAT-006 evidence 유효.
- Evidence:
test_buy_fill_enqueues_one_ledger_item_and_writer_records_itPASSED.
-
REQ-018 AC-2 (매도 체결 → closed/inactive + sell 원장 1건):
- Evidence:
test_sell_fill_enqueues_sell_ledger_itemPASSED.
- Evidence:
-
REQ-018 AC-3 (
FillStatus결정적 execution_id + 계산된 fee + 계산된 tax 운반):- Evidence:
- 매수:
test_buy_fill_...—t.fee > 0.0 and t.tax == 0.0(매수 무세) PASSED. - 매도:
test_paper_sell_fill_carries_policy_tax—fs.fee == calculate_fee("sell", amount),fs.tax == calculate_tax("sell", amount),fs.tax > 0.0PASSED.
- 매수:
- Evidence:
-
REQ-018 AC-4 (portfolio_id 부재 → 기록 skip + 슬롯 전이 정상):
- 변경 범위 밖. Evidence:
test_portfolio_id_absent_skips_ledger_but_transitions_slotPASSED + 전체 회귀.
- 변경 범위 밖. Evidence:
-
REQ-018 AC-5 (원장 기록 단일 주체 = 집행 경로):
- 변경 범위 밖. fee/tax 는 어댑터 산출, 기록 주체(
execution.py:_record_ledger) 불변. - Evidence:
_record_ledger단일 enqueue 지점 유지(line 396-397fee/tax전달), 전체 회귀 429 passed.
- 변경 범위 밖. fee/tax 는 어댑터 산출, 기록 주체(
-
REQ-018 AC-6 (매도 tax = amount × 0.2%, 매수 tax = 0):
- Evidence:
test_calculate_tax_sell_only:calculate_tax("sell", 1_000_000) == 2000.0,calculate_tax("buy", ...) == 0.0PASSED.test_paper_buy_fill_has_zero_tax: paper 매수 fillfs.tax == 0.0PASSED.
- Evidence:
-
REQ-018 AC-7 (단일 정책 지점 + env, paper·KIS 동일,
tax=0.0하드코딩 제거):- Evidence:
test_calculate_fee_same_rate_buy_and_sell: 매수·매도 동일 수수료율 PASSED.test_fee_and_tax_zero_for_nonpositive_amount: 비양수 amount 가드 PASSED.- 단일 정책 지점:
broker_port.pycalculate_fee/calculate_tax(envTREX_KIS_FEE_BPS/TREX_KRX_TAX_SELL_BPS). paper·kis 가 동일 함수 import 사용(코드 리뷰). tax=0.0하드코딩 제거 확인:grep -rn "tax=0.0\|tax=0," trex_core/adapters trex_core/application→ 코드 사이트 0건(주석 1건만).
- Evidence:
-
REQ-018 AC-8 (KIS 응답 fee/tax 정본 우선, 부재 시 폴백):
- Evidence (design + 코드 리뷰): KIS 어댑터가 쓰는
주식일별주문체결조회(inquire-daily-ccld,output1)는 per-fill 수수료/증권거래세 필드를 제공하지 않음(docs/broker/kis/rest/국내주식/주문/계좌/021...output1 38필드 중 fee/tax 없음,tot_ccld_amt만 존재). 따라서 KIS 는 정책 추정값(calculate_fee/calculate_tax)으로 폴백 — 구조적으로 폴백 경로만 활성, 오파싱 리스크 없음(design Key Decision 3). 향후 fee/tax 노출 endpoint 도입 시 정본 우선 파싱 추가 지점 명시. - 잔여: 라이브 KIS 스모크는 REL 배포 단계 사항(paper 와 동일 산식이므로 코드 경로 동일). Blocking 아님.
- Evidence (design + 코드 리뷰): KIS 어댑터가 쓰는
-
REQ-018 AC-9 (issue #24 4건 → fee+tax 합계 1,376.9원):
- Evidence:
test_issue_24_four_fill_regression—total_fee == 177.9,total_tax == 1199.0,total == 1376.9PASSED.
- Evidence:
Evidence
-
Test:
pytest tests/application/test_fee_tax_policy.py— 6 passed (신규)pytest tests/application/test_fee_tax_policy.py test_execution_ledger.py test_execution_cancel.py— 19 passedpytest tests/— 429 passed, 45 skipped (BAT-037 423 → +6, 회귀 0)ruff check trex_core tests— All checks passed
-
Manual / Baseline 동기화 (Architecture Impact: runtime-flows):
docs/runtime-flows.md체결 → ledger outboxflow (line 254):tax=0→calculate_tax(side, amount)정책 계산 + env 변수(TREX_KIS_FEE_BPS/TREX_KRX_TAX_SELL_BPS) + paper·KIS 공유 설명 갱신. Change Log 항목(2026-06-12 BAT-038) 추가. ✓ 코드와 동기화 확인.docs/project-structure.md: 변경 불필요(모듈 구조 불변, 함수 1개 추가) — design Reference Doc Update Plan = none.tax=0.0하드코딩 제거 grep 확인(위 AC-7).
Result
- Ready for Release: true
- Blocking Issues: 없음
- AC-8 라이브 KIS 스모크는 REL 배포 단계(비거래 시간) 사항이며, paper 와 동일 정책 산식·동일 코드 경로이므로 release-ready 차단 사유 아님.