-
영구 포트폴리오 직장인에게 최적화하기 (1)재테크 2021. 1. 13. 00:21
영구 포트폴리오 (Permanent Portfolio)는 자산 간의 상관관계가 낮고 안정적인 자산을 선택하여 과거에 매크로 경제가 어떻게 달라지더라도 총자산의 손실을 최소화하는 것에 초점을 맞춘 포트폴리오다. 주식, 채권, 현금, 그리고 금을 동일하게 보유하여 변동이 있을 때마다 비싸진 종목을 팔고 싸진 종목을 사서 균형을 맞추는 방식으로 운용한다. 왜 영구 포트폴리오가 안전하고 강력한지는 백테스트를 통하여 보여주는 자료가 많이 있다.
그림 1. 영구 포트폴리오는 4가지 자산을 동일하게 보유하고 있는다. 나는 재테크 초보이고 잃지 않는 투자를 선호하기 때문에 위와 같은 자산 배분 방식을 도입하여 나의 상황에 맞게 적용해보기로 하였다. 영구 포트폴리오는 일정한 시드 머니를 분배하는 방법에만 초점을 맞추었기 때문에 시드 머니가 없고 매 달 월급을 통하여 적금식 투자를 하는 상황에 맞춰 조정이 필요했다. 가장 간단한 방법은 매 월 월급이 들어올 때마다 투자 금액을 균등하게 분배해서 투자하는 것이다. 이 다음부터 이 방식으로 영구 포트폴리오에 투자를 했을 때 1) 어느 정도의 수익을 낼 수 있는지, 2) 조금이라도 많은 수익률을 가져갈 방법은 없는지, 과거 데이터를 통하여 분석해볼 것이다.
먼저, 철저하게 전략 기반의 투자를 할 것이기 때문에 가격의 단기 변동성에 대한 반응을 하지 않기로 했다. 즉, 거래는 한 달에 한 번 이루어진다. 그리고 매 번 매수할 때마다 0.3%의 거래수수료가 든다고 가정하였다.
각 자산에 투자하기 위해 선택한 종목은 아래와 같다.
- 주식: SPDR S&P 500 (SPY) - S&P 500 지수를 추종하는 ETF
- 채권: iShares 20+ Year Treasury Bond ETF (TLT) - 만기 20년 이상의 미국 장기 국채로 구성된 ETF
- 금: iShares Gold Trust (IAU) - 금 ETF
- 현금: 원화 (연 2% 복리의 예금, 월 이자 0.165%로 가정하고 계산)
위의 종목은 미국 주식과 채권을 사용하고 있는데 주식을 좀 더 분산하고 싶으면 VT (Vanguard Total World Stock) ETF를 사용해도 되나 채권은 과거 주식과 음의 상관관계를 확실히 가지고 있는 것이 증명된 미국채를 그냥 쓰는 것이 좋다고 판단하였다.
전략 1. 균등하게 나눠서 계속 사기
이 전략은 매 달 투자 금액이 들어옴에 따라 무조건 25%씩 나눠서 자산을 사는 전략이다. 자본주의 사회예서 화폐는 계속 찍히기 때문에 자산은 결국 우상향 할 것이라 수익은 날 것 같다. 검증하기 위하여 https://kr.investing.com/에서 각 종목 및 환율의 월 단위 과거 데이터(.csv)를 수집하였다. TLT 데이터가 2005년 6월부터 시작이라서 2005년부터 백테스트를 할 것이며 매달 80만 원의 투자금액이 새로 들어오고 20만 원씩 나눠서 보유하고 있는 현금 중 최대로 살 수 있는 개수만큼 사는 전략을 취할 것이다.
백테스트 결과
그림 2. 예금 대비 영구포트폴리오의 수익률 비교 백테스트 결과에 따르면 2005년부터 2020년 1월까지 매월 80만원씩 1억 5040만 원을 투자금액에 넣은 것을 기준으로 연 2% 복리로 저축했을 때는 약 1억 7620만원 정도로 모였고 영구 포트폴리오를 활용했을 때는 약 2억 4835만 원으로 총 평가 금액이 불어났다. 생각을 전혀 안 해도 되는 아주 간단한 전략임에도 불구하고 15년간 65.1%의 수익률을 거두었다. 이 전략의 수익률을 예금 이자로 계산하면 6.14%의 복리 이자가 필요하다.
이 전략의 가장 큰 장점인 안정성에 대해서도 검증할 수 있었다. 최대 손실 (MDD) 값을 계산해보면 주식의 대 폭락장이 있었던 2009년 4월 1일 (서브프라임 사태) 기준으로 10.9%가 나온다. 매월 투자 금액을 계속 추가하기 때문에 계속 하락할 때 추가 매수를 해서 손실액의 증가에 비해 손실률이 흐려지지만 폭락장에서도 방어력이 좋다고 느꼈다. MDD가 높으면 집을 사는 등의 큰돈이 들어갈 일이 언제 생길지 모르는데 운이 안 좋게 손실을 많이 보고 있을 때 눈물을 삼키면서 돈을 빼야 한다. 많이 버는 것보다 손해 보는 것을 싫어하는 나에게는 이 전략이 잃지 않는 투자 방법으로서 매력적임을 다시 느꼈다.
구현
백테스트를 위한 구현은 python (>3.6 버전)으로 진행했고 바로 복사하여 테스트해볼 수 있게 하기 위하여 최대한 외부 패키지의 종속성을 제거하였다.
# utils.py import csv from datetime import datetime from dateutil.relativedelta import relativedelta # 데이터 전처리 def load_stock_prices(name): prices = [] with open(f'{name}.csv', encoding='utf-8-sig') as data_file: lines = csv.reader(data_file, delimiter=',') next(lines) for line in lines: prices.append(float(line[1].replace(',', ''))) if line[0] == '2005년 6월': break return prices[::-1] # 달러 가격을 원 단위로 변경 def to_kr_prices(prices, dollar_prices): return [int(p * dp) for p, dp in zip(prices, dollar_prices)] # 날짜를 string 포멧으로 정리 def get_dates(): base = datetime(2005, 6, 1) dates = [] while base <= datetime(2021, 1, 1): dates.append(base.strftime('%Y-%m-%d')) base += relativedelta(months=1) return dates # MDD 값의 계산 def get_mdd(dates, results): mdd = 0 mdd_date = None max_result = results[0] for i, result in enumerate(results[1:], 1): if result > max_result: max_result = result diff = (result - max_result) / max_result if diff < -mdd: mdd = -diff mdd_date = dates[i] return mdd, mdd_date # 결과 저장 def save_results(results, columns=['날짜', '총 투자금', '총 평가액', '현금 100%']): with open('result.csv', 'w', encoding='utf-8-sig') as result_file: writer = csv.writer(result_file) writer.writerow(columns) writer.writerows(results)
# base_strategy.py from utils import ( load_stock_prices, to_kr_prices, get_dates, save_results, get_mdd ) # 월별 데이터 전처리 dates = get_dates() dollar_prices = load_stock_prices('USD_KRW') stock_prices = to_kr_prices(load_stock_prices('SPY'), dollar_prices) bond_prices = to_kr_prices(load_stock_prices('TLT'), dollar_prices) gold_prices = to_kr_prices(load_stock_prices('IAU'), dollar_prices) # 변수 초기화 total_input = 0 deposits = [0] * 3 volumes = [0] * 3 balances = [0] * 3 cash = 0 only_cash = 0 results = [] mdd = 0 mdd_date = None for i, curr_prices in enumerate(zip(stock_prices, bond_prices, gold_prices)): # 현금 자산 업데이트 total_input += 800000 cash = cash * 1.00165 cash += 200000 only_cash = only_cash * 1.00165 only_cash += 800000 # 투자 자산 업데이트 for j in range(3): price = curr_prices[j] deposits[j] += 200000 num_buying = deposits[j] // (price * 1.003) deposits[j] -= int(num_buying * price * 1.003) volumes[j] += num_buying balances[j] = price * volumes[j] # 월별 결과 저장 results.append([ dates[i], total_input, sum(balances) + int(cash), int(only_cash) ]) # MDD 계산 mdd, mdd_date = get_mdd(dates, [r[2] for r in results]) print(mdd, mdd_date) # 결과를 csv 형식으로 저장 save_results(results)
전략의 개선 방향
지금까지는 어떤 상황에도 사기만 하는 전략을 취했지만 "수익 상황에 따라서 분할매수와 분할매도를 한다면 더 높은 수익을 얻을 수 있을지 않을까?"라는 가설을 세우게 되었다. 다음 글에서는 이 가설을 검증하기 위하여 수익 상황과 매수와 매도의 정도를 하이퍼 파라미터로 두고 시뮬레이션으로 최적의 값들을 찾아서 연평균 수익률을 높여보는 전략을 시도해보고 공유할 예정이다.
'재테크' 카테고리의 다른 글
주가 데이터 자동으로 가져오기 (gspread 이용) (1) 2021.06.22 삼성전자 주식 조금이라도 싸게 모을 수 있을까? (2) - RSI 보조지표의 활용 (0) 2021.03.01 삼성전자 주식 조금이라도 싸게 모을 수 있을까? (0) 2021.01.31 영구포트폴리오 직장인에게 최적화하기 (3) (0) 2021.01.24 영구 포트폴리오 직장인에게 최적화하기 (2) (0) 2021.01.16