我正在尝试优化组合以获得锐化率,以下是我的代码
import pandas as pd
import os
import matplotlib.pyplot as plt
import numpy as np
import scipy.optimize as spo
def get_path(sym, base_dir = "data"):
cwd = os.getcwd()
path = os.path.join(cwd, base_dir, sym)
return path
def prepare_data(files, dates):
"""Read stock data (adjusted close) for given symbols from CSV files."""
dfstocks = pd.DataFrame(index=dates)
if 'NIFTY.csv' not in files:
files.insert(0, 'NIFTY.csv')
for f in files:
# TODO: Read and join data for each symbol
files_path = get_path(f)
df_temp = pd.read_csv(files_path, index_col = "Date",
parse_dates = True,
usecols = ['Date', 'Close Price'])
df_temp = df_temp.rename(columns = {'Close Price' : f})
dfstocks = dfstocks.join(df_temp, how = 'inner')
return dfstocks
def write_data(data, outfile):
base_dir = "data"
cwd = os.getcwd()
path = os.path.join(cwd, base_dir, outfile)
data.to_csv(path)
def get_data(filename):
base_dir = "data"
cwd = os.getcwd()
path = os.path.join(cwd, base_dir, filename)
dfstocks = pd.read_csv(path, index_col = "Unnamed: 0")
del dfstocks['NIFTY.csv']
return dfstocks
def portfolio_analysis(data, alloc, init_cap, risk_free_annual):
data_norm = data.divide(data.iloc[0])
data_alloc = data_norm * alloc
data_position = data_alloc * init_cap
portfolio_value = data_position.sum(axis = 1)
daily_returns = portfolio_value - portfolio_value[0]
daily_returns = daily_returns[1:]
risk_free_daily = np.power((risk_free_annual + 1), 1.0/252) - 1
cum_return = (portfolio_value[-1]/portfolio_value[0]) - 1
avg_day_return = daily_returns.mean()
std_day_return = daily_returns.std()
sharpe_ratio = (daily_returns - risk_free_daily).mean()/std_day_return
annualized_sharpe_ratio = np.power(252, 0.5) * sharpe_ratio
return (annualized_sharpe_ratio * -1)
def sharpe(alloc, data):
risk_free_annual_return = 0.08
initial_capital = 307267
return portfolio_analysis(data, alloc, initial_capital, risk_free_annual_return)
def analyze():
files = ["NIFTY.csv", "AGARIND.csv", "AIFL.csv", "EMMBI.csv", "IGL.csv", "JAMNAAUTO.csv", "KPRMILL.csv"]
start_date = '12/1/2015'
end_date = '9/21/2017'
dates = pd.date_range(start_date, end_date)
dfstocks = prepare_data(files, dates)
write_data(dfstocks, 'ClosePriceAll.csv')
filename = "ClosePriceAll.csv"
dfstocks = get_data(filename)
risk_free_annual_return = 0.08
initial_capital = 307267
allocation = [0.148, 0.112, 0.218, 0.184, 0.195, 0.143]
portfolio_analysis(dfstocks, allocation, initial_capital, risk_free_annual_return)
res = spo.minimize(sharpe, allocation, args = [dfstocks], method = 'SLSQP', options = {'disp' : True})
if __name__ == "__main__":
analyze()
此代码运行错误,以下是错误消息:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-7-c3e09b18fc12> in <module>()
95
96 if __name__ == "__main__":
---> 97 analyze()
98
<ipython-input-7-c3e09b18fc12> in analyze()
91 allocation = [0.148, 0.112, 0.218, 0.184, 0.195, 0.143]
92 portfolio_analysis(dfstocks, allocation, initial_capital, risk_free_annual_return)
---> 93 res = spo.minimize(sharpe, allocation, args = [dfstocks], method = 'SLSQP', options = {'disp' : True})
94 #print res
95
C:\Users\viupadhy\AppData\Local\Continuum\Anaconda2\lib\site-packages\scipy\optimize\_minimize.pyc in minimize(fun, x0, args, method, jac, hess, hessp, bounds, constraints, tol, callback, options)
456 elif meth == 'slsqp':
457 return _minimize_slsqp(fun, x0, args, jac, bounds,
--> 458 constraints, callback=callback, **options)
459 elif meth == 'dogleg':
460 return _minimize_dogleg(fun, x0, args, jac, hess,
C:\Users\viupadhy\AppData\Local\Continuum\Anaconda2\lib\site-
packages\scipy\optimize\slsqp.pyc in _minimize_slsqp(func, x0, args, jac,
bounds, constraints, maxiter, ftol, iprint, disp, eps, callback, **unknown_options)
368 fx = float(np.asarray(func(x)))
369 except:
--> 370 raise ValueError("Objective function must return a scalar")
371 # Compute the constraints
372 if cons['eq']:
ValueError: Objective function must return a scalar
你能帮忙解决问题吗? 具体问题可以是对最小化器的调用是否正确? 如果我正确使用了args参数? 这个错误消息的含义是什么&#34; ValueError:目标函数必须返回一个标量&#34;? 感谢。