การหา shape ratio สูงสุดและเส้น CML ด้วย Python

การทำ portfolio optimization ด้วย google colab X

NUTHDANAI WANGPRATHAM
3 min readMay 10, 2020

ครั้งที่แล้วเราพูดถึงการหาการหาเส้นโค้งประสิทธิภาพและเราหลายคนสงสัยว่าของผมทำใมมันไม่โค้ง เพราะผมดันใส่สินทรัพย์ปราจการความเสี่ยงคือตราสารหนี้ลงไปด้วยและนี่คือจอกศักดิ์สิทธิ์ ตอนนี้เราจะพบว่าพอร์ตฟอลิโอเดียวบนเส้นโค้งกลุ่มหลักทรัพย์ที่มีประสิทธิภาพที่เราใส่ใจจริงๆและนั่นคือพอร์ตโฟลิโอที่ให้อัตราส่วนชาร์ปสูงสุดแก่เรา แต่เมื่อเราใส่สินทรัพย์ที่ไม่มีความเสี่ยงและอยู่บนสมมติฐานบ้างอย่างตามมฤษฎี CAPM เราจะได้รูปนี้ขึ้นมา

ที่มา: Capital Market Lineby Glyn Holton | Jun 5, 2013

เราจะเเบ่งสินทรัพย์ออกเป็นสองส่วนคือสินทรัพย์เสี่ยงและสินทรัพย์ปราศจากความเสี่ยงโดยเส้น 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)-1
er = 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)

เรียบร้อยครับ

อ่านตอนอื่นๆได้ที่

  1. การคำนวณผลตอบแทนการลงทุนด้วย Python
  2. การหาความผันผวนของพอร์ตการลงทุนด้วย Python
  3. การหา Max Drawdown ด้วย Python
  4. การวัด การเบี่ยงเบนของผลตอบแทนด้วย Python
  5. การวัด SemiDeviation ด้วย Python
  6. การวัด VaR. และ CVaR. ด้วย Python
  7. รีวิวการใช้ ffn. ใน Python
  8. การหา Top Drawdown ด้วย Python
  9. การหาค่า Sharpe ratio ด้วย Python
  10. การหากลุ่มหลักรัพย์ที่เส้นประสิทธิภาพ Efficient Frontier ด้วย Python
  11. การหา shape ratio สูงสุดและเส้น CML ด้วย Python
  12. การสร้างมูลค่าตลาดแบบถ่วงน้ำหนักด้วย PYTHON
  13. ข้อจำกัดของการกระจายความเสี่ยงและการทำประกันพอร์ตการลงทุน
  14. การจำลอง ผลตอบแทนด้วย RANDOM WALK Generation และ Montecarlo simulation
  15. Sharpe Style Analysis
  16. Factor Investing ด้วย Python
  17. วิเคราะห์ ประเภทกองทุนรวมด้วย Python
  18. การทำ Portfolio optimization
  19. สร้างแนวรับแนวต้านวิเคราะห์หุ้นด้วย Python

--

--

NUTHDANAI WANGPRATHAM
NUTHDANAI WANGPRATHAM

Written by NUTHDANAI WANGPRATHAM

I am a learner and have a multipotential life. You can contact me at nutdnuy@gmail.com

No responses yet