본문 바로가기

재테크

VAA 공격형 전략 Python 자동화 코드

 퀀트투자에 대한 관심으로 3월 초에 강환국 작가의 "거인의 포트폴리오"라는 책을 읽었다. 책에 소개된 전략들 중 VAA 공격형 전략으로 직접 투자해보고 싶었다. 특징과 조건은 아래와 같다.

 

VAA 공격형 전략

  • 특징
    • 가장 높은 수익률
    • 하지만 최근 수익률이 매우 저조함
  • 자산 종류
    • 공격형 자산 : 미국 주식(SPY), 선진국 주식(EFA), 개발도상국 주식(EEM), 미국 혼합채권(AGG)
    • 안전자산 : 미국 회사채(LQD), 미국 중기국채(IEF), 미국 단기국채(SHY)
  • 전략
    • 매월 말 1회 리밸런싱
    • 모멘텀 스코어 : (12 * 1개월 수익률) + (4 * 3개월 수익률) + (2 * 6개월 수익률) + (1 * 12개월 수익률)
    if all(공격형 자산 모멘텀 스코어) >= 0:
    	투자(max(공격형 자산 모멘텀 스코어))
    else:
    	투자(max(안전자산 모멘텀 스코어))

 하지만 이 방법은 위처럼 직접 수집해야 할 정보가 상당히 많아 번거롭다. 그래서 자동화 코드를 만들었다. 코드를 구현한지는 좀 됐지만 어쩌다보니 글을 쓰는 걸 계속 미루게 되었다. 코드는 python의 라이브러리인 FinanceDataReader의 힘을 빌렸다.(만약 사용하시려는 분이 있다면 라이브러리 설치 후 사용하시기 바랍니다.)

 

"""VAA 공격형 전략
강환국 <거인의 포트폴리오>에 나온 VAA 공격형 전략의 ETF를 뽑아주는 코드입니다.
FinanceDataReader API를 활용했으며, 코드를 실행한 날짜 기준으로 ETF를 뽑아줍니다."""

from FinanceDataReader import DataReader
from datetime import timedelta

date_start = '20210101'
AGGRESSIVE_ASSET_LIST = ['SPY', 'EFA', 'EEM', 'AGG']
SAFE_ASSET_LIST = ['LQD', 'IEF', 'SHY']
TOTAL_ASSET_LIST = AGGRESSIVE_ASSET_LIST + SAFE_ASSET_LIST
vaa_etf_data_dict = dict()
for etf_name in TOTAL_ASSET_LIST:
    vaa_etf_data_dict[etf_name] = DataReader(etf_name, date_start)

SPY = vaa_etf_data_dict['SPY']
today = SPY.index[-1]

one_year_ago = today - timedelta(365)
six_month_ago = today - timedelta(365//2)
three_month_ago = today - timedelta(365//4)
one_month_ago = today - timedelta(365//12)
date_list = [one_year_ago, six_month_ago, three_month_ago, one_month_ago]
point = [1, 2, 4, 12]

def momentum_score(etf_name):
    """이름이 etf_name인 ETF의 모멘텀 스코어 리턴"""
    etf_data = vaa_etf_data_dict[etf_name]
    today_price = etf_data.loc[today].Close
    score = 0
    print(f'{etf_name} 과거 수익률', ':', end=' ')
    for i in range(4):
        date = date_list[i]
        past_price = etf_data.loc[etf_data.index > date].iloc[0].Close
        earning_rate = (today_price - past_price) / past_price * 100
        print(f'{earning_rate:.3f}%', end=' | ')
        score += point[i] * earning_rate
    print()
    return score

etf_scores = []

print("공격형 자산")
for etf_name in AGGRESSIVE_ASSET_LIST:
    score = momentum_score(etf_name)
    etf_scores.append(score)
    print("{} 모멘텀 스코어 : {:.2f}".format(etf_name, score))

print('-----------------------------------------------------')
print("안전자산")
for etf_name in SAFE_ASSET_LIST:
    score = momentum_score(etf_name)
    etf_scores.append(score)
    print("{} 모멘텀 스코어 : {:.2f}".format(etf_name, score))


invest_aggressively = True
for i in range(len(AGGRESSIVE_ASSET_LIST)):
    if etf_scores[i] < 0:
        invest_aggressively = False


print()
if invest_aggressively:
    print("모든 공격형 자산의 스코어가 0 이상이므로")
    print("모멘텀 스코어가 가장 높은 \"공격형 자산\"에 투자합니다.")
    aggressive_scores = etf_scores[:len(AGGRESSIVE_ASSET_LIST)]
    selected = AGGRESSIVE_ASSET_LIST[aggressive_scores.index(max(aggressive_scores))]
else:
    print("스코어가 0미만인 공격형 자산이 있으므로")
    print("모멘텀 스코어가 가장 높은 \"안전 자산\"에 투자합니다.")
    safe_scores = etf_scores[len(AGGRESSIVE_ASSET_LIST):]
    selected = SAFE_ASSET_LIST[safe_scores.index(max(safe_scores))]

print(f'투자할 종목 : <{selected}>')