Inspiration:
http://travisvaught.blogspot.de/2011/09/modern-portfolio-theory-python.html
http://www.casact.org/pubs/forum/95fforum/95ff355.pdf
http://www.quantandfinancial.com/2013/07/mean-variance-portfolio-optimization.html
Correlation $$ \rho_{X,Y}=\mathrm{corr}(X,Y)={\mathrm{cov}(X,Y) \over \sigma_X \sigma_Y} ={E[(X-\mu_X)(Y-\mu_Y)] \over \sigma_X\sigma_Y} $$
Covariance $$ r_{xy}=\frac{\sum\limits_{i=1}^n (x_i-\bar{x})(y_i-\bar{y})}{(n-1) s_x s_y} =\frac{\sum\limits_{i=1}^n (x_i-\bar{x})(y_i-\bar{y})} {\sqrt{\sum\limits_{i=1}^n (x_i-\bar{x})^2 \sum\limits_{i=1}^n (y_i-\bar{y})^2}}, $$
Define
$R = \left( \begin{array}{c} R_1\\ \vdots\\ R_N\\ \end{array} \right)$
to be the random vector of returns where
$E(R) = \left( \begin{array}{c} \mu_1\\ \vdots\\\ \mu_N\\ \end{array} \right)$
and $\Sigma$ to the covariance matrix of $R$. Let
$w = \left( \begin{array}{c} w_1\\ \vdots\\ w_N\\ \end{array} \right)$
be a vector of portfolio weights so that $w_1 + \ldots + w_N = 1^T w = 1$. The expected return of the portfolio is $$ \sum_{i=1}^N w_i \mu_i = w^T \mu$$
The variance of the return of the portfolio is
$$ w^T \Sigma w $$Thus, given a target \mu_P, the efficient portfolio minimizes the variance above subject to:
$$w^T = \mu_P$$and $$w^T 1 = 1$$
Quadratic programming function to be minimized
$$ \frac{1}{2} x^T D x - d^T x$$
In [12]:
#%%timeit
#Get the data
symbols = ['AAPL', 'GOOG', 'IBM']
from datetime import datetime
import pandas.io.pytables
import pandas.io.data as web
import time
t0 = datetime(2007, 2, 1)
t1 = datetime(2007, 5, 1)
if True:
stx = web.DataReader(symbols, data_source="yahoo", start=t0, end=t1)
else:
with pandas.io.pytables.get_store('snp500.h5') as store:
stx = store['stx']
#stx.Returns = stx.Close / stx.Close.shift(1)
#print stx.Close
In [13]:
stx.Returns = stx.Close / stx.Close.shift(1)
print stx.Returns.quantile(q=0.05)
In [11]:
print stx.Returns.sum(axis=1).quantile(q=0.05)
In [19]:
%%time
stx.Close['Market'] = stx.Close.sum(axis=1)
stx.Returns = stx.Close / stx.Close.shift(1)
print stx.Returns.quantile(q=0.05)
In [16]:
print stx.Returns.quantile(q=0.05)
In [17]:
data = stx.Returns[t0:t1][ symbols ]
def calibrate( data ):
mu = data.mean(axis=0)
sigma = data.cov()
return mu, sigm
def return_stats( w, mean, sigma):
return w.T.dot(mean), w.dot(sigma).dot(w.T)
# def return_var( portfolio, sigma):
mu, s = calibrate(data)
w = np.array( [0.2, 0.38, 0.42])
print return_stats( w, mu, s )
In [18]:
A = np.concatenate( (np.ones(3), mu))
muP = np.linspace(0.01, 0.2, num=300)
sdP = muP.copy()
#A, muP, sdP
In [ ]:
## http://ivanidris.net/wordpress/index.php/2010/11/21/jarque-bera-the-capm-and-undervalued-stocks
## http://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.minimize.html#scipy.optimize.minimize
In [15]:
import numpy as np
from scipy.optimize import minimize
def get_func( mean, sigma):
def func(w, sign=1.0):
return w.dot(sigma).dot(w.T)
return func
def compute_optimal_portfolio(target_value, allow_short_selling=True):
target_value = 1.05
mean, sigma = calibrate(data)
#cons = [{'type': 'eq', 'fun': lambda w: np.sum(w) - 1.0},
# {'type': 'eq', 'fun': lambda w: w.T.dot(mean) - target_value}]
cons = ({'type': 'eq', 'fun': lambda w: np.sum(w) - 1.0},
{'type': 'eq', 'fun': lambda w: w.T.dot(mean) - target_value})
if not allow_short_selling:
bnds = ((0, None) for x in mean)
optimal_portfolio = minimize( get_func(mean, sigma), np.array([.2,.3,.5]), method='SLSQP', constraints = cons, bounds=bnds)
else:
optimal_portfolio = minimize( get_func(mean, sigma), np.array([.2,.3,.5]), method='SLSQP', constraints = cons)
return optimal_portfolio
In [ ]:
# http://stackoverflow.com/questions/18218355/scipy-optimization-with-grouped-bounds
# http://www.quantandfinancial.com/2013/07/mean-variance-portfolio-optimization.html
In [1]:
f = lambda x: 2 * x
f(4)
Out[1]:
In [16]:
for ret in returns:
w = compute_optimal_portfolio(1.0, allow_short_selling=False)
if w.success: print w
In [51]:
w
Out[51]:
In [29]:
risk = np.linspace(0., 0.5, num=50)
returns = np.linspace( 0., 2.0, num=100)
np.meshgrid(returns, risk)
np.meshgrid??
In [61]:
Out[61]:
In [6]:
from ggplot import *
tau = 250
theta = tau
t = np.linspace(1,tau, tau, endpoint=True)
t
w = np.exp( (t - tau) / theta)
plot(w)
Out[6]:
In [14]:
import pandas
pandas.ewmcorr