코인 자동매매 프로그램 만들기 : 거래소 API 활용하기
토이 프로젝트/암호화폐 자동거래 봇(Bot) 만들기

코인 자동매매 프로그램 만들기 : 거래소 API 활용하기

by TechNyang 2024. 10. 14.
반응형

이번 포스팅에는 CCXT 및 거래소 API를 활용하여 캔들 정보 및 가격정보를 조회하는 부분을 말씀드리고자 합니다.

API는 버전에 따라 사용법이 달라질 수 있습니다.

 

만약 본 포스팅과 API사용법이 다르다면 각 거래소 API 문서를 참고하시기 바랍니다.

아직 개발환경이 구축되지 않으신 분은 아래 포스팅을 참고하시기 바랍니다.

 

 

코인 자동매매 프로그램 만들기 : 파이썬으로 환경구축하기

24시간 365일 거래가 가능한 암호화폐 시장. 이제 더 이상 시세를 일일히 확인 할 필요가 없습니다. 이제 여러분 만의 전략을 사용하여, 프로그램이 실시간으로 시세 및 매수시점과 매도시점을 

technyang.tistory.com

 

 

거래소 연동하기

ccxt모듈이 설치가 되었으면 ccxt를 import하여 대표적인 원(KRW)화 거래소인 업비트와 빗썸을 연동해 보도록 하겠습니

다.

 

업비트

import ccxt
exchange = ccxt.upbit({'apiKey': 여기에 apiKey를 입력하세요.'',
                    'secret': 여기에 secretKey를 입력하세요.'',
                    'enableRateLimit': True # 시장가로 주문이 들어가는 것을 막으려면 True
                    })

빗썸

import ccxt
exchange = ccxt.bithumb({'apiKey': 여기에 apiKey를 입력하세요.'',
                    'secret': 여기에 secretKey를 입력하세요.'',
                    'enableRateLimit': True # 시장가로 주문이 들어가는 것을 막으려면 True
                    })

 

잔고 조회하기

거래소에 입금되어 있는 잔고를 조회하는 메소드를 작성하겠습니다.

잔고조회는 업비트와 빗썸의 코드는 서로 상이하니 이 점 유의하시기 바랍니다.

 

업비트

def getBalance(): 
    bal = exchange.fetch_balance()
    return bal['KRW']['free']

 

 

업비트에서는 fetch_balance메소드를 호출하면 어떠한 값들이 Return되는지 확인해보겠습니다.

{'info': [{'currency': 'KRW',
   'balance': '24062.21741314',
   'locked': '0.0',
   'avg_buy_price': '0',
   'avg_buy_price_modified': True,
   'unit_currency': 'KRW'},
  {'currency': 'ETH',
   'balance': '0.01842293',
   'locked': '0.0',
   'avg_buy_price': '1802884.62',
   'avg_buy_price_modified': False,
   'unit_currency': 'KRW'}],
 'KRW': {'free': 24062.21741314, 'used': 0.0, 'total': 24062.21741314},
 'ETH': {'free': 0.01842293, 'used': 0.0, 'total': 0.01842293},
 'LTC': {'free': 0.02117857, 'used': 0.0, 'total': 0.02117857},
 'BCH': {'free': 0.00679347, 'used': 0.0, 'total': 0.00679347},
 'ADA': {'free': 9.36024203, 'used': 0.0, 'total': 9.36024203},
 'MED': {'free': 516.63846153, 'used': 0.0, 'total': 516.63846153},
 'RFR': {'free': 798.97742363, 'used': 0.0, 'total': 798.97742363},
 'ORBS': {'free': 208.92555555, 'used': 0.0, 'total': 208.92555555},
 'CHZ': {'free': 186.58730158, 'used': 0.0, 'total': 186.58730158},
 중 략
 'total': {'KRW': 24062.21741314,
  'ETH': 0.01842293,
  'LTC': 0.02117857,
  'BCH': 0.00679347,
  'ADA': 9.36024203}}

 

결과값은 딕셔너리 형태로 이루어져 있는데요.

