Skip to content

๐Ÿ“ˆ ํŒŒ์ด์ฌ ํ•œ๊ตญํˆฌ์ž์ฆ๊ถŒ REST ๊ธฐ๋ฐ˜ Trading API ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

License

Notifications You must be signed in to change notification settings

Soju06/python-kis

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

header

1. ํŒŒ์ด์ฌ์šฉ ํ•œ๊ตญํˆฌ์ž์ฆ๊ถŒ API ์†Œ๊ฐœ โœจ

ํ•œ๊ตญํˆฌ์ž์ฆ๊ถŒ์˜ ํŠธ๋ ˆ์ด๋”ฉ OPEN API ์„œ๋น„์Šค๋ฅผ ํŒŒ์ด์ฌ ํ™˜๊ฒฝ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“  ๊ฐ•๋ ฅํ•œ ์ปค๋ฎค๋‹ˆํ‹ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ž…๋‹ˆ๋‹ค.

2.0.0 ๋ฒ„์ „ ์ด์ „์˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ์—ฌ๊ธฐ, ๋ฌธ์„œ๋Š” 1, 2, 3์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

1.1. ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํŠน์ง•

๐Ÿ“ ๋ชจ๋“  ๊ฐ์ฒด์— ๋Œ€ํ•œ Type hint
  • ๋ชจ๋“  ํ•จ์ˆ˜์™€ ํด๋ž˜์Šค์— ๋Œ€ํ•ด ์ถ”์ƒํ™” ๋ฐ Typing์„ ์ ์šฉํ•˜์—ฌ, ํŒŒ์ด์ฌ์˜ ๋™์  ํƒ€์ดํ•‘์„ ๋ณด์™„ํ•ฉ๋‹ˆ๋‹ค.
  • IDE์˜ ์ž๋™์™„์„ฑ์„ 100% ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๊ณต์‹ ๋ฌธ์„œ ์—†์ด ์ •ํ™•ํ•˜๊ณ  ๋ฒ„๊ทธ ์—†๋Š” ๊ฐœ๋ฐœ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
๐Ÿ”— ๋ณต๊ตฌ ๊ฐ€๋Šฅํ•œ ์›น์†Œ์ผ“ ํด๋ผ์ด์–ธํŠธ
  • ์‹ค์‹œ๊ฐ„ ์‹œ์„ธ, ํ˜ธ๊ฐ€, ์ฒด๊ฒฐ ๋“ฑ์˜ ์‹ค์‹œ๊ฐ„ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์˜ค๋Š” ๊ณผ์ •์—์„œ ๋„คํŠธ์›Œํฌ ๋ฌธ์ œ ๋“ฑ์œผ๋กœ ์ธํ•ด ์—ฐ๊ฒฐ์ด ๋Š๊ฒผ์„ ๋•Œ, ์™„๋ฒฝํžˆ ๋ณต๊ตฌํ•  ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“ค์–ด์กŒ์Šต๋‹ˆ๋‹ค.
  • ์žฌ์—ฐ๊ฒฐ ์ด์ „์— ๋“ฑ๋ก๋œ ์กฐํšŒ๋„ ์ž๋™์œผ๋กœ ๋‹ค์‹œ ๋“ฑ๋กํ•˜์—ฌ ์œ ์‹ค์„ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค.
  • ํ•œ๊ตญํˆฌ์ž์ฆ๊ถŒ์˜ ์›น์†Œ์ผ“ ์กฐํšŒ ์‹œ์Šคํ…œ์„ ํŒŒ์ด์ฌ์˜ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ ์‹œ์Šคํ…œ๊ณผ ์™„๋ฒฝํžˆ ํ†ตํ•ฉํ•˜์—ฌ, GC์— ์˜ํ•ด ์ด๋ฒคํŠธ ๊ตฌ๋…์ด ๊ด€๋ฆฌ๋ฉ๋‹ˆ๋‹ค.
๐Ÿ–‹๏ธ ํ‘œ์ค€ ์˜์–ด ๋„ค์ด๋ฐ
  • ํ•œ๊ตญํˆฌ์ž์ฆ๊ถŒ์˜ API์˜ ๊ฒฝ์šฐ, ํ•œ๊ธ€ ๋ฐœ์Œ์ด๋‚˜ ๋น„ํ‘œ์ค€ ์•ฝ์–ด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์Šต๋‹ˆ๋‹ค.
  • ์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ๋ชจ๋“  ๊ฐ์ฒด์— ๋Œ€ํ•ด ํ‘œ์ค€ ์˜์–ด ๋„ค์ด๋ฐ์„ ์ ์šฉํ•˜์—ฌ, ์ดํ•ดํ•˜๊ธฐ ์‰ฝ๋„๋ก ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.

