AlgoLab Blog · 미국주식 분할매수 봇 · 2026

무한매수법 자동매매 — KIS API 함정 7가지

한국투자증권 · 해외주식 주문 2026-09-07 · 약 8분 읽기 · 알고랩 AlgoLab
한 줄 요약

무한매수법류 분할매수 봇의 핵심 주문은 LOC(장마감지정가)인데, KIS 해외주식 주문 API에서는 ORD_DVSN=34이고 미국 매수 TTTT1002U에서만 됩니다. 가장 크게 걸리는 것은 모의투자 VTTT1002U00(지정가)만 지원한다는 점입니다 — 전략의 핵심 주문을 모의로는 한 번도 못 돌려 봅니다. 나머지 여섯은 ⑴ 매수에는 MOO·MOC가 없다(매수 00·32·34 / 매도 00·31·32·33·34), ⑵ 모의 매도 tr_idVTTT1001U라 실전 TTTT1006U와 숫자가 다름, ⑶ 예약주문(order-resv)은 지정가만(예약매도 TTTT3016U만 MOO), ⑷ 예약주문은 증거금을 안 보고 당일 만료, ⑸ 접수 10:00~23:20(서머타임 22:20)에 16:30~16:45 정산 제한, ⑹ 매수가능금액 TTTS3007R은 종목코드·주문단가를 넣어야 나옵니다.

먼저 밝혀 둡니다. 이 글은 무한매수법의 수익성을 검증하거나 권하는 글이 아닙니다. 특정 종목·ETF·전략을 추천하지 않습니다. 다루는 것은 오직 "이 형태의 전략을 코드로 옮기면 KIS API가 무엇을 허용하고 무엇을 막는가"입니다. 3배 레버리지 ETF의 구조적 특성은 레버리지 ETF 27년 백테스트에서 따로 다뤘으니 그쪽을 먼저 보시는 편이 순서상 맞습니다.

목차

  1. 분할매수 봇이 실제로 내야 하는 주문
  2. 함정 1 — LOC는 ORD_DVSN=34, 모의투자에는 없다
  3. 함정 2 — 매수와 매도의 주문구분이 비대칭이다
  4. 함정 3 — 모의 매도 tr_idVTTT1001U
  5. 함정 4 — 예약주문은 지정가만 된다
  6. 함정 5 — 예약주문은 증거금을 보지 않는다
  7. 함정 6 — 접수 시간과 서머타임
  8. 함정 7 — 매수가능금액은 종목·단가가 필요하다
  9. 하루치 루프를 코드로 옮기면
  10. 자주 묻는 질문

1. 분할매수 봇이 실제로 내야 하는 주문

무한매수법으로 널리 알려진 형태는 원금을 일정 회차로 나눠 매일 조금씩 사고, 평단 대비 일정 비율 위에 매도를 걸어 두는 분할매수 전략입니다. 버전(V1·V2 등)마다 회차 수와 매수 배분 방식, 매도 조건이 다르므로 이 글은 특정 버전의 규칙을 옮긴 것이 아니라, 어느 버전이든 공통으로 필요한 주문 동작만 기준으로 삼습니다.

코드로 옮기면 하루 루프는 대개 이 넷입니다.

  1. 잔고·평단 읽기 — 해외주식 잔고 TTTS3012R
  2. 남은 매수 여력 확인 — 매수가능금액조회 TTTS3007R
  3. 그날 매수 주문 — 지정가 일부 + LOC 일부 (TTTT1002U)
  4. 평단 위 매도 주문 — 지정가 또는 LOC (TTTT1006U)

이 중 3·4번이 이 글의 대부분입니다. 잔고 쪽은 함정이 따로 한 무더기라 KIS API 해외주식 잔고 TTTS3012R 함정 6가지로 분리했습니다.

출처 — 아래 스펙은 전부 한국투자증권 공식 저장소 koreainvestment/open-trading-apiexamples_llm/overseas_stock/ 예제 원문에서 확인한 것입니다(order·order_resv·inquire_psamount·inquire_ccnl). 정책과 시간은 바뀔 수 있으니 KIS Developers 공식 문서를 함께 확인하십시오.

