금리와 채권가격 비교 그리고 채권금리를 이용한 투자 백테스트
본문 바로가기
파이썬(Python)/파이썬으로 투자실험

금리와 채권가격 비교 그리고 채권금리를 이용한 투자 백테스트

by Squat Lee 2024. 4. 24.

당연한 얘기겠지만 금리와 채권가격의 움직임이 어떤지 궁금해졌습니다.

 

TLT 채권가격과 금리비교 그래프

 

장기채권 투자하는 ETF인  TLT와 미국 30년 이상의 채권금리를 비교했습니다.

 

단순히 눈으로 보기에는 방향이 반대로 움직이는 것 같지 않나요?

 

이걸 가지고 투자에 이용할 수 있을까 하는 생각을 했습니다. 막상 눈으로 봐서 서로 반대로 움직인다 하더라도 수치적으로 어떻게 Code를 짜야할지 모르겠네요.

 

그래서 이동평균 개념을 도입해 봤습니다.

 

채권금리의 일정기간동안 고점과 저점을 이용해서 현재 채권금리의 백분율을 구하는 것입니다.

 

그러면 현재 금리가 80% 수준인지 90% 수준인지 가늠할 수 있겠죠? 그 다음에 이 백분율을 비중으로 해서 주식ETF와 채권 ETF를 각각 투자하는 것입니다.

 

그럴듯 하지 않나요?

 

우선 금리 이동평균을 이용해서 백분율로 나타내 보겠습니다.

 

채권과 채권금리, 그리고 채권금리의 백분율

 

위의 그래프와 같이 결과가 나왔습니다. 

 

파란색은 채권금리이고, 빨간색은 TLT의 가격입니다. 녹색점선은 채권금리의 이동평균 백분율입니다.

 

백분율은 0 ~ 1까지 표시가 됩니다. 이것이 채권의 비율이 되며, "1 - 채권비중"은 주식 ETF의 비중이 됩니다.

 

그럼 실제 이렇게 했을 때 투자결과가 어떻게 나오는지 백테스트를 해 보겠습니다.

 

백테스트 조건

  • 초기자금 2억원, 매월 2백만원씩 추가 투자
  • 매매수수료, 배당소득세, 양도소득세 고려
  • 매월 리밸런싱

채권비율로 QQQ와 TLT 투자결과

 

 

결과는 나쁘지 않게 나온것 같습니다.

 

CAGR은 8.8%이고, MDD는 -38.7%입니다. 

 

구  분 QQQ 적립식 투자 TLT 적립식 투자 QQQ + TLT(채권금리비율)
CAGR 11.7 1.9 8.8
MDD -53.4 -38.1 -38.7
총수익률 1,181 104 662
양도세 부과여부 미부과 미부과 총 2억 8백만원 세금부과

 

 

월별 리밸런싱 때문에 양도세가 부과됨에도 불구하고 수익률이 괜찮습니다. QQQ 적립투자의 수익률이 가장 높으나 MDD 또한 높아서 실제 투자에서는 견디기가 힘들 것 같습니다.

 

사실 2021년에 주식과 채권이 함께 하락했던 시기가 있었습니다. 그 전 20년까지는 서로 반대로 움직였거든요. 그 시기 때문에 CAGR이 낮아졌지만, 나름 괜찮은 결과인 것 같습니다.

 

백테스트를 한 파이썬 코드는 아래와 같습니다.

 

채권가격과 채권금리 상관관계

import pandas as pd
from pandas_datareader import data as pdr
import yfinance as yf
yf.pdr_override()
from datetime import datetime
import numpy as np
import matplotlib.pyplot as plt

p1 = 'TLT'
bond = '^TYX' #Treasury Yield 30 years

# 미 채권
    # 13 WEEK TREASURY BILL (^IRX)
    # Treasury Yield 5 Years (^FVX)
    # CBOE Interest Rate 10 Year T No (^TNX)
    # Treasury Yield 30 Years (^TYX)

start = datetime(2002, 1, 1)
end = datetime(2024, 2, 29)

df = pdr.get_data_yahoo(p1, start, end)
df_b = pdr.get_data_yahoo(bond, start, end)

df.rename(columns={'Adj Close':'주가'}, inplace=True)
df_b.rename(columns={'Adj Close':'금리'}, inplace=True)

