python 哈里马克沃维茨演示
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python 哈里马克沃维茨演示相关的知识,希望对你有一定的参考价值。
# -*- coding: utf-8 -*-
"""
Created on Sat Nov 24 16:41:12 2018
@author: JON7390
src: https://blog.quantopian.com/markowitz-portfolio-optimization-2/
"""
import cvxopt as opt
import matplotlib.pyplot as plt
# %matplotlib inline
import numpy as np
import pandas as pd
from cvxopt import blas, solvers
np.random.seed(123)
# Turn off progress printing
solvers.options['show_progress'] = False
### Demo #####################################################################
## NUMBER OF ASSETS
n_assets = 4
## NUMBER OF OBSERVATIONS
n_obs = 1000
return_vec = np.random.randn(n_assets, n_obs)
plt.plot(return_vec.T, alpha=.4)
plt.xlabel('time')
plt.ylabel('returns')
def rand_weights(n):
''' Produces n random weights that sum to 1 '''
k = np.random.rand(n)
return k / sum(k)
print (rand_weights(n_assets))
print (rand_weights(n_assets))
def random_portfolio(returns):
'''
Returns the mean and standard deviation of returns for a random portfolio
'''
p = np.asmatrix(np.mean(returns, axis=1))
w = np.asmatrix(rand_weights(returns.shape[0]))
C = np.asmatrix(np.cov(returns))
mu = w * p.T
sigma = np.sqrt(w * C * w.T)
# This recursion reduces outliers to keep plots pretty
if sigma > 2:
return random_portfolio(returns)
return mu, sigma
n_portfolios = 500
means, stds = np.column_stack([random_portfolio(return_vec) for i in range(n_portfolios)])
plt.plot(stds, means, 'o', markersize=5)
plt.xlabel('std')
plt.ylabel('mean')
plt.title('Mean and standard deviation of returns of randomly generated portfolios')
# optimizer
def optimal_portfolio(returns):
n = len(returns)
returns = np.asmatrix(returns)
# returns_h = np.asmatrix(return_vec)
N = 100
mus = [10**(5.0 * t/N - 1.0) for t in range(N)]
# Convert to cvxopt matricess
# S-> covariance matrix
S = opt.matrix(np.cov(returns))
# pbar -> expected returns
pbar = opt.matrix(np.mean(returns, axis=1))
# Create constraint matrices
# all weight >= 0
G = -opt.matrix(np.eye(n)) # negative n x n identity matrix
h = opt.matrix(0.0, (n ,1))
# weights sum up to 1
A = opt.matrix(1.0, (1, n))
b = opt.matrix(1.0)
# Calculate [efficient frontier] weights using quadratic programming
# x-> weighted portfolios| solvers.qp(P,q,G,h,A,b)
portfolios = [solvers.qp(mu*S, -pbar, G, h, A, b)['x'] for mu in mus]
## CALCULATE RISKS AND RETURNS FOR FRONTIER
returns = [blas.dot(pbar, x) for x in portfolios]
risks = [np.sqrt(blas.dot(x, S*x)) for x in portfolios]
## CALCULATE THE 2ND DEGREE POLYNOMIAL OF THE FRONTIER CURVE
# what?
m1 = np.polyfit(returns, risks, 2)
x1 = np.sqrt(m1[2] / m1[0])
# CALCULATE THE [OPTIMAL PORTFOLIO]
wt = solvers.qp(opt.matrix(x1 * S), -pbar, G, h, A, b)['x']
return np.asarray(wt), returns, risks
weights, returns, risks = optimal_portfolio(return_vec)
plt.plot(stds, means, 'o')
plt.ylabel('mean')
plt.xlabel('std')
plt.plot(risks, returns, 'y-o')
print (weights)
### Real Test ################################################################
from zipline.utils.factory import load_bars_from_yahoo
end = pd.Timestamp.utcnow()
start = end - 2500 * pd.tseries.offsets.BDay()
data = load_bars_from_yahoo(stocks=['IBM', 'GLD', 'XOM', 'AAPL',
'MSFT', 'TLT', 'SHY'],
start=start, end=end)
data.loc[:, :, 'price'].plot(figsize=(8,5))
plt.ylabel('price in $')
from zipline.api import (history,
set_slippage,
slippage,
set_commission,
commission,
order_target_percent)
from zipline import TradingAlgorithm
def initialize(context):
'''
Called once at the very beginning of a backtest (and live trading).
Use this method to set up any bookkeeping variables.
The context object is passed to all the other methods in your algorithm.
Parameters
context: An initialized and empty Python dictionary that has been
augmented so that properties can be accessed using dot
notation as well as the traditional bracket notation.
Returns None
'''
# Turn off the slippage model
set_slippage(slippage.FixedSlippage(spread=0.0))
# Set the commission model (Interactive Brokers Commission)
set_commission(commission.PerShare(cost=0.01, min_trade_cost=1.0))
context.tick = 0
def handle_data(context, data):
'''
Called when a market event occurs for any of the algorithm's
securities.
Parameters
data: A dictionary keyed by security id containing the current
state of the securities in the algo's universe.
context: The same context object from the initialize function.
Stores the up to date portfolio as well as any state
variables defined.
Returns None
'''
# Allow history to accumulate 100 days of prices before trading
# and rebalance every day thereafter.
context.tick += 1
if context.tick < 100:
return
# Get rolling window of past prices and compute returns
prices = history(100, '1d', 'price').dropna()
returns = prices.pct_change().dropna()
try:
# Perform Markowitz-style portfolio optimization
weights, _, _ = optimal_portfolio(returns.T)
# Rebalance portfolio accordingly
for stock, weight in zip(prices.columns, weights):
order_target_percent(stock, weight)
except ValueError as e:
# Sometimes this error is thrown
# ValueError: Rank(A) < p or Rank([P; A; G]) < n
pass
# Instantinate algorithm
algo = TradingAlgorithm(initialize=initialize,
handle_data=handle_data)
# Run algorithm
results = algo.run(data)
results.portfolio_value.plot()
以上是关于python 哈里马克沃维茨演示的主要内容,如果未能解决你的问题,请参考以下文章