sharebook-kr / pyupbit

python wrapper for upbit API
Apache License 2.0
482 stars 311 forks source link

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

암호화폐 목록

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 파라미터는 조회단위를 지정합니다. 파라미터에는 다음 값을 지정할 수 있습니다.

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"))

intervalminute1로 지정한 경우 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"))

리스트 안에 딕셔너리로 호가정보가 들어있습니다.

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을 이용해서 현재가, 호가, 체결에 대한 정보를 수신합니다.

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)