Skip to content

LaytonAI/kis-wrapper

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

25 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

KIS Wrapper

ํ•œ๊ตญํˆฌ์ž์ฆ๊ถŒ Open API Python SDK

ํŠน์ง•

  • ๊ฐ„๊ฒฐํ•œ ํ•จ์ˆ˜ ๊ธฐ๋ฐ˜ API
  • ๊ตญ๋‚ด/ํ•ด์™ธ์ฃผ์‹ ์ง€์›
  • ์‹ค์‹œ๊ฐ„ WebSocket
  • ๋ชจ์˜ํˆฌ์ž/์‹ค์ „ ํ™˜๊ฒฝ ์ „ํ™˜
  • ์ž๋™ ํ† ํฐ ๊ด€๋ฆฌ

์„ค์น˜

pip install kis

๋˜๋Š” ๊ฐœ๋ฐœ ํ™˜๊ฒฝ:

git clone https://github.com/your-repo/kis-wrapper
cd kis-wrapper
uv sync

๋น ๋ฅธ ์‹œ์ž‘

ํ™˜๊ฒฝ ์„ค์ •

# .env
KIS_APP_KEY=your_app_key
KIS_APP_SECRET=your_app_secret
KIS_ACCOUNT=12345678-01

๊ธฐ๋ณธ ์‚ฌ์šฉ

import os
from kis import KIS, domestic

kis = KIS(
    app_key=os.environ["KIS_APP_KEY"],
    app_secret=os.environ["KIS_APP_SECRET"],
    account=os.environ["KIS_ACCOUNT"],
    env="paper",  # ๋ชจ์˜ํˆฌ์ž
)

# ์‚ผ์„ฑ์ „์ž ํ˜„์žฌ๊ฐ€
p = domestic.price(kis, "005930")
print(f"ํ˜„์žฌ๊ฐ€: {p['stck_prpr']}์›")

# ํ˜ธ๊ฐ€
ob = domestic.orderbook(kis, "005930")

# ์ผ๋ด‰ (์ตœ๊ทผ 30์ผ)
candles = domestic.daily(kis, "005930")

์ฃผ๋ฌธ

# ๋งค์ˆ˜ (์ง€์ •๊ฐ€)
order = domestic.buy(kis, "005930", qty=10, price=70000)
print(f"์ฃผ๋ฌธ๋ฒˆํ˜ธ: {order['ODNO']}")

# ๋งค์ˆ˜ (์‹œ์žฅ๊ฐ€)
order = domestic.buy(kis, "005930", qty=10)

# ๋งค๋„
order = domestic.sell(kis, "005930", qty=5, price=72000)

# ์ฃผ๋ฌธ ์ทจ์†Œ
domestic.cancel(kis, order_no="0001234567", qty=5)

# ์ฃผ๋ฌธ ์ •์ •
domestic.modify(kis, order_no="0001234567", qty=10, price=71000)

๊ณ„์ขŒ ์กฐํšŒ

# ์ž”๊ณ  (์˜ˆ์ˆ˜๊ธˆ + ๋ณด์œ ์ข…๋ชฉ)
bal = domestic.balance(kis)

# ๋ณด์œ ์ข…๋ชฉ๋งŒ
positions = domestic.positions(kis)
for p in positions:
    print(f"{p['prdt_name']}: {p['hldg_qty']}์ฃผ")

# ํŠน์ • ์ข…๋ชฉ ํฌ์ง€์…˜
pos = domestic.position(kis, "005930")
if pos:
    print(f"์ˆ˜์ต๋ฅ : {pos['profit_rate']:.2f}%")

# ๋ฏธ์ฒด๊ฒฐ ์ฃผ๋ฌธ
pending = domestic.pending_orders(kis)

ํ•ด์™ธ์ฃผ์‹

from kis import overseas

# ์• ํ”Œ ํ˜„์žฌ๊ฐ€
p = overseas.price(kis, "AAPL", "NAS")
print(f"AAPL: ${p['last']}")

