유자차의 재테크 공부방

[자산분배] 변형(수정) 듀얼 모멘텀 - 파이썬으로 직접 백테스팅하기-(1) 본문

자산배분

[자산분배] 변형(수정) 듀얼 모멘텀 - 파이썬으로 직접 백테스팅하기-(1)

유자차H 2022. 12. 5. 19:08
반응형

변형(수정) 듀얼 모멘텀 전략에 따라 다음과 같이 구현하여 매월말 투자할 종목을 구해보았습니다.

 

전략 로직
1. 공격형 자산의 최근 1년 수익률 비교하여 높은 1개에 투자
2. 만약 SPY가 0이하이면, 안전형 자산 8개의 최근 6개월 수익률 비교하여 가장 점수가 높은 자산 3개(Top3)에 투자
3. Top3 중 0이하인 ETF는 현금(BIL)로 대체
 
 
import pandas as pd
import yfinance as yf # 야후 파이낸스 부르기

ticker_agg = ["SPY", "EFA"]
ticker_safe = ["SHY", "IEF", "TLT", "TIP", "LQD", "HYG", "BWX", "EMB"]
ticker_all = ticker_agg+ticker_safe+["BIL"]

# 데이터 불러오기
df = yf.download(ticker_all) # 야후 파이낸스에서 tickers에 해당하는 데이터 모두 불러오기
df = df["Adj Close"] # 불러온 데이터 중 Adj Close 데이터만 
df.dropna(inplace=True) # 데이터가 없는 곳이 있는 행은 삭제

# 월말 데이터만 뽑기
rebal_data = pd.DataFrame() # 월말 데이터 저장할 곳
df["year"] = df.index.year # year정보 담긴 year 열 만들기
df["month"] = df.index.month # month 정보 담긴 month 열 만들기
df["day"] = df.index.day # day 정보 담긴 day 열 만들기
days_df = df.groupby(["year","month"])["day"].max() # year, month로 그룹해서 day들 중 최대값만 뽑음
for i in range(len(days_df)): # 위 과정을 통해 뽑힌 데이터 중 day 값이 25일 이상 되면 rebal_data에 저장
    if days_df.iloc[i] >= 25: 
        day = "{}-{}-{}".format(days_df.index[i][0], days_df.index[i][1], days_df.iloc[i])
        rebal_data = pd.concat([rebal_data,df[df.index==day]])

rebal_data.head()

 

for i in range(12, rebal_data.shape[0]):
    date = rebal_data.index[i]
    print(date)
    # 최근 12개월 수익률 구하기
    agg_m12 = rebal_data[ticker_agg].iloc[i]/rebal_data[ticker_agg].iloc[i-12] -1
    
    res={}
    if agg_m12["SPY"] < 0:
        # safe
        safe_m6 = rebal_data[ticker_safe].iloc[i]/rebal_data[ticker_safe].iloc[i-6] -1
        safe_top3 = safe_m6.nlargest(3)
        bil_m6 = rebal_data["BIL"].iloc[i]/rebal_data["BIL"].iloc[i-6] -1

        for j in range(3):
            if safe_top3.iloc[j] <= bil_m6:
                name = "BIL"
            else:
                name = safe_top3.index[j]
            
            if name in res.keys():
                res[name] += 100/3
            else:
                res[name] = 100/3
        
    else:
        # aggresive
        agg_top1 = agg_m12.nlargest(1)
        res[agg_top1.index[0]] = 100.0
    
    print("매수할 종목 : ", res)
    print("="*50)

 

강환국님이 매월 말에 올려주는 동적 자사배분을 보면(2022.11부터 추가)

다음과 같이 투자하라고 나옵니다.

11월 - 변형 듀얼모멘텀: 현금 100%
12월 - 변형 듀얼모멘텀: 현금 100%
 
강환국님이 올려주신 것과 제 결과와 같습니다.
하지만 변형 듀얼 모멘텀을 추가한지 아직 2개월 밖에 되지 않아
2개월의 결과만 보고는 구현한 것이 백퍼센트 맞다고 하지 못하겠습니다.
 
구현에 있어 잘못된 부분을 발견하신다면 알려주세요!!

 

반응형
Comments