利用python构建马科维茨_Markowitz投资组合之Python模拟

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

金钱永不眠:资本世界的暗流涌动和金融逻辑,香帅无花(唐涯),中信出版社

金融数学-金融工程引论,马雷克/托马斯,人大出版社

你可能感兴趣的:(利用python构建马科维茨)