[컴퓨터] 경제적 독립하기/[투자] Project tatabox

듀얼 모멘텀(VAA)전략을 이용한 호주 ETF 매수매도 백테스팅 해보기

Bright_Ocean 2020. 7. 10. 21:30
반응형

 

 

안녕하세요

Bright_Ocean 입니다.

최근들어서 호주 주식 투자를 위한 계량적 방법을 많이 고민하고 있는데요.

오늘은 벡테스팅해본것이 있어 한번 올려 보려고 합니다.

 

 

 

https://allocatesmartly.com/vigilant-asset-allocation-dr-wouter-keller-jw-keuning/

 

Vigilant Asset Allocation from Dr. Wouter Keller and JW Keuning - AllocateSmartly

This is a test of the “Vigilant Asset Allocation” (VAA) strategy from the recently published paper: Breadth Momentum and Vigilant Asset Allocation, by Dr. Wouter Keller and JW Keuning. This is an aggressive momentum trading model, similar in spirit to

allocatesmartly.com

 

최근 Keller 선생님의

듀얼 모멘텀의 업그레이드 버전인 

Vigiland Asset Allocation(VAA)에 관한 위의 포스팅을 본적이 있습니다.

 

 

 

 

방법이 매우 직관적이고 전략도 자세히 나와있어서

한번 호주시장에 올라온 ETF로 따라해 볼까? 라는 생각이 들어 백테스팅을 하였습니다.

 

 

 

 

이 전략을 백테스팅하려면 우선 종가 데이터가 필요합니다.

지난 가격데이터는 invesing.com에 올라와 있어 그것을 모두 다운로드 하여 사용하였습니다.

 

 

 

 

우선 10년이상 주식으로 이루어진 ETF를 CommSec에서 찾아보았는데...

엥?? 몇개 없습니다.

그중 서로 시장이 다른 4개를 추려서 테스팅을 해보기로 하였습니다.

 

제가 고른 ETF는

 

 

 

1. iShares MSCI Emerging Markets (IEM)

2. iSharesEurope (IEU)

3. iShares Core S&P 500 (IVV)

4. SPDR S&P/ASX 200 Fund (STW)

 

 

 

요렇게 미국, 호주, 유럽, 이머징 마켓을 두루 골라보았습니다.

실제 포스팅에서는 Aggregate bond ETF도 들어가 있지만 

데이터가 없어 구하지 못하였습니다.

 

 

 

저는 이번전략에서 공격형 방어형의 자산을 나누지 않고 공격형만 같은 전략으로 투자했을때

과연 얼마나 이윤이 나올 것인가 만을 보고 싶었기 때문에 

방어형 자산으로 들어가있는경우는 그냥 같은 금액으로 두기로 하였습니다.

 

 

전략은 아래와 같습니다.

 

 

p0 = 현재가격, p1 = 1달전가격, p3 = 3달전 가격, p6 = 6달전 가격, p12 = 12달전 가격

모멘텀 = (12 * (p0 / p1 – 1)) + (4 * (p0 / p3 – 1)) + (2 * (p0 / p6 – 1)) + (p0 / p12 – 1)

 

 

1. 모든 ETF의 모멘텀이 0 이상일시,

가장 높은 모멘텀을 가진 ETF로 100% 투자한다

 

2. 하나의 모멘텀이라도 0 이하로 떨어질 시.

현금 100% 를 가진다.

매달 리밸런싱을 한다.

 

 

 

 

 

우선 가격데이터의 변화 부터 보시지요.

2007년 11월 부터 현재까지의 데이터의 변화 입니다.

 

 

 

최근 코로나 바이러스로 인한 낙폭이 저의 마음을 아프게 하네요 ㅜㅜㅜ

물론 저도 재대로 쳐맞아서 복구중에 있습니다...

 

코드도 올려드릴게요

 

 

 

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

#data input
IEM = pd.read_csv("IEM.csv").sort_index(ascending = False)
IEU = pd.read_csv("IEU.csv").sort_index(ascending = False)
IVV = pd.read_csv("IVV.csv").sort_index(ascending = False)
STW = pd.read_csv("STW.csv")
STW = STW.iloc[:153, :].sort_index(ascending = False)

#price data
IEM_price = IEM['Price']
IEU_price = IEU['Price']
IVV_price = IVV['Price']
STW_price = STW['Price']

#plotting
plt.plot(IEM['Date'], IEM_price, label = 'IEM')
plt.plot(IEU['Date'], IEU_price, label = 'IEU')
plt.plot(STW['Date'], STW_price, label = 'STW')
plt.legend(loc = 'best')

 

 

자 이제 전략에 필요한 코드들을 한번 짜봅시다.

 

 

#cal momentum
def momentum_cal(ETF_price):
    momentum = []
    for i in range(len(ETF_price)):
        if i >= 12:
            mo = (12 * (ETF_price[i]/ETF_price[i-1] -1)) + \
            (4 * (ETF_price[i]/ETF_price[i-3] -1)) + \
            (2 * (ETF_price[i]/ETF_price[i-6] -1)) + \
            (ETF_price[i]/ETF_price[i-12] -1)
            momentum.append(mo)
    return momentum  

#momentum
IEM_momentum = momentum_cal(IEM_price)
IEU_momentum = momentum_cal(IEU_price)
IVV_momentum = momentum_cal(IVV_price)
STW_momentum = momentum_cal(STW_price)