2. 함정 1 — LOC는 ORD_DVSN=34, 그런데 모의투자에는 없다

해외주식 주문은 POST /uapi/overseas-stock/v1/trading/order 하나이고, 시장과 매수·매도를 tr_id로 가릅니다. 미국 매수는 TTTT1002U입니다. 여기서 LOC를 쓰려면 ORD_DVSN34를 넣습니다.

공식 예제의 ord_dvsn 설명 원문은 이렇습니다.

[Header tr_id TTTT1002U(미국 매수 주문)]
00 : 지정가  32 : LOO(장개시지정가)  34 : LOC(장마감지정가)
* 모의투자 VTTT1002U(미국 매수 주문)로는 00:지정가만 가능

여기가 이 글에서 가장 중요한 한 줄입니다. 분할매수 전략의 매수는 대부분 LOC로 나가는데, 모의투자에서는 그 주문 유형 자체를 낼 수 없습니다. 즉 "모의로 한 달 돌려 보고 실전에 붙인다"는 통상적인 검증 순서가 이 전략에서는 성립하지 않습니다. 모의에서 확인되는 것은 인증·계좌 파라미터·지정가 주문 흐름까지이고, 주문 유형 분기는 실계좌 최소 수량으로 따로 확인해야 합니다.

모의와 실전의 차이 전반은 KIS 모의투자 실전 전환 — tr_id·도메인 바꿀 것 6가지에 정리해 뒀습니다. 이 글의 LOC 건은 그 목록에 없던 "모의에 아예 없는 기능" 유형입니다.

3. 함정 2 — 매수와 매도의 주문구분이 비대칭이다

같은 예제의 매도 쪽 원문을 나란히 놓으면 목록이 다릅니다.

ORD_DVSN의미미국 매수 TTTT1002U미국 매도 TTTT1006U
00지정가OO
31MOO(장개시시장가)XO
32LOO(장개시지정가)OO
33MOC(장마감시장가)XO
34LOC(장마감지정가)OO

매수에는 시장가 계열(MOO·MOC)이 없습니다. 매수 주문 유형을 설정값으로 받는 봇이라면 매도용 코드표를 그대로 재사용하는 순간 31·33이 매수로 새어 들어갑니다. 거래소별로도 목록이 달라, 홍콩 매도 TTTS1001U00 지정가와 50 단주지정가뿐입니다.

또 하나, 같은 예제는 시장가라도 단가를 비우지 말라고 명시합니다 — "1주당 가격 * 시장가의 경우 1주당 가격을 공란으로 비우지 않음 0으로 입력". 주문 유형별 허용 목록은 거래소마다 다르므로 표로 두고 호출 전에 검증하십시오.

4. 함정 3 — 모의 매도 tr_idVTTT1001U

KIS의 모의 전환은 보통 tr_id 앞글자를 T에서 V로 바꾸는 규칙으로 알려져 있습니다. 미국 매도는 여기서 어긋납니다.

동작실전 tr_id모의 tr_id규칙대로인가
미국 매수TTTT1002UVTTT1002UO
미국 매도TTTT1006UVTTT1001UX — 숫자가 다름
해외주식 잔고TTTS3012RVTTS3012RO
매수가능금액TTTS3007RVTTS3007RO

tr_id[0] = "V" 같은 문자열 치환으로 환경을 전환하면 매도만 조용히 틀립니다. 환경별 tr_id는 계산하지 말고 표로 못 박아 두십시오.

TR_ID = {
    ("us_buy",  "real"): "TTTT1002U", ("us_buy",  "demo"): "VTTT1002U",
    ("us_sell", "real"): "TTTT1006U", ("us_sell", "demo"): "VTTT1001U",  # 규칙 예외
    ("balance", "real"): "TTTS3012R", ("balance", "demo"): "VTTS3012R",
    ("psamt",   "real"): "TTTS3007R", ("psamt",   "demo"): "VTTS3007R",
}

5. 함정 4 — 예약주문은 지정가만 된다