df= pd.merge(df['주가'], df_b['금리'], left_index=True, right_index=True)

window = 253
#이동평균
df['이동평균'] = df['금리'].rolling(window=120, min_periods=1).mean()
df[f'{window}일고점'] = df['금리'].rolling(window=window, min_periods=1).max()
df[f'{window}일저점'] = df['금리'].rolling(window=window, min_periods=1).min()
df['최근금리백분율'] = round((df['금리']-df[f'{window}일저점'])/(df[f'{window}일고점']-df[f'{window}일저점']), 4)

print(df)

plt.rcParams['figure.figsize'] = (16, 9)

fig, ax1 = plt.subplots()
ax1.set_xlabel('DATE')
ax1.set_ylabel('Price')
ax1.plot(df.index, df['주가'], color='red', label=p1)

ax2 = ax1.twinx()
ax2.set_ylabel('Rate')
ax2.plot(df.index, df['금리'], color='blue', label='Rate')
ax2.plot(df.index, df['최근금리백분율'], color='green', label='Rate', linestyle='--')
plt.grid(True)
plt.legend(loc='best')

plt.show()

 

 

백테스트 코드

import pandas as pd
from pandas_datareader import data as pdr
import yfinance as yf
yf.pdr_override()
from datetime import datetime
import numpy as np
import matplotlib.pyplot as plt

pd.options.display.float_format = '{:,.2f}'.format

#투자자산
p1 = 'QQQ'
p2 = 'TLT'

# 리밸런싱 제한비율
최대 = 1
최소 = 0
현금비율 = 0.8 #투자자산 모두가 모멘텀이 0일때의 현금비율
이율 = 0.03
window = 253 #채권 고점과 저점을 구하는 기간

#절대모멘텀(0), 상대모멘텀(1), 고정비율(2), 상대모멘텀과현금분배(3), 채권금리와 절대모멘텀을 이용해서투자(4), 채권금리를 이용해서 투자(5)
li_strategy = ['Absolute Momentum',  'Relative momentum', 'Fixed rate', 'Relative moment & Cash',
               'Momentum & Bond Rate', 'Bond Rate']

모멘텀종류 = li_strategy[5]
moment_months = 6
p1비율 = 0.9 #fixed rate 투자자산 배분비율
매매수수료 = 0.0025
배당소득세 = 0.154

start = datetime(1990, 1, 1)
end = datetime.today()

초기투자금 = 200000000/1318
매월투자금 = 2000000/1318

배당금적용여부 = 1 #1이면 적용, 0이면 미적용
양도소득세적용여부 = 1 #1이면 적용, 0이면 미적용
엑셀파일출력 = 0 #1이면 적용, 0이면 미적용

def get_div(p):
    ticker1 = yf.Ticker(p)
    div = ticker1.dividends.tz_localize(None)
    return div



#데이터 가져오기
def get_data(p1, p2, start, end):
    df1 = pdr.get_data_yahoo(p1, start, end)
    df1.rename(columns={'Adj Close':'p1주가'}, inplace=True)

    df2 = pdr.get_data_yahoo(p2, start, end)
    df2.rename(columns={'Adj Close':'p2주가'}, inplace=True)

    df_ex = pdr.get_data_yahoo('USDKRW=X', start, end) #환율
    df_ex.rename(columns={'Adj Close': '환율'}, inplace=True)

    df_r = pdr.get_data_yahoo('^TYX', start, end)  #금리
    df_r.rename(columns={'Adj Close': '금리'}, inplace=True)

    df = pd.merge(df1['p1주가'], df2['p2주가'], left_index=True, right_index=True, how='inner')
    df = pd.merge(df, df_ex['환율'], left_index=True, right_index=True)
    df = pd.merge(df, df_r['금리'], left_index=True, right_index=True)

    return df

# 세금계산을 위해서 년도별 마지막날 구하기
df_y = get_data(p1, p2, start, end)
df_y['date'] = df_y.index
df_y = df_y.groupby(by=df_y.index.year).last()
li_lastdays = df_y['date'].to_list()

# 배당데이터에 다른 데이터 넣기
def merge_div(p1, p2, start, end):
    df = get_data(p1, p2, start, end)
    div1 = get_div(p1)
    div2 = get_div(p2)
    if 배당금적용여부 == 1:
        df['배당금1'] = div1
        df['배당금2'] = div2
        df.fillna(0, inplace=True)
    else:
        df['배당금1'] = 0
        df['배당금2'] = 0
    return df

