AlgoLab Blog · KIS API 실무 · 2026

KIS API 미국주식 주문 — TTTT1002U와 ORD_DVSN

한국투자증권 · 해외주식 2026-08-18 · 약 8분 읽기 · 알고랩 AlgoLab
한 줄 요약 KIS API에서 미국주식 주문은 국내주식과 경로·tr_id·주문구분이 전부 다른 별개의 API입니다. 경로는 /uapi/overseas-stock/v1/trading/order, tr_id미국 매수 TTTT1002U · 미국 매도 TTTT1006U (모의는 VTTT1002U · VTTT1001U)입니다. 바디에는 OVRS_EXCG_CD(NASD·NYSE·AMEX)와 티커 문자열 PDNO, 가격 OVRS_ORD_UNPR를 넣습니다. 가장 많이 막히는 곳은 ORD_DVSN이 매수와 매도에서 다르다는 점입니다 — 미국 매수는 00(지정가)·32(LOO)·34(LOC)뿐이고, 매도에만 31(MOO)·33(MOC)이 더 있습니다. 모의투자에서는 00(지정가)만 됩니다.

KIS API 발급부터 첫 주문까지를 따라 국내주식 매수가 한 번 나가고 나면 다음 질문은 대개 같습니다. "그럼 테슬라도 이 코드로 사면 되나요?"

답은 아니오입니다. 국내주식 주문 코드에서 종목코드만 TSLA로 바꾸면 경로·tr_id·필수 파라미터 세 군데에서 동시에 막힙니다. 해외주식은 같은 계좌·같은 appkey를 쓰지만 사실상 다른 API 묶음입니다. 이 글은 그중 미국주식 주문 한 건을 넣는 데 필요한 것만 다룹니다.

이 글에서 다루는 것

  1. 국내주식 주문과 다른 3가지
  2. tr_id — 시장별·실전/모의별로 갈린다
  3. OVRS_EXCG_CD와 PDNO(티커)
  4. ORD_DVSN — 매수와 매도가 비대칭이다
  5. 실제 요청 코드와 응답
  6. 주문 뒤 확인 — 미체결·체결내역·잔고
  7. 한국 새벽에 안 깨는 법 — 예약주문
  8. 자주 막히는 자리 5곳

1. 국내주식 주문과 다른 3가지

국내주식 현금주문은 /uapi/domestic-stock/v1/trading/order-cashtr_id TTTC0802U(매수)를 붙여 보냅니다. 해외주식은 이 세 가지가 전부 바뀝니다.

국내주식 현금주문해외주식 주문
경로/uapi/domestic-stock/v1/trading/order-cash/uapi/overseas-stock/v1/trading/order
tr_id(매수)TTTC0802UTTTT1002U(미국)
종목 필드PDNO = 6자리 숫자 005930PDNO = 티커 AAPL
가격 필드ORD_UNPROVRS_ORD_UNPR
거래소 지정없음(또는 EXCG_ID_DVSN_CD)OVRS_EXCG_CD 필수
시장가ORD_DVSN 01매수에는 없음

계좌 필드인 CANO·ACNT_PRDT_CD는 국내와 동일한 규칙이라 계좌번호 8자리 + 상품코드 2자리를 그대로 씁니다. hashkey도 마찬가지로 국내주식 주문과 같은 규칙이 적용됩니다.

2. tr_id — 시장별·실전/모의별로 갈린다

한국투자증권이 공개한 오픈API 예제 코드 기준, 미국 시장의 tr_id는 다음과 같습니다.

구분실전모의
미국 매수TTTT1002UVTTT1002U
미국 매도TTTT1006UVTTT1001U

여기서 한 번은 반드시 틀립니다. 실전은 매수 ...1002U · 매도 ...1006U인데, 모의는 매수 VTTT1002U · 매도 VTTT1001U로 뒷자리 규칙이 다릅니다. "앞의 TV로 바꾸면 모의가 된다"는 국내주식식 습관으로 짜면 매수는 되는데 매도만 실패하는 상태가 됩니다. 모의와 실전 전환을 코드로 분기할 때 tr_id문자열 치환이 아니라 표(dict)로 관리해야 하는 이유입니다.

