AlgoLab Blog · 키움 REST API · KRX 금시장 · 2026

키움 금현물 API 23종 — 주문수량 1은 1g

키움 · 금현물/주문 2026-09-16 · 약 8분 읽기 · 알고랩 AlgoLab
한 줄 요약 키움 REST API 명세에는 금현물 전용 TR이 23개 올라와 있고, 그중 네 개(kt50000~kt50003)는 실제 주문 API입니다. 즉 증권사 REST API로 KRX 금시장에 직접 주문을 낼 수 있습니다. 다만 주식 코드를 그대로 재사용하면 첫 호출부터 막힙니다 — 종목코드가 005930이 아니라 M04020000이고, ord_qty: "1"1kg이 아니라 1g이며, 매매구분은 세 가지뿐이라 시장가가 없습니다. 그리고 결정적으로 금현물 실시간 시세 항목이 존재하지 않습니다 — 봇은 폴링으로만 설계됩니다.

이 글에서 다루는 것

  1. 금현물 TR 23종 지도 — 경로가 5개로 흩어져 있다
  2. 주문수량 1이 1g인 근거 세 가지
  3. 주식 주문 kt10000과 다른 네 곳
  4. 실시간이 없다 — 0I는 KRX 금현물이 아니다
  5. 응답이 0으로 채운 고정폭 문자열이다
  6. 같은 이름 필드의 단위가 TR마다 다르다
  7. 체결 조회 3종의 파라미터가 서로 안 맞는다
  8. 부가가치세 필드의 정체
  9. 금현물 봇 설계 체크리스트

1. 금현물 TR 23종 — 경로가 5개로 흩어져 있다

키움증권은 2025년 9월 REST API를 통한 KRX금시장 거래 서비스를 개시했고, 이후 공식 명세에 금현물 전용 TR이 들어와 있습니다. 문제는 이 23개가 한 경로에 모여 있지 않다는 것입니다. 키움 REST API는 api-id 헤더로 TR을 구분하고 URL은 기능군으로 나뉘므로, 금현물도 다섯 경로에 흩어집니다.

경로TR용도
/api/dostk/mrkcondka50010 체결추이 · ka50012 일별추이 · ka50087 예상체결 · ka50100 시세정보 · ka50101 호가시세 5종
/api/dostk/chartka50079 틱 · ka50080 분봉 · ka50081 일봉 · ka50082 주봉 · ka50083 월봉 · ka50091 당일틱 · ka50092 당일분봉차트 7종
/api/dostk/ordrkt50000 매수 · kt50001 매도 · kt50002 정정 · kt50003 취소주문 4종
/api/dostk/acntkt50020 잔고 · kt50021 예수금 · kt50030 체결전체 · kt50031 체결 · kt50032 거래내역 · kt50075 미체결계좌 6종
/api/dostk/frgnisttka52301 금현물투자자현황수급 1종

경로를 틀리면 어떤 에러가 오는지는 명세의 오류코드표에 그대로 있습니다. 공통 오류 37개 중 1504"해당 URI에서는 지원하는 API ID가 아닙니다. API ID={?}, URI={?}"입니다. kt50000/api/dostk/acnt로 보내면 인증이 멀쩡해도 여기서 끊깁니다. 경로·api-id·토큰 삼박자는 키움 REST API 자동매매 가이드에 정리해 둔 것과 동일한 규칙이고, 키 발급 자체가 처음이라면 키움 REST API 인증키 발급 가이드부터 보시는 편이 빠릅니다.

거래 대상은 두 종목뿐입니다. 모든 금현물 TR의 stk_cd 설명이 동일하게 "M04020000: 금 99.99_1kg, M04020100: 미니금 99.99_100g"으로 적혀 있습니다. 주식처럼 종목 마스터를 내려받아 유니버스를 구성하는 단계가 통째로 없습니다.

2. 주문수량 1은 1kg이 아니라 1g이다