df = merge_div(p1, p2, start, end)

#월말투자금 넣기
df_m = df
df_m['date'] = df_m.index #멀티인덱스로 만들어지기에 별도의 날짜컬럼을 만들고
df_m = df_m.groupby(by=[df.index.year, df.index.month]).last() #매월 마지막날만 필터
li_monthlast = df_m['date'].to_list() #매월 마지막날을 리스트로

# 월말 날짜만 가져오기
def get_monthly_end(df_d):
    df_d['Odate'] = df_d.index
    df = df_d.groupby(by=[df_d.index.year, df_d.index.month]).last()
    df.set_index('Odate', inplace=True)
    return df

#평균모멘텀스코어 구하기
def score(df_d, moment_months, 모멘텀종류, window):
    mm = int(moment_months)
    df = get_monthly_end(df_d)
    df['현금비율'] = 0
    li_score1 = []
    li_score2 = []
    for i in range(len(df)):
        if i < mm:
            li_score1.append(0.5)
            li_score2.append(0.5)
        else:
            val1 = 0
            val2 = 0
            for m in range(1, mm+1):
                if df['p1주가'].iloc[i] - df['p1주가'].iloc[i-m] > 0:
                    val1 += 1
                if df['p2주가'].iloc[i] - df['p2주가'].iloc[i-m] > 0:
                    val2 += 1

            if val1 == 0:
                li_score1.append(최소)
            elif val1 == mm:
                li_score1.append(최대)
            else:
                li_score1.append(val1 / mm)

            if val2 == 0:
                li_score2.append(최소)
            elif val2 == mm:
                li_score2.append(최대)
            else:
                li_score2.append(val2 / mm)


    df['평균모멘텀스코어1'] = li_score1
    df['평균모멘텀스코어2'] = li_score2

    if 모멘텀종류 == 'Relative momentum':
        df['투자비율'] = df['평균모멘텀스코어1'] / (df['평균모멘텀스코어1'] + df['평균모멘텀스코어2'])
        df = df[['투자비율', '평균모멘텀스코어1', '평균모멘텀스코어2', '현금비율']]
        for i in range(len(df)):
            if (df['평균모멘텀스코어1'].iloc[i] == 0.1) & (df['평균모멘텀스코어2'].iloc[i] == 0.1):
                df['투자비율'].iloc[i] = 0.5

    elif 모멘텀종류 == 'Absolute Momentum':
        df['투자비율'] = li_score1
        df = df[['투자비율', '평균모멘텀스코어1', '평균모멘텀스코어2', '현금비율']]

    elif 모멘텀종류 == 'Momentum & Bond Rate': #채권금리가 높을때는 채권을 사고, 낮을때는 평균모멘텀스코어를 이용해서 자산분배
        df[f'{window}일고점'] = df['금리'].rolling(window=window, min_periods=1).max()
        df[f'{window}일저점'] = df['금리'].rolling(window=window, min_periods=1).min()
        df['최근금리백분율'] = round((df['금리'] - df[f'{window}일저점']) / (df[f'{window}일고점'] - df[f'{window}일저점']), 4)
        df['채권비율'] = 0
        for i in range(len(df)):
            if df['최근금리백분율'].iloc[i] > 0.9:
                df['채권비율'].iloc[i] = 0.6
            else:
                df['채권비율'].iloc[i] = 0
        df['투자비율'] = np.where(df['채권비율'] > 0, 1 - df['채권비율'], df['평균모멘텀스코어1'])
        df = df[['투자비율', '평균모멘텀스코어1', '평균모멘텀스코어2', '현금비율']]

    elif 모멘텀종류 == 'Bond Rate': #채권금리에 따라 투자비중 조정
        df[f'{window}일고점'] = df['금리'].rolling(window=window, min_periods=1).max()
        df[f'{window}일저점'] = df['금리'].rolling(window=window, min_periods=1).min()
        df['최근금리백분율'] = round((df['금리'] - df[f'{window}일저점']) / (df[f'{window}일고점'] - df[f'{window}일저점']), 4)
        df['채권비율'] = df['최근금리백분율']
        df['투자비율'] = 1 - df['채권비율']
        df = df[['투자비율', '평균모멘텀스코어1', '평균모멘텀스코어2', '현금비율']]

    elif 모멘텀종류 == 'Fixed rate':
        df['투자비율'] = p1비율
        df = df[['투자비율', '평균모멘텀스코어1', '평균모멘텀스코어2', '현금비율']]

    elif 모멘텀종류 == 'Relative moment & Cash':
        df['투자비율'] = df['평균모멘텀스코어1'] / (df['평균모멘텀스코어1'] + df['평균모멘텀스코어2'])
        df = df[['투자비율', '평균모멘텀스코어1', '평균모멘텀스코어2', '현금비율']]
        for i in range(len(df)):
            if (df['평균모멘텀스코어1'].iloc[i] == 최소) & (df['평균모멘텀스코어2'].iloc[i] == 최소):
                df['현금비율'].iloc[i] = 현금비율
                df['투자비율'].iloc[i] = 0.5

    else:
        print("투자비율을 제대로 선택하세요")

    return df