#price
IEM_price = IEM_price[:141]
IEU_price = IEU_price[:141]
IVV_price = IVV_price[:141]
STW_price = STW_price[:141]

#df momentum + price
IEM_df = pd.DataFrame({'price':list(IEM_price), 'momentum':IEM_momentum})
IEU_df = pd.DataFrame({'price':list(IEU_price), 'momentum':IEU_momentum})
IVV_df = pd.DataFrame({'price':list(IVV_price), 'momentum':IVV_momentum})
STW_df = pd.DataFrame({'price':list(STW_price), 'momentum':STW_momentum})

 

 

먼저 모멘텀에 필요한 함수를 만들고 각각의 price데이터에 적용시켜서 mometum을 구해보았어요.

 

 

 

이제 이 모멘텀을 전략에 맞게 투자하였을 때 어떤 결과가 나오는지 함께 보시죠

기본자금은 10000 즉, AUD $10000 을 투자하였을 때 결과가 어떤지 살펴보았습니다.

 

 

def money_cal(df, initial_price):
    stock_number = int(initial_price / df['price'][i])
    current_money = stock_number * df['price'][i]
    cash = initial_price - current_money
    next_money = stock_number * df['price'][i+1]
    money = next_money + cash
    initial_price = money
    return initial_price
    
    
#cal price    
initial_price = 10000
asset_list = [initial_price]
IEM_num = 0
IEU_num = 0
IVV_num = 0
STW_num = 0
for i in range(len(IEM_df)-1):
    if IEM_df['momentum'][i] >= 0 and IEU_df['momentum'][i] >= 0 \
    and IVV_df['momentum'][i] >= 0 and STW_df['momentum'][i] >= 0:
        max_momentum = max(IEM_df['momentum'][i],IEU_df['momentum'][i],IVV_df['momentum'][i],STW_df['momentum'][i])

        if max_momentum > 0:
            if max_momentum == IEM_df['momentum'][i]:
                initial_price = money_cal(IEM_df, initial_price)
                IEM_num += 1
                asset_list.append(initial_price)
            elif max_momentum == IEU_df['momentum'][i]:
                initial_price = money_cal(IEU_df, initial_price)
                IEU_num += 1
                asset_list.append(initial_price)
            elif max_momentum == IVV_df['momentum'][i]:
                initial_price  = money_cal(IVV_df, initial_price)
                IVV_num += 1
                asset_list.append(initial_price)
            elif max_momentum == STW_df['momentum'][i]:
                initial_price = money_cal(STW_df, initial_price)
                STW_num += 1
                asset_list.append(initial_price)
        else: 
            initial_price == initial_price
            asset_list.append(initial_price)
    else:
        initial_price == initial_price
        asset_list.append(initial_price)

 

기본자산에서 최대로 구매할 수 있는 stock 수를 먼저 계산한 뒤 구매할 수 있는 최대 금액을 뺀 

나머지는 현금 cash로 남겨 두었습니다 (코드에 생성된 함수의 부분입니다)

식으로 나타내보면 아래와 같습니다.

 

구매 가능 자산 = int((총자산 / stock price)) * stock price

남은 자산  = 총자산 - 구매가능 자산

 

그런뒤에

한달 뒤 변환 ETF의 거래가격에 stock 수를 곱해서 한달 뒤 변한 총 가격에서 cash를 더해주면

다음달 변한 가격이 됩니다.

 

한달 후 stock 자산 = 한달후 가격 * 구매했던 stock 수

한달후 자산 = 한달 후 stock 자산 + 위에서 계산한 남은 자산

 

 

최종적인 결과를 한번 살펴볼까요?

 

 

 

 

안타깝게도 자산이 점점 줄어드는 것을 볼수 있습니다 ㅜㅜ

다시 한번 가격데이터와 함께 비교해 보도록 해보죠.

 

 

 

 

VAA의 장점이 하락장에는 빠르게 빠져나와 손실을 최소한으로 줄이고 

상승장에 들어가서 이윤을 먹고 나오는 전략인데 

이상하게 해당기간에는 손실은 큰것에 비해 상승장에서는 이윤을 많이 못내는 것이 보입니다.

 

 

 

원래는 MDD 와 Annualized return 그래프도 그려볼 생각이였으나.....

너무 결과가 좋지 못하여 다음에 도전해볼 생각입니다.

저는 이 전략으로 처음에 투자를 할생각이였는데,

백테스트를 안했다면 큰일날 뻔했네요.

 

 

 

 

이 전략에 대한 코드를 짜면서 해당 전략은 모멘텀을 구할때

1달의 변화에 많은 가중치를 주게 되는데

1달전 변화율을 빼는 다른 전략들과 상충되어

궁금증이 생겼습니다.

 

 

 

실제로 모든 가중치를 같은 비중으로 둘 때

해당 기간에서는 더 좋은 결과를 보입니다.

하지만 그래도 손실입니다.

 

 

 

 

이 코드에는 거래 수수료가 들어가 있지 않으니

거래 수수료까지 고려한다면

좋지 못한 결과라고 할 수 있겠습니다.

 

 

다음에는 다른 백테스팅으로 돌아올게요.

 

다음에 다시 만나요

 

반응형