미국 외 시장도 각각 별도의 tr_id를 씁니다. 홍콩(SEHK)·중국(SHAA·SZAA)· 일본(TKSE)·베트남(HASE·VNSE)을 함께 다룰 계획이라면 처음부터 (시장, 매수/매도, 실전/모의) → tr_id 매핑 테이블을 만들어 두는 편이 낫습니다.

3. OVRS_EXCG_CD와 PDNO(티커)

OVRS_EXCG_CD주문이 나갈 거래소입니다. 공개 예제에 명시된 값은 다음과 같습니다.

코드거래소코드거래소
NASD미국 나스닥SEHK홍콩
NYSE미국 뉴욕SHAA중국 상해
AMEX미국 아멕스SZAA중국 심천
TKSE일본 도쿄HASE / VNSE베트남 하노이 / 호치민

종목이 실제 상장된 거래소와 코드가 어긋나면 주문은 거부됩니다. "미국주식이니까 전부 NASD"로 하드코딩한 봇이 흔한데, 뉴욕에 상장된 종목을 NASD로 보내면 그 종목만 조용히 실패합니다. 종목 목록을 관리할 때 티커와 거래소코드를 한 쌍으로 저장해야 합니다.

PDNO도 국내와 다릅니다. 국내는 005930 같은 6자리 숫자지만 해외는 AAPL·TSLA 같은 티커 문자열입니다. 국내 종목코드 마스터 파일을 파싱해 만든 종목 딕셔너리를 그대로 해외에 쓰면 여기서 어긋납니다.

4. ORD_DVSN — 매수와 매도가 비대칭이다

이 글에서 가장 실무적인 부분입니다. 공개 예제에 적힌 허용값은 매수와 매도가 다릅니다.

ORD_DVSN의미미국 매수미국 매도
00지정가
31MOO(장개시 시장가)×
32LOO(장개시 지정가)
33MOC(장마감 시장가)×
34LOC(장마감 지정가)
ORD_DVSN — 미국주식 매수 00 지정가 32 LOO 34 LOC 31 MOO 33 MOC 매도 00 지정가 32 LOO 34 LOC 31 MOO 33 MOC 모의투자 : 00(지정가)만 허용 점선 = 매수에서 사용 불가
미국 매수·매도의 ORD_DVSN 허용값 (KIS 공개 예제 기준 · 2026-08-18)

국내주식의 시장가(ORD_DVSN 01)에 해당하는 값이 미국 매수에는 없습니다. "일단 시장가로 사고 본다"는 로직을 그대로 옮기면 주문 자체가 나가지 않습니다. 현실적인 대안은 지정가 00에 호가 대비 여유를 준 가격을 넣는 것입니다. 다만 여유를 크게 주면 그만큼 불리한 가격에 체결될 수 있으므로, 주문 유형별 성질을 이해한 상태에서 폭을 정해야 합니다.

모의투자 제약. 공개 예제에는 모의투자에서 00(지정가)만 가능하다고 명시돼 있습니다. 모의에서 LOO·LOC 분기를 테스트할 수 없다는 뜻이므로, 그 분기는 실전 전환 시점에 처음 실행되는 코드가 됩니다. 수량을 최소로 두고 따로 확인하십시오.

5. 실제 요청 코드와 응답

미국 나스닥 종목을 지정가로 1주 매수하는 최소 형태입니다. 토큰 발급은 access_token 재발급 규칙과 동일합니다.

import requests

BASE = "https://openapi.koreainvestment.com:9443"   # 모의: openapivts...:29443

TR = {                       # (시장, 매수/매도, 실전/모의) → tr_id
    ("US", "BUY",  "REAL"): "TTTT1002U",
    ("US", "SELL", "REAL"): "TTTT1006U",
    ("US", "BUY",  "PAPER"): "VTTT1002U",
    ("US", "SELL", "PAPER"): "VTTT1001U",
}