#투자금 컬럼 데이터프레임으로 만들기
df['투자금'] = 0
for i, m in enumerate(li_monthlast):
    if i == 0:
        df['투자금'].loc[m] = 초기투자금
    else:
        df['투자금'].loc[m] = 매월투자금

#MDD 구하기
def get_mdd(col):
    window = 252
    peak = col.rolling(window, min_periods=1).max()
    drawdown = col/peak - 1
    연도별mdd = drawdown.rolling(window, min_periods=1).min()
    mdd = 연도별mdd.min()
    return mdd

# 적립식 투자하면서 자산변동 계산
df_score = score(df, moment_months, 모멘텀종류, window)
df = pd.merge(df, df_score, left_index=True, right_index=True, how='outer')
df = df[df.index >= li_monthlast[0]]

df[['p1주식수', 'p1금액', 'p2주식수', 'p2금액', '합계', '원금누계', '실현손익', '실현손익1',
    '실현손익2', '연간양도세', '매수평단1', '매수평단2', '주식수변화1', '주식수변화2', '적립합계1',
    '적립합계2', '적립주식수1', '적립주식수2', '현금']] = 0

for m in range(len(df)):
    if m == 0:
        df['합계'].iloc[m] = df['투자금'].iloc[m] * (1-매매수수료) + df['현금'].iloc[m]
        df['p1금액'].iloc[m] = (df['합계'].iloc[m] - df['현금'].iloc[m]) * p1비율
        df['p1주식수'].iloc[m] = df['p1금액'].iloc[m] / df['p1주가'].iloc[m]
        df['p2금액'].iloc[m] = (df['합계'].iloc[m] - df['현금'].iloc[m]) - df['p1금액'].iloc[m]
        df['p2주식수'].iloc[m] = df['p2금액'].iloc[m] / df['p2주가'].iloc[m]
        df['원금누계'].iloc[m] = df['투자금'].iloc[m]
        df['적립합계1'].iloc[m] = df['투자금'].iloc[m] * (1-매매수수료)
        df['적립주식수1'].iloc[m] = df['적립합계1'].iloc[m] / df['p1주가'].iloc[m]
        df['적립합계2'].iloc[m] = df['투자금'].iloc[m] * (1 - 매매수수료)
        df['적립주식수2'].iloc[m] = df['적립합계2'].iloc[m] / df['p2주가'].iloc[m]
        for c in range(1, 3):
            if df[f"p{c}금액"].iloc[m] != 0:
                df[f'매수평단{c}'].iloc[m] = df[f'p{c}주가'].iloc[m]
                df[f'주식수변화{c}'].iloc[m] = 0
        df['실현손익'].iloc[m] = 0
    else:
        df['현금'].iloc[m] = df['현금'].iloc[m-1]
        df['현금비율'].iloc[m] = df['현금비율'].iloc[m-1]
        df['합계'].iloc[m] = df['투자금'].iloc[m] * (1-매매수수료) + \
                           (df['p1주가'].iloc[m] * df['p1주식수'].iloc[m-1]) + \
                           (df['p2주가'].iloc[m] * df['p2주식수'].iloc[m-1]) + \
                           (df['배당금1'].iloc[m] * df['p1주식수'].iloc[m-1] +
                            df['배당금2'].iloc[m] * df['p2주식수'].iloc[m-1]) * (1 - 배당소득세) + \
                           df['현금'].iloc[m]
        #적립투자
        df['적립합계1'].iloc[m] = df['투자금'].iloc[m] * (1-매매수수료) + \
                                df['p1주가'].iloc[m] * df['적립주식수1'].iloc[m-1] + df['배당금1'].iloc[m-1] * (1 - 배당소득세)
        df['적립주식수1'].iloc[m] = df['적립합계1'].iloc[m] / df['p1주가'].iloc[m]
        df['적립합계2'].iloc[m] = df['투자금'].iloc[m] * (1 - 매매수수료) + \
                               df['p2주가'].iloc[m] * df['적립주식수2'].iloc[m - 1] + df['배당금2'].iloc[m-1] * (1 - 배당소득세)
        df['적립주식수2'].iloc[m] = df['적립합계2'].iloc[m] / df['p2주가'].iloc[m]

        # 매월 리밸런싱 할 때는 주식수가 변하지만
        if df['투자금'].iloc[m] > 0:
            df['현금'].iloc[m] = df['합계'].iloc[m-1] * df['현금비율'].iloc[m] * (1 + 이율)
            df['p1금액'].iloc[m] = (df['합계'].iloc[m] - df['현금'].iloc[m]) * df['투자비율'].iloc[m]
            df['p1주식수'].iloc[m] = df['p1금액'].iloc[m] / df['p1주가'].iloc[m]
            df['p2금액'].iloc[m] = df['합계'].iloc[m] - df['p1금액'].iloc[m] - df['현금'].iloc[m]
            df['p2주식수'].iloc[m] = df['p2금액'].iloc[m] / df['p2주가'].iloc[m]

            for c in range(1, 3):
                df[f'주식수변화{c}'].iloc[m] = df[f'p{c}주식수'].iloc[m] - df[f'p{c}주식수'].iloc[m - 1]
                # 주식수가 늘었을 때(매수)
                if (df[f'주식수변화{c}'].iloc[m] > 0) & (df[f'매수평단{c}'].iloc[m-1] == 0):
                    df[f'매수평단{c}'].iloc[m] = df[f'p{c}주가'].iloc[m]
                    df[f'실현손익{c}'].iloc[m] = 0
                elif (df[f'주식수변화{c}'].iloc[m] > 0) & (df[f'매수평단{c}'].iloc[m-1] != 0):
                    df[f'매수평단{c}'].iloc[m] = (df[f'매수평단{c}'].iloc[m-1] + df[f'주식수변화{c}'].iloc[m] * df[f'p{c}주가'].iloc[m]) / \
                                               (1+df[f'주식수변화{c}'].iloc[m])
                    df[f'실현손익{c}'].iloc[m] = 0
                # 전량매도
                elif (df[f'주식수변화{c}'].iloc[m] < 0) & (df[f'p{c}금액'].iloc[m] == 0):
                    df[f'매수평단{c}'].iloc[m] = 0
                    # 실현손익 구하기 : 매도한 금액 - (주식수변화 X 매수평단)
                    df[f'실현손익{c}'].iloc[m] = - df[f'주식수변화{c}'].iloc[m] * (df[f'p{c}주가'].iloc[m] - df[f'매수평단{c}'].iloc[m-1])
                else: #일부매도 또는 유지
                    df[f'매수평단{c}'].iloc[m] = df[f'매수평단{c}'].iloc[m - 1]
                    # 실현손익 구하기 : 매도한 금액 - (주식수변화 X 매수평단)
                    df[f'실현손익{c}'].iloc[m] = - df[f'주식수변화{c}'].iloc[m] * (df[f'p{c}주가'].iloc[m] - df[f'매수평단{c}'].iloc[m-1])

        # 리밸런싱을 안 하는 날에는 주식수가 고정
        else:
            for c in range(1, 3):
                df[f'p{c}주식수'].iloc[m] = df[f'p{c}주식수'].iloc[m-1]
                df[f'p{c}금액'].iloc[m] = df[f'p{c}주식수'].iloc[m] * df[f'p{c}주가'].iloc[m]
                df[f'평균모멘텀스코어{c}'].iloc[m] = df[f'평균모멘텀스코어{c}'].iloc[m-1]
                df[f'투자비율'].iloc[m] = df[f'투자비율'].iloc[m - 1]
                df[f'매수평단{c}'].iloc[m] = df[f'매수평단{c}'].iloc[m - 1]
                df[f'실현손익{c}'].iloc[m] = 0
        df['실현손익'].iloc[m] = df['실현손익1'].iloc[m] + df['실현손익2'].iloc[m]
        df['원금누계'].iloc[m] = df['원금누계'].iloc[m - 1] + df['투자금'].iloc[m]

        # 실현손익으로 양도소득세 계산 및 합계, 주식금액을 양도소득세를 제외한 금액으로 정정
        if 양도소득세적용여부 == 1: #양도소득세 적용시 금액을 계산
            if (df.index[m] in li_lastdays) & (df.index[m].month == 12):
                연간실현손익 = df['실현손익'].loc[str(df.index[m])[:4]].sum() * df['환율'].iloc[m] #원화로 변환
                print(f'{str(df.index[m])[:4]}년 실현손익: {round(연간실현손익,0):,}')
                if 연간실현손익 >= 2500000:
                    df['연간양도세'].iloc[m] = ((연간실현손익 - 2500000) * 0.22)/df['환율'].iloc[m] #달러로 변환
                    print(f"{df['연간양도세'].index[m]}연간양도세 : {round(df['연간양도세'].iloc[m]*df['환율'].iloc[m],0):,}")
                    df['합계'].iloc[m] = df['투자금'].iloc[m] * (1 - 매매수수료) + \
                                       (df['p1주가'].iloc[m] * df['p1주식수'].iloc[m - 1]) + (
                                                   df['p2주가'].iloc[m] * df['p2주식수'].iloc[m - 1]) + \
                                       (df['배당금1'].iloc[m] * df['p1주식수'].iloc[m - 2] + df['배당금2'].iloc[m] *
                                        df['p2주식수'].iloc[m - 2]) * (1 - 배당소득세) - df['연간양도세'].iloc[m] + \
                                       df['현금'].iloc[m]
                    df['p1금액'].iloc[m] = (df['합계'].iloc[m] - df['현금'].iloc[m]) * df['투자비율'].iloc[m]
                    df['p1주식수'].iloc[m] = df['p1금액'].iloc[m] / df['p1주가'].iloc[m]
                    df['p2금액'].iloc[m] = df['합계'].iloc[m] - df['현금'].iloc[m] - df['p1금액'].iloc[m]
                    df['p2주식수'].iloc[m] = df['p2금액'].iloc[m] / df['p2주가'].iloc[m]


