From trading-tools
Queries Kiwoom Securities REST API for stock info (ka10001), account assets (kt00004), daily returns (ka01690). Handles OAuth 2.0 auth, token caching, rate limiting, mock/live env switching.
npx claudepluginhub dandacompany/dantelabs-agentic-school --plugin trading-toolsThis skill uses the workspace's default tool permissions.
키움증권 REST API와 상호작용하기 위한 종합 가이드입니다. OAuth 2.0 인증, 주식 기본정보 조회(ka10001), 계좌 자산 현황(kt00004), 일별잔고수익률(ka01690), 모의투자/실전투자 환경 관리, Rate Limiting 대응을 포함합니다.
Guides Shioaji Python API for Taiwan markets: place/modify/cancel stock/futures/options orders, stream real-time ticks/bidask, fetch historical data, query accounts on TWSE/TPEX/TAIFEX.
Queries Kraken crypto exchange account via kraken_cli.py wrapper for portfolio summaries, net worth, holdings, staking rewards, market data, orders, and trades.
Integrates with Trading 212 API for authentication via API keys, placing buy/sell market/limit/pending orders, cancellations, balance/position/portfolio checks, P&L, order history, dividends, and instrument searches.
Share bugs, ideas, or general feedback.
키움증권 REST API와 상호작용하기 위한 종합 가이드입니다. OAuth 2.0 인증, 주식 기본정보 조회(ka10001), 계좌 자산 현황(kt00004), 일별잔고수익률(ka01690), 모의투자/실전투자 환경 관리, Rate Limiting 대응을 포함합니다.
npx dlabs install trading-tools
프로젝트 루트에 .env 파일이 없으면 이 스킬의 .env.example을 복사하여 생성:
# 프로젝트 루트로 이동
cd /path/to/your-project
# .env 파일이 없으면 스킬의 .env.example 복사
if [ ! -f .env ]; then
cp .claude/skills/kiwoom-api/.env.example .env
echo "✅ .env 파일 생성됨. API 키를 입력하세요."
fi
# .env 파일 편집
nano .env # 또는 vim, code 등
필수 환경 변수:
# 거래 환경: mock (모의투자) | prod (실전투자)
TRADING_ENV=mock
# API 인증 정보 (openapi.kiwoom.com에서 발급)
KIWOOM_REST_API_KEY=your_api_key
KIWOOM_REST_API_SECRET=your_api_secret
# 계좌번호 (모의투자: 50으로 시작)
KIWOOM_ACCOUNT_NO=5012345678
.env 파일의 TRADING_ENV 값을 변경하여 환경 전환:
# 모의투자 (기본값, 권장)
TRADING_ENV=mock
# 실전투자 (신중히!)
TRADING_ENV=prod
환경별 API 엔드포인트:
| 환경 | TRADING_ENV | Base URL |
|---|---|---|
| 모의투자 | mock | https://mockapi.kiwoom.com |
| 실전투자 | prod | https://api.kiwoom.com |
import httpx
import os
from dotenv import load_dotenv
# 프로젝트 루트의 .env 로드
load_dotenv()
api_key = os.getenv("KIWOOM_REST_API_KEY")
api_secret = os.getenv("KIWOOM_REST_API_SECRET")
trading_env = os.getenv("TRADING_ENV", "mock")
# Base URL 결정
base_url = (
"https://mockapi.kiwoom.com" if trading_env == "mock"
else "https://api.kiwoom.com"
)
# 토큰 발급
url = f"{base_url}/oauth2/token"
data = {
"grant_type": "client_credentials",
"appkey": api_key,
"secretkey": api_secret
}
response = httpx.post(url, json=data, timeout=30.0)
result = response.json()
if result.get('return_code') == 0:
token = result['token']
print(f"Token: {token}")
else:
print(f"Error: {result.get('return_msg')}")
토큰은 약 1시간 동안 유효합니다. 토큰을 캐싱하여 불필요한 재발급을 방지합니다:
import time
class KiwoomAPIClient:
def __init__(self):
self.token = None
self.token_expires = None
def _get_token(self) -> str:
# 캐시된 토큰이 유효하면 재사용
if self.token and self.token_expires:
if time.time() < self.token_expires:
return self.token
# 토큰 발급
# ... (위 코드 참조)
self.token = result['token']
self.token_expires = time.time() + 3600
return self.token
def get_stock_info(self, stock_code: str) -> dict:
"""
주식기본정보요청 (ka10001)
Args:
stock_code: 종목코드 6자리 (예: "005930" 삼성전자)
Returns:
주가 정보 딕셔너리
"""
token = self._get_token()
url = f"{self.base_url}/api/dostk/stkinfo"
headers = {
"Content-Type": "application/json;charset=UTF-8",
"api-id": "ka10001",
"authorization": f"Bearer {token}"
}
body = {"stk_cd": stock_code}
response = httpx.post(url, headers=headers, json=body, timeout=30.0)
result = response.json()
if result.get('return_code') == 0:
return result
else:
raise Exception(f"API 오류: {result.get('return_msg')}")
{
"return_code": 0,
"return_msg": "정상적으로 처리되었습니다",
"stk_cd": "005930",
"stk_nm": "삼성전자",
"cur_prc": "-160400",
"pred_pre": "-8700",
"flu_rt": "-5.14",
"trde_qty": "31734276",
"mac": "9512858",
"per": "32.47",
"eps": "4950",
"pbr": "2.77",
"roe": "9.0",
"bps": "57930",
"250hgst": "+169400",
"250lwst": "-50800"
}
투자 시작 전 자산 현황을 한눈에 파악:
from kiwoom_api_client_template import KiwoomAPIClient
client = KiwoomAPIClient()
summary = client.get_asset_summary()
print(f"환경: {summary['environment']}")
print(f"예수금: {summary['deposit']:,}원")
print(f"추정예탁자산: {summary['estimated_asset']:,}원")
print(f"보유종목: {summary['holdings_count']}개")
print(f"누적손익: {summary['cumulative_pnl']:+,}원 ({summary['cumulative_pnl_pct']:+.2f}%)")
보유종목별 상세 평가 현황:
data = client.get_account_evaluation()
# 계좌 요약
s = data["summary"]
# deposit, d2_deposit, total_evaluation, total_asset,
# total_purchase, estimated_asset,
# today_pnl, monthly_pnl, cumulative_pnl,
# today_pnl_pct, monthly_pnl_pct, cumulative_pnl_pct
# 보유종목 리스트
for h in data["holdings"]:
print(f"{h['name']} | {h['quantity']}주 | 손익: {h['pnl_pct']:+.2f}%")
# code, name, quantity, avg_price, current_price,
# evaluation, pnl_amount, pnl_pct, purchase_amount
특정 일자 기준 잔고 및 수익률:
# 오늘 기준
daily = client.get_daily_balance_pnl()
# 특정 일자
daily = client.get_daily_balance_pnl("20260207")
s = daily["summary"]
# total_purchase, total_evaluation, total_pnl, total_pnl_pct,
# deposit, estimated_asset, cash_ratio
for h in daily["holdings"]:
print(f"{h['name']} | 비중: {h['buy_ratio']:.1f}% | 수익률: {h['pnl_pct']:+.2f}%")
# code, name, current_price, quantity, avg_price,
# buy_ratio, evaluation, eval_ratio, pnl_amount, pnl_pct
체결된 주문의 결제 잔고, 예수금, 신용/대출 현황:
# ⚠️ 실전투자 전용 - 모의투자에서는 Exception 발생
client = KiwoomAPIClient(use_mock=False) # 실전투자 명시
data = client.get_settlement_balance()
# 계좌 요약
s = data["summary"]
# deposit, deposit_d1, deposit_d2, orderable_cash,
# withdrawable, unsettled_cash,
# total_buy_amount, total_evaluation,
# total_pnl, total_pnl_pct,
# substitute_amount, credit_collateral_rate
# 종목별 체결잔고
for h in data["holdings"]:
print(f"{h['name']} | 결제잔고: {h['settlement_balance']}주 | 현잔고: {h['current_quantity']}주")
# code, name, settlement_balance, current_quantity,
# current_price, avg_price, purchase_amount,
# evaluation, pnl_amount, pnl_pct,
# credit_type, loan_date, expire_date
| API | 메서드 | 모의투자 | 용도 |
|---|---|---|---|
| kt00004 | get_account_evaluation() | 지원 | 현재 보유종목 + 손익 현황 |
| ka01690 | get_daily_balance_pnl() | 지원 | 특정 일자 잔고 + 종목별 비중 |
| kt00005 | get_settlement_balance() | 미지원 | 체결잔고 (실전투자 전용) |
키움증권 API는 요청 횟수 제한이 있습니다. HTTP 429 오류를 방지하기 위해:
import time
def get_multiple_stocks(self, stock_codes: list, delay: float = 1.0) -> dict:
"""
여러 종목 조회 (Rate Limiting 대응)
Args:
stock_codes: 종목코드 리스트
delay: 요청 간 대기 시간 (초)
Returns:
종목별 데이터 딕셔너리
"""
results = {}
for i, code in enumerate(stock_codes):
if i > 0:
time.sleep(delay) # 첫 요청 제외하고 대기
try:
results[code] = self.get_stock_info(code)
except Exception as e:
results[code] = {"error": str(e)}
return results
권장 사항:
재사용 가능한 클라이언트 템플릿이 제공됩니다:
# 템플릿 위치
.claude/skills/kiwoom-api/assets/kiwoom_api_client_template.py
템플릿 특징:
사용 방법:
from kiwoom_api_client_template import KiwoomAPIClient
client = KiwoomAPIClient() # .env 기준 자동 결정
client = KiwoomAPIClient(use_mock=True) # 명시적 모의투자
# 주식 정보
data = client.get_stock_info("005930")
# 자산 현황 (가장 자주 쓰는 메서드)
summary = client.get_asset_summary()
print(f"예수금: {summary['deposit']:,}원")
# 상세 계좌 평가
evaluation = client.get_account_evaluation()
# 일별 잔고 수익률
daily = client.get_daily_balance_pnl("20260207")
# KRX (국내 주식)
"005930" # 삼성전자
# NASDAQ
"039490_NX" # 셀트리온
# NYSE
"039490_AL" # 셀트리온
| return_code | 의미 |
|---|---|
| 0 | 정상 처리 |
| 2 | 입력 값 오류 |
| 3 | 인증 실패 |
| 5 | Rate Limit 초과 |
.env 파일에 API Key/Secret 확인TRADING_ENV 설정 확인 (mock/prod)모의투자에서는 해당업무가 제공되지 않습니다서비스 TR을 확인 바랍니다 (return_code: 0이지만 데이터 비어있음).env.example이 프로젝트 루트의 .env보다 먼저 매칭됨.env를 우선 탐색 후 .env.example을 fallback으로 탐색하도록 수정api_endpoints.md - 키움증권 REST API 엔드포인트 상세 스펙. OAuth, 주식정보, 계좌, 거래 API 포함.
account.md - 계좌 관련 API (ka01690 일별잔고수익률) 상세 스펙.
environment_config.md - 환경 설정 및 관리 가이드. 환경 변수 목록, Python에서 환경 확인 방법 포함.
market_price.md - 시세 API (호가, 일주월시분, 시분, 시세표성정보, 신주인수권) 상세 스펙.
ranking.md - 순위정보 API (호가잔량상위, 호가잔량급증, 잔량율급증, 거래량급증, 전일대비등락률상위) 상세 스펙.
institution.md - 기관/외국인 매매동향 API (외국인종목별, 기관) 상세 스펙.
sector.md - 업종 프로그램 매매 API 상세 스펙.
short_selling.md - 공매도 추이 API 상세 스펙.
stock_info.md - 종목정보 API (실시간순위, 기본정보, 거래원, 체결정보, 신용매매, 일별거래, 신고저가, 상하한가, 고저가근접, 가격급등락, 거래량갱신, 매물대집중, 고저PER) 상세 스펙.
misc.md - 기타 API (토큰 발급/폐기) 상세 스펙.
kiwoom_api_client_template.py - 재사용 가능한 Kiwoom API 클라이언트 템플릿. OAuth 인증, 토큰 캐싱, 주식정보(ka10001), 계좌평가(kt00004), 일별잔고(ka01690), 체결잔고(kt00005) API 구현 포함.
| API ID | 용도 | URL | 모의투자 |
|---|---|---|---|
| au10001 | 토큰 발급 | /oauth2/token | 지원 |
| ka10001 | 주식기본정보 | /api/dostk/stkinfo | 지원 |
| kt00004 | 계좌평가현황 | /api/dostk/acnt | 지원 |
| ka01690 | 일별잔고수익률 | /api/dostk/acnt | 지원 |
| kt00005 | 체결잔고 | /api/dostk/acnt | 미지원 (실전투자 전용) |
| kt10000 | 매수주문 | /api/dostk/ordr | 지원 |
| kt10001 | 매도주문 | /api/dostk/ordr | 지원 |
엔드포인트: /api/dostk/ordr
**모든 파라미터 값은 문자열(String)**이어야 합니다. 정수를 그대로 보내면 타입 불일치 에러 발생.
body = {
"dmst_stex_tp": "KRX", # 거래소 구분 (필수)
"stk_cd": "005930", # 종목코드 (필수)
"ord_qty": "4", # 주문수량 (필수, 문자열!)
"ord_uv": "0", # 주문단가 (필수, 시장가="0")
"trde_tp": "3", # 매매구분 (필수)
}
| 파라미터 | 설명 | 값 | 비고 |
|---|---|---|---|
dmst_stex_tp | 거래소 구분 | "KRX", "NXT", "SOR" | 누락 시 1511 에러 |
stk_cd | 종목코드 | "005930" | 6자리 문자열 |
ord_qty | 주문수량 | "4" | 반드시 문자열, int 시 1517 에러 |
ord_uv | 주문단가 | "0" (시장가), "50000" (지정가) | 반드시 문자열 |
trde_tp | 매매구분 | "0"=지정가, "3"=시장가, "5"=조건부지정가 |
공식 API와 다른 이름을 사용하면 필수입력 파라미터 에러 발생:
| 잘못된 이름 | 올바른 이름 | 에러 |
|---|---|---|
qty | ord_qty | 1511: 필수입력 파라미터 |
ordr_prc | ord_uv | 1511: 필수입력 파라미터 |
trd_dvsn | trde_tp | 1511: 필수입력 파라미터 |
| 파라미터 | 불필요 이유 |
|---|---|
acnt_no | OAuth 토큰에 계좌 정보 포함 |
{
"ord_no": "0362917",
"dmst_stex_tp": "KRX",
"return_code": 0,
"return_msg": "KRX 매수주문이 완료되었습니다."
}
curl ifconfig.me로 현재 IP 확인 후 등록