Skip to content

sharebook-kr/pyupbit

Folders and files

NameName
Last commit message
Last commit date

Latest commit

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

Repository files navigation

pyupbit

Python Wrapper for Upbit API

Documentation

https://pyupbit.readthedocs.io/en/latest/

Installation

ํŒŒ์ด์ฌ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์œผ๋กœ ์ตœ์‹  ๋ฒ„์ „์˜ Anaconda๋ฅผ ์„ค์น˜ํ•˜์„ธ์š”. (Python3 ๋ฒ„์ „์šฉ)

pip install pyupbit

pyjwt ๋ชจ๋“ˆ์„ ํ•„์š”๋กœ ํ•ฉ๋‹ˆ๋‹ค. (pyjwt >= 2.0)

pip install pyjwt

Import

import pyupbit

Quotation API

  • Websocket์€ ์ดˆ๋‹น 5ํšŒ, ๋ถ„๋‹น 100ํšŒ ์—ฐ๊ฒฐ ์š”์ฒญํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์ข…๋ชฉ, ์บ”๋“ค, ์ฒด๊ฒฐ, ํ‹ฐ์ปค, ํ˜ธ๊ฐ€ API๋Š” ๋ถ„๋‹น 600ํšŒ, ์ดˆ๋‹น 10ํšŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

์•”ํ˜ธํ™”ํ ๋ชฉ๋ก

get_tickers ํ•จ์ˆ˜๋Š” ์—…๋น„ํŠธ๊ฐ€ ์ง€์›ํ•˜๋Š” ๋ชจ๋“  ์•”ํ˜ธํ™”ํ ๋ชฉ๋ก์„ ์–ป์–ด์˜ต๋‹ˆ๋‹ค.

print(pyupbit.get_tickers())
['KRW-BTC', 'KRW-DASH', 'KRW-ETH', 'BTC-NEO', 'BTC-ETH', 'BTC-LTC', ... ]

์—…๋น„ํŠธ๊ฐ€ ์ง€์›ํ•˜๋Š” ์•”ํ˜ธํ™”ํ ๋ชฉ๋ก ์ค‘ ํŠน์ • ์‹œ์žฅ(fiat)์— ๋งค๋งค๊ฐ€ ๊ฐ€๋Šฅํ•œ ๋ชฉ๋ก๋งŒ ์–ป์–ด์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. KRW/BTC/USDT ์‹œ์žฅ์„ ์กฐํšŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

print(pyupbit.get_tickers(fiat="KRW"))
['KRW-BTC', 'KRW-DASH', 'KRW-ETH', 'KRW-NEO', 'KRW-MTL', 'KRW-LTC', ...]

์ตœ๊ทผ ์ฒด๊ฒฐ๊ฐ€๊ฒฉ

get_current_price ํ•จ์ˆ˜๋Š” ์•”ํ˜ธํ™”ํ์˜ ํ˜„์žฌ๊ฐ€๋ฅผ ์–ป์–ด์˜ต๋‹ˆ๋‹ค. ํ•จ์ˆ˜๋กœ ํ‹ฐ์ปค๋ฅผ ๋„ฃ์–ด์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค.

print(pyupbit.get_current_price("KRW-BTC"))

float ํƒ€์ž…์˜ ํ˜„์žฌ๊ฐ€๊ฐ€ ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค.

8392000.0

๋ฆฌ์ŠคํŠธ์— ์—ฌ๋Ÿฌ ๊ฐœ์˜ ํ‹ฐ์ปค๋ฅผ ์ž…๋ ฅํ•ด ํ•œ ๋ฒˆ์— ํ˜„์žฌ๊ฐ€๋ฅผ ์กฐํšŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

print(pyupbit.get_current_price(["KRW-BTC", "KRW-XRP"]))

์—ฌ๋Ÿฌ ์ข…๋ชฉ์„ ์กฐํšŒํ•œ ๊ฒฝ์šฐ ๋”•์…”๋„ˆ๋ฆฌ๋กœ ํ˜„์žฌ๊ฐ€๋ฅผ ๋ฆฌํ„ดํ•ฉ๋‹ˆ๋‹ค.

{'KRW-BTC': 8300000.0, 'KRW-XRP': 511.0}