df = df[['p1주가', 'p1주식수', 'p1금액', '배당금1', 'p2주가', 'p2주식수', 'p2금액', '배당금2',
         '투자금', '합계', '원금누계', '실현손익', '환율', '연간양도세', '투자비율', '평균모멘텀스코어1',
         '평균모멘텀스코어2', '매수평단1', '매수평단2', '실현손익1', '실현손익2', '적립합계1', '적립주식수1',
         '적립합계2', '적립주식수2', '현금비율', '현금']]

# 2가지 자산의 누적수익률을 비교하기 위해 백분율로 표현
for c in range(1, 3):
    df[f'주가백분율{c}'] = df[f'p{c}주가'] / df[f'p{c}주가'].iloc[0]
df['전략백분율'] = df['합계'] / df['원금누계']
df['적립백분율1'] = df['적립합계1'] / df['원금누계']
df['적립백분율2'] = df['적립합계2'] / df['원금누계']

df.dropna(inplace=True)

print(f'투자방법 : {모멘텀종류}')

#CAGR
diff = df.index[-1].year - df.index[0].year
cagr_etf1 = (df['p1주가'].iloc[-1] / df['p1주가'].iloc[0]) ** (1 / diff) - 1
cagr_etf2 = (df['p2주가'].iloc[-1] / df['p2주가'].iloc[0]) ** (1 / diff) - 1
cagr_전략 = (df['합계'].iloc[-1] / df['합계'].iloc[0]) ** (1 / diff) - 1
cagr_전략_실질 = (df['합계'].iloc[-1] / df['원금누계'].iloc[-1]) ** (1 / diff) - 1
cagr_적립1 = (df['적립합계1'].iloc[-1] / df['원금누계'].iloc[-1]) ** (1 / diff) - 1
cagr_적립2 = (df['적립합계2'].iloc[-1] / df['원금누계'].iloc[-1]) ** (1 / diff) - 1
cagr = f'CAGR({p1}) : {round(cagr_etf1*100, 1)} / CAGR({p2}) : {round(cagr_etf2*100, 1)} /' \
       f'CAGR(전략) : {round(cagr_전략*100, 1)} CAGR(실질전략) : {round(cagr_전략_실질*100, 1)}'
