본문 바로가기

파이썬

[파이썬] 업비트 API로 자동매매 프로그램 만들기(매수/매도/주문정보확인)

반응형

안녕하세요

취미로 파이썬으로 이것저것 해보고 있는 사람입니다 ㅎㅎ

코인 변동성돌파 전략을 구현하기 위해 자동매매 API를 최근에 접해보았는데요,

필수 기초적인 내용을 정리해 보았습니다.

 

본격적으로 시작하기 앞서 준비단계는 아래와 같습니다 !

 

1. 업비트 Open API 신청하기

 

먼저 시작하기 앞서서, 업비트 Opne api 를 사용하기 위해선 Acess Key를 발급받아야 합니다

주소링크는 아래 더보기를 열어주세요

Open API 사용하기를 누르면 Access Key를 발급 받을 수 있습니다.

업비트 개발자센터로 가면 Open API 레퍼런스를 볼 수 있으니, 개발에 참고하시기 바랍니다.

 

이곳에서 본인이 원하는 기능을 체크하고, 보안을 위해 특정IP에서만 실행을 해줍니다.

(출금하기 등 일부 기능은 필수적으로 하게 되어있음)

 

발급받게되면, Access Key 와 Secret Key 가 생성되는데 이걸 메모장에 잘 저장해놓으시면 됩니다.

Secret Key는 앞으로 더이상 조회 불가능..!

저장한 API Key를 저장한 문서는 암호화를 권고드립니다.. 유출되면, 자산에 피해를 입을 수 있습니다.

 

참고) 본인 IP 주소 확인하는법

저는 ipconfig 를 통해 확인한 IP주소를 넣었는데, 안되더라구요 ㅋㅋ

www.myip.com/

위 링크에서 본인 IP확인하셔서 넣으시는걸 추천드립니다.

 

2. 파이썬 필요 라이브러리

 

import pyupbit
import jwt
import uuid
import hashlib
from urllib.parse import urlencode
import requests

 

위의 라이브러리중 설치가 안된분들은 pip install 명령을 통해 설치해주시면 됩니다.

 

==============================================================

 

자 이제 준비는 완료되었고 자동매매에 필요한 필수 코드를 살펴보겠습니다.

 

3. 먼저 자동매매 Class 와 init 함수를 생성해줍니다.

 

import pyupbit
import jwt
import uuid
import hashlib
from urllib.parse import urlencode
import requests
from datetime import datetime, timedelta
import time
import schedule

class VB_Trade:

    def __init__(self):
        # Upbit API
        self.access_key = '{본인 Access key 입력}'
        self.secret_key = '{본인 Secret key 입력}'
        self.server_url = 'https://api.upbit.com'

        self.upbit = pyupbit.Upbit(self.access_key, self.secret_key)

다른 함수에서도 key에 접근할수 있도록 앞에 self. 을 붙여주었습니다.

 

 

4. 계좌 정보 불러오기

 

balance = self.upbit.get_balances()

balance
[{'currency': 'KRW', 'balance': '105.66052861', 'locked': '0.0', 'avg_buy_price': '0', 
'avg_buy_price_modified': True, 'unit_currency': 'KRW'}, {'currency': 'XRP', 
'balance': '17.0', 'locked': '0.0', 'avg_buy_price': '582', 
'avg_buy_price_modified': False, 'unit_currency': 'KRW'}]

upbit.get_balances()를 통해 계좌정보를 불러올 수 있습니다.

원화부터 코인들 각각의 정보가 리스트안 딕셔너리 형태로 반환되는 걸 볼 수있습니다.

 

만약 내 계좌에 있는 특정 코인이나 원화 잔고를 알고 싶다면 아래와 같이 개별 조회도 가능합니다.

KRW_Balance = self.upbit.get_balance(ticker="KRW")
XRP_Balance = self.upbit.get_balance(ticker="KRW-XRP")

 

5. 현재가 조회하기

 

get_current_price 함수에 티커를 넣어주면 조회가 됩니다.

pyupbit.get_current_price("KRW-XRP")

 

6. 매수/매도 주문하기

 

지정가 매수/매도

