안녕하세요. 개발하는 stocker입니다. 오늘은 비트코인 1분 봉을 활용하여 원하는 시간 봉 데이터를 만들어보는 실습을 진행하려 합니다!
가장 먼저 아래와 같이 1분 봉 데이터를 준비했습니다. 몇 가지 예시를 통해서 1분 봉으로 다른 시간 대의 봉을 만들어 보겠습니다.
그리고 본격적인 진행에 앞서 몇 가지 준비해야할 것들이 있습니다.
첫 번째는 Datetime Column을 만듦니다. 위 데이터프레임의 index 칼럼을 통하여 만들 수 있습니다. 코드로 보시면 다음과 같습니다.
df["Datetime"] = df.index
두 번째는 결과로 담을 빈 DataFrame을 만드는 것 입니다. 기존에 있던 데이터프레임과 비슷한 구조이지만 row가 비어있는 DataFrame을 아래와 같이 코드로 작성하여 생성합니다.
result_df = pd.DataFrame(columns=['Datetime', 'Open', 'High', 'Low', 'Close', 'Volumn'])
아래와 같은 반복 로직으로 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
결과를 보시면 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
이상으로 포스팅 마치겠습니다. 더 좋은 방법이 있거나 부족한 부분, 더 궁금하신 부분이 있다면 댓글로 달아주시면 감사하겠습니다!