크립토

[데이터수집] 가상자산(암호화폐) 1분봉 시세정보 수집 - 업비트

코대장 2021. 6. 6. 15:52
반응형

[데이터수집] 가상자산(암호화폐) 1분봉 시세정보 수집 - 업비트

 

서론

지난 포스팅에서는 pyupbit 모듈을 사용해서 시세정보(OHLCV)를 획득하여 이동평균선 데이터를 시각화 했었습니다.

'''한줄요약'''
df = pyupbit.get_ohlcv("KRW-ETH") #원화기준 이더리움 시세정보 가져오기

(아래 참고)

https://mskim8717.tistory.com/99

 

이동평균선 데이터시각화 및 상승/하락 추세 판단 활용

이동평균선(이평선) 데이터 활용한 상승/하락 돈을 벌기위한 기초투자 전략은 바로 저점에서 사서(매수) 고점에서 파는(매도)일 것입니다. 하지만 그 누구도 언제가 저점인지, 고점인지 알 수가

mskim8717.tistory.com

 

이번에는 가상자산별 시계열 데이터를 수집 및 저장해보고, 직접 가상자산에 대한 백테스트도 진행 해보려고 합니다.

보여드릴 것은

업비트 오픈API를 활용한 월별 그리고 가상자산별 시세정보(시가, 고가, 저가, 종가, 거래량) 수집에 대한 포스팅입니다.

참고로 수집단위는 1분봉 입니다.

 

 

반응형

 

본론

개발환경: 주피터노트북

우선, 주피터노트북 화면을 넓게 보기위해서 사이즈를 키워볼게요.

from IPython.core.display import display, HTML
display(HTML("<style>.container { width:80% !important; }</style>"))

다음은 파이썬 라이브러리를 불러오구요.

import pandas as pd
import pyupbit
from datetime import datetime, time, date, timedelta
from calendar import monthrange
from time import sleep

여기서부터, 데이터 수집을 위한 작업이 시작 되는데요,

저는 일단 월별 그리고 가상자산별(예를들어, 비트코인, 이더리움 등) 두가지를 수집 조건으로 정했어요.

기준은 1분봉이구요.

year = 2020
month = 12
YYYYMM = str(year) + '{0:02d}'.format(month)

# 해당 년월 마지막 일(28일, 30일, 31일)
end_day = monthrange(year, month)[1]

my_ticker = "KRW-BTC"
my_interval = "minutes1"

now = datetime.now()

월별 데이터 수집이기 때문에 매달 1일부터 말일까지 기간을 정합니다.

참고로 매달 말일(1월이면 31일, 9월이면 30일 등등) 정보를 얻는데는 

파이썬 calendar 모듈에 monthrange 라는 함수를 사용하면 쉽게 얻을 수 있어요.

'''참고'''
monthrange(year, month)

첫번째 리턴값 : 매달 1일의 요일(0:월 1:화 2:수 3:목 4:금 5:토 6:일)
두번째 리턴값 : 매달 말일 값

9월 1일은 수요일이기 때문에 튜플의 첫번째 리턴값은 2이며, 9월은 30일이 말이라서 두번째 리턴값도 확인 가능합니다.

pyupbit 모듈을 통해서 1분봉 데이터를 수집할껀데요.

최대 200개까지만 한번에 호출이 가능합니다. 따라서 200개를 200분으로 가정했을 때,

일일 데이터를 3시간 20분 간격으로 나눠서 가져오려고 합니다.

def get_upbit_ohlcv(now, ticker, year, month):
    df = pd.DataFrame(columns=['open', 'high', 'low', 'close', 'volume'])

    # 해당 년월 1일부터
    from_date = date(year, month, 1)

    # 해당 년월 마지막 일(28일, 30일, 31일)
    end_day = monthrange(year, month)[1]
    to_date = date(year, month, end_day)
    
    # 해당 년월 마지막 일자가 현재 프로그램 수행일자보다 큰 경우
    if to_date >= now.date():
        to_date = now.date()
        end_day = to_date.day
    
    temp_list = []
    # 해당 년월 1일부터 말일(또는 프로그램 수행일자)까지 데이터 수집 실시
    for day in range(1, end_day+1):
        cnt = 200 # default
        base_time = datetime.combine(from_date, time(3, 20, 0))
        # print(base_time)
        for i in range(8):
            try:
                df_temp = pyupbit.get_ohlcv(ticker, interval='minute1', count=cnt, to=base_time)
                # print(i, 'base_time:', base_time, 'shape:', df_temp.shape)
                df = pd.concat([df, df_temp], axis=0)
                if i == 6:
                    base_time += timedelta(hours=0, minutes=40)
                else:
                    base_time += timedelta(hours=3, minutes=20)
            except Exception as e:
                print('Exception:', e)
            
        from_date = from_date + timedelta(days=1)
        sleep(0.5)
        
    return df
df = get_upbit_ohlcv(now, ticker=my_ticker, year=year, month=month)

200개의 불러온 데이터 중에는 3시간 20분 중 빠져 있는 데이터가 발생할 수 있습니다.

따라서 'index' 칼럼(시간정보) 기준으로 혹시라도 중복된 데이터가 있다면 날려주도록 합니다.

df.reset_index(inplace=True)
df.drop_duplicates('index', inplace=True)

그리고 시간대도 1일부터 말일까지 중에 0시부터 23시 59분까지 데이터만 추출합니다.

df = df[(datetime.combine(date(year, month, 1), time(0, 0, 0)) <= df['index']) & (df['index'] < datetime.combine(date(year, month, end_day), time(23, 59, 59)))]

다 됐네요.

이제 CSV 파일로 저장하면 끝이죠.

fileName = '{}_{}_ohlcv.csv'.format(YYYYMM, my_ticker)
df.to_csv('./data/'+fileName, index=None)

 

결론

자체 백테스트를 하기 위해 업비트 1분봉 데이터를 수집해 봤습니다.

다음 포스팅에서는 백테스트 결과를 보여드릴 수 있겠네요.

 

소스코드