get_current_price ํ•จ์ˆ˜๋Š” ์ตœ๋Œ€ 100๊ฐœ์˜ ์•”ํ˜ธํ™”ํ๋ฅผ ์กฐํšŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 100๊ฐœ ์ด์ƒ์ผ ๊ฒฝ์šฐ ๋ถ„ํ• ํ•ด์„œ ๋ฐ˜๋ณต ์กฐํšŒํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ฐจํŠธ ๋ฐ์ดํ„ฐ

get_ohlcv ํ•จ์ˆ˜๋Š” ๊ณ ๊ฐ€/์‹œ๊ฐ€/์ €๊ฐ€/์ข…๊ฐ€/๊ฑฐ๋ž˜๋Ÿ‰์„ DataFrame์œผ๋กœ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

df = pyupbit.get_ohlcv("KRW-BTC")
print(df.tail())

๋‚ ์งœ๊ฐ€ ์˜ค๋ฆ„์ฐจ์ˆœ์œผ๋กœ ์ •๋ ฌ๋ผ ์ตœ๊ทผ ๋‚ ์งœ๊ฐ€ ๋งˆ์ง€๋ง‰์— ์œ„์น˜ํ•ฉ๋‹ˆ๋‹ค.

2021-03-21 09:00:00  67849000.0  68715000.0  65451000.0  67120000.0   8097.428878
2021-03-22 09:00:00  67064000.0  68380000.0  64345000.0  64725000.0   8366.410551
2021-03-23 09:00:00  64728000.0  66279000.0  63000000.0  65458000.0   9961.040596
2021-03-24 09:00:00  65458000.0  68370000.0  64500000.0  64777000.0  11366.404524
2021-03-25 09:00:00  64777000.0  65305000.0  63319000.0  64257000.0   2770.703203

count ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” ์กฐํšŒ ๊ฐฏ์ˆ˜๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ์ตœ๊ทผ ์˜์—…์ผ ๋ถ€ํ„ฐ ์ด์ „ count๋งŒํผ์˜ ์ด์ „ ์˜์—…์ผ๊นŒ์ง€ ์กฐํšŒํ•ฉ๋‹ˆ๋‹ค. count ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์ž…๋ ฅํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ default value๋Š” 200์ž…๋‹ˆ๋‹ค.

df = pyupbit.get_ohlcv("KRW-BTC", count=5)
print(len(df))

์œ„ ์ฝ”๋“œ๋Š” ์ตœ๊ทผ ์˜์—…์ผ ๋ถ€ํ„ฐ ๊ณผ๊ฑฐ 5๊ฐœ์˜ ๋ฐ์ดํ„ฐ๊ฐ€ ์กฐํšŒ๋ฉ๋‹ˆ๋‹ค.

5

get_ohlcv ํ•จ์ˆ˜๋Š” ์›น ์„œ๋ฒ„๋กœ 200๊ฐœ์”ฉ ๋ฐ์ดํ„ฐ๋ฅผ ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค. 200๊ฐœ ์ด์ƒ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์š”์ฒญํ•œ๋‹ค๋ฉด 0.1(default) ์ฃผ๊ธฐ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ง‘ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค๋ฅธ API์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ์กฐํšŒ ์ฃผ๊ธฐ(period)๋ฅผ ๋Š˜๋ ค์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋•Œ period ์˜ต์…˜์„ ์‚ฌ์šฉํ•ด์„œ ์ฃผ๊ธฐ๋ฅผ ์ดˆ(second) ๋‹จ์œ„๋กœ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์กฐํšŒํ•˜๋Š” ๋ฐ์ดํ„ฐ์˜ ๊ฐฏ์ˆ˜๊ฐ€ 200๊ฐœ ์ดํ•˜๋ผ๋ฉด period ์˜ต์…˜์€ ๋ฌด์‹œ๋ฉ๋‹ˆ๋‹ค.

df = pyupbit.get_ohlcv("KRW-BTC", count=600, period=1)