한국 시간으로 자는 사이에 주문을 넣으려면 예약주문 POST /uapi/overseas-stock/v1/trading/order-resv가 있습니다. 그런데 공식 문서의 유의사항 원문에 이렇게 적혀 있습니다.

4) 지정가주문만 가능
 * 단 미국 예약매도주문(TTTT3016U)의 경우,
   MOO(장개시시장가)로 주문 접수 가능

예약주문 경로로는 LOC를 낼 수 없습니다. LOC 매수를 쓰는 전략이라면 예약주문이 아니라 정규장 시간에 봇이 깨어 있어야 합니다. 한국 기준 밤 11시 30분(서머타임 시 10시 30분) 이후에 도는 스케줄러가 필요하다는 뜻이고, 그래서 이 유형의 봇은 24시간 서버 운영이 사실상 전제가 됩니다.

예약주문 파라미터도 일반 주문과 이름이 다릅니다. 수량은 ORD_QTY가 아니라 FT_ORD_QTY, 단가는 OVRS_ORD_UNPR이 아니라 FT_ORD_UNPR3입니다. 아시아 시장에서만 쓰는 SLL_BUY_DVSN_CD·RVSE_CNCL_DVSN_CD·RSVN_ORD_RCIT_DT가 따로 있고, 미국은 ORD_DVSN을 씁니다. 한 함수로 미국과 아시아를 같이 받으면 인자가 반씩 죽습니다.

6. 함정 5 — 예약주문은 증거금을 보지 않는다

같은 유의사항의 다음 줄입니다.

2) 증거금 및 잔고보유 : 체크 안함
3) 주문전송 불가사유
 - 매수증거금 부족: 수수료 포함 매수금액부족, 환전,
   시세이용료 출금, 인출에 의한 증거금 부족
 - 기타 매수증거금 부족, 매도가능수량 부족,
   주권변경 등 권리발생으로 인한 주문불가사유 발생
1) 예약주문 유효기간 : 당일
 - 미국장 마감 후, 미체결주문은 자동취소
 - 미국휴장 시, 익 영업일로 이전

접수는 성공했는데 전송 단계에서 빠지는 경우가 구조적으로 존재한다는 뜻입니다. 분할매수 봇은 회차를 세면서 도는데, "넣었다고 기록했지만 실제로는 안 나간 날"이 생기면 회차 카운터가 실제 보유와 어긋납니다.

대응 — 접수 응답을 성공으로 기록하지 말고, 다음 날 잔고(TTTS3012R)와 주문체결내역(TTTS3035R, /uapi/overseas-stock/v1/trading/inquire-ccnl)으로 회차를 재계산하십시오. 카운터는 봇의 메모리가 아니라 계좌가 진실입니다. 수수료 포함 금액 부족이 원인으로 명시돼 있으니 매수 금액에 수수료 여유를 두는 것도 같이 필요합니다.

7. 함정 6 — 접수 시간과 서머타임

미국 예약주문의 접수·전송 시간도 공식 문서에 한국시간 기준으로 못 박혀 있습니다.

10:00 16:30~16:45 ~22:20 (서머타임) ~23:20 23:30 전송 예약주문 접수 구간 정산작업 · 주문 제한 미국 정규장 23:30~06:00 (서머타임 22:30~05:00) 모든 시각은 한국시간(KST) · 출처: KIS 공식 order_resv 예제 유의사항
예약주문 접수 창과 정산 제한 구간 — 스케줄러 시각을 여기에 맞춰야 한다

봇 관점에서 실제로 문제가 되는 지점은 셋입니다.

정규장에 직접 붙어 LOC를 내는 쪽을 택했다면 한국 시간 심야에 봇이 살아 있어야 합니다. 낮에 돌리고 싶다면 미국주식 주간거래 API가 별도 경로로 있지만, 주간거래는 주문 유형과 대상 종목이 정규장과 다르니 같은 전략을 그대로 옮길 수 있다고 가정하지 마십시오.

8. 함정 7 — 매수가능금액은 종목·단가가 필요하다

