Python Forum
Minimization of variance problem
Thread Rating:
  • 1 Vote(s) - 5 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Minimization of variance problem
#1
Hello!,

I am really new to Python, I'm trying to do some financial stuff. Below you will find my code, I am having problems when trying to Minimize my variance with respect to two constraints: weights equal 1 and beta lower than 2. Any suggestions would be great :) 

My main problem is that I get the error saying that "ValueError: all the input arrays must have same number of dimensions"

#%%
#packages
from IPython import get_ipython
get_ipython().magic('reset -sf')

import numpy as np
import pandas as pd
import datetime as dt
import matplotlib as mpl
import matplotlib.pyplot as plt
get_ipython().magic('matplotlib inline')

import pandas_datareader.data as web
from pandas_datareader.famafrench import get_available_datasets
import quandl
import statsmodels.formula.api as smf
import statsmodels.api as sm
from scipy.optimize import minimize
from datetime import datetime
from zipline.api import order, symbol, record, order_target
from zipline.utils.factory import load_bars_from_yahoo
from zipline.algorithm import TradingAlgorithm
from zipline.data.bundles import register, yahoo_equities
from zipline.api import symbol, order, record, history
import zipline
import pytz
from collections import OrderedDict

#%%
#Fetching and cleaning data, compute returns

myassets = 'AAPL GOOG'
#type(myassets)

myassets = myassets.split()

#define beginning date and time

start_date = '2014-01-01'
end_date = '2015-12-31'

#extract data from yahoo
data = web.DataReader(myassets, 'yahoo', start_date, end_date)
data.items
#data.items = [x.lower() for x in data.items] 
data.items=['open', 'high', 'low', 'close', 'volume', 'adjclose'] #changing to lower case and adjclose together

#create a data rame that contains adjclose price

prices=pd.DataFrame(data.adjclose, index=data.major_axis, columns=data.minor_axis)

#make a graph
prices.plot()

#create returns
returns=(prices/prices.shift(1))-1
#returns2=prices.pct_change()

#%%
#Download Fama French factors

ff  = web.DataReader("F-F_Research_Data_Factors_daily", "famafrench",start=start_date, end=end_date)

#==============================================================================
# d1  = web.DataReader("F-F_Research_Data_Factors_daily", "famafrench",start=dt.datetime(1926,1,1))
# d2  = web.DataReader("F-F_Momentum_Factor_daily", "famafrench",start=dt.datetime(1926,1,1))
# d3  = web.DataReader("F-F_Research_Data_5_Factors_2x3_daily", "famafrench",start=dt.datetime(1926,1,1))
# 
# d1m = web.DataReader("F-F_Research_Data_Factors", "famafrench")
# d2m = web.DataReader("F-F_Momentum_Factor", "famafrench")
#==============================================================================

ff = pd.DataFrame(ff[0]/100) #tranform the % values of factors to decimals
ff.columns = (['mktrf', 'smb', 'hml', 'rf']) #change to lower case, and prettier look :)

#join returns of assets and risk free
return_rf = returns.join(ff.rf, how='inner') #inner=intersection, and outer=union

#join returns of assets and all factors
return_all = returns.join(ff, how='inner')

#return_3 = returns.join([ff.rf, ff.smb], how='inner') #only two factors

#%%
#Regressions
#Create data frame para los betas
#Compute betas for the whole period of data available.
#First: create an empty list to store the betas
#Second: run loop that goes through every id in return_ff.columns and regresses returns on the market return
#Append function passes an object into a list. 
#Third: create an array from your list
#Integrate your array into a data frame with columns equivalent to return_all.columns
betas = []

for id in return_all.columns:
    formula = id + '~mktrf'
    res = smf.ols(formula = formula, data = return_all).fit()
    betas.append(res.params[1])
betas = (betas)

betas = pd.DataFrame([betas], columns=return_all.columns)

#%%
#Minimizations
#Market neutral and no constraints

b = np.matrix(betas)
#b = np.matrix(betas.iloc[-1,:]) #this takes the last one
w = np.ones((1,6))/6

def MktNeutral(w,b):
    mktb = abs(w*b.T)
    return mktb
    
res = minimize(MktNeutral, np.ones((1,6))/6, args=(b,),options={'disp': True}, method='SLSQP')

#Minimize variance of portfolio and beta below 2

def PtfVar(w,b,vcv):
    temp = w.dot(vcv).dot(w.T)
    return temp
    
w = pd.DataFrame([],index=data.major_axis, columns=data.minor_axis)

