본문 바로가기
금융 데이터 분석

[Python](비트코인)1분 봉 데이터를 활용하여 원하는 시간의 봉 데이터 만들기

by Stocking-man 2022. 2. 20.

안녕하세요. 개발하는 stocker입니다. 오늘은 비트코인 1분 봉을 활용하여 원하는 시간 봉 데이터를 만들어보는 실습을 진행하려 합니다! 

 

가장 먼저 아래와 같이 1분 봉 데이터를 준비했습니다. 몇 가지 예시를 통해서 1분 봉으로 다른 시간 대의 봉을 만들어 보겠습니다.

BTC/USD의 2017~2022 시세 데이터

그리고 본격적인 진행에 앞서 몇 가지 준비해야할 것들이 있습니다.

 

첫 번째는 Datetime Column을 만듦니다. 위 데이터프레임의 index 칼럼을 통하여 만들 수 있습니다. 코드로 보시면 다음과 같습니다.

df["Datetime"] = df.index

Datetime Column add

 

두 번째는 결과로 담을 빈 DataFrame을 만드는 것 입니다.  기존에 있던 데이터프레임과 비슷한 구조이지만 row가 비어있는 DataFrame을 아래와 같이 코드로 작성하여 생성합니다.

result_df = pd.DataFrame(columns=['Datetime', 'Open', 'High', 'Low', 'Close', 'Volumn'])

비어 있는 DataFrame

 

아래와 같은 반복 로직으로 result_df에 timeframe분 봉을 한 행 씩 아래로 추가합니다. 
timeframe이 5이면 5분 봉, 60이면 1시간 봉, 1440이면 1일 봉이라고 생각하시면 됩니다.

코드의 자세한 동작은 주석으로 설명하였습니다. 

# 임의로 설정한 분 봉 기간
timeframe = 5 

# 첫 인덱스
idx = 0 

# IndexError가 발생하기 전까지 루프를 돈다.
while True:
    try:
        # timeframe에 해당하는 기간만큼의 분 봉데이터를 가져온다. ex) timeframe이 5라면 1분 봉 5개를 준비함.
        temp_df = df[idx: idx + timeframe] 

        # 인덱스에 timeframe을 더한다. ex) timeframe이 5인 경우: 0 -> 5
        idx += timeframe

        # timeframe분 봉의 시간 데이터
        datetime = temp_df.iloc[0].Datetime

        # timeframe분 봉의 시가 데이터: 1분 봉 데이터의 가장 앞 데이터의 시가
        open = temp_df.iloc[0].Open

        # timeframe분 봉의 고가 데이터: 1분 봉 데이터의 고가 중 가장 큰 값
        high = temp_df.High.max()

        # timeframe분 봉의 저가 데이터: 1분 봉 데이터의 저가 중 가장 작은 값
        low = temp_df.Low.min()

        # timeframe분 봉의 종가 데이터: 1분 봉 데이터의 가장 마지막 데이터의 종가
        close = temp_df.iloc[-1].Close

        # timeframe분 봉의 거래량 데이터: 모든 1분 봉 데이터의 거래량 합 
        volumn = temp_df.Volume.sum()

        # timeframe분 봉의 한 행 
        appending_df = pd.DataFrame([[datetime, open, high, low, close, volumn]], 
                                    columns=['Datetime', 'Open', 'High', 'Low', 'Close', 'Volumn'])

        # 결과 데이터의 행으로써 누적시킨다.(아래로 concat)
        result_df = pd.concat([result_df, appending_df])

    # Index에러가 발생하면 기존에 있던 데이터 개수를 넘어섰다는 의미이기 때문에 append 중지
    except IndexError:
        break

위 코드를 실행한 후의 result_df

결과를 보시면 index 부분이 조금 맘에 드시지 않으실 수 있습니다.(저만 그럴수도..?)

그래서 마지막으로 index 값을 Datetime으로 설정하면 완성입니다.!

result_df.set_index('Datetime', inplace=True)

 

지금까지 설명한 코드의 동작을 함수화하면 아래와 같습니다. 

def create_other_timeframe_df(df_1m: pd.DataFrame, timeframe: int) -> pd.DataFrame:
    """
    Args:
        df_1m: 1분 봉 df
        timeframe: int
    
    Returns:
        pd.DataFrame: 완성된 timeframe분 봉의 df
    """
    
    # 빈 DataFrame을 만든다. 
    result_df = pd.DataFrame(columns=['Datetime', 'Open', 'High', 'Low', 'Close', 'Volume'])
    
     # 첫 번째 row를 위한 idx
    idx = 0
    
    # IndexError가 발생하기 전까지 루프를 돈다.
    while True:
        try:
            # timeframe에 해당하는 기간만큼의 분 봉데이터를 가져온다. ex) timeframe이 5라면 1분 봉 5개를 준비함.
            temp_df = df[idx: idx + timeframe] 
            
            # 인덱스에 timeframe을 더한다. ex) timeframe이 5인 경우: 0 -> 5
            idx += timeframe
            
            # timeframe분 봉의 시간 데이터
            datetime = temp_df.iloc[0].Datetime
            
            # timeframe분 봉의 시가 데이터: 1분 봉 데이터의 가장 앞 데이터의 시가
            open = temp_df.iloc[0].Open
            
            # timeframe분 봉의 고가 데이터: 1분 봉 데이터의 고가 중 가장 큰 값
            high = temp_df.High.max()
            
            # timeframe분 봉의 저가 데이터: 1분 봉 데이터의 저가 중 가장 작은 값
            low = temp_df.Low.min()
            
            # timeframe분 봉의 종가 데이터: 1분 봉 데이터의 가장 마지막 데이터의 종가
            close = temp_df.iloc[-1].Close
            
            # timeframe분 봉의 거래량 데이터: 모든 1분 봉 데이터의 거래량 합 
            volume = temp_df.Volume.sum()
    
            # timeframe분 봉의 한 행 
            appending_df = pd.DataFrame([[datetime, open, high, low, close, volume]], 
                                        columns=['Datetime', 'Open', 'High', 'Low', 'Close', 'Volume'])
            
            # 결과 데이터의 행으로써 누적시킨다.(아래로 concat)
            result_df = pd.concat([result_df, appending_df])
            
        # Index에러가 발생하면 기존에 있던 데이터 개수를 넘어섰다는 의미이기 때문에 append 중지
        except IndexError:
            break
    
    # Datetime 열을 인덱스로 열로 설정
    result_df.set_index("Datetime")
    return result_df

 

이상으로 포스팅 마치겠습니다. 더 좋은 방법이 있거나 부족한 부분, 더 궁금하신 부분이 있다면 댓글로 달아주시면 감사하겠습니다!