AlgoLab Blog · 키움증권 REST · 수급 데이터 · 2026

키움 ka10062 동일순매매순위 — 평균가는 원 단위다

키움 REST · 순위정보 2026-10-25 · 약 6분 읽기 · 알고랩 AlgoLab
한 줄 요약

ka10062(동일순매매순위요청)는 기관과 외국인이 같은 방향으로 순매매한 종목을 순위로 주는 TR이고, 평균가 필드 orgn_nettrde_avg_pric·for_nettrde_avg_pric는 명세에 '단위: 백만원'으로 적혀 있지만 실제 값은 원 단위 가격입니다. 경로는 /api/dostk/rkinfo, 필수 body는 strt_dt·mrkt_tp·trde_tp·sort_cnd·unit_tp·stex_tp 6개이고 end_dt만 선택입니다. 금액 필드는 백만원 반올림이라 소량은 "0"으로 오고, sort_cnd는 "1"이 수량입니다(금액·수량 선택 TR 17개 중 13개는 1이 금액). 공식 예제 함수는 end_dt 기본값이 '20241107'로 박혀 있습니다. (공식 명세 kiwoom_api_spec.json·예제, main 953e5db 2026-09-15 기준, 2026-10-25 확인)

목차

  1. ka10062는 무엇을 주나
  2. 요청·응답 실물
  3. 함정 5가지
  4. 안전하게 받는 코드
  5. 자주 묻는 질문

1. ka10062는 무엇을 주나

"기관도 사고 외국인도 산 종목"을 한 번에 뽑는 순위 TR입니다. 응답 배열 이름이 eql_nettrde_rank(동일 순매매 순위)이고, 행마다 기관·외국인 각각의 순매매 수량·금액·평균가와 둘을 더한 합계가 들어 있습니다. 비슷한 수급 TR과 나란히 놓으면 쓰임새가 갈립니다.

TR경로단위기간 지정금액·수량 선택
ka10062rkinfo기관+외국인 동시, 종목 순위strt_dt 필수 · end_dt 선택sort_cnd 1:수량, 2:금액
ka10131frgnistt기관·외국인 연속 순매수 일수dt 필수(0이면 날짜)amt_qty_tp 0:금액, 1:수량
ka10065rkinfo장중 투자자 1개 유형 상위없음(당일 장중)amt_qty_tp 1:금액, 2:수량
ka10059stkinfo종목 1개의 투자자별 일별dt 일자amt_qty_tp 1:금액, 2:수량

며칠째 연속으로 샀는지가 궁금하면 ka10131, "이 기간에 두 주체가 함께 얼마나 샀나"를 종목 순위로 보려면 ka10062입니다. 명세에서 strt_dt는 필수인데 end_dt는 선택인 조합은 337개 TR 중 ka10062와 ka10069(대차거래상위10종목) 둘뿐입니다.

2. 요청·응답 실물

명세의 request_example 원문입니다.

POST https://api.kiwoom.com/api/dostk/rkinfo
api-id: ka10062
authorization: Bearer {접근토큰}

{
    "strt_dt": "20241106",
    "end_dt": "20241107",
    "mrkt_tp": "000",
    "trde_tp": "1",
    "sort_cnd": "1",
    "unit_tp": "1",
    "stex_tp": "3"
}
element필수명세 설명(원문)
strt_dtYYYYYMMDD
end_dtNYYYYMMDD
mrkt_tpY000:전체, 001: 코스피, 101:코스닥
trde_tpY1:순매수, 2:순매도
sort_cndY1:수량, 2:금액
unit_tpY1:단주, 1000:천주
stex_tpY1:KRX, 2:NXT 3.통합

response_example 원문입니다.