upbit.buy_market_order( {코인명}, {매수가격}, {매수갯수} )

upbit.sell_market_order( {코인명}, {매도가격}, {매도갯수} )

self.upbit.buy_limit_order("KRW-XRP", 100, 10)
self.upbit.sell_limit_order("KRW-XRP", 100, 10)

위 코드에서 매수는 리플을 100원 가격으로 10개 주문을 넣은것이고

매도도 마찬가지로 100원으로 10개 주문을 넣겠다는 의미입니다.

 

시장가 매수/매도

upbit.buy_market_order( {코인명}, {매수할 총금액} )

upbit.sell_market_order( {코인명}, {매도갯수} )

self.upbit.buy_market_order("KRW-XRP", 10000)
self.upbit.sell_market_order("KRW-XRP", 20)

위 코드에서 매수는 리플을 10000원어치 시장가로 구매하겠다는 의미고

매도는 리플을 20개만큼 시장가로 팔겠다는 뜻입니다.

 

주문 반환값

위의 주문 코드를 print 해보면 아래와 같이 반환값을 조회할 수 있습니다.

({'uuid': '82e211da-21f6-4355-9d76-83e7248e2c0c', 'side': 'bid', 'ord_type': 'limit', 'price': '100.0', 'avg_price': '0.0', 'state': 'wait', 'market': 'KRW-XRP', 'created_at': '2021-02-13T05:39:40+09:00', 'volume': '20.0', 'remaining_volume': '20.0', 'reserved_fee': '2.0', 'remaining_fee': '2.0', 'paid_fee': '0.0', 'locked': '4002.0', 'executed_volume': '0.0', 'trades_count': 0}, {'group': 'order', 'min': 78, 'sec': 6})

 

여기서 'uuid' 값으로 주문을 취소할 수도 있고 나중에 체결상태를 확인할 수 있으니 아래와 같이 반환값을 저장해두는 것이 좋습니다.

ret = self.upbit.buy_market_order(ticker, my_cash_available)
print(ret['uuid'])

 

7. 주문 취소하기

 

위 주문에서 반환값으로 얻었던 uuid값을 이용하여 주문을 취소할 수 있습니다.

아래와 같이 uuid를 직접입력하거나 저장해두었던 반환값을 불러옵니다.

upbit.cancel_order('e57a3bc0-0b0b-4540-96f2-f35f19c51e8d')
upbit.cancel_order(ret['uuid'])

 

8. 주문정보 확인하기

 

주문정보를 확인할 수 있는 함수는 pyupbit 라이브러리에서 레퍼런스를 찾지 못하여...

업비트 사이트에 있는 내용을 참조해서 함수로 만들었습니다.

함수에 orderid에 주문의 'uuid' 값을 넣으면 주문정보를 조회할 수 있도록 하였습니다.

이 함수를 통해 자동매매 주문이 체결되었는지 여부를 확인할 수 있습니다.

    def orders_status(self, orderid):
        query = {
            'uuid': f'{orderid}',
        }
        query_string = urlencode(query).encode()

        m = hashlib.sha512()
        m.update(query_string)
        query_hash = m.hexdigest()

        payload = {
            'access_key': self.access_key,
            'nonce': str(uuid.uuid4()),
            'query_hash': query_hash,
            'query_hash_alg': 'SHA512',
        }

        jwt_token = jwt.encode(payload, self.secret_key)
        authorize_token = 'Bearer {}'.format(jwt_token)
        headers = {"Authorization": authorize_token}

        res = requests.get(self.server_url + "/v1/order", params=query, headers=headers)

        return res.json()

반환값으로 아래와 같은 딕셔너리 타입으로 반환됩니다.

 

{ "uuid": "9ca023a5-851b-4fec-9f0a-48cd83c2eaae", "side": "ask", "ord_type": "limit", "price": "4280000.0", "state": "done", "market": "KRW-BTC", "created_at": "2019-01-04T13:48:09+09:00", "volume": "1.0", "remaining_volume": "0.0", "reserved_fee": "0.0", "remaining_fee": "0.0", "paid_fee": "2140.0", "locked": "0.0", "executed_volume": "1.0", "trades_count": 1, "trades": [ { "market": "KRW-BTC", "uuid": "9e8f8eba-7050-4837-8969-cfc272cbe083", "price": "4280000.0", "volume": "1.0", "funds": "4280000.0", "side": "ask" } ] }

 