interval ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” ์กฐํšŒ๋‹จ์œ„๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ํŒŒ๋ผ๋ฏธํ„ฐ์—๋Š” ๋‹ค์Œ ๊ฐ’์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • day/minute1/minute3/minute5/minute10/minute15/minute30/minute60/minute240/week/month
print(pyupbit.get_ohlcv("KRW-BTC", interval="day")              # ์ผ๋ด‰ ๋ฐ์ดํ„ฐ (5์ผ)
print(pyupbit.get_ohlcv("KRW-BTC", interval="minute1"))         # ๋ถ„๋ด‰ ๋ฐ์ดํ„ฐ
print(pyupbit.get_ohlcv("KRW-BTC", interval="week"))            # ์ฃผ๋ด‰ ๋ฐ์ดํ„ฐ

to ํŒŒ๋ผ๋ฏธํ„ฐ์— ์ž…๋ ฅ๋œ ์ด์ „ ๋‹จ์œ„(interval)๊นŒ์ง€์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ์ดํ„ฐํ”„๋ ˆ์ž„์œผ๋กœ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋‹ค์Œ ์ฝ”๋“œ๋Š” 2020-10-10์ผ ๋ณด๋‹ค ํ•˜๋ฃจ ์ „์ธ 2020-10-09์„ ๊นŒ์ง€์˜ 200๊ฐœ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•ฉ๋‹ˆ๋‹ค. ๋‹จ์œ„๋ฅผ ์„ค์ •ํ•˜์ง€ ์•Š์•˜์œผ๋‹ˆ ๋‹จ์œ„๋Š” ์ผ๋ด‰์ž…๋‹ˆ๋‹ค.

print(pyupbit.get_ohlcv("KRW-BTC", to="20201010"))

interval์„ minute1๋กœ ์ง€์ •ํ•œ ๊ฒฝ์šฐ 2020-10-10 ๋ณด๋‹ค 1๋ถ„ ์ด์ „ (2020-10-09 23:59:00)๊นŒ์ง€์˜ 200๊ฐœ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

print(pyupbit.get_ohlcv("KRW-BTC", interval="minute1", to="20201010"))

๊ธฐ์ค€ ์‹œ๊ฐ„ ๋‹จ์œ„๋กœ shift๋œ ์ผ๋ด‰์„ ๊ณ„์‚ฐํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ) 2019-06-01 12:00:00 ~ 2019-06-02 11:59:59

print(pyupbit.get_daily_ohlcv_from_base("KRW-BTC", base=12))

์˜ˆ) 2019-06-01 13:00:00 ~ 2019-06-02 12:59:59

print(pyupbit.get_daily_ohlcv_from_base("KRW-BTC", base=13))

๋งค์ˆ˜/๋งค๋„ ํ˜ธ๊ฐ€

get_orderbook ํ•จ์ˆ˜๋Š” ๋งค์ˆ˜/๋งค๋„ ํ˜ธ๊ฐ€ ์ •๋ณด๋ฅผ ์กฐํšŒํ•ฉ๋‹ˆ๋‹ค.

print(pyupbit.get_orderbook(ticker="KRW-BTC"))

๋ฆฌ์ŠคํŠธ ์•ˆ์— ๋”•์…”๋„ˆ๋ฆฌ๋กœ ํ˜ธ๊ฐ€์ •๋ณด๊ฐ€ ๋“ค์–ด์žˆ์Šต๋‹ˆ๋‹ค.

  • market : ์•”ํ˜ธํ™”ํ ํ‹ฐ์ปค
  • timestamp : ์กฐํšŒ์‹œ๊ฐ„ (๋‹จ์œ„ ms)
  • orderbook_units : ๋งค๋„ํ˜ธ๊ฐ€/๋งค์ˆ˜ํ˜ธ๊ฐ€ ์ •๋ณด
[{'market': 'KRW-BTC', 'timestamp': 1532118943687, 'total_ask_size': 17.08116346, 'total_bid_size': 3.07150192, 'orderbook_units': [{'ask_price': 8390000.0, 'bid_price': 8389000.0, 'ask_size': 3.16057415, 'bid_size': 0.5515136}, {'ask_price': 8392000.0, 'bid_price': 8387000.0, 'ask_size': 0.71247596, 'bid_size': 0.95157819}, {'ask_price': 8393000.0, 'bid_price': 8386000.0, 'ask_size': 3.70536818, 'bid_size': 0.15824907}, {'ask_price': 8398000.0, 'bid_price': 8385000.0, 'ask_size': 0.00481809, 'bid_size': 0.00119147}, {'ask_price': 8399000.0, 'bid_price': 8383000.0, 'ask_size': 1.1228337, 'bid_size': 0.05}, {'ask_price': 8400000.0, 'bid_price': 8380000.0, 'ask_size': 0.48354827, 'bid_size': 0.00613734}, {'ask_price': 8401000.0, 'bid_price': 8375000.0, 'ask_size': 0.00433629, 'bid_size': 0.05}, {'ask_price': 8402000.0, 'bid_price': 8374000.0, 'ask_size': 2.7434153, 'bid_size': 0.32104953}, {'ask_price': 8420000.0, 'bid_price': 8373000.0, 'ask_size': 0.0028, 'bid_size': 0.5010063}, {'ask_price': 8428000.0, 'bid_price': 8370000.0, 'ask_size': 5.14099352, 'bid_size': 0.48077642}]}]