{
    "eql_nettrde_rank": [
        {
            "stk_cd": "005930",
            "rank": "1",
            "stk_nm": "삼성전자",
            "cur_prc": "-206000",
            "pre_sig": "5",
            "pred_pre": "-500",
            "flu_rt": "-0.24",
            "acc_trde_qty": "85",
            "orgn_nettrde_qty": "+2",
            "orgn_nettrde_amt": "0",
            "orgn_nettrde_avg_pric": "206000",
            "for_nettrde_qty": "+275",
            "for_nettrde_amt": "+59",
            "for_nettrde_avg_pric": "213342",
            "nettrde_qty": "+277",
            "nettrde_amt": "+59"
        }
    ],
    "return_code": 0,
    "return_msg": "정상적으로 처리되었습니다"
}

3. 함정 5가지

① 평균가 필드의 '백만원'은 표기 오류다

명세는 두 평균가 필드를 이렇게 적습니다.

element명세 설명(원문)예시 값
orgn_nettrde_avg_pric단위: 백만원206000
for_nettrde_avg_pric단위: 백만원213342
cur_prc단위: 원, 부호가 포함된 숫자-206000

예시 값을 그대로 검산했습니다(Python 3.10.4, 2026-10-25).

qty: orgn+for = 277   nettrde_qty = 277
amt: orgn+for = 59    nettrde_amt = 59
orgn 2주   x 206000원 =     412000원 = 0.41백만원  -> 응답 orgn_nettrde_amt 0
for  275주 x 213342원 =   58669050원 = 58.67백만원 -> 응답 for_nettrde_amt +59
평균가를 백만원으로 읽으면 for 금액 = 58669050백만원 = 58.7조원

평균가를 원으로 읽어야 금액 필드와 맞고, 백만원으로 읽으면 275주 매수가 58조 원이 됩니다. 명세 337개 TR에서 평균가 성격의 응답 필드를 전수로 찾으면 ka10014 shrts_avg_pric, ka10045 orgn_prsm_avg_pric, ka10058 prsm_avg_pric, ka10170 buy_avg_pric, kt00004 avg_prc 등 모두 '단위: 원'이고 '백만원'으로 적힌 곳은 ka10062 두 필드뿐입니다. 명세 설명을 그대로 믿고 * 1_000_000을 곱하는 변환 코드를 만들지 마십시오.

② 금액은 백만원 반올림 — 소량은 0이 된다

위 검산에서 기관 2주(41만 2천 원)는 orgn_nettrde_amt "0"으로 왔습니다. 금액 필드 넷(orgn_nettrde_amt·for_nettrde_amt·nettrde_amt)은 백만원 정수라서 50만 원 미만은 0, 그 이상은 1로 뭉개집니다. sort_cnd "2"(금액)로 정렬하면 하위권은 0과 1이 줄지어 동점이 되고, "기관 순매수 금액 > 0" 같은 필터는 실제로 산 종목을 떨어뜨립니다. 원 단위 금액이 필요하면 수량 × 평균가로 다시 계산하는 편이 정확합니다(①에서 평균가가 원이라는 점이 여기서 쓰입니다).

③ sort_cnd "1"은 수량이다 — 다른 TR과 반대

명세에서 금액·수량 선택값을 받는 TR 17개를 전수로 비교한 결과입니다.

"1"의 의미TR필드
금액ka10059 · ka10060 · ka10061 · ka10064 · ka10065 · ka10066 · ka90003 · ka90005 · ka90007 · ka90008 · ka90009 · ka90010 · ka90013 (13개)amt_qty_tp 1:금액, 2:수량
수량ka10062sort_cnd 1:수량, 2:금액
수량(0이 금액)ka10131 · ka10051amt_qty_tp 0:금액, 1:수량
금액&수량ka10063amt_qty_tp 1: 금액&수량

수급 TR 여러 개를 함수 하나로 감싸며 "1 = 금액"을 상수로 두면 ka10062에서는 에러 없이 수량 정렬 목록이 옵니다. 필드 이름부터 sort_cnd로 달라서 래퍼가 키 이름을 바꿔 넣는 구조라면 더 잘 숨습니다. ka10062는 "정렬 기준"이고 응답에는 수량·금액이 둘 다 오므로, 어느 쪽으로 받든 값 자체는 같고 순위 순서만 바뀝니다. trde_tp 1이 순매수인 쪽은 ka10037·ka10039·ka10065와 같은 계열입니다(ka10037 글의 trde_tp 표 참고).