2. ์‚ฌ์šฉ ์„ค๋ช… โš™๏ธ

OpenAPI ์„œ๋น„์Šค ์‹ ์ฒญ ๋ฐฉ๋ฒ•
  1. ํ•œ๊ตญํˆฌ์ž์ฆ๊ถŒ ๊ณ„์ขŒ์™€ ์•„์ด๋””๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. KIS ํŠธ๋ ˆ์ด๋”ฉ ์„œ๋น„์Šค๋Š” KIS Developers ์„œ๋น„์Šค๋ฅผ ํ†ตํ•ด ์‹ ์ฒญ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

image

  1. ์„œ๋น„์Šค๋ฅผ ์‹ ์ฒญ์ด ์™„๋ฃŒ๋˜๋ฉด, ์•„๋ž˜์™€ ๊ฐ™์ด ์•ฑ ํ‚ค๋ฅผ ๋ฐœ๊ธ‰ ๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

image

2.1. ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์„ค์น˜ ๐Ÿ“ฆ

๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ํŒŒ์ด์ฌ 3.11์„ ๊ธฐ์ค€์œผ๋กœ ์ž‘์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

pip install python-kis
์‚ฌ์šฉ๋œ ๋ชจ๋“ˆ ๋ณด๊ธฐ
requests>=2.32.3
websocket-client>=1.8.0
cryptography>=43.0.0
colorlog>=6.8.2

2.2. ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์‚ฌ์šฉ ๐Ÿ“š

2.2.1. PyKis ๊ฐ์ฒด ์ƒ์„ฑ

  1. ์‹œํฌ๋ฆฟ ํ‚ค๋ฅผ ํŒŒ์ผ๋กœ ๊ด€๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ• (๊ถŒ์žฅ)

    ๋จผ์ € ์‹œํฌ๋ฆฟ ํ‚ค๋ฅผ ํŒŒ์ผ๋กœ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.

     from pykis import KisAuth
    
     auth = KisAuth(
         # HTS ๋กœ๊ทธ์ธ ID  ์˜ˆ) soju06
         id="YOUR_HTS_ID",
         # ์•ฑ ํ‚ค  ์˜ˆ) Pa0knAM6JLAjIa93Miajz7ykJIXXXXXXXXXX
         appkey="YOUR_APP_KEY",
         # ์•ฑ ์‹œํฌ๋ฆฟ ํ‚ค  ์˜ˆ) V9J3YGPE5q2ZRG5EgqnLHn7XqbJjzwXcNpvY . . .
         secretkey="YOUR_APP_SECRET",
         # ์•ฑ ํ‚ค์™€ ์—ฐ๊ฒฐ๋œ ๊ณ„์ขŒ๋ฒˆํ˜ธ  ์˜ˆ) 00000000-01
         account="00000000-01",
         # ๋ชจ์˜ํˆฌ์ž ์—ฌ๋ถ€
         virtual=False,
     )
    
     # ์•ˆ์ „ํ•œ ๊ฒฝ๋กœ์— ์‹œํฌ๋ฆฟ ํ‚ค๋ฅผ ํŒŒ์ผ๋กœ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.
     auth.save("secret.json")

    ๊ทธ ํ›„, ์ €์žฅ๋œ ์‹œํฌ๋ฆฟ ํ‚ค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ PyKis ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

    from pykis import PyKis, KisAuth
    
    # ์‹ค์ „ํˆฌ์ž์šฉ PyKis ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
    kis = PyKis("secret.json", keep_token=True)
    kis = PyKis(KisAuth.load("secret.json"), keep_token=True)
    
    # ๋ชจ์˜ํˆฌ์ž์šฉ PyKis ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
    kis = PyKis("secret.json", "virtual_secret.json", keep_token=True)
    kis = PyKis(KisAuth.load("secret.json"), KisAuth.load("virtual_secret.json"), keep_token=True)
  2. ์‹œํฌ๋ฆฟ ํ‚ค๋ฅผ ์ง์ ‘ ์ž…๋ ฅํ•˜๋Š” ๋ฐฉ๋ฒ•

    from pykis import PyKis
    
    # ์‹ค์ „ํˆฌ์ž์šฉ ํ•œ๊ตญํˆฌ์ž์ฆ๊ถŒ API๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
    kis = PyKis(
        id="soju06",  # HTS ๋กœ๊ทธ์ธ ID
        account="00000000-01",  # ๊ณ„์ขŒ๋ฒˆํ˜ธ
        appkey="PSED321z...",  # AppKey 36์ž๋ฆฌ
        secretkey="RR0sFMVB...",  # SecretKey 180์ž๋ฆฌ
        keep_token=True,  # API ์ ‘์† ํ† ํฐ ์ž๋™ ์ €์žฅ
    )
    
    # ๋ชจ์˜ํˆฌ์ž์šฉ ํ•œ๊ตญํˆฌ์ž์ฆ๊ถŒ API๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
    kis = PyKis(
        id="soju06",  # HTS ๋กœ๊ทธ์ธ ID
        account="00000000-01",  # ๋ชจ์˜ํˆฌ์ž ๊ณ„์ขŒ๋ฒˆํ˜ธ
        appkey="PSED321z...",  # ์‹ค์ „ํˆฌ์ž AppKey 36์ž๋ฆฌ
        secretkey="RR0sFMVB...",  # ์‹ค์ „ํˆฌ์ž SecretKey 180์ž๋ฆฌ
        virtual_id="soju06",  # ๋ชจ์˜ํˆฌ์ž HTS ๋กœ๊ทธ์ธ ID
        virtual_appkey="PSED321z...",  # ๋ชจ์˜ํˆฌ์ž AppKey 36์ž๋ฆฌ
        virtual_secretkey="RR0sFMVB...",  # ๋ชจ์˜ํˆฌ์ž SecretKey 180์ž๋ฆฌ
        keep_token=True,  # API ์ ‘์† ํ† ํฐ ์ž๋™ ์ €์žฅ
    )