ticker ํŒŒ๋ผ๋ฏธํ„ฐ์— ๋ฆฌ์ŠคํŠธ๋กœ ํ‹ฐ์ปค๋ฅผ ๋„ฃ์œผ๋ฉด, ํ•œ ๋ฒˆ์— ์—ฌ๋Ÿฌ ์ข…๋ชฉ์˜ ํ˜ธ๊ฐ€๋ฅผ ์กฐํšŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

print(pyupbit.get_orderbook(ticker=["KRW-BTC", "KRW-XRP"]))

Exchange API

์ฃผ๋ฌธ์€ ์ดˆ๋‹น 8ํšŒ, ๋ถ„๋‹น 200ํšŒ / ์ฃผ๋ฌธ ์™ธ ์š”์ฒญ์€ ์ดˆ๋‹น 30ํšŒ, ๋ถ„๋‹น 900ํšŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

๋กœ๊ทธ์ธ

Access Key์™€ Sercret Key๋ฅผ ์‚ฌ์šฉํ•ด์„œ Upbit ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์›นํŽ˜์ด์ง€์—์„œ ๋กœ๊ทธ์ธํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

import pyupbit

access = "73kVqowGQOGEjdR31221j31j2ifekjkgjekgjekg"          # ๋ณธ์ธ ๊ฐ’์œผ๋กœ ๋ณ€๊ฒฝ
secret = "egjekgj3iekeEEkej3i3j3iejjwiEejiejeEeijg"          # ๋ณธ์ธ ๊ฐ’์œผ๋กœ ๋ณ€๊ฒฝ
upbit = pyupbit.Upbit(access, secret)

์ž”๊ณ  ์กฐํšŒ

get_balance ๋ฉ”์„œ๋“œ๋Š” ์ž…๋ ฅ๋ฐ›์€ ํ‹ฐ์ปค์˜ ๋ณด์œ  ์ˆ˜๋Ÿ‰ ์ •๋ณด๋ฅผ ์กฐํšŒํ•ฉ๋‹ˆ๋‹ค.

print(upbit.get_balance("KRW-XRP"))     # KRW-XRP ์กฐํšŒ
print(upbit.get_balance("KRW"))         # ๋ณด์œ  ํ˜„๊ธˆ ์กฐํšŒ

get_balances ๋ฉ”์„œ๋“œ๋Š” ๋ณด์œ  ์ค‘์ธ ๋ชจ๋“  ์•”ํ˜ธํ™”ํ์˜ ์ž”๊ณ  ๋ฐ ๋‹จ๊ฐ€ ์ •๋ณด๋ฅผ ๋”•์…”๋„ˆ๋ฆฌ๋กœ ์กฐํšŒํ•ฉ๋‹ˆ๋‹ค.

print(upbit.get_balances())
[{'currency': 'KRW',
  'balance': '0.34689181',
  'locked': '0.0',
  'avg_buy_price': '0',
  'avg_buy_price_modified': True,
  'unit_currency': 'KRW'},
 {'currency': 'BTC',
  'balance': '0.00174304',
  'locked': '0.0',
  'avg_buy_price': '64387000',
  'avg_buy_price_modified': False,
  'unit_currency': 'KRW'},]

์ง€์ •๊ฐ€ ๋งค์ˆ˜/๋งค๋„ ์ฃผ๋ฌธ

์ง€์ •ํ•œ ๊ฐ€๊ฒฉ์— ์ฃผ๋ฌธ์„ ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ์€ ์›ํ™” ์‹œ์žฅ์— ๋ฆฌํ”Œ์„ 600์›์— 20๊ฐœ ๋งค๋„ ํ•ฉ๋‹ˆ๋‹ค.