국내주식은 계좌만으로 매수가능금액이 나오지만, 해외주식 매수가능금액조회 TTTS3007R은 다릅니다. 필수 파라미터에 종목코드와 주문단가가 들어갑니다.

GET /uapi/overseas-stock/v1/trading/inquire-psamount
tr_id: TTTS3007R        # 모의: VTTS3007R
params = {
    "CANO": cano, "ACNT_PRDT_CD": acnt_prdt_cd,
    "OVRS_EXCG_CD": "NASD",
    "OVRS_ORD_UNPR": "1.4",   # 23.8 형식(정수 23자리 · 소수 8자리)
    "ITEM_CD": "QQQ",         # 종목코드 필수
}

"오늘 얼마 살 수 있나"를 물으려면 오늘 넣을 단가를 먼저 정해야 합니다. 분할매수 봇의 순서가 자연히 단가 결정 → 여력 조회 → 수량 결정으로 고정됩니다. 통화별 증거금을 따로 보려면 해외증거금 통화별조회 TTTC2101R(/uapi/overseas-stock/v1/trading/foreign-margin)이 있습니다.

9. 하루치 루프를 코드로 옮기면

위 일곱을 반영하면 하루 루프의 뼈대는 이렇게 됩니다. 값은 예시이고, 회차 배분 규칙은 각자의 전략대로 채워 넣으십시오.

def daily_round(env="real"):
    # 1) 계좌가 진실 — 회차는 잔고에서 역산한다
    bal = inquire_balance(cano, prdt, ovrs_excg_cd="NASD",
                          tr_crcy_cd="USD", env_dv=env)
    held_qty, avg_price = read_position(bal, TICKER)

    # 2) 오늘 단가를 먼저 정하고 → 여력을 묻는다
    unit_price = decide_unit_price(avg_price)
    psamt = inquire_psamount(cano, prdt, "NASD",
                             ovrs_ord_unpr=f"{unit_price:.2f}",
                             item_cd=TICKER, env_dv=env)

    # 3) 매수 — LOC는 실전에서만. 모의는 지정가로 폴백
    ord_dvsn = "34" if env == "real" else "00"     # VTTT1002U는 00만 가능
    order(cano, prdt, "NASD", TICKER,
          ord_qty=str(qty), ovrs_ord_unpr=f"{unit_price:.2f}",
          ord_dv="buy", ord_svr_dvsn_cd="0",
          ord_dvsn=ord_dvsn, env_dv=env)

    # 4) 매도 — tr_id 는 계산하지 말고 표에서 꺼낸다
    #    ("us_sell","demo") -> VTTT1001U  (VTTT1006U 아님)
    order(cano, prdt, "NASD", TICKER,
          ord_qty=str(held_qty), ovrs_ord_unpr=f"{target:.2f}",
          ord_dv="sell", ord_svr_dvsn_cd="0",
          ord_dvsn="34", env_dv=env)

주의할 점 둘. 첫째 env_dvdemo일 때 ord_dvsn00으로 떨어뜨리는 폴백은 편의를 위한 것이지 검증이 아닙니다 — 지정가로 통과했다고 LOC가 통과한다는 뜻은 아닙니다. 둘째 회차 카운터를 로컬 파일에 두지 마십시오. 예약주문 미전송·휴장 이전 때문에 봇의 기록과 계좌가 갈라지므로, 매 루프에서 잔고와 inquire-ccnl로 다시 세는 편이 안전합니다.

세금·수수료를 전략 파라미터에 넣어야 합니다. 해외주식은 양도소득 과세 대상이고 환전 비용도 붙습니다. 목표 수익률을 코드에 상수로 박기 전에 자동매매 세금 가이드를 확인해 비용 이후 기준으로 다시 계산하십시오. 세부 요건은 국세청·증권사 공식 안내가 기준입니다.

10. 정리 — 옮기기 전에 확정할 것