2.2.2. ์‹œ์„ธ ์กฐํšŒ

stock.quote() ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•˜์—ฌ ๊ตญ๋‚ด์ฃผ์‹ ๋ฐ ํ•ด์™ธ์ฃผ์‹์˜ ์‹œ์„ธ๋ฅผ ์กฐํšŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

from pykis import KisQuote

# ์—”๋น„๋””์•„์˜ ์ƒํ’ˆ ๊ฐ์ฒด๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.
stock = kis.stock("NVDA")

quote: KisQuote = stock.quote()
quote: KisQuote = stock.quote(extended=True) # ์ฃผ๊ฐ„๊ฑฐ๋ž˜ ์‹œ์„ธ

# PyKis์˜ ๋ชจ๋“  ๊ฐ์ฒด๋Š” repr์„ ํ†ตํ•ด ์ฃผ์š” ๋‚ด์šฉ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
# ๋ฐ์ดํ„ฐ๋ฅผ ํ™•์ธํ•˜๋Š” ์šฉ๋„์ด๋ฏ€๋กœ ์‹ค์ œ ํ”„๋กœํผํ‹ฐ ํƒ€์ž…๊ณผ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
print(quote)
KisForeignQuote(
    symbol='NVDA',
    market='NASDAQ',
    name='์—”๋น„๋””์•„',
    sector_name='๋ฐ˜๋„์ฒด ๋ฐ ๋ฐ˜๋„์ฒด์žฅ๋น„',
    volume=1506310,
    amount=160791125,
    market_cap=2593332000000,
    indicator=KisForeignIndicator(
        eps=1.71,
        bps=2,
        per=63.88,
        pbr=54.65,
        week52_high=140.76,
        week52_low=39.2215,
        week52_high_date='2024-06-20',
        week52_low_date='2023-10-31'
    ),
    open=109.21,
    high=109.38,
    low=104.37,
    close=105.42,
    change=-3.79,
    unit=1,
    tick=0.01,
    risk='none',
    halt=False,
    overbought=False
)

2.2.3. ์ž”๊ณ  ์กฐํšŒ

account.balance() ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•˜์—ฌ ์˜ˆ์ˆ˜๊ธˆ ๋ฐ ๋ณด์œ  ์ข…๋ชฉ์„ ์กฐํšŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

