Почему ограничения в моем scipy minim не работают или не соблюдаются? - PullRequest
0 голосов
/ 09 мая 2020

Я создаю функцию, которая минимизирует дисперсию портфеля, изменяя веса его активов.

Моя функция scipy.minimize не соблюдает указанные мной ограничения (сумма весов должна = 1 ).

Кто нибудь может помочь? :)

Вот мой код:

import pandas as pd
import pandas_datareader.data as web
import numpy as np
import datetime
from scipy import stats
from scipy.optimize import minimize
import math

tickers_list=['GOOGL', 'AAPL', 'AMZN','TOT']
start_date=datetime.datetime(2010, 1, 1)
end_date=datetime.datetime(2011, 1, 1)
init_w = 1/len(tickers_list)
init_weights = np.array([init_w for i in range(0,len(tickers_list))])

def get_prices(tickers_list, start_date, end_date):
    prices = pd.DataFrame([web.DataReader(t,'yahoo', start_date, end_date).loc[:, 'Adj Close']
                           for t in tickers_list], index=tickers_list).T.asfreq('B').ffill()
    return prices

def get_returns(prices):
    returns = prices.pct_change()[1:]
    return returns

prices = get_prices(tickers_list, start_date, end_date)
returns = get_returns(prices)
av_returns = returns.mean()
matcov=returns.cov()
num_portfolios = 25000

risk_free = get_prices(['^TYX'], start_date, end_date)
risk_free_rates = get_returns(risk_free)
final_risk_free_rate = risk_free_rates.mean()

def portfolio_annualised_performance(weights, mean_returns, cov_matrix):
    returns = np.sum(mean_returns*weights ) *252
    std = np.sqrt(np.dot(weights.T, np.dot(cov_matrix, weights))) * np.sqrt(252)
    return std, returns

def neg_sharpe_ratio(weights, mean_returns, cov_matrix, risk_free_rate):
    p_var = portfolio_annualised_performance(weights, mean_returns, cov_matrix)[0]
    p_ret = portfolio_annualised_performance(weights, mean_returns, cov_matrix)[1]
    return -(p_ret - risk_free_rate) / p_var

def max_sharpe_ratio(mean_returns, cov_matrix, risk_free_rate):
    num_assets = len(mean_returns)
    args = (mean_returns, cov_matrix, risk_free_rate)
    constraints = ({'type': 'eq', 'fun': lambda x: np.sum(x) - 1})
    bounds = ((0.0, 1.0),)*num_assets # A n-tuple of 2 tuples 
    result = minimize(neg_sharpe_ratio, num_assets*[1./num_assets,], args=args,
                        method='SLSQP', bounds=bounds, constraints=constraints, options {'gtol':1e-10})
    return result


result_test = max_sharpe_ratio(av_returns, matcov, final_risk_free_rate)
print("result_test :", result_test.x)
...