보유하고 있는 원화를 나타내는 부분은 위 결과값에서 붉은색으로 표기되어 있는 부분입니다.

저는 KRW키의 free키의 value를 가져다 사용하겠습니다.

 

빗썸

def getBalance(): 
    bal = exchange.fetch_balance()
    return bal['info']['data']['available_krw']

 

빗썸의 fetch_balance의 값은 딕셔너리로 동일하나 데이터들은 위 업비트와는 다름 모습을 하고 있습니다.

여기서는 이용가능한 원화인 available_krw의 값을 사용합니다.

{'info': {'status': '0000',
  'data': {'total_krw': '79942.500901',
   'in_use_krw': '0.00000000',
   'available_krw': '79942.50090100',
   'total_btc': '0.00001572',
   'in_use_btc': '0.00000000',
   'available_btc': '0.00001572',
   'xcoin_last_btc': '54434000',
   중략
   'XTZ': 0.0,
   'YFI': 0.0,
   'ZEC': 0.0,
   'ZIL': 0.0,
   'ZRX': 0.0}}

 

여기서 잠깐 잔고조회하는 함수를 파이참에서 사용하는 법 및 주피터 노트북을 사용하는 법에 대해 말씀드리겠습니다.

위 소스에 main함수 추가한 모습
main함수를 추가한 모습

 

잔고조회 하는 함수를 작성하신 후 if __name__ == ‘__main__’:을 작성해 주세요.

이것은 프로그램이 수행되는 진입점입니다.

 

그리고 그 밑에 getBalace한수를 호출을 해주시고 return으로 전달받은 bal[‘KRW’][‘free’]값을 print문을 이용하여 화면에 표시해줍니다.

 

차트정보(캔들정보) 조회하기

기술적 분석을 사용하기 위해서는 기본적으로 암호화폐별 차트정보를 불러와야 합니다.

ccxt에서 업비트는 분봉, 일봉, 주봉, 월봉을 지원하며, 그 중 분봉은 1분, 3분, 5분, 15분, 30분, 1시간, 4시간을 지원합니다.

 

ccxt에서 빗썸은 분봉과 일봉을 지원하며, 그 중 분봉은 1분, 3분, 5분, 10분, 30분, 1시간, 6시간, 12시간을 지원합니다.

차트정보는 ccxt 모듈의 fetch_ohlcv메소드를 호출하며 방식은 아래와 같습니다.

ohlcv = exchange.fetch_ohlcv(ticker, period)

 

ticker부분에는 암호화폐의 코드를 넣어주시면 되는데요.

구조는 종목코드/시장입니다.

 

여기서 시장은 원화시장이냐, 비트코인시장이냐, 달러시장이냐를 나타냅니다.

예를 들어 원화 시장에서의 비트코인은 BTC/KRW로 표기해주시면 되고, 비트코인 시장에서의 이더리움은 ETH/BTC, 달러시장에서의 리플은 XRP/USDT로 표기해주시면 됩니다.

 

하지만 cctx 모듈에서 빗썸은 원화시장 외에는 지원을 해주지 않고 있으니, 이점 참고하세요.

period부분은 봉의 기간을 입력하시면 됩니다. 아래 표를 참고하세요.

  1분봉 3분봉 5분봉 10분봉 15분봉 30분봉 1시간봉 4시간봉 6시간봉 12시간봉 일봉 주봉 월봉
빗썸 1m 3m 5m 10m X 30m 1h X 6h 12h 1d X X
업비트 1m 3m 5m X 15m 30m 1h 4h X X 1d 1w 1M

 

원화시장에서의 비트코인의 30분봉을 가져오기 위해서는 아래처럼 호출하시면 됩니다.

ohlcv = exchange.fetch_ohlcv(‘BTC/KRW’ , ’30m’)

 

ohlcv를 출력해보면 아래와  같은 데이터들이 확인이 되실텐데요.

이것만 봐서는 뭐가 뭔지 잘 모르실 것입니다. 좌측부터 순서대로 날짜, 시가, 고가, 저가, 종가, 거래량을 나타냅니다.

[[1614582000000, 52374000.0, 52648000.0, 52350000.0, 52587000.0, 124.42321103],
 [1614583800000, 52587000.0, 52965000.0, 52439000.0, 52849000.0, 138.61897534],
 [1614585600000, 52849000.0, 53481000.0, 52834000.0, 53387000.0, 272.1063819],
 [1614587400000, 53396000.0, 53694000.0, 53233000.0, 53500000.0, 324.55582004],
 [1614589200000, 53500000.0, 54050000.0, 53494000.0, 53673000.0, 375.41051635],

 

기술적 분석을 하려면 캔들정보가 많이 쓰일텐데요. 이 캔들정보를 보다 쉽게 사용하기 위해 DataFrame형식으로 변환하도록 하겠습니다.

import pandas as pd

df = pd.DataFrame(ohlcv, columns=['date', 'open', 'high', 'low', 'close', 'volume'])

 

판다스를 import해서 list형식의 ohlcv를 DataFrame형식으로 변환했습니다.

확실히 각 Data들이 어떠한 값인이 쉽게 알 수 있게 되었습니다.

date, open, high, low, close, volume을 컬럼으로 각 정보가 보여지고 있다.
DataFrame 변환 결과

 

그런데 여기서 한가지 문제가 발생합니다.

만일 업비트에서 10분봉을 활용한 전략을 구현하고 싶은데, ccxt에서는 업비트의 10분봉을 지원하지 않습니다.

 

그럼 10분봉을 어떻게 만들까요?

다행히 5분봉은 지원하고 있으니 5분봉을 가지고 만들 수 있을 것 같습니다.

아래는 5분봉을 가지고 10분봉을 만드는 로직입니다.

ohlcv_10m = []  # 만들어진 10분봉을 담을 LIST
timestpam = 0
open = 1
high = 2
low = 3
close = 4
volume = 5

ohlcv = exchange.fetch_ohlcv(ticker, '5m')

while ohlcv is None:
    time.sleep(0.1)
    ohlcv = exchange.fetch_ohlcv(ticker, '5m')  # 5분 봉을 가져온다.
if len(ohlcv) > 2:  # 10분봉을 만들기 위해서는 최소 2개의 봉 DATA가 필요하다.
    for i in range(0, len(ohlcv) - 1, 2): #2개씩 묶어야 하므로 반복문은 2씩 증가한다.
        highs = [ohlcv[i + j][high] for j in range(0, 2) if ohlcv[i + j][high]] 
        lows = [ohlcv[i + j][low] for j in range(0, 2) if ohlcv[i + j][low]] 
        volumes = [ohlcv[i + j][volume] for j in range(0, 2) if ohlcv[i + j][volume]]
        candle = [
            ohlcv[i + 0][timestpam],
            ohlcv[i + 0][open],
            max(highs) if len(highs) else None, # 2개의 봉 DATA 중 가장 높은 가격을 10분봉의 고가로 지정
            min(lows) if len(lows) else None, # 2개의 봉 DATA 중 가장 낮은 가격을 10분봉의 저가로 지정
            ohlcv[i + 1][close], # 2개의 봉중 나중 봉의 종가를 10분봉의 종가로 지정
            sum(volumes) if len(volumes) else None  #2개의 5분봉 데이터의 거래량을 합한 값을 10분봉의 거래량으로 지정
        ]
        ohlcv_10m.append((candle))
dataframe = pd.DataFrame(ohlcv_10m, columns=['date', 'open', 'high', 'low', 'close', 'volume'])

 

만들어진 DataFrame이 정말로 10분봉인지 확인을 해봐야겠지요?

DataFrame의 date컬럼 값 중 마지막 날짜와 그 전날짜를 확인해 보았습니다. 확실히 10분 차이가 나죠?

date컬럼의 각 값들이 정확히 10분 차이가 발생하고 있음을 보여주고 있는 사진
각 date의 값이 10분의 차이를 보여주고 있다.

 

그럼 이제 암호화폐 코드와 기간을 받아서 캔들정보를 조회하는 함수를 만들어 보겠습니다.

소스는 아래와 같습니다. (빗썸과 업비트 공통)

def getCandleStick(ticker, period):
    if period == '10m':
        ohlcv_10m = []  # 10분 봉을 얻기위함.
        timestpam = 0
        open = 1
        high = 2
        low = 3
        close = 4
        volume = 5

        ohlcv = exchange.fetch_ohlcv(ticker, '5m')

        while ohlcv is None:
            time.sleep(0.1)
            ohlcv = exchange.fetch_ohlcv(ticker, '5m')  # 5분 봉을 가져온다.
        if len(ohlcv) > 2:  # 10분봉을 만드는 부분
            for i in range(0, len(ohlcv) - 1, 2):
                highs = [ohlcv[i + j][high] for j in range(0, 2) if ohlcv[i + j][high]]
                lows = [ohlcv[i + j][low] for j in range(0, 2) if ohlcv[i + j][low]]
                volumes = [ohlcv[i + j][volume] for j in range(0, 2) if ohlcv[i + j][volume]]
                candle = [
                    ohlcv[i + 0][timestpam],
                    ohlcv[i + 0][open],
                    max(highs) if len(highs) else None,
                    min(lows) if len(lows) else None,
                    ohlcv[i + 1][close],
                    sum(volumes) if len(volumes) else None
                ]
                ohlcv_10m.append((candle))
        dataframe = pd.DataFrame(ohlcv_10m, columns=['date', 'open', 'high', 'low', 'close', 'volume'])
        return dataframe

    else:
        ohlcv = exchange.fetch_ohlcv(ticker, period)
        dataframe = pd.DataFrame(ohlcv, columns=['date', 'open', 'high', 'low', 'close', 'volume'])
        return dataframe

 

거래가능한 코인목록 조회하기

코인 리스트는 fetch_tickers()를 통하여 조회해 올 수 있습니다.

coins = exchange.fetch_tickers()

 

위 코드를 실행한 결과는 다음과 같습니다.

업비트의 경우 원화 마켓과, BTC마켓, USDT모두 조회가 되기 때문에 양이 상당히 많습니다.

그래서 일부만 보여드리겠습니다.

 

거래소 API를 통해 코인 목록이 조회된 모습
거래소 API를 통해 코인 목록이 조회된 모습

 

참고로 빗썸의 경우에는 원화시장에서 거래되는 암호화폐만 조회가 됩니다.

거래시장이 다양한 업비트를 기준으로 설명을 드리겠습니다.

 

우선 저는 원화시장에서 거래되는 코인 리스트만 받아오고 싶다고 가정하겠습니다.

이를 위해서는 /뒤가 KRW인 것만 가져오면 되겠지요?

혹은 암호화폐 이름에서 뒤 3글자가 KRW인 것을 가져와도 되겠군요. 이를 함수로 표현해보겠습니다.

def getCoinData():
    totalCoinList = []
    coins = exchange.fetch_tickers() #전체 코인 리스트를 불러옴.
    tickerList = coins.keys() #딕셔너리 형태이므로 Key값(코인 이름)만 가져옴.
    for coin in tickerList:
        if coin[-3:] == 'KRW': #코인의 이름에서 마지막 3글자가 KRW이면.
            totalCoinList.append(coin) # 그 코인을 새로운 리스트에 담는다.
    return totalCoinList

 

 

암호화폐 현재가격 구하기

자동매매 봇을 왜 쓸까요?

저는 실시간으로 암호화폐의 가격을 이용할 수 있기 때문이라고 생각합니다.

그만큼 자동거래의 꽃이라고 볼 수 있는데요. 이 현재가격을 가져오는 방법도 아주 간단합니다.

currPrice = exchange.fetch_ticker(ticker)['close']

 

ticker에는 여러분께서 조회하고 싶은 암호화폐의 코드와 시장을 넣어주시면 됩니다.

currPrice = exchange.fetch_ticker(‘BTC/KRW’)['close'] 이렇게요.

 

 

다음 포스팅에는 파이썬을 이용하여 기술적 분석지표를 만드는 법에 대해 포스팅하겠습니다.

반응형

TOP

Designed by 티스토리

loading