[Python] CPPI 실습 on Python
CPPI 실습 on Python
변석준 교수님의 강의 엑셀파일 및 직전 기수 py 코드는 아래 링크를 통해 다운 받으실 수 있습니다.
ZIP 파일은 암호로 보호받고있으며, 암호는 본 과정 카이스트 와이파이 비밀번호와 같습니다.
본 포스팅의 python 코드는 아래 링크를 통해 다운 받으실 수 있습니다.
1. Parameter 설정
initial_budget=10000
protection_floor=0.85
m=4 #multiplier
floor=initial_budget*protection_floor
rate=0.02 # yearly
변수들을 설정해주는 코드입니다.
initial_budget은 초기 투자금액, rate는 CMA 연간 기준 금리입니다.
2. Stock Price 데이터 불러오기 (S&P500)
import pandas as pd
df=pd.read_excel('CPPI(data).xlsx', index_col=0)
df
교수님의 실습자료; CPPI(data).xlsx 파일을 불러오는 과정입니다.
데이터를 df라는 변수로 지정하였고, df는 아래와 같습니다.
sp500 | |
---|---|
2000-01-31 | 1394.46 |
2000-02-29 | 1366.42 |
2000-03-31 | 1498.58 |
2000-04-28 | 1452.43 |
2000-05-31 | 1420.60 |
... | ... |
2021-08-31 | 4522.68 |
2021-09-30 | 4307.54 |
2021-10-29 | 4605.38 |
2021-11-30 | 4567.00 |
2021-12-31 | 4766.18 |
264 rows × 1 columns
3. 주식 수익률 계산
stock_profit=[0]
for i in range(1, len(df)):
stock_profit.append(df['sp500'][i]/ df['sp500'][i-1] -1)
df['stock_profit']=stock_profit
stock_only_budget=[initial_budget]
for i in range(1, len(df)):
stock_only_budget.append(stock_only_budget[i-1]*(1+df['stock_profit'][i]))
df['stock_only_budget']=stock_only_budget
df
본 df에서는 S&P500의 월별 인덱스가 나와있고, 월별 수익률을 계산할 수 있습니다.
[기준월 인덱스] / [전월 인덱스]를 구해 1(100%)를 빼주면 손익률(stock_profit)을 구할 수 있습니다.
손익률 리스트를 기반으로 10K 달러에 대해 주식 100% 투자 시의 금액 변동을 확인할 수 있습니다(stock_only_budget).
결과는 아래와 같습니다.
sp500 | stock_profit | stock_only_budget | |
---|---|---|---|
2000-01-31 | 1394.46 | 0.000000 | 10000.000000 |
2000-02-29 | 1366.42 | -0.020108 | 9798.918578 |
2000-03-31 | 1498.58 | 0.096720 | 10746.668961 |
2000-04-28 | 1452.43 | -0.030796 | 10415.716478 |
2000-05-31 | 1420.60 | -0.021915 | 10187.456076 |
... | ... | ... | ... |
2021-08-31 | 4522.68 | 0.028990 | 32433.199948 |
2021-09-30 | 4307.54 | -0.047569 | 30890.380506 |
2021-10-29 | 4605.38 | 0.069144 | 33026.261062 |
2021-11-30 | 4567.00 | -0.008334 | 32751.029072 |
2021-12-31 | 4766.18 | 0.043613 | 34179.395608 |
264 rows × 3 columns
4. CPPI 계산
budget=[initial_budget]
logs_cushion=[]
logs_stock=[]
logs_cma=[]
for i in range(len(df)):
cushion=budget[i]-floor
logs_cushion.append(cushion)
stock_invest=min(budget[i], m*cushion)
logs_stock.append(stock_invest)
cma_invest=budget[i]-stock_invest
logs_cma.append(cma_invest)
if i != len(df)-1:
budget.append(stock_invest*(1+df['stock_profit'][i+1]) + cma_invest*(1+rate/12))
CPPI 전략을 통한 포트폴리오 budget 변화를 계산해보겠습니다.
먼저, 리스트를 생성하여 월별 budget, cushion, stock, cma의 추이를 기록할 수 있게 세팅을 하였습니다.
이후 for부터 시작하는 코드는 반복문입니다. 월별로 각 지표들을 계산하는 것인데, 과정은 아래와 같습니다.
- cushion은 현재의 budget에서 floor를 뺀 값입니다. floor는 초반 코드에서 초기금액(initial_budget)에 protection_floor를 곱한 값입니다.
- logs_cushion 리스트에 1에서 계산한 cushion 값을 추가(append)해 줍니다.
- 주식투자금액(stock_invest)은 현재의 budget과 m(multiplier)*cushion의 값 중 작은 값을 선택합니다.
- 2와 같은 방식으로 logs_stock라는 리스트에 주식투자금액(stock_invest)을 추가해줍니다.
- CMA 투자금액은 현재 budget에서 주식투자금액을 제외한 나머지 값입니다.
- 2나 4와 마찬가지로 logs_cma 리스트에 계산된 cma 값을 추가해줍니다.
- 지금까지 cushion, 주식투자금액, CMA투자금액을 계산하였습니다. 이를 통해 다음 달의 budget을 계산할 수 있습니다.
- 남은 코드에 대해 부연설명을 드리자면, 당월 기준 다음월의 budget을 계산하는 것이기 때문에 마지막 행에 대해서는 다음월 계산을 하지 않도록 조건문을 붙여 반복문을 끝내도록 하였습니다.
df['CPPI budget']=budget
df['floor']=floor
df['cusihon']=logs_cushion
df['stock_invest']=logs_stock
df['cma_invest']=logs_cma
df['stock_prop']=df['stock_invest']/df['CPPI budget']
반복문 상에서 기록된 logs 리스트들을 표(df)에 저장해줍니다.
추가로 저장된 stock_invest와 CPPI budget 열을 연산시켜 주식투자비중(stock_prop)을 계산하여 저장하겠습니다. (마지막 줄)
5. 결과 시각화 및 파일 저장
df # show final calculated data table
최종 결과 표(df)는 아래와 같습니다.
sp500 | stock_profit | stock_only_budget | CPPI budget | floor | cusihon | stock_invest | cma_invest | stock_prop | |
---|---|---|---|---|---|---|---|---|---|
2000-01-31 | 1394.46 | 0.000000 | 10000.000000 | 10000.000000 | 8500.0 | 1500.000000 | 6000.000000 | 4000.000000 | 0.600000 |
2000-02-29 | 1366.42 | -0.020108 | 9798.918578 | 9886.017813 | 8500.0 | 1386.017813 | 5544.071253 | 4341.946560 | 0.560799 |
2000-03-31 | 1498.58 | 0.096720 | 10746.668961 | 10429.476385 | 8500.0 | 1929.476385 | 7717.905539 | 2711.570846 | 0.740009 |
2000-04-28 | 1452.43 | -0.030796 | 10415.716478 | 10196.316439 | 8500.0 | 1696.316439 | 6785.265758 | 3411.050682 | 0.665462 |
2000-05-31 | 1420.60 | -0.021915 | 10187.456076 | 10053.302441 | 8500.0 | 1553.302441 | 6213.209764 | 3840.092677 | 0.618027 |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
2021-08-31 | 4522.68 | 0.028990 | 32433.199948 | 31834.844961 | 8500.0 | 23334.844961 | 31834.844961 | 0.000000 | 1.000000 |
2021-09-30 | 4307.54 | -0.047569 | 30890.380506 | 30320.488751 | 8500.0 | 21820.488751 | 30320.488751 | 0.000000 | 1.000000 |
2021-10-29 | 4605.38 | 0.069144 | 33026.261062 | 32416.964783 | 8500.0 | 23916.964783 | 32416.964783 | 0.000000 | 1.000000 |
2021-11-30 | 4567.00 | -0.008334 | 32751.029072 | 32146.810505 | 8500.0 | 23646.810505 | 32146.810505 | 0.000000 | 1.000000 |
2021-12-31 | 4766.18 | 0.043613 | 34179.395608 | 33548.825333 | 8500.0 | 25048.825333 | 33548.825333 | 0.000000 | 1.000000 |
264 rows × 9 columns
시각화를 해보겠습니다.
python에는 matplotlib라는 시각화를 위한 라이브러리(기능)을 제공합니다.
from matplotlib import pyplot as plt
plt.figure(figsize=(16,9))
plt.plot(df.index, df['stock_only_budget'])
plt.plot(df.index, df['CPPI budget'])
plt.plot(df.index, df['floor'])
plt.show()
df.index는 표(df)의 세로축에 해당하는 월 간격을 지정하고, 각각 주식100%투자 금액추이(stock_only_budget), CPPI를 통한 금액추이(CPPI_budget), 그리고 floor를 그래프로 그려 위와 같이 시각화하였습니다.
plt.figure(figsize=(16,9))
plt.plot(df.index, df['stock_prop'])
plt.show()
이번 그래프에서는 월별 주식투자비중(stock_prop)을 시각화하였습니다.
df.to_excel('CPPI_calculated.xlsx')
마지막으로 최종 결과 표(df)를 CPPI_calculated.xlsx라는 이름의 파일로 저장하겠습니다.
이상으로 CPPI on Python 실습을 마치겠습니다.
FAQ
본 포스팅의 코드에 대한 질문은 본 포스팅 아래 댓글로 남겨주시면 최대한 답변드릴 수 있도록 하겠습니다.
댓글남기기