def order_us(token, appkey, appsecret, cano, prdt, exchange, ticker,
             qty, price, side="BUY", env="REAL"):
    url = BASE + "/uapi/overseas-stock/v1/trading/order"
    body = {
        "CANO": cano,                    # 계좌 앞 8자리
        "ACNT_PRDT_CD": prdt,            # 상품코드 2자리
        "OVRS_EXCG_CD": exchange,        # NASD / NYSE / AMEX
        "PDNO": ticker,                  # 티커 문자열 (예: AAPL)
        "ORD_QTY": str(qty),
        "OVRS_ORD_UNPR": f"{price:.2f}", # 해외 주문단가
        "ORD_SVR_DVSN_CD": "0",
        "ORD_DVSN": "00",                # 00=지정가 (매수는 00/32/34만)
    }
    headers = {
        "content-type": "application/json; charset=utf-8",
        "authorization": f"Bearer {token}",
        "appkey": appkey,
        "appsecret": appsecret,
        "tr_id": TR[("US", side, env)],
        "custtype": "P",
    }
    return requests.post(url, headers=headers, json=body, timeout=10).json()

정상 접수되면 응답의 rt_cd0이고 output에 주문번호가 들어옵니다. 아래는 필드 구조를 보이기 위해 값을 임의로 채운 예시입니다.

{
  "rt_cd": "0",
  "msg_cd": "APBK0013",
  "msg1": "주문 전송 완료 되었습니다.",
  "output": {
    "KRX_FWDG_ORD_ORGNO": "01790",
    "ODNO": "0000123456",
    "ORD_TMD": "223015"
  }
}

rt_cd0이어도 "샀다"는 뜻이 아닙니다. 이것은 주문이 접수됐다는 응답일 뿐입니다. 지정가 주문은 체결되지 않은 채 남아 있을 수 있고, 미국장은 한국 새벽이라 봇이 접수만 확인하고 잠들면 다음 날 포지션이 없는 채로 매도 로직이 돌아갑니다. 실패 응답의 msg_cdKIS 에러코드 규칙을 따르며, 호출을 몰아치면 국내와 마찬가지로 유량 제한에 걸립니다.

6. 주문 뒤 확인 — 미체결·체결내역·잔고

해외주식은 조회 tr_id도 국내와 완전히 별개입니다. 공개 예제 기준으로 정리하면 다음과 같습니다.

용도tr_id (실전 / 모의)경로주요 파라미터
잔고TTTS3012R / VTTS3012R/uapi/overseas-stock/v1/trading/inquire-balanceOVRS_EXCG_CD, TR_CRCY_CD, CTX_AREA_FK200
미체결TTTS3018R/uapi/overseas-stock/v1/trading/inquire-nccsOVRS_EXCG_CD, SORT_SQN
주문체결내역TTTS3035R / VTTS3035R/uapi/overseas-stock/v1/trading/inquire-ccnlORD_STRT_DT, ORD_END_DT, CCLD_NCCS_DVSN
매수가능금액TTTS3007R / VTTS3007R/uapi/overseas-stock/v1/trading/inquire-psamountOVRS_EXCG_CD, OVRS_ORD_UNPR, ITEM_CD

매수가능금액이 국내와 결정적으로 다른 점OVRS_ORD_UNPR(주문 단가)와 ITEM_CD(종목)를 입력으로 요구한다는 것입니다. "지금 얼마까지 살 수 있나"가 종목과 가격에 따라 달라진다는 뜻이라, 국내 매수가능조회처럼 계좌 잔액만 물어보는 감각으로 부르면 값이 비어 보입니다.

잔고 조회는 CTX_AREA_FK200·CTX_AREA_NK200를 쓰는 연속조회 구조입니다. 보유 종목이 많으면 한 번에 다 오지 않으므로 국내 잔고조회 연속조회와 같은 방식으로 반복 호출해야 합니다.

7. 한국 새벽에 안 깨는 법 — 예약주문

미국 정규장은 한국 시각으로 밤·새벽입니다. 24시간 도는 서버가 없다면 해외주식 예약주문 API가 현실적인 선택입니다.

구분tr_id (실전 / 모의)
미국 매수 예약TTTT3014U / VTTT3014U
미국 매도 예약TTTT3016U / VTTT3016U
아시아 시장 예약TTTS3013U / VTTS3013U

경로는 /uapi/overseas-stock/v1/trading/order-resv입니다. 다만 예약주문은 접수 시점과 실제 주문 시점 사이에 시장이 움직인다는 성질이 있어, 변동성이 큰 구간에서는 의도와 다른 가격에 걸릴 수 있습니다. 예약 가능 시간·취소 방법·시장별 제약은 공식 안내에서 반드시 확인하십시오.