# ๋งค์ˆ˜ (์ง€์ •๊ฐ€)
order = overseas.buy(kis, "AAPL", "NAS", qty=1, price=150.00)

# ๋งค์ˆ˜ (์‹œ์žฅ๊ฐ€ - ๋ฏธ๊ตญ๋งŒ ์ง€์›)
order = overseas.buy(kis, "AAPL", "NAS", qty=1)

# ์ž”๊ณ  ์กฐํšŒ
bal = overseas.balance(kis)  # ์ „์ฒด
bal = overseas.balance(kis, "NAS")  # ๋‚˜์Šค๋‹ฅ๋งŒ

# ํ™˜์œจ
rate = overseas.exchange_rate(kis)

๊ฑฐ๋ž˜์†Œ ์ฝ”๋“œ

์ฝ”๋“œ ๊ฑฐ๋ž˜์†Œ
NYS ๋‰ด์š• (NYSE)
NAS ๋‚˜์Šค๋‹ฅ (NASDAQ)
AMS ์•„๋ฉ•์Šค (AMEX)
HKS ํ™์ฝฉ
SHS ์ƒํ•ด
SZS ์‹ฌ์ฒœ
TSE ๋„์ฟ„
HNX ํ•˜๋…ธ์ด
HSX ํ˜ธ์น˜๋ฏผ

์‹ค์‹œ๊ฐ„ ๋ฐ์ดํ„ฐ (WebSocket)

import asyncio
from kis import KIS, WSClient

async def main():
    kis = KIS(app_key, app_secret, account, env="paper")
    ws = WSClient(kis)

    async def on_price(data):
        print(f"{data['symbol']}: {data['price']:,}์› (๊ฑฐ๋ž˜๋Ÿ‰: {data['volume']})")

    await ws.subscribe("H0STCNT0", ["005930", "000660"], on_price)

    try:
        await ws.run()
    except KeyboardInterrupt:
        await ws.close()

asyncio.run(main())

TR ID ๋ชฉ๋ก

TR ID ์„ค๋ช…
H0STCNT0 ๊ตญ๋‚ด์ฃผ์‹ ์‹ค์‹œ๊ฐ„์ฒด๊ฒฐ
H0STASP0 ๊ตญ๋‚ด์ฃผ์‹ ์‹ค์‹œ๊ฐ„ํ˜ธ๊ฐ€
H0STCNI0 ์ฒด๊ฒฐํ†ต๋ณด
HDFSCNT0 ํ•ด์™ธ์ฃผ์‹ ์‹ค์‹œ๊ฐ„์ฒด๊ฒฐ

ํ™˜๊ฒฝ ์ „ํ™˜

# ๋ชจ์˜ํˆฌ์ž -> ์‹ค์ „
kis_prod = kis.switch("prod")

# ๋˜๋Š” ์ฒ˜์Œ๋ถ€ํ„ฐ ์‹ค์ „
kis = KIS(app_key, app_secret, account, env="prod")

๊ณ„์‚ฐ ์œ ํ‹ธ๋ฆฌํ‹ฐ

from kis import calc

# ์ˆ˜์ต๋ฅ 
rate = calc.profit_rate(buy_price=70000, current_price=75000)
print(f"์ˆ˜์ต๋ฅ : {float(rate) * 100:.2f}%")

# ์ˆ˜์ต๊ธˆ
profit = calc.profit_amount(70000, 75000, qty=10)

# ํ‰๊ท ๋‹จ๊ฐ€
orders = [{"price": 70000, "qty": 10}, {"price": 72000, "qty": 5}]
avg = calc.avg_price(orders)

์Šค๋ƒ…์ƒท

from kis import snapshot

# ํ˜„์žฌ ์ƒํƒœ ์ €์žฅ
data = snapshot.snapshot(kis, "005930")
snapshot.save(data, "snapshots/005930.json")