여기서 가장 비싼 실수가 납니다. 종목명이 "금 99.99_1Kg"이라 ord_qty: "1"이 1kg이라고 읽기 쉽습니다. 아닙니다. 1g입니다. 종목명의 1Kg은 실물 인출 단위이지 주문 단위가 아닙니다. 근거가 셋입니다.

ord_qty: "1" 을 어떻게 읽나 오해 — 종목명 "금 99.99_1Kg" 1 x 1kg = 1,000g 약 1.5억원 주문 실제 — KRX 매매수량단위 1g 1 x 1g = 1g 약 15만원 주문 명세가 남긴 유일한 단서 kt50032 · uncl_ocr → 한글명 "미수(원/g)" — 다른 필드는 전부 "단위: 1주"
명세의 수량 표기는 주식과 같은 "1주"지만, 실제 단위는 1g이다
  1. KRX 금시장의 매매수량단위가 1g입니다(호가가격단위 10원, 매매거래시간 09:00~15:30). 거래소 제도이고 API 이전의 사실입니다.
  2. 명세 안에 단 한 곳, 단위를 g으로 적은 필드가 있습니다. kt50032uncl_ocr 한글명이 "미수(원/g)"입니다. 나머지는 전부 주식 명세를 복사한 "단위: 1주"입니다.
  3. 공식 요청 예시가 스스로 증명합니다. kt50000의 요청 예시가 ord_qty 1에 ord_uv 160000입니다. 1kg이라면 단가가 1억 6천만원대여야 합니다.
{
    "stk_cd": "M04020000",
    "ord_qty": "1",          // 1g (1kg 아님)
    "ord_uv": "160000",      // 원/g
    "trde_tp": "00"
}

잔고 응답에서도 같은 스케일이 확인됩니다. kt50020 예시는 real_qty 2, cur_prc 151,780, est_amt 301,569이고 2 × 151,780 = 303,560으로 수량이 g 스케일일 때만 자릿수가 맞습니다(남는 차이가 무엇인지는 단정하지 않습니다 — 실호출로 대조하십시오).

수량 단위를 틀리면 자본 관리가 1,000배로 어긋납니다. 주식 봇에서 쓰던 "평가금액의 몇 퍼센트를 수량으로 환산" 코드를 그대로 가져오면 의도한 금액의 1,000분의 1을 주문하거나(안전), 잔고를 확인하지 않은 채 1,000배를 시도합니다(위험). 주문 수량 산정은 종목군을 바꿀 때마다 단위부터 다시 확인해야 합니다.

3. 주식 주문 kt10000과 다른 네 곳

금현물 주문 kt50000은 주식 주문 kt10000과 같은 URL(/api/dostk/ordr)을 씁니다. 같은 경로라서 "파라미터도 같겠지"라고 넘어가면 네 군데서 걸립니다.

주식 kt10000금현물 kt50000
dmst_stex_tp필수 — KRX/NXT/SOR파라미터 자체가 없다
trde_tp0보통 3시장가 5조건부 6최유리 7최우선 61/62/81시간외 1000보통 · 10IOC · 20FOK 셋뿐
cond_uv조건단가 있음없음
stk_cd6자리 숫자 (005930)M으로 시작 (M04020000)

특히 매매구분 코드의 자릿수가 다릅니다. 주식은 보통이 한 자리 "0", 금현물은 두 자리 "00"입니다. 상수를 공유하면 형식 오류(1517"입력 값 형식이 올바르지 않습니다")로 떨어집니다. 그리고 시장가가 없습니다. 즉시 체결이 필요하면 IOC/FOK에 호가를 실어 보내고 잔여 수량을 직접 처리해야 합니다(미체결 조회는 kt50075).

