Programming for trading

[Python] 업비트API로 비트코인 1분봉 가져오기

quantoasis 2023. 1. 17. 17:50
반응형

 

오늘은 업비트에서 비트코인 1분봉 데이터를 가져오는 코드를 작성해 보도록 하겠습니다.

 

조대표님이 만드신 pyupbit을 이용할 예정입니다. 관련 깃허브는 아래 링크 참고하세요.

 

 

GitHub - sharebook-kr/pyupbit: python wrapper for upbit API

python wrapper for upbit API . Contribute to sharebook-kr/pyupbit development by creating an account on GitHub.

github.com

 

우선 데이터를 받기 위해 필요한 모듈입니다. 

 

from datetime import timedelta
import pandas as pd
import pyupbit
import datetime  as dt
from datetime import datetime
import time

 

아래는 거래소별 코드를 만들어주는 함수입니다. 예를 들어서 업비트의 비트코인 코드는 KRW-BTC인데 바이낸스의 티커는 BTCUSDT거든요. BTC를 인풋 해주면 거래소 별로 코드를 반환해 줍니다.

 

def ticker_listmapping(ticker, exchange):
    if exchange == 'upbit':
        result = "KRW-" + ticker
    elif exchange == 'binance':
        result= ticker + 'USDT'
    return result

 

이제 pyupbit의 get_ohlcv를 이용하여 분봉데이터를 가져와보겠습니다.

 

upbit_get_data는 시작일과 종료일 그리고 코드를 넣으면 해당 일자의 분봉을 반환해 주는 함수입니다.

 

우선 datetime의 astimezone()이라는 함수를 통해서 시세 시간을 astimezoned로 변경해 주었습니다. 

 

그리고 get_ohlcv에서 symbol, interval, count, to를 입력합니다. count는 to를 기준으로 과거 데이터를 개수만큼 가져오겠다는 변수입니다.

 

예를 들어 start가 2023-01-16 00:00이라면 2023-01-15 00:00 ~ 2023-01-15 23:59의 데이터를 가져오게 됩니다. 하루 24시간 * 60 분하면 1140개의 데이터가 생성되니까요.

 

그리고 start가 end가 될 때까지 concat함수를 통해 데이터프레임에 요청한 데이터를 계속 쌓아줍니다.

 

마지막에는 쌓인 데이터를 조금 핸들링해 주었는데요, 저는 datetime형식보다 date와 time을 나눠서 int형식으로 저장하는 것을 선호합니다. 그래서 date와 time을 수정해 주었어요. 또한 symbol도 데이터프레임에 추가해 줍니다.

 


def upbit_get_data(start_date, end_date, symbol):
    df = pd.DataFrame(columns=['open', 'high', 'low', 'close', 'volume'])
    start_date = datetime.strptime(start_date + ' 00:00', '%Y-%m-%d %H:%M')
    end_date = datetime.strptime(end_date + ' 23:59', '%Y-%m-%d %H:%M')

    start = start_date + timedelta(days=1)
    end = end_date + timedelta(days=1)

    while start <= end:

        to = start
        if to == None:
            to = datetime.datetime.now()
        elif isinstance(to, str):
            to = pd.to_datetime(to).to_pydatetime()
        elif isinstance(to, pd._libs.tslibs.timestamps.Timestamp):
            to = to.to_pydatetime()

        if to.tzinfo is None:
            to = to.astimezone()
        to = to.astimezone(dt.timezone.utc)
        to = to.strftime("%Y-%m-%d %H:%M:%S")

        for i in range(3):
            try:
                df_temp = pyupbit.get_ohlcv(symbol, interval='minutes1', count=1440, to=to)
                df = pd.concat([df, df_temp], axis=0)
                break
            except Exception as e:
                print(f'Attempt {i+1} failed: {e}')
                if i == 2:
                    raise Exception('API call failed after 3 attempts')
                time.sleep(60)
        start = start + timedelta(days=+1)

    df = df[(df.index >= start_date) & (df.index <= end_date)]
    df.reset_index(inplace=True)
    df['date'] = df['index'].apply(lambda x: x.strftime('%Y%m%d'))
    df['time'] = df['index'].apply(lambda x: x.strftime('%H%M%S')).astype(int)
    df['symbol'] = symbol
    df =df[['date','time','symbol','open', 'high', 'low', 'close', 'volume']]

    print(symbol, ' / upbit 완료')
    return df

 

아래는 tickerlist에 비트코인(BTC)과 이더리움(ETH)을 넣고 for문을 통해 데이터를 요청하는 코드입니다. 

 

위에서 정의한 ticker_listmapping과 upbit_get_data를 호출해 주었습니다. 

 

df_up=pd.DataFrame()

tickerlist = ['BTC','ETH']
for ticker in tickerlist:
    symbol_up =ticker_listmapping(ticker,'upbit')
    start_date = '2023-01-16'
    end_date = '2023-01-16'
    df_up_temp = upbit_get_data(start_date, end_date, symbol_up)
    df_up = pd.concat([df_up, df_up_temp])
    time.sleep(1)
    
print(df_up)

 

 

깔끔하게 잘 출력되었네요. 코드는 여러 블로그와 chatGPT를 이용했는데, 특히 chatGPT에게 에러처리에 관한 조언을 얻었습니다.

 

감사합니다.

반응형