[2026-05-19] KIS API TR_ID 수정 — 외국인/기관 수급·업종 지수 API 교체
- get_foreign_institution_rank: FHKST04430000(없는 서비스) → FHPTJ04400000(foreign-institution-total) - get_sector_trend: FHKST03010100(일봉 오용) → FHPUP02100000(inquire-index-price) 15개 업종 다중 호출 - 두 함수 모두 실거래 API 테스트 통과 확인 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+59
-34
@@ -413,61 +413,86 @@ class KISClient:
|
||||
return result
|
||||
|
||||
async def get_foreign_institution_rank(self, top_n: int = 30) -> Dict:
|
||||
"""외국인/기관 순매수 상위 (AI 판단용)"""
|
||||
"""외국인/기관 순매수 상위 (AI 판단용) — FHPTJ04400000"""
|
||||
data = await self._request(
|
||||
method = "GET",
|
||||
path = "/uapi/domestic-stock/v1/quotations/inquire-investor",
|
||||
tr_id = "FHKST04430000",
|
||||
path = "/uapi/domestic-stock/v1/quotations/foreign-institution-total",
|
||||
tr_id = "FHPTJ04400000",
|
||||
params = {
|
||||
"FID_COND_MRKT_DIV_CODE": "J",
|
||||
"FID_COND_MRKT_DIV_CODE" : "J",
|
||||
"FID_COND_SCR_DIV_CODE" : "20171",
|
||||
"FID_INPUT_ISCD" : "0000",
|
||||
"FID_DIV_CLS_CODE" : "0",
|
||||
"FID_BLNG_CLS_CODE" : "0",
|
||||
"FID_TRGT_CLS_CODE" : "111111111",
|
||||
"FID_TRGT_EXLS_CLS_CODE" : "000000",
|
||||
"FID_INPUT_PRICE_1" : "",
|
||||
"FID_INPUT_PRICE_2" : "",
|
||||
"FID_VOL_CNT" : "",
|
||||
"FID_INPUT_DATE_1" : "",
|
||||
"FID_INPUT_DATE_2" : "",
|
||||
"FID_PERIOD_DIV_CODE" : "D",
|
||||
"FID_RANK_SORT_CLS_CODE" : "1", # 순매수량 기준 정렬
|
||||
"FID_ETC_CLS_CODE" : "0",
|
||||
}
|
||||
)
|
||||
foreign = []
|
||||
institution = []
|
||||
for row in data.get("output", [])[:top_n]:
|
||||
entry = {
|
||||
"ticker": row.get("mksc_shrn_iscd", ""),
|
||||
"name" : row.get("hts_kor_isnm", ""),
|
||||
"amount": int(row.get("frgn_ntby_qty", "0")),
|
||||
}
|
||||
foreign.append(entry)
|
||||
entry2 = {
|
||||
"ticker": row.get("mksc_shrn_iscd", ""),
|
||||
"name" : row.get("hts_kor_isnm", ""),
|
||||
"amount": int(row.get("orgn_ntby_qty", "0")),
|
||||
}
|
||||
institution.append(entry2)
|
||||
for row in data.get("output", []):
|
||||
ticker = row.get("mksc_shrn_iscd", "")
|
||||
name = row.get("hts_kor_isnm", "")
|
||||
try:
|
||||
frgn_qty = int(row.get("frgn_ntby_qty") or 0)
|
||||
except (ValueError, TypeError):
|
||||
frgn_qty = 0
|
||||
try:
|
||||
orgn_qty = int(row.get("orgn_ntby_qty") or 0)
|
||||
except (ValueError, TypeError):
|
||||
orgn_qty = 0
|
||||
foreign.append({"ticker": ticker, "name": name, "amount": frgn_qty})
|
||||
institution.append({"ticker": ticker, "name": name, "amount": orgn_qty})
|
||||
|
||||
return {
|
||||
"foreign" : sorted(foreign, key=lambda x: x["amount"], reverse=True)[:top_n],
|
||||
"institution": sorted(institution, key=lambda x: x["amount"], reverse=True)[:top_n],
|
||||
}
|
||||
|
||||
# 업종코드 → 업종명 (KOSPI 주요 업종)
|
||||
_SECTOR_CODES = [
|
||||
("0001", "KOSPI"),
|
||||
("0028", "반도체"),
|
||||
("0150", "2차전지"),
|
||||
("0018", "전기전자"),
|
||||
("0011", "의약품"),
|
||||
("0010", "화학"),
|
||||
("0016", "철강금속"),
|
||||
("0017", "기계"),
|
||||
("0006", "건설업"),
|
||||
("0027", "금융업"),
|
||||
("0026", "통신업"),
|
||||
("0020", "운수창고"),
|
||||
("0021", "유통업"),
|
||||
("0009", "음식료품"),
|
||||
("0024", "전기가스업"),
|
||||
]
|
||||
|
||||
async def get_sector_trend(self) -> list:
|
||||
"""업종별 등락률 (AI 판단용)"""
|
||||
"""업종별 등락률 (AI 판단용) — FHPUP02100000 다중 호출"""
|
||||
result = []
|
||||
for code, name in self._SECTOR_CODES:
|
||||
try:
|
||||
data = await self._request(
|
||||
method = "GET",
|
||||
path = "/uapi/domestic-stock/v1/quotations/inquire-daily-itemchartprice",
|
||||
tr_id = "FHKST03010100",
|
||||
path = "/uapi/domestic-stock/v1/quotations/inquire-index-price",
|
||||
tr_id = "FHPUP02100000",
|
||||
params = {
|
||||
"FID_COND_MRKT_DIV_CODE": "U", # 업종
|
||||
"FID_INPUT_ISCD" : "0001",
|
||||
"FID_INPUT_DATE_1" : "",
|
||||
"FID_INPUT_DATE_2" : "",
|
||||
"FID_PERIOD_DIV_CODE" : "D",
|
||||
"FID_ORG_ADJ_PRC" : "0",
|
||||
"FID_COND_MRKT_DIV_CODE": "U",
|
||||
"FID_INPUT_ISCD" : code,
|
||||
}
|
||||
)
|
||||
result = []
|
||||
for row in data.get("output1", []):
|
||||
result.append({
|
||||
"sector" : row.get("hts_kor_isnm", ""),
|
||||
"change_pct": float(row.get("prdy_ctrt", "0")),
|
||||
})
|
||||
o = data.get("output", {})
|
||||
change_pct = float(o.get("bstp_nmix_prdy_ctrt") or 0)
|
||||
result.append({"sector": name, "change_pct": change_pct})
|
||||
except Exception as e:
|
||||
logger.warning(f"업종 지수 조회 실패 [{name}/{code}]: {e}")
|
||||
return result
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user