from pykis import KisBalance

# ์ฃผ ๊ณ„์ขŒ ๊ฐ์ฒด๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.
account = kis.account()

balance: KisBalance = account.balance()

print(repr(balance)) # repr์„ ํ†ตํ•ด ๊ฐ์ฒด์˜ ์ฃผ์š” ๋‚ด์šฉ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
KisIntegrationBalance(
    account_number=KisAccountNumber('50113500-01'),
    deposits={
        'KRW': KisDomesticDeposit(account_number=KisAccountNumber('50113500-01'), currency='KRW', amount=2447692, exchange_rate=1),
        'USD': KisForeignPresentDeposit(account_number=KisAccountNumber('50113500-01'), currency='USD', amount=0, exchange_rate=1384.6),
    },
    stocks=[
        KisDomesticBalanceStock(account_number=KisAccountNumber('50113500-01'), market='KRX', symbol='000660', qty=14, price=192600, amount=2696400, profit=22900, profit_rate=0.856555077613615111277351786),
        KisDomesticBalanceStock(account_number=KisAccountNumber('50113500-01'), market='KRX', symbol='039200', qty=118, price=39600, amount=4672800, profit=-199500, profit_rate=-4.094575457176282248630010467)
    ],
    purchase_amount=7545800,
    current_amount=7369200,
    profit=-176600,
    profit_rate=-2.340374778022211031302181346
)

2.2.4. ๋งค๋„/๋งค์ˆ˜ ์ฃผ๋ฌธ

stock.order(), stock.buy(), stock.sell(), stock.modify(), stock.cancel() ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•˜์—ฌ ๋งค์ˆ˜/๋งค๋„ ์ฃผ๋ฌธ ๋ฐ ์ •์ •/์ทจ์†Œ๋ฅผ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

from pykis import KisOrder

# SKํ•˜์ด๋‹‰์Šค 1์ฃผ ์‹œ์žฅ๊ฐ€ ๋งค์ˆ˜ ์ฃผ๋ฌธ
order: KisOrder = hynix.buy(qty=1)
# SKํ•˜์ด๋‹‰์Šค 1์ฃผ ์ง€์ •๊ฐ€ ๋งค์ˆ˜ ์ฃผ๋ฌธ
order: KisOrder = hynix.buy(price=194700, qty=1)
# SKํ•˜์ด๋‹‰์Šค ์ „๋Ÿ‰ ์‹œ์žฅ๊ฐ€ ๋งค๋„ ์ฃผ๋ฌธ
order: KisOrder = hynix.sell()
# SKํ•˜์ด๋‹‰์Šค ์ „๋Ÿ‰ ์ง€์ •๊ฐ€ ๋งค๋„ ์ฃผ๋ฌธ
order: KisOrder = hynix.sell(price=194700)

print(order.pending) # ๋ฏธ์ฒด๊ฒฐ ์ฃผ๋ฌธ์ธ์ง€ ์—ฌ๋ถ€
print(order.pending_order.pending_qty) # ๋ฏธ์ฒด๊ฒฐ ์ˆ˜๋Ÿ‰

order: KisOrder = order.modify(price=195000) # ๋‹จ๊ฐ€ ์ •์ •
order: KisOrder = order.modify(qty=10) # ์ˆ˜๋Ÿ‰ ์ •์ •

order.cancel() # ์ฃผ๋ฌธ ์ทจ์†Œ

# ๋ฏธ์ฒด๊ฒฐ ์ฃผ๋ฌธ ์ „์ฒด ์ทจ์†Œ
for order in account.pending_orders():
    order.cancel()

2.2.4. ์‹ค์‹œ๊ฐ„ ์ฒด๊ฒฐ๊ฐ€ ์กฐํšŒ

๊ตญ๋‚ด์ฃผ์‹ ๋ฐ ํ•ด์™ธ์ฃผ์‹์˜ ์‹ค์‹œ๊ฐ„ ์ฒด๊ฒฐ๊ฐ€ ์กฐํšŒ๋Š” stock.on("price", callback) ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•˜์—ฌ ์ˆ˜์‹ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

from pykis import KisRealtimePrice, KisSubscriptionEventArgs, KisWebsocketClient, PyKis

def on_price(sender: KisWebsocketClient, e: KisSubscriptionEventArgs[KisRealtimePrice]):
    print(e.response)

