💡 딱 한 줄: "코드 몇 줄로 자동으로 금 사고팔기"
프로그래밍으로 금을 자동으로 사고팔 수 있다는 거 아시나요?
키움증권에서 2025년 9월부터 REST API를 통한 KRX 금시장 거래를 지원하기 시작했어요. 이제 HTS나 MTS 없이도, 파이썬이나 자바스크립트 같은 프로그래밍 언어로 직접 금 거래를 할 수 있게 된 거죠.
오늘은 키움증권 REST API로 금현물을 거래하는 방법을 처음부터 끝까지 알려드릴게요. 프로그래밍 초보자도 따라할 수 있도록 쉽게 설명하겠습니다!
이 글에서 배울 것들
- 키움 REST API가 뭔지
- 금현물 주문에 필요한 API 목록
- 실제로 주문하는 방법 (코드 예시)
- 잔고 확인, 시세 조회하는 방법
- 실전 운영 팁
REST API가 뭔가요?
어려운 말 같지만 간단해요.
REST API는 웹 주소(URL)로 명령을 보내는 방식이에요.
예를 들어:
- https://api.kiwoom.com/금매수 → 금을 사라
- https://api.kiwoom.com/잔고확인 → 내 잔고 알려줘
이런 식으로 인터넷을 통해 증권사 시스템에 명령을 보내는 거죠.
왜 좋은가요?
- HTS 켤 필요 없음
- 자동화 가능
- 여러 계좌 동시 관리 가능
- 24시간 돌릴 수 있음 (서버에서)
시작하기 전 준비물
1. 키움증권 계좌
- 금현물 거래 가능한 계좌
- REST API 사용 신청 (키움증권 홈페이지에서)
2. API 인증 정보
- API Key (앱 키)
- Secret Key (비밀 키)
- Access Token (접근 토큰)
3. 개발 환경
- 파이썬 3.x 설치
- 또는 자바스크립트 (Node.js)
- 또는 다른 프로그래밍 언어
금현물 주문 API 전체 목록
키움 REST API에서 제공하는 금현물 관련 API들이에요.
주문 관련 API
API ID 기능 설명
| kt50000 | 금현물 매수 | 금을 삽니다 |
| kt50001 | 금현물 매도 | 금을 팝니다 |
| kt50002 | 금현물 정정 | 주문 내용 수정 |
| kt50003 | 금현물 취소 | 주문 취소 |
잔고/예수금 확인 API
API ID 기능 설명
| kt00018 | 잔고 확인 | 내가 가진 금 확인 |
| kt50020 | 예수금 확인 | 살 수 있는 돈 확인 |
| kt50021 | 주문체결 전체조회 | 오늘 주문 전부 보기 |
| kt50030 | 주문체결 조회 | 체결된 주문만 보기 |
| kt50031 | 거래내역 조회 | 거래 이력 보기 |
| kt50032 | 미체결 조회 | 아직 안 체결된 주문 |
시세/호가 조회 API
API ID 기능 설명
| ka50087 | 시세 정보 | 현재 금 시세 |
| ka50100 | 호가 정보 | 매수/매도 호가 |
| ka50079 | 분봉 차트 | 1분/5분/... 차트 |
| ka50080 | 일봉 차트 | 일별 차트 |
| ka50081 | 주봉 차트 | 주별 차트 |
| ka50082 | 월봉 차트 | 월별 차트 |
실제로 금 매수하는 방법
1단계: API 기본 설정
모든 API 요청에는 이 정보가 필요해요.
import requests
import json
# API 기본 정보
BASE_URL = "https://api.kiwoom.com" # 실서버
# BASE_URL = "https://mockapi.kiwoom.com" # 테스트용
ACCESS_TOKEN = "your_access_token_here" # 발급받은 토큰
2단계: 매수 주문 보내기
지정가로 금 10g 사는 예시:
def buy_gold():
# API 엔드포인트
url = f"{BASE_URL}/api/dostk/ordr"
# 헤더 설정
headers = {
"Authorization": f"Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json;charset=UTF-8",
"api-id": "kt50000" # 금현물 매수
}
# 주문 내용
data = {
"dmst_stex_tp": "KRX", # 거래소: KRX
"stk_cd": "GOLD_CODE", # 금 종목코드
"ord_qty": "10", # 수량: 10g
"ord_uv": "100000", # 가격: 100,000원
"trde_tp": "0" # 주문유형: 지정가
}
# API 호출
response = requests.post(url, headers=headers, json=data)
# 결과 확인
if response.status_code == 200:
result = response.json()
print("주문 성공!", result)
return result
else:
print("주문 실패:", response.text)
return None
# 실행
buy_gold()
코드 설명:
- url: 주문을 보낼 주소
- headers: 인증 정보와 API 종류
- data: 실제 주문 내용
- dmst_stex_tp: 거래소 (KRX 고정)
- stk_cd: 금 종목코드
- ord_qty: 몇 그램 살지
- ord_uv: 얼마에 살지
- trde_tp: 주문 방식
3단계: 시장가로 매수하기
가격 상관없이 바로 사고 싶을 때:
data = {
"dmst_stex_tp": "KRX",
"stk_cd": "GOLD_CODE",
"ord_qty": "10",
"trde_tp": "3" # 3: 시장가
# ord_uv는 생략
}
주문 유형 코드표
trde_tp 값에 따라 주문 방식이 달라져요.
코드 주문 유형 설명
| 0 | 지정가 | 내가 정한 가격에 |
| 3 | 시장가 | 현재가로 즉시 |
| 5 | 조건부지정가 | 조건 만족 시 |
| 6 | 최유리 | 가장 유리한 가격 |
| 10 | IOC 지정가 | 즉시 체결, 안되면 취소 |
| 20 | FOK 지정가 | 전량 체결, 안되면 취소 |
| 28 | 스톱 지정가 | 스톱로스용 |
처음엔 0(지정가)이나 3(시장가)만 쓰세요!
잔고 확인하는 방법
주문 전에 내가 금을 얼마나 가지고 있는지 확인:
def check_balance():
url = f"{BASE_URL}/api/tr/balance" # 잔고 조회 URL
headers = {
"Authorization": f"Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"api-id": "kt00018" # 금현물 잔고확인
}
response = requests.get(url, headers=headers)
if response.status_code == 200:
balance = response.json()
print("현재 잔고:", balance)
return balance
else:
print("조회 실패:", response.text)
return None
# 실행
check_balance()
예수금(살 수 있는 돈) 확인
def check_deposit():
url = f"{BASE_URL}/api/tr/deposit"
headers = {
"Authorization": f"Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"api-id": "kt50020" # 금현물 예수금
}
response = requests.get(url, headers=headers)
if response.status_code == 200:
deposit = response.json()
print("사용 가능 금액:", deposit)
return deposit
else:
print("조회 실패:", response.text)
return None
현재 금 시세 확인
def check_gold_price():
url = f"{BASE_URL}/api/tr/price"
headers = {
"Authorization": f"Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"api-id": "ka50087" # 금현물 시세정보
}
data = {
"stk_cd": "GOLD_CODE" # 금 종목코드
}
response = requests.get(url, headers=headers, params=data)
if response.status_code == 200:
price = response.json()
print("현재 금 시세:", price)
return price
else:
print("조회 실패:", response.text)
return None
주문 취소하는 방법
실수로 주문했거나 마음이 바뀌었을 때:
def cancel_order(order_no):
url = f"{BASE_URL}/api/dostk/ordr"
headers = {
"Authorization": f"Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"api-id": "kt50003" # 금현물 취소주문
}
data = {
"dmst_stex_tp": "KRX",
"org_order_no": order_no # 원주문번호
}
response = requests.post(url, headers=headers, json=data)
if response.status_code == 200:
result = response.json()
print("취소 성공!", result)
return result
else:
print("취소 실패:", response.text)
return None
실전 운영 순서 (권장)
실제로 자동 매매 프로그램 만들 때 이 순서를 따르세요:
1단계: 사전 점검
# 1. 예수금 확인
deposit = check_deposit()
# 2. 현재 시세 확인
price = check_gold_price()
# 3. 잔고 확인
balance = check_balance()
2단계: 주문 결정
# 조건 판단 (예시)
if deposit > 1000000 and price < 100000:
# 예수금 100만원 넘고, 시세가 10만원 미만이면 매수
buy_gold()
3단계: 주문 전송
order_result = buy_gold()
order_no = order_result['order_no'] # 주문번호 저장
4단계: 체결 모니터링
import time
def check_order_status(order_no):
# kt50032: 미체결 조회
# kt50030: 체결 조회
pass # 위와 비슷한 방식으로 구현
# 10초마다 체결 확인
while True:
status = check_order_status(order_no)
if status == "체결완료":
break
time.sleep(10)
5단계: 사후 확인
# 체결 후 잔고 재확인
new_balance = check_balance()
실전 팁 & 주의사항
1. 테스트는 모의 서버에서
# 테스트용
BASE_URL = "https://mockapi.kiwoom.com"
# 실전용 (돈 진짜 나감!)
BASE_URL = "https://api.kiwoom.com"
처음엔 반드시 모의 서버에서 연습하세요!
2. 에러 처리 필수
try:
result = buy_gold()
except Exception as e:
print(f"오류 발생: {e}")
# 알림 보내기 (이메일, 텔레그램 등)
3. 주문 유형 상수로 관리
# 주문 유형 상수
ORDER_TYPE = {
"지정가": "0",
"시장가": "3",
"IOC": "10",
"FOK": "20"
}
# 사용
data = {
"trde_tp": ORDER_TYPE["지정가"]
}
4. 금 종목코드 확인
금 종목코드는 키움증권 API 문서에서 확인하세요.
- 실제 코드로 교체 필요
- 테스트 환경과 실전 환경의 코드가 다를 수 있음
5. API 호출 제한 확인
- 초당 요청 수 제한
- 일일 요청 수 제한
- 제한 초과 시 일시 차단
너무 자주 호출하지 마세요!
6. 로그 남기기
import logging
logging.basicConfig(
filename='gold_trading.log',
level=logging.INFO
)
def buy_gold():
logging.info(f"매수 시도: {datetime.now()}")
# ... 주문 코드 ...
logging.info(f"매수 완료: {result}")
전체 코드 예시 (통합)
import requests
import json
import time
from datetime import datetime
class KiwoomGoldTrader:
def __init__(self, access_token, is_test=True):
self.access_token = access_token
self.base_url = "https://mockapi.kiwoom.com" if is_test else "https://api.kiwoom.com"
def _make_headers(self, api_id):
return {
"Authorization": f"Bearer {self.access_token}",
"Content-Type": "application/json;charset=UTF-8",
"api-id": api_id
}
def check_balance(self):
"""잔고 확인"""
url = f"{self.base_url}/api/tr/balance"
headers = self._make_headers("kt00018")
response = requests.get(url, headers=headers)
return response.json() if response.status_code == 200 else None
def check_deposit(self):
"""예수금 확인"""
url = f"{self.base_url}/api/tr/deposit"
headers = self._make_headers("kt50020")
response = requests.get(url, headers=headers)
return response.json() if response.status_code == 200 else None
def get_price(self, stock_code):
"""시세 확인"""
url = f"{self.base_url}/api/tr/price"
headers = self._make_headers("ka50087")
params = {"stk_cd": stock_code}
response = requests.get(url, headers=headers, params=params)
return response.json() if response.status_code == 200 else None
def buy(self, stock_code, quantity, price=None):
"""매수"""
url = f"{self.base_url}/api/dostk/ordr"
headers = self._make_headers("kt50000")
data = {
"dmst_stex_tp": "KRX",
"stk_cd": stock_code,
"ord_qty": str(quantity),
"trde_tp": "3" if price is None else "0"
}
if price:
data["ord_uv"] = str(price)
response = requests.post(url, headers=headers, json=data)
return response.json() if response.status_code == 200 else None
def sell(self, stock_code, quantity, price=None):
"""매도"""
url = f"{self.base_url}/api/dostk/ordr"
headers = self._make_headers("kt50001")
data = {
"dmst_stex_tp": "KRX",
"stk_cd": stock_code,
"ord_qty": str(quantity),
"trde_tp": "3" if price is None else "0"
}
if price:
data["ord_uv"] = str(price)
response = requests.post(url, headers=headers, json=data)
return response.json() if response.status_code == 200 else None
# 사용 예시
trader = KiwoomGoldTrader(
access_token="your_token_here",
is_test=True # 테스트 모드
)
# 잔고 확인
balance = trader.check_balance()
print("잔고:", balance)
# 시세 확인
price = trader.get_price("GOLD_CODE")
print("현재가:", price)
# 매수 (시장가로 10g)
result = trader.buy("GOLD_CODE", 10)
print("매수 결과:", result)
관련해서 함께 보면 좋은 글
해시태그
#키움증권 #RESTAPI #금거래 #자동매매 #금현물 #KRX금시장 #파이썬 #API연동
마무리: 작은 것부터 시작하세요
REST API로 금 거래, 어렵지 않죠?
처음엔 복잡해 보이지만, 결국 URL에 정보를 보내고 결과를 받는 것뿐이에요.
시작 단계별 로드맵:
1주차: 조회만
- 잔고 확인
- 시세 확인
- 예수금 확인
- 주문은 안 함
2주차: 모의 주문
- 모의 서버에서 주문 연습
- 매수/매도/취소 모두 테스트
- 실전은 아직
3주차: 소액 실전
- 가장 작은 단위로 실전 주문
- 모든 과정 로그 남기기
- 문제없으면 금액 늘리기
4주차: 자동화
- 조건 설정 (시세, 시간 등)
- 자동 매수/매도 로직
- 24시간 모니터링
절대 서두르지 마세요. API는 도구일 뿐, 투자 전략이 더 중요합니다.
궁금한 점이나 에러가 나면 댓글로 공유해주세요. 함께 해결해봐요!
※ 투자 유의사항
금 투자에는 가격 변동 위험이 있으며, API를 통한 자동 거래는 예상치 못한 손실을 발생시킬 수 있습니다. 충분한 테스트 후 소액부터 시작하시고, 투자 판단과 책임은 본인에게 있습니다.
※ API 사용 전 확인사항
- 키움증권 REST API 이용약관 확인
- 금현물 거래 가능 계좌 개설
- API 사용 신청 및 승인
- 테스트 환경에서 충분한 연습
'IT와 과학 > 주식자동매매기술' 카테고리의 다른 글
| 📆 월간 업데이트 | AI 반도체 투자 리포트 (2025-10) (0) | 2025.10.14 |
|---|---|
| 📊 양자컴퓨팅 투자 완벽 가이드 (2025년 10월 최신) (0) | 2025.10.14 |
| 가격은 오르는데 왜 불안할까? | 진짜 매수세와 가짜 매수세 구분법 (0) | 2025.10.06 |
| 주식매매타이밍 잡기 - 신고가 돌파했는데 왜 떨어질까? | 진짜 신고가와 가짜 신고가 구분법 (0) | 2025.10.06 |
| 반등인 줄 알았는데 다시 떨어지는 이유 | ROC 모멘텀으로 진짜 반등 찾기 (0) | 2025.10.05 |