백테스트-수익률 구하는 방법(pandas-월별 수익률, 누적수익률, log 수익률, 누적 log 수익률)
안녕하세요, 이번 포스팅부터 본격적으로 주가 정보를 분석해보도록 하겠습니다. 처음으로 분석해 볼 데이터는 수익률 데이터입니다. 구체적으로는 월별 수익률과, 누적 수익률, 월별 log 수익률, 누적 log 수익률입니다.
우선 지난 시간에서 월별 말일의 주가로 정리한 데이터를 확인해보겠습니다.
1.월별 수익률
DataFrame에서 월별 수익률을 계산하는 것은 매우 쉽습니다! 저도 처음에는 이전 가격대비 변경액을 백분율로 계산을 했었는데, 알고보니 pct_change()라는 유용한 함수를 제공하더라구요.
pandas.DataFrame.pct_change란?
기본적으로 바로 이전 행의 백분율 변경을 계산합니다. 이것은 요소의 시계열 변화율을 비교할 때 유용합니다.
이미 월별 말일 데이터로 준비를 해두었길래, 이 함수만 사용하면 간편하게 수익률을 월별 수익률을 구할 수 있습니다.
# 1.수익률 계산
df_PROFIT = df_PRICE.pct_change()
df_PROFIT
결과 DataFrame)
이전 달의 주가가 없는 첫 행과, 상장 이전 데이터가 없는 GLD의 초기를 제외하고는 모두 이전 달 말일 대비 변경률이 계산되었습니다. 그리고 주가의 변경률이 곧 수익률이기 때문에 수익률 구하기는 매우 간단하게 끝났습니다😎 보기 편하게 100을 곱하는 작업은 모든 수익률을 구하고 마지막에 진행하도록 하겠습니다.
2.누적 수익률
누적 수익률은 방금 전에 구한 수익률을 이용해서 구하게 됩니다. 주의해아할 점은 누적 수익률은 단순 덧셈이 아닌 곱셉으로 계산되어 진다는 점입니다.
10000원이었던 주식이 첫째 달에 10% 상승하고 둘째 달에 20% 상승하게 된다면 누적 수익률은 30%가 아닌, 32%가 됩니다. 아래 예시를 한 번 살펴보겠습니다.
기존 | 10,000원 | 0% |
첫째달 | 11,000원 | 10% 상승 |
둘째달 | 13,200원 | 20% 상승 |
누적 수익률 | 32% 상승 |
따라서 수익률이 각각 r1, r2 일 때, 누적수익률은 r1 + r2 가 아니라, (1+r1)*(1+r2)-1 로 계산하게 됩니다.
이번에는 DataFrame의 유용한 함수인 cumprod를 사용해보겠습니다. cumprod는 누적 곱을 계산해주는 함수로, 첫행부터 이전행까지의 곱한 값을 반환해줍니다.
# 2.누적 수익률 계산
df_PROFIT_ACC = (1+df_PROFIT).cumprod()-1
df_PROFIT_ACC
결과 DataFrame)
3.월별 log 수익률
주가 데이터를 분석할 때 log 수익률로 차트를 그려서 보는 이유는 아래 포스팅에서 잘 설명하여 공유합니다 : )
import numpy as np
#3.월별 log 수익률 계산
df_LOG_PROFIT = np.log(df_PROFIT+1)
df_LOG_PROFIT
결과 DataFrame)
4.누적 log 수익률
#4.누적 log 수익률 계산
df_LOG_PROFIT_ACC = df_LOG_PROFIT.cumsum()
df_LOG_PROFIT_ACC
결과 DataFrame)
5.전체 소스 코드
위의 각각의 항목에서는 새로운 DataFrame을 만들어서 월별 수익률, 누적 수익률, 월별 log 수익률, 누적 log 수익률을 따로 담고 표기하였지만, 저는 실제로 백테스트를 진행할 때에는 아래와 같이 기존의 주가 DataFrame에 필드를 추가해서 여러 수익률들을 함께 표기합니다. 이는 백테스트를 진행하는 당사자가 어떤 것이 더 편한지에 따라 다르니 편하신대로 사용하시면 됩니다 : )
# 각 자산별 수익률 계산
col_list_P = [col+'_P' for col in df_PRICE[TICKER].columns]
col_list_PA = [col+'_PA' for col in df_PRICE[TICKER].columns]
col_list_LP = [col+'_LP' for col in df_PRICE[TICKER].columns]
col_list_LPA = [col+'_LPA' for col in df_PRICE[TICKER].columns]
df_PRICE[col_list_P] = df_PRICE[TICKER].pct_change()
df_PRICE[col_list_PA] = (1+df_PRICE[col_list_P]).cumprod()-1
df_PRICE[col_list_LP] = np.log(df_PRICE[col_list_P]+1)
df_PRICE[col_list_LPA] = df_PRICE[col_list_LP].cumsum()
# 백분율을 %로 전환
df_PRICE[col_list_P+col_list_PA+col_list_LP+col_list_LPA] = df_PRICE[col_list_P+col_list_PA+col_list_LP+col_list_LPA] * 100
결과 DataFrame)
위에서 구한 누적 log 수익률을 그래프로 나타내보겠습니다. (그래프 그리는 방법은 따로 또 포스팅 해볼게요😁)
그래프를 보니 수익률이 정상적으로 잘 구해진 것 같습니다. 포스팅 내용 중 이해가 되지 않거나, 문의가 있으시면 언제든지 댓글로 남겨주세요~!
공감과 댓글, 공유는 큰 힘이 됩니다!
도움이 되셨다면 널리널리 알려주세요😉