From 988a56c07cef43328e0af80f1034889f01733f47 Mon Sep 17 00:00:00 2001 From: agentson Date: Tue, 24 Feb 2026 09:15:40 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20KR=20=EB=93=B1=EB=9D=BD=EB=A5=A0?= =?UTF-8?q?=EC=88=9C=EC=9C=84=20API=20=ED=8C=8C=EB=9D=BC=EB=AF=B8=ED=84=B0?= =?UTF-8?q?=20=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95=20=E2=80=94=20?= =?UTF-8?q?=EC=8A=A4=EC=BA=90=EB=84=88=20=EB=AF=B8=EB=8F=99=EC=9E=91=20?= =?UTF-8?q?=ED=95=B4=EA=B2=B0=20(#240)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 실전 API가 fid_rank_sort_cls_code='0000'(4자리)를 거부함. '0'(1자리)으로 수정하고, 실전 응답의 종목코드 키가 mksc_shrn_iscd 대신 stck_shrn_iscd임을 반영하여 파싱 수정. Co-Authored-By: Claude Sonnet 4.6 --- src/broker/kis_api.py | 4 ++-- tests/test_broker.py | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/broker/kis_api.py b/src/broker/kis_api.py index 1f4899b..953a604 100644 --- a/src/broker/kis_api.py +++ b/src/broker/kis_api.py @@ -430,7 +430,7 @@ class KISBroker: "fid_cond_mrkt_div_code": "J", "fid_cond_scr_div_code": "20170", "fid_input_iscd": "0000", - "fid_rank_sort_cls_code": "0000", + "fid_rank_sort_cls_code": "0", "fid_input_cnt_1": str(limit), "fid_prc_cls_code": "0", "fid_input_price_1": "0", @@ -466,7 +466,7 @@ class KISBroker: rankings = [] for item in data.get("output", [])[:limit]: rankings.append({ - "stock_code": item.get("mksc_shrn_iscd", ""), + "stock_code": item.get("stck_shrn_iscd") or item.get("mksc_shrn_iscd", ""), "name": item.get("hts_kor_isnm", ""), "price": _safe_float(item.get("stck_prpr", "0")), "volume": _safe_float(item.get("acml_vol", "0")), diff --git a/tests/test_broker.py b/tests/test_broker.py index 2c15b4c..5213013 100644 --- a/tests/test_broker.py +++ b/tests/test_broker.py @@ -354,6 +354,8 @@ class TestFetchMarketRankings: assert "ranking/fluctuation" in url assert headers.get("tr_id") == "FHPST01700000" assert params.get("fid_cond_scr_div_code") == "20170" + # 실전 API는 4자리("0000") 거부 — 1자리("0")여야 한다 (#240) + assert params.get("fid_rank_sort_cls_code") == "0" @pytest.mark.asyncio async def test_volume_returns_parsed_rows(self, broker: KISBroker) -> None: @@ -376,6 +378,27 @@ class TestFetchMarketRankings: assert result[0]["price"] == 75000.0 assert result[0]["change_rate"] == 2.5 + @pytest.mark.asyncio + async def test_fluctuation_parses_stck_shrn_iscd(self, broker: KISBroker) -> None: + """실전 API는 mksc_shrn_iscd 대신 stck_shrn_iscd를 반환한다 (#240).""" + items = [ + { + "stck_shrn_iscd": "015260", + "hts_kor_isnm": "에이엔피", + "stck_prpr": "794", + "acml_vol": "4896196", + "prdy_ctrt": "29.74", + "vol_inrt": "0", + } + ] + mock_resp = _make_ranking_mock(items) + with patch("aiohttp.ClientSession.get", return_value=mock_resp): + result = await broker.fetch_market_rankings(ranking_type="fluctuation") + + assert len(result) == 1 + assert result[0]["stock_code"] == "015260" + assert result[0]["change_rate"] == 29.74 + # --------------------------------------------------------------------------- # KRX tick unit / round-down helpers (issue #157)