使用python scipy的optimize.minimize优化锐化率的投资组合

时间:2017-10-24 13:36:10

标签: python numpy optimization scipy minimization

我正在尝试优化组合以获得锐化率,以下是我的代码

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;? 感谢。

0 个答案:

没有答案