【发布时间】:2020-11-28 19:53:20
【问题描述】:
我目前正在使用 Python,并且在使用 Scipy.optimize 时得到了奇怪的结果 - 特别是最小化函数。 def optimize_portfolio(initial,returns,rf) 之前的一切似乎都运行良好。最小化的前几次迭代运行良好,但之后似乎参数“权重”和“返回”在def portfolio_stats(returns,weights,rf) 中切换,我不知道为什么。如果有人能弄清楚发生了什么,那将不胜感激!
from math import exp
import numpy as np
import pandas_datareader.data as web
import matplotlib.pyplot as plt
import scipy.optimize as optimization
#Get data from Yahoo
def stock_data(stocks,start_date,end_date):
start_date= start_date
end_date= end_date
data=web.DataReader(stocks,data_source='yahoo',start=start_date,end=end_date)['Adj Close']
return data
#Calulate daily log returns (as opposed to arithmetic returns)
def stock_returns(data):
daily_returns=(data/data.shift(1))
daily_returns=np.log(daily_returns)
return daily_returns
#Get statistics for stocks (yearly approximate based on log returns)
def stock_stats(returns):
expected=returns.mean()*252
variance=returns.var()*252
covariance=returns.cov()*252
return [expected,variance,covariance]
#Get statistics for porfolio (yearly approximate based on log returns)
def portfolio_stats(returns,weights,rf):
expected=np.sum(returns.mean()*weights)*252
variance =np.dot(weights.T,np.dot(returns.cov()*252,weights))
sd=np.sqrt(variance)
sharpe=(expected-rf)/sd
return [expected,sd,sharpe]
#Run simulation of portfolios
def monte_carlo_porfolios(stocks,returns,simulations,rf):
mc_expected=[]
mc_sd=[]
optimum=[]
sharpe=0
for i in range(simulations):
weights=np.random.random(len(stocks))
weights /= np.sum(weights)
stats =portfolio_stats(returns,weights,rf)
expected =stats[0]
sd =stats[1]
mc_expected.append(expected)
mc_sd.append(sd)
if (expected-rf)/sd>sharpe:
optimum=weights
sharpe=(expected-rf)/sd
mc_expected=np.array(mc_expected)
mc_sd=np.array(mc_sd)
return [mc_expected,mc_sd,np.array(optimum)]
#Define function to minmise
def min_func_sharpe(weights,*args):
return -portfolio_stats(weights,args[0],args[1])[2]
#Find best combination via optimization algorithm
def optimize_portfolio(initial,returns,rf):
constraints = ({'type':'eq','fun':lambda x:np.sum(x)-1})
bounds = tuple((0,1) for x in range(len(stocks)))
optimum = optimization.minimize(fun=min_func_sharpe,x0=initial,args=(returns,rf),method='SLSQP',bounds=bounds,constraints=constraints)
return optimum
stocks = ['AAPL','WMT','TSLA','GE','AMZN','DB']
start_date ='01/01/2010'
end_date ='01/01/2020'
rf=0.02
data = stock_data(stocks,start_date,end_date)
log_returns = stock_returns(data)
monte_carlo = monte_carlo_porfolios(stocks,log_returns,1000,rf)
print(optimize_portfolio(monte_carlo[2],log_returns,rf))
【问题讨论】:
-
你能指定一个最小的工作示例
-
我在把它放在这里之前删除了相当多的功能哈哈。嗯,就简化而言,导致问题的函数是optimize_portfolio()。优化投资组合试图最小化函数 min_func_sharpe。 min_func_sharpe 基于函数投资组合统计。所有其他功能都可以忽略,但它们是程序运行所必需的。
-
更充实的 MWE(即有人可以运行的东西)会有所帮助。为什么在
min_fun_sharpe中指定附加参数为*args,而不是明确指定它们?如果这是问题所在,我会感到惊讶,但它似乎确实引入了一些不必要的谜团。用实际参数替换它是我要开始的地方。 -
当我可以访问 IDE 时,我会编写一个 MWE。我最初明确地将它们指定,但我将其更改为 *args 希望它可以解决我的错误。
标签: python scipy scipy-optimize-minimize