ticket = hynix.on("price", on_price)

print(kis.websocket.subscriptions) # ํ˜„์žฌ ๊ตฌ๋…์ค‘์ธ ์ด๋ฒคํŠธ ๋ชฉ๋ก

input("Press Enter to exit...")

ticket.unsubscribe()
{KisWebsocketTR(id='H0STCNT0', key='000660')}
Press Enter to exit...
[08/02 13:50:42] INFO: RTC Connected to real server
[08/02 13:50:42] INFO: RTC Restoring subscriptions... H0STCNT0.000660
[08/02 13:50:42] INFO: RTC Subscribed to H0STCNT0.000660
KisDomesticRealtimePrice(market='KRX', symbol='000660', time='2024-08-02T13:50:44+09:00', price=174900, change=-18400, volume=8919304, amount=1587870362300)
KisDomesticRealtimePrice(market='KRX', symbol='000660', time='2024-08-02T13:50:44+09:00', price=174800, change=-18500, volume=8919354, amount=1587879102300)
KisDomesticRealtimePrice(market='KRX', symbol='000660', time='2024-08-02T13:50:45+09:00', price=174800, change=-18500, volume=8919358, amount=1587879801500)
KisDomesticRealtimePrice(market='KRX', symbol='000660', time='2024-08-02T13:50:45+09:00', price=174900, change=-18400, volume=8920313, amount=1588046831000)
KisDomesticRealtimePrice(market='KRX', symbol='000660', time='2024-08-02T13:50:45+09:00', price=174800, change=-18500, volume=8920319, amount=1588047879800)

[08/02 13:50:48] INFO: RTC Unsubscribed from H0STCNT0.000660

3. ํŠœํ† ๋ฆฌ์–ผ ๋ชฉ๋ก ๐Ÿ“–

4. Changelog โœจ

ver 2.0.3

ver 2.0.2

  • KisBalance, KisChart ๋“ฑ __iter__ ๋ฉ”์„œ๋“œ์˜ ๋ฐ˜ํ™˜ ํƒ€์ž…์ด ๋ˆ„๋ฝ๋˜์–ด์žˆ๋Š” ๋ฒ„๊ทธ๋ฅผ ์ˆ˜์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ์ฃผ๋ฌธ ์ˆ˜๋Ÿ‰์„ ์ž…๋ ฅํ•  ๋•Œ Decimal ํƒ€์ž… ์ด์™ธ์˜ int, float ํƒ€์ž…์„ ์ž…๋ ฅํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ฐœ์„ ํ–ˆ์Šต๋‹ˆ๋‹ค.

ver 2.0.1

  • ์ดˆ๊ธฐ ์›น์†Œ์ผ“ ์ด๋ฒคํŠธ ๊ตฌ๋…์‹œ ํด๋ผ์ด์–ธํŠธ ์ ‘์† ํ›„ ๊ตฌ๋…์„ ์š”์ฒญํ•˜๋Š” ์ฝ”๋“œ์—์„œ _connected_event๊ฐ€ set ๋˜์–ด์žˆ์ง€ ์•Š์•„, ์š”์ฒญ์ด ๋ฌด์‹œ๋˜๋Š” ๋ฒ„๊ทธ๋ฅผ ์ˆ˜์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.

ver 2.0.0

  • ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์™„์ „ํžˆ ์ƒˆ๋กญ๊ฒŒ ๋ณ€๊ฒฝ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
  • ๋ชจ๋“  ๊ฐ์ฒด์— ๋Œ€ํ•œ ์ถ”์ƒํ™” ๋ฐ ๋„ค์ด๋ฐ์ด ๋ณ€๊ฒฝ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
  • ํ•œ๊ตญํˆฌ์ž์ฆ๊ถŒ์˜ ๊ตญ๋‚ด, ํ•ด์™ธ API ๊ตฌ๋ถ„ ์—†์ด ๋™์ผํ•œ ์ธํ„ฐํŽ˜์ด์Šค๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์‹ค์‹œ๊ฐ„ ์‹œ์„ธ ์กฐํšŒ๋Š” ์ƒˆ๋กœ์šด ์ด๋ฒคํŠธ ์‹œ์Šคํ…œ์œผ๋กœ ๋ณ€๊ฒฝ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
  • ๊ณ„์ขŒ ๋ฐ ์ƒํ’ˆ Scope ํ™œ์šฉ์ด ๊ทน๋Œ€ํ™”๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