④ 공식 예제의 end_dt 기본값은 2024-11-07이다

공식 예제 examples/국내주식/순위정보/get_domestic_same_direction_net_trade_rank.py의 함수 시그니처입니다.

def get_domestic_same_direction_net_trade_rank(
    strt_dt: str,
    mrkt_tp: str,
    trde_tp: str,
    sort_cnd: str,
    unit_tp: str,
    stex_tp: str,
    end_dt: str | None = '20241107',
) -> dict[str, pd.DataFrame]:
    ...
    if end_dt is not None:
        body["end_dt"] = end_dt  # 종료일자

필수 인자 6개는 기본값이 없는데 선택 인자 end_dt만 명세 예시 날짜를 기본값으로 갖고 있습니다. strt_dt='20261020'만 바꿔 부르면 body에는 "end_dt": "20241107"이 함께 실려 시작일보다 2년 앞선 종료일을 요청합니다. 이때 서버가 빈 목록을 주는지, 오류를 주는지, 종료일을 무시하는지는 명세에 없습니다. end_dt는 항상 명시하고, 같은 날 하루만 볼 때도 strt_dt와 같은 값을 넣는 편이 안전합니다.

⑤ 접두어·코드표가 이웃 TR과 다르다

eql_nettrde_rank[] 한 행 기관 orgn_ qty +2 · amt 0 avg 206000 (원) + 외국인 for_ qty +275 · amt +59 avg 213342 (원) = 합계 nettrde_ qty +277 · amt +59 평균가 없음 금액 = 백만원 반올림 (2주 x 206,000원 = 0.41 → 0) 평균가 명세 '백만원' → 실제 원 (275 x 213,342 = 58.67백만원 → 59)
수량과 금액은 기관 + 외국인 = 합계로 맞는다. 금액은 뭉개지고, 평균가는 원으로 읽어야 금액과 맞는다.

4. 안전하게 받는 코드

토큰은 환경변수에서 읽고 ①~④를 코드에서 막습니다. 페이지 넘김은 연속조회(cont-yn·next-key) 글, 오류 응답은 return_code 글을 참고하십시오.

import os, time, requests
import pandas as pd

BASE  = "https://api.kiwoom.com"                 # 모의: https://mockapi.kiwoom.com
TOKEN = os.environ["KIWOOM_TOKEN"]
SORT  = {"qty": "1", "amt": "2"}                 # ③ ka10062는 1이 수량

def ka10062(start, end, market="000", net_sell=False, sort="amt", stex="3", max_pages=5):
    body = {"strt_dt": start, "end_dt": end,      # ④ end_dt 항상 명시
            "mrkt_tp": market, "trde_tp": "2" if net_sell else "1",
            "sort_cnd": SORT[sort], "unit_tp": "1", "stex_tp": stex}
    rows, cont, key = [], None, None
    for _ in range(max_pages):
        h = {"api-id": "ka10062", "authorization": f"Bearer {TOKEN}",
             "Content-Type": "application/json;charset=UTF-8"}
        if cont == "Y":
            h.update({"cont-yn": "Y", "next-key": key})
        r = requests.post(BASE + "/api/dostk/rkinfo", headers=h, json=body, timeout=(3.05, 10))
        j = r.json()
        if j.get("return_code") not in (0, None):
            raise RuntimeError(f'ka10062 {j.get("return_code")} {j.get("return_msg")}')
        rows += j.get("eql_nettrde_rank", [])
        cont, key = r.headers.get("cont-yn"), r.headers.get("next-key")
        if cont != "Y":
            break
        time.sleep(0.2)

    df = pd.DataFrame(rows)
    num = [c for c in df.columns if c.endswith(("_qty", "_amt", "_pric")) or c in ("rank", "cur_prc", "pred_pre", "flu_rt")]
    for c in num:
        df[c] = pd.to_numeric(df[c].str.replace("+", "", regex=False), errors="coerce")
    # ① 평균가는 원 단위 그대로 / ② 원 단위 금액을 다시 계산
    df["orgn_amt_won"] = df["orgn_nettrde_qty"] * df["orgn_nettrde_avg_pric"]
    df["for_amt_won"]  = df["for_nettrde_qty"]  * df["for_nettrde_avg_pric"]
    df = df.rename(columns=lambda c: c.replace("for_", "frgnr_", 1) if c.startswith("for_") else c)  # ⑤ ka10131과 이름 맞춤
    bad = df[df["orgn_nettrde_qty"] + df["frgnr_nettrde_qty"] != df["nettrde_qty"]]
    if len(bad):
        print("합계 불일치 행:", bad[["stk_cd", "rank"]].to_dict("records"))
    return df.sort_values("rank")

