본문 바로가기
문송충의 코딩하기/퀀트 투자 스터디

파이썬으로 라오어 무한매수법 백테스팅, 이렇게 하는게 맞나?

by 동장군님 2022. 1. 14.
728x90
반응형

최근에 읽은 "라오어 무한매수법"이라는 책이 굉장히 인상 깊어서 파이썬으로 이러한 전략이 실제로 통하는지 백테스팅을 해보고자 한다. 우선 밑밥부터 깔자면 나는 문과생 출신으로 파이썬을 그렇게 잘하지 않고, 백테스팅은 이번이 처음이라 더더욱 익숙지 않다. 처음 연습 삼아서 하는 것으로 참고만 해주셨으면 한다.  계속 공부하고 있어 다음에는 이것보다 훨씬 정교하게 만들어보겠다. 


우선 분석에 필요한 라이브러리를 가져오도록 하겠다.

import pandas as pd
import yfinance as yf
import numpy as np
import matplotlib.pyplot as plt

다음으로는 무한매수법에 가장 많이 활용되는 3배 레버리지 ETF TQQQ 가격을 가져오도록 하겠다. 라오어 무한매수법을 정확하게 검증하려면 평단가를 기준으로 매수를 진행하는데 이걸 백테스트로 할 수가 없어서 여기서는 종가 기준으로 하겠다. 전날 종가보다 당일 종가가 높으면 1주만 매수하고 당일 종가가 낮으면 2주를 매수하는 걸로 기준을 잡았다. 마지막으로는 최대 40일까지 이 전략을 실행하는 걸로 코드를 작성했다.

tqqq=yf.download('TQQQ',start='2010-01-01')
df=pd.DataFrame(tqqq['Adj Close'])

df['diff']=(df['Adj Close']-df['Adj Close'].shift()).fillna(0)
number =[]
for i in df['diff']:
    if i>=0:
        number.append(1)
    elif i<0:
        number.append(2)

df['number']=number
df['amount']=df['Adj Close']*df['number']

df['buy']=df['amount'].rolling(window=40).sum()/df['number'].rolling(window=40).sum()
df['profit']=df['Adj Close']/df['buy']-1

40일째가 되는 날에 내 평단가와 종가를 비교해서 수익률을 계산해봤다. 2010년 이후 40일 기준 매일 무한매수법 투자를 했을 때 일자별로 수익이 어떻게 되는지 계산해보았고, 그래프로 시각화하면 다음과 같다. 

plt.figure(figsize=(12,8))
plt.plot(df.index,df.profit)

역시 재작년 코로나가 터진 시점 수익률이 개박살난 점을 확인할 수 있다. 전반적으로는 수익률 변동성이 굉장히 크다고 보인다.

 

좀 더 정확하게 수익률을 확인하기 위해서 연도별로 수익을 기록한 날짜를 세보도록 그래프로 시각화해보도록 하겠다. 

df=df.reset_index()
df['year']=df['Date'].apply(lambda x:x.year)
df['gubun']=df['profit'].apply(lambda x: '>5%' if x>0.05 else('0%' if x >= 0.0 else 'N'))

dff=pd.DataFrame(df.groupby(['year','gubun']).count()['profit']).reset_index()
dff['year']=dff['year'].astype(str)

tb=pd.pivot(dff,'year','gubun','profit')

fig,ax=plt.subplots(figsize=(12,6))
bar_width =0.25
index=np.arange(len(tb))

b1=plt.bar(index,tb['0%'],bar_width, alpha=0.4,color='red',label='0%~5%')
b2=plt.bar(index+bar_width,tb['>5%'],bar_width, alpha=0.4,color='blue',label='>5%')
b3=plt.bar(index+2*bar_width,tb['N'],bar_width, alpha=0.4,color='black',label='minus')

plt.xticks(np.arange(bar_width,len(index)+bar_width,1),tb.index.values)

def autolabel(rects):
    """Attach a text label above each bar in *rects*, displaying its height."""
    for rect in rects:
        height = rect.get_height()
        ax.annotate('{}'.format(height),
                    xy=(rect.get_x() + rect.get_width() / 2, height),
                    xytext=(0, 3),  # 3 points vertical offset
                    textcoords="offset points",
                    ha='center', va='bottom')

autolabel(b1)
autolabel(b2)
autolabel(b3)

fig.tight_layout()

plt.xlabel('Year',size=12)
plt.xlabel('Counts',size=12)
plt.legend()
plt.show()

확실히 5% 이상 수익률을 기록한 날짜가 마이너스 수익률보다 많은 점을 알 수 있다. 다만 2015년, 2011년, 2018년의 경우 마이너스 수익률이 많다.

위 백테스팅은 백 프로 정확하지가 않다. 종가 기준으로 했기 때문이다. 실제로는 대부분 평단가보다 낮은 가격에 매수할 가능성이 높고, 가격이 평단가보다 엄청 높을 경우 매수가 안될 가능성이 있어서 실제로 진행할 경우 이거보다 수익률은 더 좋을 것이다. 앞으로도 이런 식으로 몇 가지 전략을 검증하도록 하겠다.

728x90
반응형

댓글