cagr_적립 = f'CAGR(적립투자 {p1}) : {round(cagr_적립1*100, 1)} / CAGR(적립투자 {p2}) : {round(cagr_적립2*100, 1)}'
print(cagr)
print(cagr_적립)

#MDD구하기
mdd_etf1 = get_mdd(df['p1주가'])
mdd_etf2 = get_mdd(df['p2주가'])
mdd_전략 = get_mdd(df['합계'])
mdd_t = f'MDD({p1}) : {round(mdd_etf1*100,1)} / MDD({p2}) : {round(mdd_etf2*100,1)} / MDD(전략) : {round(mdd_전략*100,1)}'
mdd_적립1 = get_mdd(df['적립합계1'])
mdd_적립2 = get_mdd(df['적립합계2'])
mdd_적립 = f'MDD({p1}적립) : {round(mdd_적립1*100,1)} / MDD({p2}적립) : {round(mdd_적립2*100,1)}'
print(mdd_t)

ETF1수익률 = df['p1주가'].iloc[-1]/df['p1주가'].iloc[0] - 1
ETF2수익률 = df['p2주가'].iloc[-1]/df['p2주가'].iloc[0] - 1
전략수익률 = df['합계'].iloc[-1]/df['투자금'].sum() - 1

print(mdd_적립)
print(f'{p1} 수익률 : {round(ETF1수익률*100,0)}')
print(f'{p2} 수익률 : {round(ETF2수익률*100,0)}')
print(f'전략 수익률 : {round(전략수익률*100,0)}')

