การหา shape ratio สูงสุดและเส้น CML ด้วย Python
การทำ portfolio optimization ด้วย google colab X
ครั้งที่แล้วเราพูดถึงการหาการหาเส้นโค้งประสิทธิภาพและเราหลายคนสงสัยว่าของผมทำใมมันไม่โค้ง เพราะผมดันใส่สินทรัพย์ปราจการความเสี่ยงคือตราสารหนี้ลงไปด้วยและนี่คือจอกศักดิ์สิทธิ์ ตอนนี้เราจะพบว่าพอร์ตฟอลิโอเดียวบนเส้นโค้งกลุ่มหลักทรัพย์ที่มีประสิทธิภาพที่เราใส่ใจจริงๆและนั่นคือพอร์ตโฟลิโอที่ให้อัตราส่วนชาร์ปสูงสุดแก่เรา แต่เมื่อเราใส่สินทรัพย์ที่ไม่มีความเสี่ยงและอยู่บนสมมติฐานบ้างอย่างตามมฤษฎี CAPM เราจะได้รูปนี้ขึ้นมา
เราจะเเบ่งสินทรัพย์ออกเป็นสองส่วนคือสินทรัพย์เสี่ยงและสินทรัพย์ปราศจากความเสี่ยงโดยเส้น CML จะลากผ่านผลตอบแทนสินทรัพย์ปราศจากความเสี่ยงกับจุดที่ให้ ค่า shape ratio สูงสุดของเส้นโค้งประสิทธิภาพ
มาเริ่มกันเลย
ทำเหมือนเดิมคือ load packeges
# load packages
import pandas as pd
import numpy as np
import pandas_datareader as pdr
import seaborn as sns
from matplotlib import pyplot as plt
import pandas_datareader as web
import datetime
from scipy.optimize import minimize# not needed, only to prettify the plots.import matplotlib
from IPython.display import set_matplotlib_formats
อันดับต่อมาเราจะดึงข้อมูลเราจะใช้ข้อมูลผลตอบแทนรายอุตสาหกรรมสามารถloadได้ที่ https://github.com/nutdnuy/Portfolio_optimization_with_Python/blob/master/data/ind30_m_ew_rets.csv
ind = pd.read_csv("https://raw.githubusercontent.com/nutdnuy/Portfolio_optimization_with_Python/master/data/ind30_m_vw_rets.csv", header=0, index_col=0)/100ind.index = pd.to_datetime(ind.index, format="%Y%m").to_period('M'
หาผลตอบแทนและความแปรแปรวนรวมของแต่ละสินทรัพย์
def annualize_rets(r, periods_per_year):
compounded_growth = (1+r).prod()
n_periods = r.shape[0]
return compounded_growth**(periods_per_year/n_periods)-1er = annualize_rets(ind["1996":"2000"], 12)cov = ind["1996":"2000"].cov()
หา efficient frontier
หาผลตอบแทนของแต่พอร์การลงทุนซึ่งเท่ากับค่าเฉลี่ยถั่วนํ้าหนัก
def portfolio_return(weights, returns):return weights.T @ returns
คำนวณความผันผวนของพอร์ตการลงทุนจากความแปรปรวมร่วม
def portfolio_vol(weights, covmat):return (weights.T @ covmat @ weights)**0.5
หาค่าสัดส่วนการลงทุนที่เหมาะสมเพื่อให้ได้ผลตอบแทนตามเป้าหมาย
รับชุดของผลตอบแทนที่คาดหวังและเมทริกซ์ความแปรปรวนร่วมโดยใช้ Scipy
def minimize_vol(target_return, er, cov):n = er.shape[0]init_guess = np.repeat(1/n, n)bounds = ((0.0, 1.0),) * n # an N-tuple of 2-tuples!# construct the constraintsweights_sum_to_1 = {'type': 'eq','fun': lambda weights: np.sum(weights) - 1}return_is_target = {'type': 'eq','args': (er,),'fun': lambda weights, er: target_return -portfolio_return(weights,er)}weights = minimize(portfolio_vol, init_guess,args=(cov,), method='SLSQP',options={'disp': False},constraints=(weights_sum_to_1,return_is_target),bounds=bounds)return weights.x
คำนวณ optimal weights
def optimal_weights(n_points, er, cov):target_rs = np.linspace(er.min(), er.max(), n_points)weights = [minimize_vol(target_return, er, cov) for target_return in target_rs]return weights
ลองพอตดูกันครับ
def plot_ef(n_points, er, cov):"""Plots the multi-asset efficient frontier"""weights = optimal_weights(n_points, er, cov) # not yet implemented!rets = [portfolio_return(w, er) for w in weights]vols = [portfolio_vol(w, cov) for w in weights]ef = pd.DataFrame({"Returns": rets,"Volatility": vols})return ef.plot.line(x="Volatility", y="Returns", style='.-'ax = plot_ef(20, er, cov)ax.set_xlim(left = 0)
หาค่า Max shape ratio
เราสามารถหาค่า Max shape ratio ได้ด้วยฟังชันนี้ครับ
def msr(riskfree_rate, er, cov):n = er.shape[0]init_guess = np.repeat(1/n, n)bounds = ((0.0, 1.0),) * n # an N-tuple of 2-tuples!# construct the constraintsweights_sum_to_1 = {'type': 'eq','fun': lambda weights: np.sum(weights) - 1}def neg_sharpe(weights, riskfree_rate, er, cov):r = portfolio_return(weights, er)vol = portfolio_vol(weights, cov)return -(r - riskfree_rate)/volweights = minimize(neg_sharpe, init_guess,args=(riskfree_rate, er, cov), method='SLSQP',options={'disp': False},constraints=(weights_sum_to_1,),bounds=bounds)return weights.x
สุดท้ายพอตเป็นกราฟออกมา
# plot EFax = plot_ef(20, er, cov)ax.set_xlim(left = 0)# get MSRrf = 0.1w_msr = msr(rf, er, cov)r_msr = portfolio_return(w_msr, er)vol_msr = portfolio_vol(w_msr, cov)# add CMLcml_x = [0, vol_msr]cml_y = [rf, r_msr]ax.plot(cml_x, cml_y, color=’green’, marker=’o’, linestyle=’dashed’, linewidth=2, markersize=12)
เรียบร้อยครับ
อ่านตอนอื่นๆได้ที่
- การคำนวณผลตอบแทนการลงทุนด้วย Python
- การหาความผันผวนของพอร์ตการลงทุนด้วย Python
- การหา Max Drawdown ด้วย Python
- การวัด การเบี่ยงเบนของผลตอบแทนด้วย Python
- การวัด SemiDeviation ด้วย Python
- การวัด VaR. และ CVaR. ด้วย Python
- รีวิวการใช้ ffn. ใน Python
- การหา Top Drawdown ด้วย Python
- การหาค่า Sharpe ratio ด้วย Python
- การหากลุ่มหลักรัพย์ที่เส้นประสิทธิภาพ Efficient Frontier ด้วย Python
- การหา shape ratio สูงสุดและเส้น CML ด้วย Python
- การสร้างมูลค่าตลาดแบบถ่วงน้ำหนักด้วย PYTHON
- ข้อจำกัดของการกระจายความเสี่ยงและการทำประกันพอร์ตการลงทุน
- การจำลอง ผลตอบแทนด้วย RANDOM WALK Generation และ Montecarlo simulation
- Sharpe Style Analysis
- Factor Investing ด้วย Python
- วิเคราะห์ ประเภทกองทุนรวมด้วย Python
- การทำ Portfolio optimization
- สร้างแนวรับแนวต้านวิเคราะห์หุ้นด้วย Python