# ๋งค๋„
print(upbit.sell_limit_order("KRW-XRP", 600, 20))

์ฃผ๋ฌธ ์ •๋ณด๊ฐ€ ๋”•์…”๋„ˆ๋ฆฌ๋กœ ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค. uuid๋Š” ์ฃผ๋ฌธ์— ๋Œ€ํ•œ ๊ณ ์œณ๊ฐ’์œผ๋กœ ์ด๋ฅผ ์‚ฌ์šฉํ•ด ์ถ”ํ›„ ์ฃผ๋ฌธ์„ ์ทจ์†Œํ•˜๊ฑฐ๋‚˜ ์ •์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

{'uuid': '0bcf0916-a7f5-49ed-80a9-a45e9e190cd3',
 'side': 'ask',
 'ord_type': 'limit',
 'price': '600.0',
 'state': 'wait',
 'market': 'KRW-XRP',
 'created_at': '2021-03-21T15:24:11+09:00',
 'volume': '20.0',
 'remaining_volume': '20.0',
 'reserved_fee': '0.0',
 'remaining_fee': '0.0',
 'paid_fee': '0.0',
 'locked': '20.0',
 'executed_volume': '0.0',
 'trades_count': 0}

๋‹ค์Œ์€ ์›ํ™” ์‹œ์žฅ์— ๋ฆฌํ”Œ์„ 613์›์— 10๊ฐœ ๋งค์ˆ˜ ํ•ฉ๋‹ˆ๋‹ค.

# ๋งค์ˆ˜
print(upbit.buy_limit_order("KRW-XRP", 613, 10))
{'uuid': '1907dcdc-2b96-4d85-9963-866f7aa220cd',
 'side': 'bid',
 'ord_type': 'limit',
 'price': '613.0',
 'state': 'wait',
 'market': 'KRW-XRP',
 'created_at': '2021-03-21T15:10:32+09:00',
 'volume': '10.0',
 'remaining_volume': '10.0',
 'reserved_fee': '3.065',
 'remaining_fee': '3.065',
 'paid_fee': '0.0',
 'locked': '6133.065',
 'executed_volume': '0.0',
 'trades_count': 0}

์‹œ์žฅ๊ฐ€ ๋งค์ˆ˜/๋งค๋„ ์ฃผ๋ฌธ

์‹œ์žฅ๊ฐ€ ๋งค์ˆ˜๋Š” ์ตœ์šฐ์„  ๋งค๋„ํ˜ธ๊ฐ€์— ์ฆ‰์‹œ ๋งค์ˆ˜ํ•ฉ๋‹ˆ๋‹ค. buy_market_order ๋ฉ”์„œ๋“œ๋กœ ํ‹ฐ์ปค์™€ ๋งค์ˆ˜ ๊ธˆ์•ก๋งŒ์„ ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค. ๋งค์ˆ˜ ๊ธˆ์•ก์€ ์ˆ˜์ˆ˜๋ฃŒ๋ฅผ ์ œ์™ธํ•œ ๊ธˆ์•ก์ž…๋‹ˆ๋‹ค. ๋‹ค์Œ ์˜ˆ์ œ์—์„œ ์ฃผ๋ฌธํ•œ 10000์›์€ ์ˆ˜์ˆ˜๋ฃŒ๊ฐ€ ์ œ์™ธ๋œ ๊ธˆ์•ก์ž…๋‹ˆ๋‹ค. ์ˆ˜์ˆ˜๋ฃŒ๊ฐ€ 0.05%๋ผ๋ฉด ์ˆ˜์ˆ˜๋ฃŒ๋ฅผ ํฌํ•จํ•œ 10005์›์˜ ํ˜„๊ธˆ์„ ๋ณด์œ ํ•˜๊ณ  ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

print(upbit.buy_market_order("KRW-XRP", 10000))

๋‹ค์Œ์€ ๋ฆฌํ”Œ 30๊ฐœ๋ฅผ ์‹œ์žฅ๊ฐ€ ๋งค๋„ํ•ฉ๋‹ˆ๋‹ค. ๋งค๋„๋Œ€๊ธˆ์ด ์ด 10000์›์ด๋ผ๋ฉด ์ˆ˜์ˆ˜๋ฃŒ๋ฅผ ์ œ์™ธํ•œ ๊ธˆ์•ก์ด ์ž…๊ธˆ๋ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ ์ˆ˜์ˆ˜๋ฃŒ๊ฐ€ 0.05%๋ผ๋ฉด 9995์› ๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