# ๋กœ๋“œ ๋ฐ ๊ฒ€์ฆ
loaded = snapshot.load("snapshots/005930.json")
assert snapshot.verify(loaded)

API ๋ ˆํผ๋Ÿฐ์Šค

KIS ํด๋ž˜์Šค

KIS(app_key: str, app_secret: str, account: str, env: Env = "paper")
์†์„ฑ/๋ฉ”์„œ๋“œ ์„ค๋ช…
is_paper ๋ชจ์˜ํˆฌ์ž ์—ฌ๋ถ€
switch(env) ํ™˜๊ฒฝ ์ „ํ™˜
close() ์—ฐ๊ฒฐ ์ข…๋ฃŒ

domestic ๋ชจ๋“ˆ

ํ•จ์ˆ˜ ์„ค๋ช…
price(kis, symbol) ํ˜„์žฌ๊ฐ€ ์กฐํšŒ
orderbook(kis, symbol) ํ˜ธ๊ฐ€ ์กฐํšŒ
daily(kis, symbol, period="D") ์ผ/์ฃผ/์›”๋ด‰
buy(kis, symbol, qty, price=None) ๋งค์ˆ˜
sell(kis, symbol, qty, price=None) ๋งค๋„
cancel(kis, order_no, qty) ์ทจ์†Œ
modify(kis, order_no, qty, price) ์ •์ •
balance(kis) ์ž”๊ณ  ์กฐํšŒ
positions(kis) ๋ณด์œ ์ข…๋ชฉ
orders(kis, start_date, end_date) ์ฃผ๋ฌธ๋‚ด์—ญ
pending_orders(kis) ๋ฏธ์ฒด๊ฒฐ
position(kis, symbol) ์ข…๋ชฉ๋ณ„ ํฌ์ง€์…˜
sell_all(kis, symbol) ์ „๋Ÿ‰ ๋งค๋„
cancel_remaining(kis, order_no) ๋ฏธ์ฒด๊ฒฐ ์ „๋Ÿ‰ ์ทจ์†Œ

overseas ๋ชจ๋“ˆ

ํ•จ์ˆ˜ ์„ค๋ช…
price(kis, symbol, exchange) ํ˜„์žฌ๊ฐ€ ์กฐํšŒ
daily(kis, symbol, exchange, period="D") ๊ธฐ๊ฐ„๋ณ„ ์‹œ์„ธ
buy(kis, symbol, exchange, qty, price=None) ๋งค์ˆ˜
sell(kis, symbol, exchange, qty, price=None) ๋งค๋„
cancel(kis, exchange, order_no, qty) ์ทจ์†Œ
balance(kis, exchange=None) ์ž”๊ณ  ์กฐํšŒ
exchange_rate(kis) ํ™˜์œจ ์กฐํšŒ

WSClient ํด๋ž˜์Šค

WSClient(kis: KIS, max_retries: int = 5, retry_delay: float = 1.0)
๋ฉ”์„œ๋“œ ์„ค๋ช…
connect() WebSocket ์—ฐ๊ฒฐ
subscribe(tr_id, symbols, callback) ๊ตฌ๋…
unsubscribe(tr_id, symbols) ๊ตฌ๋… ํ•ด์ œ
run() ๋ฉ”์‹œ์ง€ ์ˆ˜์‹  ๋ฃจํ”„
close() ์—ฐ๊ฒฐ ์ข…๋ฃŒ

๊ฐœ๋ฐœ

# ํ…Œ์ŠคํŠธ
uv run pytest

# ์ปค๋ฒ„๋ฆฌ์ง€
uv run pytest --cov=kis

# ๋ฆฐํŠธ
uv run ruff check kis/

# ํฌ๋งท
uv run ruff format kis/

๋ผ์ด์„ ์Šค

MIT License

About

Korea Investment & Securities API wrapper for Python

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors