코딩 강의/유용한 스킬 없을까요

파이썬 데이터프레임 차트 n일봉 또는 n시간봉 캔들 데이터 계산 방법 (주식, 비트코인)

변태 개발자 아미넴 2021. 11. 22.

비트코인 프로그램 매매 준비를 하면서 작성해 본 유용한 함수가 있어서 공유합니다. 어느 정도 관심있는 사람은 잘 알겠지만 파이썬 pyupbit 라이브러리(모듈)를 활용하면 데이터프레임 형태의 캔들 정보를 쉽게 가져올 수 있습니다.

 

잘 모르시는 분은 다음 글 참고 바랍니다.

 

pyupbit 라이브러리를 통한 비트코인 가상화폐 거래소 API(파이썬) 사용 방법

 

pyupbit 라이브러리를 통한 비트코인 가상화폐 거래소 API(파이썬) 사용 방법

오늘은 pyupbit 라이브러리를 이용하여 업비트에서 제공하는 API를 좀 더 손쉽게 사용하는 방법을 알아 보겠습니다. 고마운 분들이 API를 사용하기 편리하게 만들어 놓았습니다. 우리는 그냥 가져

sangminem.tistory.com

 

pyupbit에서 제공하는 get_ohlcv 메서드를 보면 다음과 같은 interval 값을 지원합니다.

 

day / minute1 / minute3 / minute5 / minute10 / minute15 / minute30 / minute60 / minute240 / week / month

 

위에서 보는 바와 같이 1시간(60분)봉, 4시간(240분)봉은 있고 1일봉 7일(1주)봉은 있지만 프로그램 매매를 짜다 보면 직전 2시간, 3시간봉 또는 2일봉, 5일봉과 같이 자체적으로 지원하지 않는 캔들 데이터를 얻고 싶을 경우가 있을 겁니다.

 

지금부터 그 방법에 대한 설명과 함께 작성한 함수를 제공해 드리고자 합니다.

 

저는 비트코인 프로그램 매매를 하고 있어서 그 기준으로 설명을 드리겠지만 결국 주식도 같은 구조이므로 충분히 응용하실 수 있습니다.

 

차트의 캔들 정보에는 다음과 같이 시가, 고가, 저가, 종가, 거래량과 같은 정보가 있습니다. 반대로 이 정보가 있으면 우리가 직접 차트를 만들고 분석할 수 있다는 의미가 됩니다.

 

예시로 비트코인 1일봉 데이터 200일치를 가져와서 5일봉을 구해보겠습니다.

df = pyupbit.get_ohlcv(ticker="KRW-BTC", interval="day", count=200)
print(df)

 

다음은 출력한 값입니다.

 

먼저 계산한 결과를 담기 위해 다음과 같이 딕셔너리 데이터 구조를 선언해 놓습니다.

tempObj = {
    'open': [],
    'high': [],
    'low': [],
    'close': [],
    'volume': [],
    'value': []
}

 

먼저 200일을 n일로 나눈 몫을 구합니다.

dfLen = math.floor(len(df)/n)

 

dfLen 크기 만큼 for문을 돌면서 값을 계산하여 선언해 놓은 딕셔너리에 추가할 예정입니다. fromVal은 계산 값이 0일 경우 None으로 처리해 주기 위해 만든 변수입니다.

for i in range(dfLen):
    fromVal = -1*n*i if -1*n*i != 0 else None
    tempObj['값 구분'].append('계산한 값')

 

n일치씩 그루핑한 각 묶음의 가장 빠른 일자의 시가(open)가 n일봉의 시가가 됩니다.

df.iloc[-1*n*(i+1)]['open']

 

기준일 ~ n-1일 사이의 고가(high) 중 가장 큰 값이 n일봉의 고가가 됩니다.

df.iloc[-1*n*(i+1):fromVal]['high'].max()

 

마찬가지로 기준일 ~ n-1일 사이의 저가(low) 중 가장 작은 값이 n일봉의 저가가 됩니다.

df.iloc[-1*n*(i+1):fromVal]['low'].min()

 

종가는 시가와 비슷하게 n일치씩 그루핑한 각 묶음 중 가장 늦은 일자의 종가(close)가 n일봉의 종가가 됩니다.

df.iloc[-1*n*i-1]['close']

 

그리고 기준일 ~ n-1일의 거래량을 모두 더한 값이 n일봉의 거래량이 됩니다.

df.iloc[-1*n*(i+1):fromVal]['volume'].sum()

 

거래량과 동일한 방식으로 거래대금을 구할 수 있습니다. 거래량 보다는 거래대금이 실질적으로 더 중요하므로 필히 구해 놓도록 합니다.

df.iloc[-1*n*(i+1):fromVal]['value'].sum()

 

위의 내용을 종합하여 함수를 만들어 보았습니다. 마지막 데이터프레임을 형성할 때 pandas.DataFrame(tempObj)[::-1] 부분은 기존 데이터 순서와 맞춰주기 위해 계산한 데이터를 역순으로 배열한 것입니다.

# 특정 시간 간격으로 데이터 프레임 재구성
import pandas
import math

def get_df(df, n):
    tempObj = {
        'open': [],
        'high': [],
        'low': [],
        'close': [],
        'volume': [],
        'value': []
    }
    dfLen = math.floor(len(df)/n)
    for i in range(dfLen):
        fromVal = -1*n*i if -1*n*i != 0 else None
        tempObj['open'].append(df.iloc[-1*n*(i+1)]['open'])
        tempObj['high'].append(df.iloc[-1*n*(i+1):fromVal]['high'].max())
        tempObj['low'].append(df.iloc[-1*n*(i+1):fromVal]['low'].min())
        tempObj['close'].append(df.iloc[-1*n*i-1]['close'])
        tempObj['volume'].append(df.iloc[-1*n*(i+1):fromVal]['volume'].sum())
        tempObj['value'].append(df.iloc[-1*n*(i+1):fromVal]['value'].sum())
    resDf = pandas.DataFrame(tempObj)[::-1]
    return resDf

df = pyupbit.get_ohlcv(ticker="KRW-BTC", interval="day", count=200)
df5 = get_df(df, 5)
print(df5)

 

5일봉의 결과는 다음과 같습니다. 200일치를 5개씩 묶어 계산했으므로 40 라인이 도출됩니다. 인덱스 대신 날짜를 넣어주면 더 좋을 수도 있지만 실제 매매에서는 필요한 경우가 거의 없어서 저는 구하지 않았습니다.

 

이 함수에 1시간봉 캔들 데이터를 넣으면 2, 3시간봉도 구할 수 있게 됩니다.

모두들 부자되세요!

BIG

댓글0

💲 추천 글