8. 자주 막히는 자리 5곳

  1. 모의 매도 tr_idVTTT1001U입니다. 규칙으로 유추하지 말고 표로 관리하십시오.
  2. 거래소코드 하드코딩 — 뉴욕 상장 종목을 NASD로 보내면 그 종목만 실패합니다.
  3. 매수 시장가 시도31·33은 매도 전용입니다. 매수는 00·32·34뿐입니다.
  4. 가격 소수점OVRS_ORD_UNPR는 문자열입니다. 부동소수 오차가 그대로 실리지 않도록 자릿수를 고정해 보내십시오.
  5. 서머타임 — 미국 개장 시각이 국내 기준으로 1시간 이동합니다. 시각을 상수로 박으면 1년에 두 번 스케줄이 어긋납니다.

환전 방식(원화 주문 가능 여부·통합증거금 적용 여부)은 계좌 설정에 따라 달라지고 정책도 바뀝니다. 이 부분은 코드가 아니라 계좌 조건의 문제이므로, 자동매매를 붙이기 전에 증권사 안내로 자기 계좌 상태를 먼저 확인하는 편이 빠릅니다. 증권사별로 해외주식을 API로 열어 주는 범위 자체가 다르다는 점도 함께 보십시오.

🛠️
미국주식 봇은 "돌아가는 것"보다 "새벽에 안 죽는 것"이 어렵습니다

주문 접수·체결 확인·재시도·서머타임까지 붙여 실제로 도는 상태로 만들어 드립니다.

제작 상담하기 →

자주 묻는 질문

Q. 국내주식 봇 코드를 재사용할 수 있나요?

인증·토큰·hashkey·에러 처리 계층은 재사용됩니다. 그러나 주문·조회 계층은 경로와 tr_id가 전부 달라 사실상 새로 써야 합니다. 처음부터 브로커 계층을 인터페이스로 분리해 두는 편이 유지보수가 쉽습니다.

Q. 미국 매수에 시장가가 정말 없나요?

공개 예제 기준 미국 매수 ORD_DVSN00·32·34뿐입니다. 실무에서는 지정가에 여유 폭을 준 가격으로 대체합니다.

Q. 체결 여부를 실시간으로 받을 수 있나요?

국내주식은 웹소켓 체결통보(H0STCNI0)가 있습니다. 해외주식 실시간 지원 범위는 별도 명세를 따르므로, 우선 TTTS3018R·TTTS3035R 폴링으로 확인 로직을 만들어 두는 편이 안전합니다.

Q. 주문을 취소·정정하려면요?

해외주식에도 정정·취소 API가 따로 있으며 원주문번호(ODNO)를 반드시 보관해야 합니다. 구조는 국내 정정·취소와 같은 발상입니다 — 주문번호를 안 들고 있으면 취소할 방법이 없습니다.

확인 캐치. 이 글의 경로·tr_id·파라미터명·허용값은 2026년 8월 18일 기준 한국투자증권이 공개한 오픈API 예제 코드의 명세에 근거합니다. 본문의 응답 예시는 필드 구조를 보이기 위해 값을 임의로 채운 것이며 실제 체결 내역이 아닙니다. API 스펙·거래 가능 시장·환전 및 증거금 정책은 변경될 수 있으므로 구현 전 KIS Developers 공식 문서와 증권사 안내에서 직접 확인하십시오. 본 글은 특정 종목·시장에 대한 어떠한 예측이나 투자 권유도 담고 있지 않습니다.

마무리

한 줄로 줄이면 이렇습니다. 미국주식 주문은 국내주식 주문의 확장이 아니라 별개의 API다. tr_id는 표로 관리하고, 거래소코드는 종목과 한 쌍으로 저장하고, 매수에는 시장가가 없다는 것만 기억하면 첫 주문은 나갑니다.

나머지 난이도는 전부 "한국이 잠든 시간에 봇이 혼자 판단한다"는 데서 나옵니다. 접수와 체결을 구분하지 않는 코드가 그 시간대에 가장 비싼 실수를 합니다.

미국주식 자동매매, 맡기고 싶다면

KIS 해외주식 API 연동부터 새벽 무인 운영까지 실제로 도는 상태로 만들어 드립니다. 24시간 빠른 답변 가능합니다.

무료 상담 시작하기