정정 kt50002도 다릅니다. 요청 바디가 stk_cd·orig_ord_no· mdfy_qty·mdfy_uv이고 정정수량과 정정단가가 모두 필수입니다 — "가격만 올리고 수량은 그대로" 같은 부분 정정이 없어 원주문 수량을 봇이 기억해야 합니다. 주식 정정·취소 kt10002 코드를 재사용할 수 없는 지점입니다.

4. 실시간이 없다 — 0I는 KRX 금현물이 아니다

이것이 금현물 봇 설계를 가장 크게 바꾸는 사실입니다. 키움 REST API의 실시간(WebSocket) 항목은 15종이고, 전부 펼치면 이렇습니다 — 00 주문체결, 04 잔고, 0A 주식기세, 0B 주식체결, 0C 주식우선호가, 0D 주식호가잔량, 0E 주식시간외호가, 0F 주식당일거래원, 0G ETF NAV, 0H 주식예상체결, 0I 국제금환산가격, 0J 업종지수, 0U 업종등락, F4·F5 미국주식.

KRX 금현물의 체결·호가에 해당하는 실시간 항목이 없습니다. 이름 때문에 0I를 금현물 체결로 오해하기 쉬운데, 0I의 등록 요소(item)는 종목코드가 아니라 MGD(원/g) 또는 MGU($/온스)입니다. 국제 금 환산 시세이지 KRX 금시장의 체결 데이터가 아닙니다.

# 등록 요청 — item 이 종목코드가 아니다
{"trnm": "REG", "grp_no": "1", "refresh": "1",
 "data": [{"item": ["MGU"], "type": ["0I"]}]}

# 수신
{"trnm": "REAL", "data": [{
    "type": "0I", "name": "국제금환산가격", "item": "MGU",
    "values": {"10": "-337782", "25": "5", "11": "-1674", "12": "-0.49"}
}]}

여기에 또 하나가 숨어 있습니다. 명세는 MGU"$/온스, 소수점2자리"라고 적고 현재가 10-337782를 보냅니다. 소수점이 제거된 100배 정수로 3,377.82달러입니다 (전일대비 11의 -1674 = -16.74달러, 등락율 12의 -0.49%와 일관됩니다). MGD(원/g)는 소수점 언급이 없어 같은 규칙인지 명세로 확정되지 않습니다 — float()가 성공하면서 값만 100배로 틀어지는 유형이라 ETF NAV 0G와 같은 방식으로 등록 요소별 실호출 대조를 먼저 하십시오.

그래서 금현물 봇은 폴링입니다. 주식 체결 0B·호가 0D로 이벤트를 받아 처리하던 구조를 금현물에 그대로 옮길 수 없습니다. ka50100(시세정보)이나 ka50101을 주기적으로 호출하는 루프가 되며, 호출 한도가 즉시 설계 제약이 됩니다. 명세 오류코드에도 1700(API별 유량 초과)과 1702(그룹 요청 개수 초과)가 따로 있습니다 — 키움 REST API 호출 한도부터 정한 뒤 전략을 얹는 순서가 맞습니다.

5. 응답이 0으로 채운 고정폭 문자열이다

계좌 계열(kt50020·kt50021·kt50032)의 숫자 필드는 모두 "좌측 0-padding 처리된 부호 포함 N자리 숫자"입니다. 그런데 N이 TR마다 다릅니다.

# kt50020 잔고확인 — 12자리
"tot_entr":  "000098740486"   # 98,740,486원
"real_qty":  "000000000002"   # 2g
"est_lspft": "-00000003201"   # -3,201원  (부호가 맨 앞)

# kt50021 예수금 — 15자리
"entra":     "000000098740486"
"ord_alow_amt": "000000098740486"

int()는 두 경우 모두 통과합니다. 문제는 자릿수를 상수로 박아 슬라이싱하는 코드와 부호를 떼지 않고 문자열로 대소를 비교하는 코드입니다. 앞엣것은 kt50020 기준 파서를 kt50021에 돌리는 순간 조용히 틀린 값을 만들고, 뒤엣것은 "-00000003201""000000000000"보다 작다는 것을 알지 못합니다. 부호를 포함한 채 int()에 그대로 넘기는 것이 유일하게 안전합니다.