for id in data.major_axis[::]:
    b = np.matrix(betas)
    #b = np.matrix(betas.iloc[-1,:])
[color=#cc6666]    [/color][color=#ff66cc]vcv = np.array(return_all.loc[:,:].cov())[/color]
    #vcv = np.array(return_all.loc[t-pd.DateOffset(days = 365):t,:].cov())
    
    cons = ({'type': 'ineq',
    'fun' : lambda x,b: 0.2-abs(x.dot(b.T)),
    'args': (b,)},
    {'type':'eq',
     'fun': lambda x: x.sum()-1})     


[color=#ff6699]res = minimize(PtfVar, np.ones((1,6))/6 , args=(b,vcv,),constraints=cons,options={'disp': True,'ftol':1e-12}, method='SLSQP')#, jac=func_deriv,  options={'disp': True})[/color]
w.loc[t,:]=res.x
Thanksss!!!
Reply
#2
Hello and welcome!

Your code is rather long, and you did not show the whole error message.

Can you write a much shorter code example which will show the same error?
Reply
#3
Like that? Sorry, First time using Forums as well  Tongue

#packages
from IPython import get_ipython
get_ipython().magic('reset -sf')
import numpy as np
import pandas as pd
import datetime as dt
import matplotlib as mpl
import matplotlib.pyplot as plt
get_ipython().magic('matplotlib inline')

import pandas_datareader.data as web
from pandas_datareader.famafrench import get_available_datasets
import quandl

import statsmodels.formula.api as smf
import statsmodels.api as sm
from scipy.optimize import minimize

from datetime import datetime
from zipline.api import order, symbol, record, order_target
from zipline.utils.factory import load_bars_from_yahoo
from zipline.algorithm import TradingAlgorithm
from zipline.data.bundles import register, yahoo_equities
from zipline.api import symbol, order, record, history
import zipline
import pytz
from collections import OrderedDict

#%%
#Fetching and cleaning data, compute returns

myassets = 'AAPL GOOG'
#type(myassets)
myassets = myassets.split()
#define beginning date and time
start_date = '2014-01-01'
end_date = '2015-12-31'
#extract data from yahoo
data = web.DataReader(myassets, 'yahoo', start_date, end_date)
data.items
#data.items = [x.lower() for x in data.items] 
data.items=['open', 'high', 'low', 'close', 'volume', 'adjclose'] #changing to lower case and adjclose together
prices=pd.DataFrame(data.adjclose, index=data.major_axis, columns=data.minor_axis)
returns=(prices/prices.shift(1))-1


#%%
#Download Fama French factors

ff  = web.DataReader("F-F_Research_Data_Factors_daily", "famafrench",start=start_date, end=end_date)

ff = pd.DataFrame(ff[0]/100) #tranform the % values of factors to decimals
ff.columns = (['mktrf', 'smb', 'hml', 'rf']) #change to lower case, and prettier look :)
#join returns of assets and risk free
return_rf = returns.join(ff.rf, how='inner') #inner=intersection, and outer=union
#join returns of assets and all factors
return_all = returns.join(ff, how='inner')

#return_3 = returns.join([ff.rf, ff.smb], how='inner') #only two factors

#%%
#Regressions
betas = []

for id in return_all.columns:
    formula = id + '~mktrf'
    res = smf.ols(formula = formula, data = return_all).fit()
    betas.append(res.params[1])
betas = (betas)

betas = pd.DataFrame([betas], columns=return_all.columns)

#%%
#Minimizations
#Minimize variance of portfolio and beta below 2,5

def PtfVar(w,b,vcv):
    temp = w.dot(vcv).dot(w.T)
    return temp
    
w = pd.DataFrame([],index=data.major_axis, columns=data.minor_axis)

for id in data.major_axis[::]:
    b = np.matrix(betas)
    #b = np.matrix(betas.iloc[-1,:])
    vcv = np.array(return_all.loc[:,:].cov())
    #vcv = np.array(return_all.loc[t-pd.DateOffset(days = 365):t,:].cov())
    
    cons = ({'type': 'ineq',
    'fun' : lambda x,b: 0.2-abs(x.dot(b.T)),
    'args': (b,)},
    {'type':'eq',
     'fun': lambda x: x.sum()-1})     


res = minimize(PtfVar, np.ones((1,6))/6 , args=(b,vcv,),constraints=cons,options={'disp': True,'ftol':1e-12}, method='SLSQP')#, jac=func_deriv,  options={'disp': True})
w.loc[t,:]=res.x
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020