ver 1.0.6

  • ์ƒํ’ˆ๊ธฐ๋ณธ์กฐํšŒ๊ฐ€ ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

  • ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ๋ถ„๋ฆฌํ•˜์˜€์Šต๋‹ˆ๋‹ค. ๊ฐ๊ฐ์˜ ํŒŒ์ผ์— ๋‚˜๋‰˜์–ด์žˆ๋˜ Version, ์ ‘์† URL, API Rate Limit ๋“ฑ์˜ ์ƒ์ˆ˜ ๋ฐ์ดํ„ฐ๋ฅผ __env__.py๋กœ ์˜ฎ๊ฒผ์Šต๋‹ˆ๋‹ค.

  • ์˜ˆ์™ธ๊ตฌ์กฐ ๋ณ€๊ฒฝ ๊ธฐ์กด HTTP Error, RT_CD Error๋ฅผ ๋ชจ๋‘ ValueError๋กœ ์ฒ˜๋ฆฌํ•˜๋˜ ๊ตฌ์กฐ์—์„œ ๊ฐ๊ฐ์˜ KisHTTPError, KisAPIError ์˜ˆ์™ธ ๊ฐ์ฒด๋กœ ๋‚˜๋ˆ„์—ˆ๊ณ , rt_cd, msg_cd ๋“ฑ์˜ ๋ณ€์ˆ˜๋ฅผ ์˜ˆ์™ธ ๊ฐ์ฒด์—์„œ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ณ€๊ฒฝํ•˜์˜€์Šต๋‹ˆ๋‹ค.

  • ์—‘์„ธ์Šคํ† ํฐ ๋ฐœ๊ธ‰ Thread Safe ์—‘์„ธ์Šค ํ† ํฐ์ด ๋ฐœ๊ธ‰๋˜์–ด์žˆ์ง€ ์•Š์€ ์ƒํƒœ์—์„œ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ๋กœ KisAccessToken.ensure() ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด Thread Lock ๋˜์ง€ ์•Š๊ณ  ๋‹ค์ˆ˜๊ฐ€ KisAccessToken.issue()๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜์˜€์Šต๋‹ˆ๋‹ค.

ver 1.0.5

  • RTClient์—์„œ ์›น์†Œ์ผ“ ์—ฐ๊ฒฐ์ด ๋Š์–ด์กŒ์„ ๋•Œ, ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ๊ฐ€ ์ž˜๋ชป๋˜๋Š” ๋ฒ„๊ทธ๋ฅผ ์ˆ˜์ •ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

  • RTClient์—์„œ ์žฌ์—ฐ๊ฒฐ์‹œ ์‹ค์‹œ๊ฐ„ ์กฐํšŒ๊ฐ€ ๋ณต๊ตฌ๋˜์ง€ ์•Š๋Š” ๋ฒ„๊ทธ๋ฅผ ์ˆ˜์ •ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

  • ํœด์žฅ์ผ ์กฐํšŒ๊ฐ€ ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

  • ํ•ด์™ธ ์ฃผ์‹ ์ฃผ๋ฌธ์ด ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

  • ํ•ด์™ธ ๋ฏธ์ฒด๊ฒฐ ์กฐํšŒ๊ฐ€ ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

ver 1.0.4

ver 1.0.3

ver 1.0.2

  • API ์ดˆ๋‹น ์š”์ฒญ ์ œํ•œ์„ ๋„˜์–ด๋ฒ„๋ฆฌ๋Š” ๋ฒ„๊ทธ๋ฅผ ์ˆ˜์ •ํ•˜์˜€์Šต๋‹ˆ๋‹ค.
  • period_price ์‘๋‹ต ๋ฐ์ดํ„ฐ์˜ stck_fcam๊ฐ’ float์œผ๋กœ ๋ณ€๊ฒฝํ•˜์˜€์Šต๋‹ˆ๋‹ค.
  • utils.KRXMarketOpen ๊ณตํœด์ผ ๋ฐ์ดํ„ฐ๊ฐ€ 1๊ฐœ์ธ ๊ฒฝ์šฐ ์˜ค๋ฅ˜ ๋ฐœ์ƒํ•˜๋Š” ๋ฒ„๊ทธ ์ˆ˜์ •ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

License

MIT