6. 같은 이름 필드의 단위가 TR마다 다르다

일별 데이터를 받는 방법이 두 가지입니다. 시세의 ka50012(금현물일별추이)와 차트의 ka50081(금현물일봉차트). 같은 날짜에 같은 값이 오는데 명세의 단위 표기가 다릅니다.

TR필드명세 단위2025-08-26 예시값
ka50012trde_qty 누적 거래량1000주304439
ka50081acc_trde_qty 누적 거래량1주304439
둘 다acc_trde_prica 거래대금백만원45980

검산하면 어느 쪽이 맞는지 나옵니다. 같은 날 종가가 151,680원/g이므로 304,439g × 151,680원 ≈ 461.7억원이고 거래대금 45,980백만원 = 459.8억원입니다. 수량을 1g으로 읽었을 때만 거래대금과 맞습니다. ka50012의 "1000주" 표기를 믿고 1,000을 곱하면 1,000배 어긋납니다.

규칙 하나로 정리하면: 금현물에서 수량과 금액이 같이 오는 응답을 만나면 수량 × 가격이 금액과 자릿수가 맞는지를 한 번 계산해 보십시오. 명세의 단위 주석보다 이 검산이 빠르고 확실합니다. 이 글도 그렇게 판정했습니다.

차트 계열에는 비대칭이 하나 더 있습니다. 틱차트 ka50079upd_stkpc_tp(수정주가구분)가 필수인데 분봉 ka50080은 선택이고, 당일 차트 ka50091·ka50092에는 그 파라미터가 아예 없습니다. 금에는 액면분할도 배당도 없어 수정주가라는 개념 자체가 무의미한데 값을 요구합니다 — 주식 차트 명세를 복사한 흔적으로 보입니다. 필수인 곳에서 빠뜨리면 1511(필수 입력 값 없음)로 떨어지므로 TR별 파라미터 표를 따로 들고 가는 편이 안전합니다.

7. 체결 조회 3종의 파라미터가 서로 안 맞는다

주문 상태를 확인하는 TR이 세 개인데, 셋의 요청 규격이 미묘하게 다릅니다. 같은 뜻의 파라미터가 이름부터 다릅니다.

kt50030 체결전체kt50031 체결kt50075 미체결
매도수구분slby_tp (필수)sell_tp (필수)sell_tp (필수)
ord_dt 주문일자필수선택필수
qry_tp 조회구분선택필수선택
mrkt_deal_tp 시장구분필수없음필수
dmst_stex_tp선택필수선택

slby_tpsell_tp는 한글명이 똑같이 "매도수구분"입니다. 공통 요청 빌더를 하나 만들어 세 TR에 돌리면 kt50030에서만 1511이 뜹니다. 파라미터 매핑을 TR별 딕셔너리로 분리해 두는 것이 유일한 해법입니다.

8. 부가가치세 필드의 정체

잔고 kt50020vlad_tax(부가가치세), 거래내역 kt50032gold_spot_vat(금현물부가가치세) 필드가 있습니다. "금을 사고팔 때 부가세가 붙나?" 하고 놀라기 쉬운데, 명세의 예시값을 보면 수수료에 대한 부가세입니다.

# kt50032 거래내역 — 매수 1건
"rmrk_nm":        "금현물매수",
"deal_qty":       "000000000000008",   # 8g
"uv_exrt":        "159290.00",         # 원/g
"cmsn":           "000000000003820",   # 수수료 3,820원
"gold_spot_vat":  "000000000000382",   # 382원 = 3,820의 10%
"mdia_nm":        "REST API"

