Implement BAT-006: portfolio-hub ledger integration (REQ-017~019)

- REQ-017: LedgerPort contract (application/ledger_port.py) + portfolio-hub
  adapter + in-memory stub (adapters/ledger/), TREX_PORTFOLIO_HUB_* config
- REQ-018: fill→ledger recording in execution loop; FillStatus carries
  execution_id (deterministic synth) + fee; paper/kis adapters updated
- REQ-019: ledger outbox + retry worker (application/ledger_outbox.py),
  correlation_id idempotency, outcome vocabulary; 002_create_ledger_outbox.sql
- Tests: in-memory/portfolio-hub ledger, execution ledger hook, outbox,
  domain import sweep

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-04 22:57:31 +09:00
co-authored by Claude Opus 4.8
parent 6277d610ea
commit 13837acc60
20 changed files with 1224 additions and 15 deletions
+19 -3
View File
@@ -15,7 +15,12 @@ from typing import Optional
import httpx
from trex_core.application.broker_port import FillStatus, OrderAck, OrderRequest
from trex_core.application.broker_port import (
FillStatus,
OrderAck,
OrderRequest,
calculate_fee,
)
_KST = timezone(timedelta(hours=9))
_MOCK_HINTS = ("openapivts", "virtual", "mock")
@@ -175,8 +180,19 @@ class KISBroker:
if ccld_qty <= 0:
return FillStatus(state="accepted", raw=row)
if ccld_qty >= ord_qty and ord_qty > 0:
return FillStatus(state="filled", filled_qty=ccld_qty,
avg_price=float(avg) if avg else None, raw=row)
# Deterministic execution_id (dcy-004 OQ-3, orbit kis.py rule):
# kis-daily-ccld:{ord_dt}:{ord_gno_brno}:{odno}:{tot_ccld_qty}
ord_dt = str(row.get("ord_dt") or today)
ord_gno_brno = str(row.get("ord_gno_brno") or "")
row_odno = str(row.get("odno") or odno)
execution_id = f"kis-daily-ccld:{ord_dt}:{ord_gno_brno}:{row_odno}:{ccld_qty}"
fill_price = float(avg) if avg else 0.0
fee = calculate_fee(side, ccld_qty * fill_price)
return FillStatus(
state="filled", filled_qty=ccld_qty,
avg_price=fill_price or None,
execution_id=execution_id, fee=fee, tax=0.0, raw=row,
)
return FillStatus(state="partially_filled", filled_qty=ccld_qty,
avg_price=float(avg) if avg else None, raw=row)