유자차의 재테크 공부방

[자산배분] BAA - 파이썬으로 직접 백테스팅 해보기 - (1) 본문

자산배분

[자산배분] BAA - 파이썬으로 직접 백테스팅 해보기 - (1)

유자차H 2022. 9. 5. 18:16
반응형

BAA 전략을 모르신다면 BAA 이론 정리한 게시물을 읽고 오시면 되겠습니다!

 

사용하는 라이브러리는 다음과 같습니다.

import pandas as pd
import yfinance as yf # 주가 데이터 받기위한 라이브러리
import quantstats as qs # 리포트 형식으로 시각화해주는 라이브러리

 

# yahoo finance에서 필요 종목들의 공통 시작일부터 종가 데이터 받기
def get_yahoo_data(tickers, get_type="Adj Close"):
    df = yf.download(tickers)
    df = df[get_type]
    df.dropna(inplace=True)
    return df

# 리밸런싱 하는 날의 데이터만 뽑기(월말 데이터만 추출)  
def get_rebal_date(df, rebal="month"):
    res_df = pd.DataFrame()
    df["year"] = df.index.year
    df["month"] = df.index.month
    df["day"] = df.index.day
    days_df = df.groupby(["year","month"])["day"].max()
    for i in range(len(days_df)):
        if days_df.iloc[i] > 25:
            day = "{}-{}-{}".format(days_df.index[i][0], days_df.index[i][1], days_df.iloc[i])
            res_df = pd.concat([res_df,df[df.index==day]])
    return res_df

# 필요한 종목의 ticker들
tickers_canary = ["SPY","EEM","EFA","AGG"]
tickers_g4 = ["QQQ","EEM","EFA","AGG"]
tickers_g12 = ["SPY", "QQQ", "IWM","VGK","EWJ", "EEM", "VNQ","DBC","GLD", "TLT", "HYG", "LQD"]
tickers_safe = ["TIP","DBC","BIL","IEF","TLT","LQD","AGG"]
tickers_all = list(set(tickers_canary+tickers_g4+tickers_g12+tickers_safe))
data = get_yahoo_data(tickers_all) # 모든 데이터
rebal_data = get_rebal_date(data) # 월말 데이터
rebal_data.head(3)

각 종목의 월말 데이터만 추출되어 나옵니다.

 

 

canary_data = rebal_data[tickers_canary]
profit = rebal_data.pct_change()
n=12
for i in range(n, rebal_data.shape[0]):
    print(rebal_data.index[i])
    
    # 1-3-6-12 점수 구하기
    m1 = (canary_data.iloc[i]-canary_data.iloc[i-1])/canary_data.iloc[i-1]
    m3 = (canary_data.iloc[i]-canary_data.iloc[i-3])/canary_data.iloc[i-3]
    m6 = (canary_data.iloc[i]-canary_data.iloc[i-6])/canary_data.iloc[i-6]
    m12 = (canary_data.iloc[i]-canary_data.iloc[i-12])/canary_data.iloc[i-12]
    score = m1*12 + m3*4 + m6*2 +m12

    buy = dict()
    if min(score) <= 0: # 안전자산
        safe = rebal_data[tickers_safe].iloc[i] / rebal_data[tickers_safe].iloc[i-n:i].mean()
        safe_top3 = safe.nlargest(3)
        for j in range(3):
            try:
                if safe_top3[j] > safe["BIL"]:
                    name = safe_top3.index[j]
                else:
                    name = "BIL"
                buy[name] += (1/3)*100
            except:
                buy[name] = (1/3)*100
        print("safe : ", buy)
    else: # 공격형(g4) 또는 중도형(g12)
        g4 = rebal_data[tickers_g4].iloc[i] / rebal_data[tickers_g4].iloc[i-n:i].mean()
        g4_top1 = g4.nlargest(1)
        buy[g4_top1.index[0]] = 100
        print("G4 : ", buy)
        buy=dict()
        g12 = rebal_data[tickers_g12].iloc[i] / rebal_data[tickers_g12].iloc[i-n:i].mean()
        g12_top6 = g12.nlargest(6)
        for j in range(6):
            buy[g12_top6.index[j]] = (1/6)*100 
        print("G12 : ", buy)

카나리아 항목만 가져와서 1-3-6-12 점수를 구합니다.

1-3-6-12 점수 구하는 방법

최근 1개월 수익률*12 + 최근 3개월 수익률*4 + 최근 6개월 수익률*2 + 최근 12개월 수익률*1

 

1-3-6-12 점수에 따라 안전자산 또는 공격형 자산에 투자하는 자산 종목을 프린트하게 만들었습니다.

공격형 자산에 투자할 종목을 뽑는 방법은

현재 종가/(전월 부터 12개월 전 종가의 평균)으로 계산했을때 가장 높은 1종목 또는 6종목에 투자합니다.

 

파이썬으로 직접 돌린 것에서 보면 8월말에 DBC 33.3% BIL 66.6%를 사라고 합니다.

강환국님이 올려준 9월 "나라면 이런거 사겠다 동적자산배분"에서 직접 구한 결과와 같이 동일하게 사라고 합니다.

 

처음으로 전략을 파이썬으로 구현해본 것이였는데 구현이 잘 되어서 다행이네요.

 

이번 게시물에서 quantstats 라이브러리를 사용하는 것을 보이지 않았습니다.

다음 게시물에서 이 전략이 시키는데로 샀을 때, 수익률이 얼마나나는지 구하고, quantstats로 시각화해보겠습니다.

반응형
Comments