382는 3,820의 정확히 10%입니다. 즉 금 매매 자체가 아니라 수수료에 붙은 부가세로 읽히고, KRX 금시장에서 매매차익에 양도·배당소득세가 붙지 않는다는 제도 설명과도 모순되지 않습니다. 실물 인출은 별개입니다 — 인출 시에는 부가가치세 10%와 예탁결제원·증권사 수수료가 따로 붙습니다. 세금·수수료는 계좌 종류와 시점에 따라 달라지므로 국세청·한국거래소·거래 증권사의 현재 안내로 대조하십시오. 이 글은 세무 자문이 아닙니다.

덤으로 실무에서 쓸모 있는 필드가 하나 보입니다. mdia_nm(매체구분명)에 "REST API"가 찍힙니다 — 봇이 낸 주문과 사람이 앱에서 낸 주문을 사후에 구분할 수 있다는 뜻이라, 계좌를 같이 쓸 때 정합성 확인이 훨씬 쉬워집니다.

9. 금현물 봇 설계 체크리스트

여기까지를 코드가 지킬 형태로 줄이면 이렇습니다.

GOLD = {
    "1kg":  "M04020000",   # 금 99.99_1kg
    "100g": "M04020100",   # 미니금 99.99_100g
}
TRDE_TP = {"limit": "00", "ioc": "10", "fok": "20"}  # 시장가 없음

