6편과 7편에서 평균모멘텀 전략과 해당 전략의 수익곡선 모멘텀까지 적용한 전략을 살펴보고 백테스트 결과를 공유하였다. 결과를 공유하며 평균모멘텀 전략에서 해당 전략의 모멘텀을 산출하여 각 자산의 비중을 산출하는 Algo클래스를 상속받은 WeighAMS 클래스의 설명을 생략하였는데 오늘은 WeighAMS() 만 다루도록 하겠다.
WeighAMS 클래스는 투자자산의 12개월 평균모멘텀을 산출하여 비중을 할당하는 기본 기능과 수익률 곡선이 있는 경우 수익곡선 모멘텀을 산출하여 안전자산의 최소비중을 우선 할당한 후에 투자자산의 평균모멘텀에 따라 각 자산의 투자비중을 계산하는 기능을 포함하고 있다.
생성자를 먼저 살펴보자.
def __init__(self, lag=1, cash_weight=0.0, returns=pd.DataFrame(), ylookback=12):
if (not returns.empty) & (ylookback < 1):
raise ValueError("lookback of Yield can't be less than 0")
super(WeighAMS, self).__init__()
self.lag = lag
self.cash_weight = cash_weight
self.returns = returns
self.ylookback = ylookback
첫번째 파라미터인 lag는 지연일을 의미하며 리밸런싱 하는 당일에 모멘텀 판단을 위한 반추기간의 마지막 날짜의 기준이다. 즉, 지연일의 기본값인 '1' 이 의미하는 바는 리밸런싱 당일에 모멘텀을 판단하기 위한 반추기간의 날짜를 하루전까지의 데이터를 사용한다는 의미이다. 두번째 파라미터인 cash_weight은 안전자산의 최소 비중을 의미한다. 기본값인 '0.0' 은 투자자산의 초기 비중을 50:50으로 한다는 의미가 된다. 총 투자금의 10%를 안전자산으로 유지하고자 한다면 '0.1' 로 설정하면 된다. 세번째 파라미터는 수익곡선이며 네번째 파라미터는 수익곡선의 모멘텀을 산출할 때의 반추기간을 의미한다.
다음은 평균모멘텀 스코어를 계산하는 정적 메소드이다.
@staticmethod
def avg_momentum_score(prc_monthly, lookback):
sumOfmomentum = 0
sumOfscore = 0
for i in range(1, lookback+1):
sumOfmomentum = prc_monthly / prc_monthly.shift(i) + sumOfmomentum
sumOfscore = np.where(prc_monthly / prc_monthly.shift(i) > 1, 1,0) + sumOfscore
sumOfmomentum[sumOfmomentum > 0] = sumOfscore/lookback
return sumOfmomentum
월단위로 리샘플링된 가격 데이터와 반추기간을 받아서 평균모멘텀을 산출하여 반환한다. 평균모멘텀에 대한 글은 아래 링크를 참조하면 된다.
다음은 수익률 곡선의 n개월(lookback) 평균모멘텀을 계산하는 정적 메소드이다.
@staticmethod
def amsofYield(returns, lag, lookback, end, target):
if (not returns.empty):
start = end - pd.DateOffset(months=lookback)
while not (start in target.universe.index):
start = start - pd.DateOffset(days=lag)
prc = returns.loc[start:end]
prc_monthly = prc.copy()
prc_monthly = prc_monthly.resample('BM').last().dropna()
ymomscore = WeighAMS.avg_momentum_score(prc_monthly, lookback)
yweight = ymomscore.loc[ymomscore.index.max()]
return yweight
수익률 데이터를 월간 단위로 리샘플링한 후에 평균모멘텀을 계산하기 위해서 상기 평균모멘텀 계산 정적 메소드를 호출하도록 되어 있다.
마지막으로 안전자산, 투자자산의 최종 투자 비중을 산출하는 메소드이다.
def __call__(self, target):
selected = target.temp['selected']
end = target.now - pd.DateOffset(days=self.lag)
while not (end in target.universe.index):
end = end - pd.DateOffset(days=self.lag)
s0 = target.now
if (not self.returns.empty):
s0 = self.returns.index.min() + pd.DateOffset(months=self.ylookback)
# 1. 전략수익률 데이터 추출 & 모멘텀 가공
if (not self.returns.empty) & (target.now >= s0):
start = end - pd.DateOffset(months=self.ylookback)
while not (start in target.universe.index):
start = start - pd.DateOffset(days=self.lag)
prc = self.returns.loc[start:end]
prc_monthly = prc.copy()
prc_monthly = prc_monthly.resample('BM').last().dropna()
ymomscore = WeighAMS.avg_momentum_score(prc_monthly, self.ylookback)
# ① 투자자산 전체 비중 산출
yweight = ymomscore.loc[ymomscore.index.max()]
# 2. 투자자산 반추기간 데이터 추출, 모멘텀 산출
start = end - pd.DateOffset(months=12)
while not (start in target.universe.index):
start = start - pd.DateOffset(days=self.lag)
prc = target.universe.loc[start:end, selected]
prc_monthly = prc.copy().drop(['cash'], axis=1)
prc_monthly = prc_monthly.resample('BM').last().dropna()
# ② 투자자산의 각 자산별 12개월 평균모멘텀 산출
weights = WeighAMS.avg_momentum_score(prc_monthly, lookback=12)
# 3. 투자자산 및 안전자산 비중 결정
weights = weights.loc[weights.index.max()]
if (not self.returns.empty) & (target.now >= s0):
# ④ 투자자산의 각 자산별 투자비중 산출
weights = weights * yweight.iloc[0] / len(weights.index)
else:
weights = weights * (1-self.cash_weight) / len(weights.index)
# ⑤ 안전자산 비중 산출
weights['cash'] = 1 - weights.sum()
target.temp['weights'] = weights
return True
코드가 약간 길어보이지만 3개의 부분으로 구성되어 있다. 첫번째 부분은 수익률 데이터로 n개월 평균모멘텀을 산출하여 총 투자금에서 투자자산에 할당될 비중(①)을 산출한다. 그리고 두번째 부분에서 투자자산의 12개월 평균모멘텀(②)을 산출하고 마지막 부분에서 투자자산에 할당될 비중(①)을 투자자산의 개수로 나누어 각 투자자산의 고정비중(③)을 계산하고 여기에 각 자산의 12개월 평균모멘텀(②)을 곱하여 각 투자자산의 투자비중(④)을 결정하고 남은 비중의 투자금은 안전자산에 할당(⑤)하여 반환하도록 구현되어 있다.
1편 : TQQQ, TMF 고정 비중 백테스트
2편 : TQQQ, TMF 상대 모멘텀 백테스트
3편 : TQQQ, TMF 절대 모멘텀 백테스트(1)
4편 : TQQQ, TMF 절대 모멘텀 백테스트(2)
5편: TQQQ,TMF 듀얼 모멘텀 백테스트
6편: TQQQ, TMF 평균 모멘텀 스코어 백테스트
7편: TQQQ, TMF 수익곡선 모멘텀 백테스트
8편: TQQQ, TMF 평균모멘텀 전략의 비중 계산 Algo 클래스
☞ 이 글은 순수하게 개인적인 의도로 테스트한 결과이며 내용상 오류가 있을 수도 있습니다.
.
'자산배분' 카테고리의 다른 글
TQQQ, TMF 가속듀얼모멘텀 백테스트 (24) | 2023.01.27 |
---|---|
TQQQ, TMF 수익곡선 모멘텀 백테스트 (18) | 2023.01.18 |
TQQQ, TMF 평균 모멘텀 스코어 백테스트 (21) | 2023.01.12 |
TQQQ, TMF 듀얼 모멘텀 백테스트 (22) | 2023.01.09 |
TQQQ, TMF 절대 모멘텀 백테스트(2) (18) | 2022.12.26 |