적립수익률1 = df['적립합계1'].iloc[-1]/df['투자금'].sum() - 1
적립수익률2 = df['적립합계2'].iloc[-1]/df['투자금'].sum() - 1
print(f'적립{p1} 수익률 : {round(적립수익률1*100,0)}')
print(f'적립{p2} 수익률 : {round(적립수익률2*100,0)}')

print(f'양도소득세 총계 : ${round(df["연간양도세"].sum(),0):,} (약 {round(df["연간양도세"].sum()*df["환율"].iloc[-1],0):,}원)')

print(f'총 투자금액 : {round(df["원금누계"].iloc[-1] * df["환율"].iloc[-1],0):,}원 / '
      f'최종자산 : {round(df["합계"].iloc[-1] * df["환율"].iloc[-1],0):,}원 / '
      f'총수익 : {round((df["합계"].iloc[-1] - df["원금누계"].iloc[-1]) * df["환율"].iloc[-1],0):,}원')
print(f'투자시작 : {df.index[0].year}년, 총투자기간 : {diff}년')

print(f'최근투자비율 : {p1} {round(df["투자비율"].iloc[-1]*100,2)}% : {p2} {round((1 - df["투자비율"].iloc[-1])*100,2)}%')

#그래프로 표현하기
plt.rcParams['figure.figsize'] = (16, 9)

plt.plot(df.index, df['주가백분율1'], color='blue', label=p1)
plt.plot(df.index, df['주가백분율2'], color='green', label=p2)
plt.plot(df.index, df['전략백분율'], color='red', label='strategy')
plt.plot(df.index, df['적립백분율1'], color='blue', label=f'{p1} Cost Averaging', linestyle='--')
plt.plot(df.index, df['적립백분율2'], color='green', label=f'{p2} Cost Averaging', linestyle='--')
plt.grid(True)
plt.legend(loc='best')

plt.title(f'{p1} {p2} {모멘텀종류} Invest({moment_months}months)_{diff}years invest')

plt.show()

#엑셀파일로 만들기
if 엑셀파일출력 == 1:
    df.to_excel(f'{모멘텀종류} 백테스트(세금포함, {p1} {p2} 모멘텀기간 {moment_months}개월 CAGR {round(cagr_전략_실질*100,1)} '
                f'MDD {round(mdd_전략*100,1)})_{diff}년 투자.xlsx')
728x90
반응형

댓글