# 1) 수량은 g. 예산을 g으로 환산한 뒤 내림.
qty = int(budget_krw // price_per_gram)

# 2) 실시간이 없으므로 시세는 폴링. 주기는 호출 한도에서 역산.
quote = post("/api/dostk/mrkcond", "ka50100", {"stk_cd": GOLD["1kg"]})

# 3) 시장가가 없으니 즉시성이 필요하면 호가 + IOC, 잔량은 직접 처리.
order = post("/api/dostk/ordr", "kt50000", {
    "stk_cd": GOLD["1kg"], "ord_qty": str(qty),
    "ord_uv": str(bid_price), "trde_tp": TRDE_TP["ioc"],
})

# 4) 미체결 확인은 kt50075 (sell_tp), 체결전체는 kt50030 (slby_tp).
# 5) 금액 파싱은 자릿수 가정 없이 int() 에 그대로.

설계상 유리한 점도 분명히 있습니다. 종목이 둘뿐이라 순위·스크리닝 단계가 없고, 상장폐지·액면분할·유상증자 같은 이벤트 처리도 필요 없습니다. 거래시간이 09:00~15:30 한 구간이라 시간외·동시호가 분기가 사라지고, NXT 라우팅 분기도 없습니다 — kt50000dmst_stex_tp가 없는 이유가 그것입니다. 봇의 복잡도 대부분은 유니버스에서 나오는데, 그 축이 통째로 빠집니다.

금현물과 금 ETF 중 무엇을 자동매매할 것인가

선택의 근거가 되는 구조적 차이만 정리합니다. 어느 쪽이 더 나은 투자인지는 이 글이 판단할 영역이 아닙니다.

KRX 금현물국내 상장 금 ETF
매매차익 과세양도·배당소득세 없음배당소득세 부과
보유 비용별도 보수 없음운용보수 발생
실시간 시세(API)없음 — 폴링0B·0D·0G 사용 가능
주문 유형보통·IOC·FOK주식과 동일(시장가 포함)
추가 계좌금현물 전용 계좌 필요기존 주식 계좌
괴리 리스크해당 없음NAV 괴리·유동성

과세와 비용은 계좌 종류·시점·상품에 따라 달라집니다. 표의 항목은 "어디를 확인해야 하는지"의 목록이지 확정된 수치가 아닙니다. 실제 판단 전에 국세청·한국거래소·거래 증권사의 현재 안내를 직접 확인하십시오.

이 글은 금 투자를 권하지 않습니다. 금값의 방향이나 수익률은 이 글의 주제가 아니며, API가 열려 있다는 사실이 그 자산을 자동매매해야 할 근거가 되지는 않습니다. 종목이 둘뿐이라 분산이 되지 않는다는 점과 실시간 시세가 없어 급변 구간에서 봇이 보는 가격이 늘 과거라는 점은 구조적 제약입니다. 어떤 백테스트도 과거 데이터에 대한 계산일 뿐 미래 성과를 보장하지 않습니다.

자주 묻는 질문

키움 REST API로 KRX 금시장을 거래할 수 있나요?

명세상 금현물 전용 TR이 23개 있고 kt50000~kt50003은 실제 주문 API입니다. 다만 API가 열려 있다는 것과 내 계좌에서 바로 호출된다는 것은 다릅니다 — 금현물 전용 계좌와 약관 동의가 필요하므로 절차는 키움증권 공식 안내에서 확인하십시오.

금현물 주문에서 주문수량 1은 얼마인가요?

1g입니다. 명세의 수량 설명은 주식과 같은 "단위: 1주"지만 KRX 금시장의 매매수량단위가 1g이고, kt50032uncl_ocr만 "원/g"으로 명시합니다. kt50000의 요청 예시(수량 1 · 단가 160000)도 1g 기준임을 보여 줍니다.

금현물에도 실시간 체결 WebSocket이 있나요?

없습니다. 실시간 항목 15종 중 KRX 금현물 체결·호가에 해당하는 것이 없습니다. 이름이 비슷한 0I는 등록 요소가 MGD(원/g)·MGU($/온스)인 국제 금 환산 시세이지 KRX 체결 데이터가 아닙니다. 금현물 봇은 ka50100 폴링 구조가 되며 호출 한도 관리가 더 중요해집니다.

금현물 주문에 시장가를 넣을 수 있나요?

명세 기준으로는 없습니다. 주식 kt10000은 매매구분이 아홉 가지지만 kt5000000 보통, 10 IOC, 20 FOK 셋뿐입니다. 자릿수도 주식은 "0", 금현물은 "00"이라 상수를 공유하면 형식 오류가 납니다.

금현물이 금 ETF보다 유리한가요?

어느 쪽이 더 나은 투자인지는 이 글이 판단할 영역이 아닙니다. 구조적 차이만 말하면 금현물은 매매차익에 양도·배당소득세가 붙지 않고 별도 보수가 없는 대신, 실물 인출 시 부가세 10%와 수수료가 붙고 API에 실시간 시세가 없습니다. 세율·수수료는 계좌 종류와 시점에 따라 달라지므로 공식 자료로 대조하십시오.

금현물 자동매매, 직접 짜기 전에

수량 단위·폴링 주기·미체결 처리는 실제로 돌려 보기 전에는 감이 잡히지 않는 부분입니다.
어떤 구조가 맞는지부터 같이 정리해 드립니다. 24시간 빠른 답변 가능합니다.

무료로 상담하기
본 글은 키움증권 공식 REST API 명세(API 337개)의 금현물 관련 TR 23개 원문과 한국거래소·언론 보도를 대조해 작성했습니다. 명세의 파라미터·필드·단위 표기는 변경될 수 있으며, 본문의 판정 중 실호출로 확인하지 않은 항목은 그 사실을 함께 적었습니다. 반드시 키움증권 개발자 포털의 현재 명세로 대조하십시오. 세금·수수료·실물 인출 조건은 국세청·한국거래소·거래 증권사의 현재 안내가 기준이며, 이 글은 세무 자문이 아닙니다. 금 가격의 방향이나 수익률에 대한 어떠한 전망도 담고 있지 않으며, 과거 데이터에 기반한 계산은 미래 성과를 보장하지 않습니다. 알고랩(퀀트웍스)은 투자자문업·투자일임업을 영위하지 않으며, 고객이 정한 규칙을 코드로 구현하는 도구 제작 서비스를 제공합니다. 투자 판단과 그 결과의 책임은 전적으로 투자자 본인에게 있습니다.