확인 항목결론
LOC 매수TTTT1002U + ORD_DVSN=34모의 불가
MOC 매수없음(매도 33만)
모의 매도 tr_idVTTT1001U(실전 TTTT1006U)
예약주문 주문유형지정가만 / 예약매도 TTTT3016U만 MOO
예약주문 증거금접수 시 체크 안 함 · 유효기간 당일
접수 시간(KST)10:00~23:20(서머타임 22:20) · 16:30~16:45 제한
매수가능금액TTTS3007RITEM_CD·OVRS_ORD_UNPR 필수

미국주식 주문 전반은 KIS API 미국주식 주문 — TTTT1002UORD_DVSN에 정리돼 있습니다. 아래 관련 글에 키 발급부터 해외 자동매매 전반까지 이어지는 순서를 걸어 뒀습니다.

자주 묻는 질문

무한매수법 같은 분할매수를 KIS API로 완전 자동화할 수 있나요?

주문 자체는 됩니다. 미국 매수 TTTT1002U00·32·34를 지원하므로 매일 정해진 수량을 LOC로 넣는 동작은 구현 가능합니다. 다만 모의투자 VTTT1002U00 되므로 LOC 경로는 실계좌에서만 검증됩니다. 평단과 보유수량은 TTTS3012R로 매번 다시 읽어야 합니다.

LOC 주문은 어떤 값으로 넣나요?

ORD_DVSN=34입니다. 매수는 00·32·34, 매도는 00·31·32·33·34목록이 다릅니다. 시장가 계열이라도 OVRS_ORD_UNPR을 비우지 말고 0을 넣으라고 공식 예제가 지시합니다. 거래소별로도 목록이 달라 홍콩 매도 TTTS1001U00·50뿐입니다.

자는 동안 주문을 넣으려면 예약주문을 쓰면 되나요?

됩니다만 지정가만 가능합니다(미국 예약매도 TTTT3016U만 MOO). LOC를 쓰는 전략이면 정규장에 봇이 깨어 있어야 합니다. 접수는 KST 10:00~23:20(서머타임 22:20), 16:30~16:45 정산 제한, 전송은 23:30(서머타임 22:30)입니다.

모의투자로 먼저 검증하면 안 되나요?

부분적으로만 됩니다. LOC·LOO는 모의에 없고, 미국 매도 모의 tr_idVTTT1001U라 문자열 치환식 환경 전환이 깨집니다. 주문체결내역도 모의계좌에서는 종목코드·매도매수구분·체결미체결구분·거래소코드에 전체 값만 넣을 수 있고 정렬순서를 쓸 수 없습니다.

매수 가능 금액은 어떻게 확인하나요?

TTTS3007R을 쓰되 ITEM_CDOVRS_ORD_UNPR함께 넣어야 합니다(단가는 정수 23·소수 8자리 형식). 통화별 증거금은 TTTC2101R로 따로 봅니다.

마무리

이 전략을 코드로 옮길 때 실제로 발목을 잡는 것은 전략 로직이 아니라 "쓰려는 주문 유형이 그 경로에서 되느냐"였습니다. LOC는 실계좌 정규장에서만, 예약주문은 지정가만, 모의는 지정가만 — 이 셋을 먼저 확정하면 나머지는 평범한 스케줄러 문제로 내려옵니다.

고지 — 알고랩(퀀트웍스)은 투자자문업·투자일임업을 영위하지 않으며, 고객의 규칙을 코드로 옮기는 도구 제공만 합니다. 이 글은 특정 종목·ETF·전략을 추천하지 않고 수익을 보장하지 않습니다. 무한매수법을 포함한 분할매수 전략의 성과는 시장·기간·비용에 따라 달라지며 손실이 발생할 수 있습니다. 본문의 tr_id·주문구분·접수시간은 2026-09-07 기준 한국투자증권 공식 저장소 예제 원문에서 확인한 값이며, API 스펙과 운영시간은 공지에 따라 바뀌므로 KIS Developers 공식 문서를 기준으로 삼으십시오. 세금·수수료 요건은 국세청과 증권사 공식 안내를 확인하십시오.

분할매수 봇, 규칙 그대로 만들어 드립니다

회차·평단·LOC 주문까지 계좌와 어긋나지 않는 구조로 짜 드립니다. 24시간 빠른 답변 가능합니다.

무료 상담 시작하기