print(upbit.sell_market_order("KRW-XRP", 30))

๋ฏธ์ฒด๊ฒฐ ์ฃผ๋ฌธ ์กฐํšŒ

get_order ๋ฉ”์„œ๋“œ๋Š” ์ž…๋ ฅ๋œ ์•”ํ˜ธํ™”ํ์˜ ๋ฏธ์ฒด๊ฒฐ ์ฃผ๋ฌธ์„ ์กฐํšŒํ•ฉ๋‹ˆ๋‹ค.

upbit.get_order("KRW-LTC")

๋ฏธ์ฒด๊ฒฐ ์ฃผ๋ฌธ์ด ์žˆ๋‹ค๋ฉด ๋ฆฌ์ŠคํŠธ๋กœ ์ƒ์„ธ ๋‚ด์—ญ์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ์€ 250000์›์— ๋งค๋„(ask) ์ฃผ๋ฌธํ•œ LTC์ด 1๊ฐœ(volume)์žˆ๋‹ค๋Š” ์˜๋ฏธ์ž…๋‹ˆ๋‹ค.

[{'uuid': '50e184b3-9b4f-4bb0-9c03-30318e3ff10a',
  'side': 'ask',
  'ord_type': 'limit',
  'price': '250000.0',
  'state': 'wait',
  'market': 'KRW-LTC',
  'created_at': '2021-03-25T14:10:53+09:00',
  'volume': '1.0',
  'remaining_volume': '1.0',
  'reserved_fee': '0.0',
  'remaining_fee': '0.0',
  'paid_fee': '0.0',
  'locked': '1.0',
  'executed_volume': '0.0',
  'trades_count': 0}]

state ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์™„๋ฃŒ๋œ ์ฃผ๋ฌธ๋“ค์„ ์กฐํšŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

print(upbit.get_order("KRW-LTC", state="done"))
[{'uuid': '0694def7-5ada-405f-b0f3-053801d5b190',
  'side': 'ask',
  'ord_type': 'market',
  'price': None,
  'state': 'done',
  'market': 'KRW-LTC',
  'created_at': '2021-03-21T14:43:40+09:00',
  'volume': '0.07336815',
  'remaining_volume': '0.0',
  'reserved_fee': '0.0',
  'remaining_fee': '0.0',
  'paid_fee': '8.39331636',
  'locked': '0.0',
  'executed_volume': '0.07336815',
  'trades_count': 1},
 {'uuid': '48d6d451-3db5-4357-9d5a-bfb8f417c943',
  'side': 'ask',
  'ord_type': 'limit',
  'price': '230000.0',
  'state': 'done',
  'market': 'KRW-LTC',
  'created_at': '2021-03-17T01:06:55+09:00',
  'volume': '0.5',
  'remaining_volume': '0.0',
  'reserved_fee': '0.0',
  'remaining_fee': '0.0',
  'paid_fee': '58.775',
  'locked': '0.0',
  'executed_volume': '0.5',
  'trades_count': 2}]

uuid๋ฅผ ์‚ฌ์šฉํ•ด์„œ ํŠน์ • ์ฃผ๋ฌธ์„ ์ƒ์„ธ ์กฐํšŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. uuid๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋‹ค๋ฅธ ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” ๋ฌด์‹œ๋ฉ๋‹ˆ๋‹ค.

order = upbit.get_order('50e184b3-9b4f-4bb0-9c03-30318e3ff10a')
print(order)

๊ฒฐ๊ณผ๋ฅผ ์ฐธ๊ณ ํ•˜๋ฉด ์ง€์ •๊ฐ€ ๋งค๋„๋ฅผ ์‹คํ–‰ํ–ˆ์œผ๋ฉฐ ์ฃผ๋ฌธ์€ ์ทจ์†Œ(cancel) ๋์Œ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค

