feat: own current KIS daily fill contract in Core

This commit is contained in:
jordan
2026-07-29 21:46:42 +09:00
parent b47d7418e8
commit 56b35b257b
12 changed files with 365 additions and 54 deletions
+82 -5
View File
@@ -85,6 +85,72 @@ def test_live_base_url_requires_allow_live():
assert b.name() == "kis-live" and b._tr_submit("buy") == "TTTC0012U"
@pytest.mark.parametrize(
("base_url", "allow_live", "expected_tr_id"),
[
(_MOCK_URL, False, "VTTC0081R"),
("https://openapi.koreainvestment.com:9443", True, "TTTC0081R"),
],
)
def test_daily_fill_request_uses_current_all_market_contract(
base_url,
allow_live,
expected_tr_id,
):
broker = KISBroker(
"12345678-01",
app_key="k",
app_secret="s",
base_url=base_url,
allow_live=allow_live,
)
tr_id, params = broker._daily_fill_request(
"20260729",
symbol="005930",
order_number="1234",
)
assert tr_id == expected_tr_id
assert params["EXCG_ID_DVSN_CD"] == "ALL"
assert params["PDNO"] == "005930"
assert params["ODNO"] == "1234"
def test_poll_fill_uses_current_all_market_contract(monkeypatch):
broker = KISBroker(
"12345678-01",
app_key="k",
app_secret="s",
base_url=_MOCK_URL,
)
seen = {}
monkeypatch.setattr(
broker,
"_headers",
lambda tr_id: seen.setdefault("tr_id", tr_id) and {},
)
class Response:
status_code = 200
def json(self):
return {"rt_cd": "0", "output1": []}
def fake_get(*args, **kwargs):
seen["params"] = kwargs["params"]
return Response()
monkeypatch.setattr("trex_core.adapters.broker.kis.httpx.get", fake_get)
status = broker.poll_fill("91258:1234", side="buy", symbol="005930")
assert status.state == "accepted"
assert seen["tr_id"] == "VTTC0081R"
assert seen["params"]["EXCG_ID_DVSN_CD"] == "ALL"
assert seen["params"]["ODNO"] == "1234"
def _kis_env():
keys = (
"TREX_KIS_BROKER_BASE_URL",
@@ -261,7 +327,12 @@ def test_submit_gateway_5xx_blocks_automatic_duplicate(monkeypatch):
def test_submit_unknown_is_resolved_by_unique_daily_order(monkeypatch):
b = KISBroker("12345678-01", app_key="k", app_secret="s", base_url=_MOCK_URL)
monkeypatch.setattr(b, "_headers", lambda _tr: {})
seen_tr_ids = []
monkeypatch.setattr(
b,
"_headers",
lambda tr_id: seen_tr_ids.append(tr_id) or {},
)
monkeypatch.setattr(
"trex_core.adapters.broker.kis.httpx.post",
lambda *a, **kw: (_ for _ in ()).throw(httpx.ReadTimeout("timed out")),
@@ -300,15 +371,21 @@ def test_submit_unknown_is_resolved_by_unique_daily_order(monkeypatch):
def json(self):
return {"rt_cd": "0", "output1": [row]}
monkeypatch.setattr(
"trex_core.adapters.broker.kis.httpx.get",
lambda *a, **kw: Response(),
)
seen_params = {}
def fake_get(*args, **kwargs):
seen_params.update(kwargs["params"])
return Response()
monkeypatch.setattr("trex_core.adapters.broker.kis.httpx.get", fake_get)
status = b.poll_fill(ack.broker_order_id, side="buy", symbol="005930")
assert status.state == "accepted"
assert status.raw["resolved_broker_order_id"] == "91258:0012345678"
assert seen_tr_ids[-1] == "VTTC0081R"
assert seen_params["EXCG_ID_DVSN_CD"] == "ALL"
assert seen_params["PDNO"] == "005930"
def test_submit_unknown_confirmed_absent_becomes_retryable_reject(monkeypatch):