if __name__ == "__main__":
    print(ka10062("20261020", "20261024").head(10))

마지막의 합계 검사는 "기관 + 외국인 = 합계"가 실제 응답에서도 성립하는지 첫 실행에서 확인하려는 장치입니다. 예시 1행에서는 수량·금액 모두 맞았지만, 실계좌 데이터에서 어긋나면 그 응답을 저장해 두고 규칙을 다시 보십시오. 순위 TR을 여러 기간·시장으로 연달아 부르면 키움 429 호출 제한에 걸리기 쉬우니 장 마감 뒤 하루 한 번 받는 구성을 권합니다.

기관과 외국인이 함께 샀다는 사실은 과거 체결 집계일 뿐 이후 가격을 알려 주지 않습니다. 이 글은 특정 종목이나 전략을 권하지 않으며, 수급 필터의 효과는 반드시 본인 데이터로 백테스트해 확인하십시오. 명세는 바뀔 수 있으니 키움 REST API 공식 문서로 현재 값을 확인하십시오.

5. 자주 묻는 질문

ka10062의 orgn_nettrde_avg_pric 단위는 백만원인가요?

명세 설명은 '단위: 백만원'이지만 응답 예시 값 206000·213342는 현재가 206000원과 같은 자릿수의 원 단위 가격입니다. 외국인 275주 × 213,342원 = 58,669,050원 = 58.67백만원이 응답 for_nettrde_amt +59와 맞습니다. 키움 명세 337개 TR 가운데 평균가 필드를 백만원으로 적은 곳은 ka10062 하나이고 나머지는 모두 원입니다.

ka10062에서 기관 순매매수량은 있는데 금액이 0인 이유는?

금액 필드는 백만원 단위로 반올림되어 옵니다. 예시의 기관 2주 × 206,000원 = 412,000원은 0.41백만원이라 orgn_nettrde_amt가 '0'입니다. 소량 종목을 금액으로 걸러 내거나 sort_cnd 2(금액)로 정렬하면 0과 동점이 많이 생기므로 수량에 평균가를 곱해 원 단위 금액을 다시 계산하는 편이 정확합니다.

ka10062의 sort_cnd 1은 금액인가요 수량인가요?

1이 수량, 2가 금액입니다. 키움 명세에서 금액·수량 선택값을 받는 TR 17개 중 ka10059·ka10064·ka10065 등 13개는 1이 금액이고, ka10062(sort_cnd)·ka10131·ka10051 셋은 1 또는 0의 의미가 다릅니다. 여러 TR을 한 함수로 감쌀 때 '1=금액'으로 고정하면 ka10062에서 수량 정렬 목록을 받습니다.

공식 예제로 ka10062를 호출할 때 주의할 점은?

공식 예제 함수의 end_dt 기본값이 '20241107'로 박혀 있습니다. strt_dt만 오늘 날짜로 바꾸고 end_dt를 생략하면 body에 2024년 11월 7일이 종료일로 들어가 시작일보다 앞선 기간을 요청하게 됩니다. end_dt를 명시하거나 None을 넘겨 body에서 빼십시오.

수급 데이터를 묶어 쓰는 키움 봇, 만들어 드립니다

보고 싶은 시장과 기간만 알려 주시면 ka10062·ka10131·ka10059 연결, 단위·부호 변환, 합계 검사까지 맞춰 드립니다. 24시간 빠른 답변 가능합니다.

무료 상담 시작하기