feat(broker): KIS venue parameterization — OrderRequest.venue + EXCG_ID_DVSN_CD (REQ-117/118, BAT-056)

- OrderRequest.venue: str = "KRX" additive 추가 (기존 위치 인수 순서 불변)
- BrokerPort.cancel_order: venue: str = "KRX" 파라미터 추가
- BrokerPort.get_current_price: market: str = "J" 파라미터 추가
- KISBroker.submit_order: EXCG_ID_DVSN_CD=req.venue 항상 명시 전송
- KISBroker.cancel_order: EXCG_ID_DVSN_CD=venue 항상 명시 전송
- KISBroker.get_current_price: FID_COND_MRKT_DIV_CODE=market 파라미터화
- PaperBroker: cancel_order/get_current_price 시그니처 정합 (venue/market 수신·무시)
- poll_fill TR 유지 (TTTC8001R) — NXT 체결 포함 여부 미확인 open item (코드 주석 기록)
- tests/adapters/broker/test_venue.py: REQ-117 AC-1~5 + REQ-118 AC-1~8 신규 17개
- docs: interface-contract.md OrderRequest/BrokerPort 섹션 + change log 추가
- docs: runtime-flows.md venue 전달 경로 명시 + change log 추가

결과: 794 passed, 47 skipped (기존 777+47 대비 신규 17개 추가 전부 통과)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VHtM5Ws1HKCKQ4JGi6GRb5
This commit is contained in:
2026-07-06 23:24:51 +09:00
co-authored by Claude Fable 5
parent dc6d7a943b
commit ee3dc83a93
9 changed files with 638 additions and 11 deletions
+10 -3
View File
@@ -105,7 +105,10 @@ class PaperBroker:
)
return FillStatus(state="partially_filled", filled_qty=o.filled, avg_price=o.price)
def cancel_order(self, broker_order_id: str, *, side: str, symbol: str, qty: int) -> bool:
def cancel_order(self, broker_order_id: str, *, side: str, symbol: str, qty: int, venue: str = "KRX") -> bool:
"""Cancel a paper order. venue is accepted for BrokerPort protocol conformance
(REQ-118) but ignored — paper has no exchange concept. Existing behavior preserved.
"""
with self._lock:
o = self._orders.get(broker_order_id)
if o is None or o.filled >= o.qty:
@@ -135,7 +138,11 @@ class PaperBroker:
with self._lock:
self._prices[symbol] = Decimal(str(price))
def get_current_price(self, symbol: str) -> Optional[Decimal]:
"""Return the programmed current price for symbol, or None if unset."""
def get_current_price(self, symbol: str, market: str = "J") -> Optional[Decimal]:
"""Return the programmed current price for symbol, or None if unset.
market accepted for BrokerPort protocol conformance (REQ-118) but
ignored — paper has no market distinction concept.
"""
with self._lock:
return self._prices.get(symbol)