MPTheory代码中的纸浆优化器问题

时间:2020-02-18 16:03:39

标签: optimization pulp scipy-optimize

我是python的新手,最近决定创建我的Markowitz优化算法。我之前已经在Excel中完成过此操作,因此我认为在python中复制它会很棒。当需要在给定的约束条件下(一定的SD水平或无空头条件)优化投资组合权重以达到最大Sharpe比率时,问题就解决了。使用excel求解器是一个相对容易的任务,但不是在python中(至少对我而言)。我在下面附上我的代码。

ibm = pd.DataFrame(stock_ibm)
aapl = pd.DataFrame(stock_aapl)
ford = pd.DataFrame(stock_ford)
verizon = pd.DataFrame(stock_verizon)
netflix = pd.DataFrame(stock_netflix)
chevron = pd.DataFrame(stock_chevron)
tesla = pd.DataFrame(stock_tesla)
microsoft = pd.DataFrame(stock_microsoft)
mastercard = pd.DataFrame(stock_mastercard)
google = pd.DataFrame(stock_google)
​
risk_free_rate = 0.0013
​
ibm.drop(['High','Low','Open','Volume','Adj Close'], axis = 1, inplace = True)
aapl.drop(['High','Low','Open','Volume','Adj Close'], axis = 1, inplace = True)
ford.drop(['High','Low','Open','Volume','Adj Close'], axis = 1, inplace = True)
verizon.drop(['High','Low','Open','Volume','Adj Close'], axis = 1, inplace = True)
netflix.drop(['High','Low','Open','Volume','Adj Close'], axis = 1, inplace = True)
chevron.drop(['High','Low','Open','Volume','Adj Close'], axis = 1, inplace = True)
tesla.drop(['High','Low','Open','Volume','Adj Close'], axis = 1, inplace = True)
microsoft.drop(['High','Low','Open','Volume','Adj Close'], axis = 1, inplace = True)
mastercard.drop(['High','Low','Open','Volume','Adj Close'], axis = 1, inplace = True)
google.drop(['High','Low','Open','Volume','Adj Close'], axis = 1, inplace = True)
ibm
Alldf = pd.concat([ibm, aapl, ford, verizon, netflix, chevron, tesla, microsoft, mastercard, google], axis=1)
Alldf
import numpy as np
Alldf_logret = Alldf.apply(lambda x: np.log(x) - np.log(x.shift(1))) 
Alldf_logret
​
Alldf_logret.drop(Alldf_logret.index[0], inplace = True)
Alldf_logret.columns = ['IBM', 'APPLE', 'FORD', 'VERIZON', 'NETFLIX', 'CHEVRON', 'TESLA', 'MICROSOFT', 'MASTERCARD', 'GOOGLE']
Alldf_logret
import statistics
import numpy as np
std1 = np.std(Alldf_logret)
​
mean1 = np.mean(Alldf_logret)
​
CovTable = Alldf_logret.cov()
CovTable
CorrTable=Alldf_logret.corr()
CorrTable
data = {'σ 10%':[0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1], 
        'σ 12%':[0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1],
        'σ 14%':[0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1],
        'No shorting':[0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1],
        'MVP':[0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1],
        'Max Sharpe/Optimal risky':[0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1]}
df1 = pd.DataFrame(data, index = Alldf_logret.columns)
df1
import math
​
m10 = df1['σ 10%'].dot(mean1)
m12 = df1['σ 12%'].dot(mean1)
m14 = df1['σ 14%'].dot(mean1)
mNS = df1['No shorting'].dot(mean1)
mMVP = df1['MVP'].dot(mean1)
mMaxSO = df1['Max Sharpe/Optimal risky'].dot(mean1)
​
var10 = (df1['σ 10%']).dot((CovTable.to_numpy())).dot((df1['σ 10%']))
var12 = (df1['σ 12%']).dot((CovTable.to_numpy())).dot((df1['σ 12%']))
var14 = (df1['σ 14%']).dot((CovTable.to_numpy())).dot((df1['σ 14%']))
varNS = (df1['No shorting']).dot((CovTable.to_numpy())).dot((df1['No shorting']))
varMVP = (df1['MVP']).dot((CovTable.to_numpy())).dot((df1['MVP']))
varMaxSO = (df1['Max Sharpe/Optimal risky']).dot((CovTable.to_numpy())).dot((df1['Max Sharpe/Optimal risky']))
​
sd10 = math.sqrt(var10)
sd12 = math.sqrt(var12)
sd14 = math.sqrt(var14)
sdNS = math.sqrt(varNS)
sdMVP = math.sqrt(varMVP)
sdMaxSO = math.sqrt(varMaxSO)
​
sharpe10 = (m10 - risk_free_rate)/sd10
sharpe12 = (m12 - risk_free_rate)/sd12
sharpe14 = (m14 - risk_free_rate)/sd14
sharpeNS = (mNS - risk_free_rate)/sdNS
sharpeMVP = (mMVP - risk_free_rate)/sdMVP
sharpeMaxSO = (mMaxSO - risk_free_rate)/sdMaxSO
​

所以,我最终要实现的目标是:我想通过仅更改权重(或df1)并限制诸如sd10 == 0.1并且不应该权重的总和来最大化sharpe10,sharpe12 ...,sharpeMaxSO超过1; sd12 == 0.12,权重之和不应超过1;对于锐化而言,两岸应该限制负的权重(我想我应该弄清楚如何添加剩余的约束,如果我只想出主要思想的话)。拥有具有优化权重的新数据帧作为优化输出将是完美的。 考虑到我需要运行优化这一事实,我确实意识到我的代码的整个逻辑结构可能是错误的(我不确定是否可以将现有的变量用作Pulp或其他优化程序的输入,我基于excel算法),但是无论如何,我们将不胜感激。预先谢谢你!

0 个答案:

没有答案