{'uuid': '50e184b3-9b4f-4bb0-9c03-30318e3ff10a', 'side': 'ask', 'ord_type': 'limit', 'price': '250000.0', 'state': 'cancel', 'market': 'KRW-LTC', 'created_at': '2021-03-25T14:10:53+09:00', 'volume': '1.0', 'remaining_volume': '1.0', 'reserved_fee': '0.0', 'remaining_fee': '0.0', 'paid_fee': '0.0', 'locked': '1.0', 'executed_volume': '0.0', 'trades_count': 0, 'trades': []}

๋งค์ˆ˜/๋งค๋„ ์ฃผ๋ฌธ ์ทจ์†Œ

์ฃผ๋ฌธ ํ•จ์ˆ˜์˜ ๋ฆฌํ„ด ๊ฐ’ ์ค‘ uuid ๊ฐ’์„ ์‚ฌ์šฉํ•ด์„œ ์ฃผ๋ฌธ์„ ์ทจ์†Œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

print(upbit.cancel_order('50e184b3-9b4f-4bb0-9c03-30318e3ff10a'))

์ •์ƒ ์ฒ˜๋ฆฌ๋๋‹ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋”•์…”๋„ˆ๋ฆฌ๊ฐ€ ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค.

{'uuid': '50e184b3-9b4f-4bb0-9c03-30318e3ff10a', 'side': 'ask', 'ord_type': 'limit', 'price': '250000.0', 'state': 'wait', 'market': 'KRW-LTC', 'created_at': '2021-03-25T14:10:53+09:00', 'volume': '1.0', 'remaining_volume': '1.0', 'reserved_fee': '0.0', 'remaining_fee': '0.0', 'paid_fee': '0.0', 'locked': '1.0', 'executed_volume': '0.0', 'trades_count': 0}

์›น์†Œ์ผ“

WebSocket์„ ์ด์šฉํ•ด์„œ ํ˜„์žฌ๊ฐ€, ํ˜ธ๊ฐ€, ์ฒด๊ฒฐ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์ˆ˜์‹ ํ•ฉ๋‹ˆ๋‹ค.

  • ์ฒซ ๋ฒˆ์งธ ํŒŒ๋ผ๋ฏธํ„ฐ์—๋Š” ์ˆ˜์‹ ์ •๋ณด๋ฅผ ์ž…๋ ฅํ•˜๋ฉฐ ticker, orderbook, transaction์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๋‘ ๋ฒˆ์งธ ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” ๊ตฌ๋…ํ•  ํ•„ํ„ฐ๋ฅผ ์„ค์ •ํ•˜๋ฉฐ ์•”ํ˜ธํ™”ํ์˜ ํ‹ฐ์ปค๋ฅผ ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค. ํ˜„์žฌ ๋ฒ„์ „์—์„œ๋Š” ์›ํ™” ์‹œ์žฅ๋งŒ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.
from pyupbit import WebSocketManager

if __name__ == "__main__":
    wm = WebSocketManager("ticker", ["KRW-BTC"])
    for i in range(10):
        data = wm.get()
        print(data)
    wm.terminate()

์ฃผ์˜: ์›น์†Œ์ผ“์˜ multiprocessing์„ ์œ„ํ•ด __name__ guard๋ฅผ ๋ฐ˜๋“œ์‹œ ์จ์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค.

PyQt5์™€ ํ•จ๊ป˜ ์›น์†Œ์ผ“์„ ์‚ฌ์šฉํ•˜๋Š” ์˜ˆ์ œ๋Š” ๋‹ค์Œ ์ฝ”๋“œ๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”.

WebSocketClient ํด๋ž˜์Šค๋Š” ์™ธ๋ถ€์—์„œ ํ”„๋กœ์„ธ์Šค ์ƒ์„ฑ ๋ฐ ํ๋ฅผ ์ „๋‹ฌํ•˜๋Š” ๊ตฌ์กฐ์—์„œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. WebSocketManager์™€ ๋‹ฌ๋ฆฌ ์‚ฌ์šฉ์ž๊ฐ€ ํ”„๋กœ์„ธ์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์‚ฌ์šฉํ•  ํ๋ฅผ ์ž…๋ ฅํ•ด์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค.

import multiprocessing as mp
import pyupbit


if __name__ == "__main__":
    queue = mp.Queue()
    proc = mp.Process(
        target=pyupbit.WebSocketClient,
        args=('ticker', ["KRW-BTC"], queue),
        daemon=True
    )
    proc.start()

    while True:
        data = queue.get()
        print(data)