KIS 시가총액 API FHPST01740000 — 함정 5가지
한국투자증권 KIS API의 국내주식 시가총액 상위는 GET /uapi/domestic-stock/v1/ranking/market-cap에 tr_id FHPST01740000으로 호출하고, fid_cond_scr_div_code=20174 고정, fid_input_iscd로 전체(0000)·코스피(0001)·코스닥(1001)·코스피200(2001)을 고릅니다. 공식 저장소 legacy/README.md의 모의투자 제공 칸이 비어 있어 실전 앱키로만 받을 수 있고, 응답의 stck_avls(시가총액)는 공식 매핑에 단위가 적혀 있지 않으므로 첫 호출에서 lstn_stcn × stck_prpr와 대조해 확정해야 합니다.
목차
- 스펙 한 장 — tr_id·URL·모의 지원
- 요청 파라미터 9개
- 요청·응답 실물
- 함정 5가지
- 봇에서 쓰는 법 — 코스피200 대형주 유니버스
- 자주 묻는 질문
거래량·등락률 순위로 종목을 고르는 스캐너는 허브 글 거래량 순위 API 종목 스캐너 — KIS 제외필터 코드 함정에서 다뤘습니다. 이 글은 같은 순위분석 묶음에 있으면서 사이트에서 다룬 적 없던 시가총액 상위 하나만 떼어 냅니다. 출처는 한국투자증권 공식 GitHub 저장소 koreainvestment/open-trading-api의 examples_llm/domestic_stock/market_cap/ 예제, MCP/KIS Code Assistant MCP/data.csv, legacy/README.md·legacy/postman/README.md입니다(2026-10-03 zipball 기준).
1. 스펙 한 장 — tr_id·URL·모의 지원
| 항목 | 값 |
|---|---|
| API명 | [국내주식] 순위분석 > 국내주식 시가총액 상위 [v1_국내주식-091] |
| 메서드 · URL | GET /uapi/domestic-stock/v1/ranking/market-cap |
| tr_id | FHPST01740000 (실전) |
| 헤더 | authorization(Bearer) · appkey · appsecret · tr_id · custtype=P |
| 모의투자 | legacy/README.md 제공 여부 칸 공란 · Postman 모의 컬렉션에 없음 |
| 실전투자 | legacy/postman/README.md ⭕ · Postman J_국내주식 시가총액 상위 |
같은 순위분석 묶음의 거래량순위(FHPST01710000)·등락률 순위(FHPST01700000)도 모의 칸이 비어 있습니다. 순위 계열은 통째로 실전 전용이라고 보는 편이 안전합니다. 모의에서 막히는 API 목록은 KIS 모의투자 한계 — 안 되는 API 10가지에 따로 정리해 두었습니다.
2. 요청 파라미터 9개
Kis Trading MCP/configs/domestic_stock.json은 아래 9개를 모두 required: true로 표시합니다. 값을 비워도 되는 것과 고정값이 섞여 있습니다.
| 파라미터 | 값 | 비고 |
|---|---|---|
fid_cond_mrkt_div_code | J | 설명은 "J:KRX, NX:NXT" — 함정 ② 참고 |
fid_cond_scr_div_code | 20174 | 화면 분류 코드, 고정 |
fid_div_cls_code | 0 전체 · 1 보통주 · 2 우선주 | 우선주 제외는 1 |
fid_input_iscd | 0000 전체 · 0001 거래소 · 1001 코스닥 · 2001 코스피200 | 업종코드 자리 |
fid_trgt_cls_code | 0 | 대상 구분, "0 : 전체"만 안내 |
fid_trgt_exls_cls_code | 0 | 대상 제외 구분, "0 : 전체"만 안내 |
fid_input_price_1 | 빈 값 또는 하한가격 | "가격 ~" |
fid_input_price_2 | 빈 값 또는 상한가격 | "~ 가격" |
fid_vol_cnt | 빈 값 또는 최소 거래량 | "거래량 ~" |
공식 chk_market_cap.py의 테스트 호출은 fid_input_price_1="50000", fid_input_price_2="1000000", fid_vol_cnt="1000"을 넣어 5만~100만 원, 거래량 1,000주 이상으로 좁힙니다. Postman 샘플은 세 값을 모두 비워 전체를 받습니다.
3. 요청·응답 실물
공식 예제 함수(market_cap())를 거치지 않고 requests로 직접 부르면 이렇습니다.
import os, requests, pandas as pd
URL = "https://openapi.koreainvestment.com:9443/uapi/domestic-stock/v1/ranking/market-cap"
headers = {
"content-type": "application/json; charset=utf-8",
"authorization": f"Bearer {os.environ['KIS_TOKEN']}",
"appkey": os.environ["KIS_APPKEY"],
"appsecret": os.environ["KIS_APPSECRET"],
"tr_id": "FHPST01740000",
"custtype": "P",
}
params = {
"fid_cond_mrkt_div_code": "J",
"fid_cond_scr_div_code": "20174",
"fid_div_cls_code": "1", # 보통주만
"fid_input_iscd": "2001", # 코스피200
"fid_trgt_cls_code": "0",
"fid_trgt_exls_cls_code": "0",
"fid_input_price_1": "",
"fid_input_price_2": "",
"fid_vol_cnt": "",
}
r = requests.get(URL, headers=headers, params=params, timeout=5)
body = r.json()
print(body["rt_cd"], body["msg_cd"], body["msg1"], "| tr_cont =", r.headers.get("tr_cont"))
df = pd.DataFrame(body["output"])
print(len(df), "rows")
응답 output 배열의 각 행은 공식 COLUMN_MAPPING 기준 11개 필드입니다(값은 문자열로 옵니다).
{
"rt_cd": "0",
"output": [
{
"mksc_shrn_iscd": "유가증권 단축 종목코드",
"data_rank": "데이터 순위",
"hts_kor_isnm": "HTS 한글 종목명",
"stck_prpr": "주식 현재가",
"prdy_vrss": "전일 대비",
"prdy_vrss_sign": "전일 대비 부호",
"prdy_ctrt": "전일 대비율",
"acml_vol": "누적 거래량",
"lstn_stcn": "상장 주수",
"stck_avls": "시가 총액",
"mrkt_whol_avls_rlim": "시장 전체 시가총액 비중"
}
]
}
4. 함정 5가지
① 모의 앱키로는 안 된다
위 표대로 모의 제공 칸이 비어 있고 모의용 Postman 컬렉션(모의계좌_POSTMAN_샘플코드_v1.6.json)에는 이 API가 아예 없습니다. 모의 서버(openapivts)로 개발을 시작한 봇은 순위 조회만 실패합니다. 해결은 시세·순위는 실전 키, 주문은 모의 키로 나누는 것입니다 — 실전 키로 조회 API만 부르는 것은 주문이 나가지 않습니다. 전환 순서는 모의→실전 전환 글에 있습니다.
② NX(NXT)라고 적혀 있지만 공식 예제는 막는다
market_cap.py의 독스트링과 data.csv는 fid_cond_mrkt_div_code를 "J:KRX, NX:NXT"로 설명합니다. 그런데 같은 파일의 검증부는 이렇습니다.
if fid_cond_mrkt_div_code != "J":
raise ValueError("조건 시장 분류 코드 확인요망!!!")
if fid_cond_scr_div_code != "20174":
raise ValueError("조건 화면 분류 코드 확인요망!!!")
즉 공식 함수로는 NX를 넣는 순간 서버에 가기도 전에 예외가 납니다. 넥스트레이드 기준 순위가 필요하면 직접 호출로 NX를 시험해 보고, 응답이 KRX와 실제로 다른지 확인한 뒤 쓰십시오. 문서와 코드가 어긋나 있으므로 KIS Developers 포털의 최신 명세 확인이 필요합니다. NXT·KRX 구분 전반은 NXT·KRX 주문 라우팅 글을 참고하십시오.
③ stck_avls에 단위가 없다
공식 매핑은 'stck_avls': '시가 총액'이 전부입니다. 원·백만 원·억 원 중 무엇인지 문서로는 알 수 없으므로, 첫 호출에서 직접 계산해 비율을 확인합니다.
for c in ["stck_prpr", "lstn_stcn", "stck_avls", "mrkt_whol_avls_rlim"]:
df[c] = pd.to_numeric(df[c], errors="coerce")
calc = df["stck_prpr"] * df["lstn_stcn"] # 원 단위 시가총액
ratio = (calc / df["stck_avls"]).round(-2).mode()[0] # 1 → 원, 1e6 → 백만 원, 1e8 → 억 원
print("stck_avls 단위 배율:", ratio)
배율을 확정한 뒤에는 상수로 박아 두고, 혹시 값이 바뀌면 알림이 오도록 이 검사를 하루 한 번 돌려 두면 됩니다. 비중 필드 mrkt_whol_avls_rlim도 퍼센트인지 비율인지 같은 방식으로 합계를 보고 판단하십시오.
④ 몇 건을 주는지 문서에 없다
data.csv의 다른 API 설명에는 "한 번의 호출에 최대 30건" 같은 문구가 있지만, 시가총액 상위 설명에는 건수 안내가 없습니다. 공식 예제는 응답 헤더 tr_cont가 "M"이면 tr_cont="N"으로 다시 불러 이어 붙이는 재귀 구조입니다. 그러니 봇은 len(df)와 tr_cont를 로그로 남기고, "상위 N개를 받았다"는 가정을 그 로그로 확인해야 합니다. 전 종목 목록이 필요하다면 이 API가 아니라 kospi_code.mst 마스터 파일 파싱이 맞는 도구입니다.
⑤ 관리종목·거래정지를 걸러 주지 않는다
거래량순위(FHPST01710000)에는 대상 제외 코드로 관리종목 등을 빼는 옵션이 있지만, 시가총액 상위의 fid_trgt_cls_code·fid_trgt_exls_cls_code는 공식 예제 검증부가 "0"만 허용합니다. 우선주는 fid_div_cls_code="1"로 뺄 수 있지만, 관리종목·투자경고 같은 상태는 받은 뒤 종목별로 걸러야 합니다. 방법은 KIS 관리종목 필터 — mang_issu_cls_code에 있습니다.
5. 봇에서 쓰는 법 — 코스피200 대형주 유니버스
시가총액 상위는 장중에 계속 부를 API가 아닙니다. 대형주 위주 전략이라면 장 시작 전 한 번 받아 유니버스 CSV로 저장하고, 장중에는 그 목록에 대해서만 현재가(FHKST01010100)나 관심종목 멀티 시세(30종목)로 시세를 봅니다.
import time
def build_universe(top_n=50):
frames = []
for iscd in ["2001"]: # 코스피200만. 코스닥까지면 "1001" 추가
params.update({"fid_input_iscd": iscd, "fid_div_cls_code": "1"})
r = requests.get(URL, headers=headers, params=params, timeout=5)
if r.json().get("rt_cd") != "0":
raise RuntimeError(r.text) # EGW00201 등은 여기서 잡힌다
frames.append(pd.DataFrame(r.json()["output"]))
time.sleep(0.05) # 공식 kis_auth.py 실전 smart_sleep 값
uni = pd.concat(frames).drop_duplicates("mksc_shrn_iscd")
uni["data_rank"] = pd.to_numeric(uni["data_rank"])
uni = uni.sort_values("data_rank").head(top_n)
uni[["mksc_shrn_iscd", "hts_kor_isnm", "stck_avls"]].to_csv("universe.csv", index=False)
return uni
호출 간격 0.05초는 공식 kis_auth.py의 실전 _smartSleep 값입니다(모의는 0.5초). 다른 봇이 같은 앱키로 돌고 있다면 초당 건수 초과 에러가 날 수 있으니 EGW00201 해결 글의 토큰 버킷을 함께 쓰십시오. 에러 코드 전반은 KIS API 에러코드 정리에 있습니다.
시가총액 순위는 종목 추천이 아니라 유니버스(검토 대상 목록)를 정하는 필터입니다. 어떤 종목을 언제 사고팔지는 별도의 전략·리스크 규칙이 정하며, 과거 대형주 성과가 미래 수익을 보장하지 않습니다. API 명세는 바뀔 수 있으니 KIS Developers 공식 문서를 확인하십시오.
6. 자주 묻는 질문
KIS API 시가총액 상위 조회의 tr_id는 무엇인가요?
국내주식 시가총액 상위의 tr_id는 FHPST01740000이고 GET /uapi/domestic-stock/v1/ranking/market-cap 으로 호출합니다. fid_cond_scr_div_code는 20174로 고정이며, fid_input_iscd에 0000(전체)·0001(거래소)·1001(코스닥)·2001(코스피200)을 넣어 시장을 고릅니다.
모의투자 앱키로 시가총액 상위 API를 호출할 수 있나요?
공식 저장소 legacy/README.md의 모의투자 제공 여부 칸이 비어 있고, Postman 샘플도 실전 컬렉션(J_국내주식 시가총액 상위)에만 들어 있습니다. 순위 데이터는 실전 앱키로 받고, 주문만 모의 계좌로 보내는 식으로 키를 나눠 쓰는 구성이 일반적입니다.
stck_avls 시가총액의 단위는 무엇인가요?
공식 예제의 컬럼 매핑에는 '시가 총액'이라고만 적혀 있고 단위가 없습니다. 첫 호출에서 lstn_stcn(상장 주수) × stck_prpr(현재가)를 직접 계산해 stck_avls와 비율을 비교하면 단위를 확정할 수 있습니다.
시가총액 상위로 전 종목 유니버스를 만들 수 있나요?
권하지 않습니다. 공식 문서에 한 번에 돌려주는 건수가 적혀 있지 않고, 공식 예제는 tr_cont가 M일 때만 다음 페이지를 이어 받습니다. 전 종목이 필요하면 종목코드 마스터 파일(kospi_code.mst·kosdaq_code.mst)을 쓰고, 시가총액 상위 API는 대형주 상위 목록 용도로 쓰는 것이 맞습니다.