Notice
Recent Posts
Recent Comments
Link
유자차의 재테크 공부방
[동적자산배분] HAA - 파이썬으로 직접 백테스트하기 (1) 본문
반응형
import pandas as pd
import yfinance as yf
# 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
agg_tickers = ["SPY","IWM","VEA","VWO","TLT","IEF","PDBC","VNQ"]
safe_tickers = ["IEF","BIL"]
all_tickers = list(set(agg_tickers+safe_tickers+["TIP"]))
data = get_yahoo_data(all_tickers)
month_data = get_rebal_date(data)
safe_num = 0
agg_num = 0
buy_history = []
# logic
# TLT 1-3-6-12 모멘텀 점수 구하기
for i in range(12, month_data.shape[0]):
m1 = (month_data["TIP"].iloc[i]-month_data["TIP"].iloc[i-1])/month_data["TIP"].iloc[i-1]
m3 = (month_data["TIP"].iloc[i]-month_data["TIP"].iloc[i-3])/month_data["TIP"].iloc[i-3]
m6 = (month_data["TIP"].iloc[i]-month_data["TIP"].iloc[i-6])/month_data["TIP"].iloc[i-6]
m12 = (month_data["TIP"].iloc[i]-month_data["TIP"].iloc[i-12])/month_data["TIP"].iloc[i-12]
score = m1 + m3 + m6 + m12
# print("TLT 모멘텀 스코어 : {}".format(score))
if score > 0:
# print("상승장")
agg_num+=1
asset_type = agg_tickers
m1 = (month_data[asset_type].iloc[i]-month_data[asset_type].iloc[i-1])/month_data[asset_type].iloc[i-1]
m3 = (month_data[asset_type].iloc[i]-month_data[asset_type].iloc[i-3])/month_data[asset_type].iloc[i-3]
m6 = (month_data[asset_type].iloc[i]-month_data[asset_type].iloc[i-6])/month_data[asset_type].iloc[i-6]
m12 = (month_data[asset_type].iloc[i]-month_data[asset_type].iloc[i-12])/month_data[asset_type].iloc[i-12]
score = m1 + m3 + m6 + m12
# print("공격자산 모멘텀 스코어 : {}".format(score))
top4 = score.nlargest(4)
buy=[]
for name, value in zip(top4.index, top4.values):
if value <= 0:
buy.append("BIL")
else:
buy.append(name)
else:
# print("하락장")
safe_num+=1
asset_type = safe_tickers
m1 = (month_data[asset_type].iloc[i]-month_data[asset_type].iloc[i-1])/month_data[asset_type].iloc[i-1]
m3 = (month_data[asset_type].iloc[i]-month_data[asset_type].iloc[i-3])/month_data[asset_type].iloc[i-3]
m6 = (month_data[asset_type].iloc[i]-month_data[asset_type].iloc[i-6])/month_data[asset_type].iloc[i-6]
m12 = (month_data[asset_type].iloc[i]-month_data[asset_type].iloc[i-12])/month_data[asset_type].iloc[i-12]
score = m1 + m3 + m6 + m12
# print("안전자산 모멘텀 스코어 : {}".format(score))
buy = list(score.nlargest(1).index)
buy_history.append(buy)
df_buy = pd.DataFrame(buy_history)
df_buy["Date"] = month_data.index[12:]
df_buy.set_index("Date", drop=True, inplace=True)
df_buy.fillna("", inplace=True)
print("상승장 : 하락장 비율 = {:.1f}% : {:.1f}%".format(agg_num/(agg_num+safe_num)*100, safe_num/(agg_num+safe_num)*100))
상승장은 71.6% 하락장은 38.4%으로 나왔다. 상승장이 하락장의 2배 이상!!
강환국님의 영상에서 상승장은 86% 하락장은 14%정도였는데, 기간에 달라서일 듯( 1971-2023.01)
2015년 12월부터 2023년 3월까지 안전자산인 경우가 25번인데
이 중 IEF는 4번밖에 안나왔다. 안전자산으로 가라 = 현금으로!! 인듯
반응형
'자산배분' 카테고리의 다른 글
[자산배분] 스노우볼72 : 자산배분 전략 백테스트 사이트 (0) | 2023.03.20 |
---|---|
[자산배분] 스노우볼72로 BAA전략 만들기 (0) | 2023.03.20 |
[동적 자산배분] HAA (0) | 2023.03.18 |
[동적 자산배분] 동적 자산배분 전략들 (0) | 2023.03.07 |
[동적 자산배분] 종합 듀얼 모멘텀- 파이썬으로 직접 백테스팅하기 - (1) (0) | 2023.03.02 |
Comments