1952年,芝加哥大学的Markowitz提出现代资产组合理论(Modern Portfolio Theory,简称MPT),为现代西方证券投资理论奠定了基础。其基本思想是,证券投资的风险在于证券投资收益的不确定性。如果将收益率视为一个数学上的随机变量的话,证券的期望收益是该随机变量的数学期望(均值),而风险可以用该随机变量的方差来表示。
对于投资组合而言,如何分配各种证券上的投资比例,从而使风险最小而收益最大?
答案是将投资比例设定为变量,通过数学规划,对每一固定收益率求最小方差,对每一个固定的方差求最大收益率,这个多元方程的解可以决定一条曲线,这条曲线上的每一个点都对应着最优投资组合,即在给定风险水平下,收益率最大,这条曲线称作“有效前沿” (Efficient Frontier)。
对投资者而言,不存在比有效前沿更优的投资组合,只需要根据自己的风险偏好在有效前沿上寻找最优策略。
以包含两项风险资产的投资组合为例,其最小方差模型与有效前沿如下图(CFA Notes Book 4, Page 155):
Paste_Image.png
期望收益与标准差分别定义如下(CFA Notes Book 4, Page 156):
Paste_Image.png
Python实现(Python 2.7.13 |Anaconda 4.3.1 (64-bit)):
数据源:
2010年~2016年美股股价–微博、搜狐、网易、百度、阿里巴巴
有约束的最优化问题:
约束条件:a. 5支美股权重之和=1; b. 给定期望收益率
通过最小二乘法计算给定收益率下对应的最小标准差
程序文件:
Get_Yahoo_Quote.py 从Yahoo! Finance获取美股数据
MPT.py 以最优化方法求解并绘制投资组合有效前沿
Get_Yahoo_Quote.py
# -*- coding: utf-8 -*-
"""
Created on Mon May 22 17:41:16 2017
@author: qiaovin
"""
import requests
import time
import pandas as pd
import warnings as ws
ws.filterwarnings("ignore")
def datetime_timestamp(dt):
time.strptime(dt, '%Y-%m-%d %H:%M:%S')
s = time.mktime(time.strptime(dt, '%Y-%m-%d %H:%M:%S'))
return str(int(s))
def get_yahoo_quote(ticker,begin_date,end_date):
s = requests.Session()
cookies = dict(B='6sji959chqf8n&b=3&s=gk')
crumb = 'hJ5N2TwcJhN'
begin = datetime_timestamp(begin_date)
end = datetime_timestamp(end_date)
r = s.get("https://query1.finance.yahoo.com/v7/finance/download/"+ticker+"?period1="+begin+"&period2="+end+"&interval=1d&events=history&crumb="+crumb,cookies=cookies,verify=False)
filename=ticker+".csv"
f = open(filename, 'w')
f.write(r.text)
f.close()
es = pd.read_csv(filename, index_col=0,parse_dates=True, sep=",", dayfirst=True)
return es
def get_yahoo_multi_quotes(tickers,begin_date,end_date):
result = pd.DataFrame()
i = 0
for ticker in tickers:
es = get_yahoo_quote(ticker,begin_date,end_date)
p = pd.DataFrame(es['Adj Close'])
p.rename(columns={'Adj Close': ticker},inplace=True)
#print(p.head())
if i == 0:
result = p
i = i + 1
else:
result =pd.merge(result,p,left_index=True,right_index=True)
return result
MPT.py
# -*- coding: utf-8 -*-
"""
Created on Sat May 27 16:39:54 2017
@author: qiaovin
"""
import numpy as np
import scipy.optimize as opt
from Get_Yahoo_Quote import get_yahoo_multi_quotes
import matplotlib.pyplot as plt
def port_return(weights):
'''
Input:
weights: weights for different securities in portfolio
Output:
pret : expected portfolio return
'''
weights = np.array(weights)
pret = np.sum(rets.mean() * weights) * 252
return pret
def port_volatility(weights):
'''
Input:
weights: weights for different securities in portfolio
Output:
pvol : expected portfolio volatility
'''
weights = np.array(weights)
pvol = np.sqrt(np.dot(weights.T, np.dot(rets.cov() * 252, weights)))
return pvol
begdate="2010-01-01 09:00:00" # beginning date
enddate="2016-12-31 09:00:00" # ending date
stocks=['WB', 'SOHU', 'NTES', 'BIDU','BABA']
data = get_yahoo_multi_quotes(stocks,begdate,enddate)
noa = len(stocks)
rets = np.log(data / data.shift(1))
'''
constraint:
1. sum of weights = 1 ;
2. fixed target return level
bound of weights: (0,1)
'''
bnds = tuple((0, 1) for x in range(noa))
target_returns = np.linspace(0.0, 0.25, 50)
target_vols = []
for target_return in target_returns:
cons = ({'type': 'eq', 'fun': lambda x: port_return(x) - target_return},
{'type': 'eq', 'fun': lambda x: np.sum(x) - 1})
res = opt.minimize(port_volatility, noa * [1. / noa,], method='SLSQP',
bounds=bnds, constraints=cons)
target_vols.append(res['fun'])
target_vols = np.array(target_vols)
plt.figure(figsize=(8, 4))
# efficient frontier
# target_returns/target_vols: Sharpe ratio (risk free rate=0)
plt.scatter(target_vols, target_returns, c=target_returns/target_vols, marker='x')
plt.grid(True)
plt.xlabel('expected volatility')
plt.ylabel('expected return')
plt.colorbar(label='Sharpe ratio')
plt.show()
执行结果:
Paste_Image.png
作者微信公众号
qrcode_small.jpg
参考:
**代码中cookie与crumb定义参见:Yahoo Finance财经数据PYTHON临时读取方法
http://www.jianshu.com/p/85d563d326a9
Yves_Hilpisch_Python_for_Finance
CFA_2017_Level_1_Schweser_Notes_Book_4
金钱永不眠:资本世界的暗流涌动和金融逻辑,香帅无花(唐涯),中信出版社
金融数学-金融工程引论,马雷克/托马斯,人大出版社