반환 데이터 의미는 아래 표를 참조하세요~

uuid 주문의 고유 아이디 String
side 주문 종류 String
ord_type 주문 방식 String
price 주문 당시 화폐 가격 NumberString
state 주문 상태 String
market 마켓의 유일키 String
created_at 주문 생성 시간 DateString
volume 사용자가 입력한 주문 양 NumberString
remaining_volume 체결 후 남은 주문 양 NumberString
reserved_fee 수수료로 예약된 비용 NumberString
remaining_fee 남은 수수료 NumberString
paid_fee 사용된 수수료 NumberString
locked 거래에 사용중인 비용 NumberString
executed_volume 체결된 양 NumberString
trade_count 해당 주문에 걸린 체결 수 Integer
trades 체결 Array[Object]
trades.market 마켓의 유일 키 String
trades.uuid 체결의 고유 아이디 String
trades.price 체결 가격 NumberString
trades.volume 체결 양 NumberString
trades.funds 체결된 총 가격 NumberString
trades.side 체결 종류 String
trades.created_at 체결 시각 DateString

9. 과거데이터 조회

과거 시가, 종가, 저가, 고가 를 조회할수 있는 함수가 있습니다.

다만 한번에 최대 200개 데이터까지 밖에 못 불러오는거 같더군용,,

print(pyupbit.get_ohlcv("KRW-BTC", interval="day", count=5))    # 5일 일봉 데이터

interval에 'minute1', 'week' 를 넣으면 분봉, 주봉 데이터도 얻을 수 있습니다.

count 는 200개 이상을 해도 에러는 안나지만, 200개까지만 불러오네요 ㅜㅜ

 

 

10. 전체 예시 코드

import pyupbit
import jwt
import uuid
import hashlib
from urllib.parse import urlencode
import requests
from datetime import datetime, timedelta
import time
import schedule


class VB_Trade:

    def __init__(self):
        # Upbit API
        self.access_key = '{입력해주세요}'
        self.secret_key = '{입력해주세요}'
        self.server_url = 'https://api.upbit.com'

        self.upbit = pyupbit.Upbit(self.access_key, self.secret_key)

    def orders_status(self, orderid):
        query = {
            'uuid': f'{orderid}',
        }
        query_string = urlencode(query).encode()

        m = hashlib.sha512()
        m.update(query_string)
        query_hash = m.hexdigest()

        payload = {
            'access_key': self.access_key,
            'nonce': str(uuid.uuid4()),
            'query_hash': query_hash,
            'query_hash_alg': 'SHA512',
        }

        jwt_token = jwt.encode(payload, self.secret_key)
        authorize_token = 'Bearer {}'.format(jwt_token)
        headers = {"Authorization": authorize_token}

        res = requests.get(self.server_url + "/v1/order", params=query, headers=headers)

        return res.json()


    def Strategy(self, ticker):

        my_cash = self.upbit.get_balance(ticker="KRW")
        my_cash_available = int(my_cash / (100.05*0.01))  # 수수료 0.05% 고려하여 실질 운영가능금액 계산

        ret = self.upbit.buy_market_order(ticker, my_cash_available)  # 시장가 매수
        buy_order_info = self.orders_status(ret['uuid'])
         
        while float(buy_order_info['remaining_volume']) != 0: # 체결여부 계속 확인하기
            buy_order_info = self.orders_status(ret['uuid'])
         
        timestamp = datetime.now()
        print(f"{timestamp} 주문량이 전부 체결되었습니다 체결량: "
        f"{buy_order_info['trades'][0]['volume']}, 매수가격 : {buy_order_info['trades'][0]['price']}")
         	

if __name__ == '__main__':
    vb = VB_Trade()
    vb.Strategy('KRW-XRP')




 

 

참조사이트

1. 업비트 API Reference

docs.upbit.com/reference

2. 위키독스 "파이썬을 이용한 비트코인 자동매매"

wikidocs.net/31063

반응형