Я пытаюсь провести Оптимизацию портфеля среднего отклонения, используя встроенный оптимизатор SLSQP в scipi, и мне трудно понять, как определить ограничение решения для весов портфеля, используя ограничение постоянной дисперсии портфеля 10%.Был в состоянии включить только ограничение, что сумма всех весов должна суммироваться до 0
Я смог использовать этот оптимизатор, чтобы найти портфель для максимизации коэффициента Шарпа портфеля и для нахождения весов, которые минимизируют дисперсию портфеля,Теперь нужно добавить дополнительное ограничение, чтобы дисперсия портфеля всегда оставалась на уровне 10%, а оптимизатор решает для весов, которые максимизируют доходность портфеля
def portfolio_annualised_performance(weights, mean_returns, carry_cov):
returns = np.sum(mean_returns*weights) *12
std = np.sqrt(np.dot(weights.T, np.dot(carry_cov, weights))) * np.sqrt(12)
return std, returns
def neg_sharpe_ratio(weights, mean_returns, carry_cov, risk_free_rate):
p_var, p_ret = portfolio_annualised_performance(weights, mean_returns, carry_cov)
return -(p_ret - risk_free_rate) / p_var
def max_sharpe_ratio(mean_returns, carry_cov, risk_free_rate):
args = (mean_returns, carry_cov, risk_free_rate)
no = int(len(mean_returns))
constraints = ({'type': 'eq', 'fun': lambda x: np.sum(x) - 0})
bound1 = (-1.0,0.0)
bound2 = (0.0,1.0)
bounds = tuple(bound2 for asset in range(int(no/2)))+tuple(bound1 for asset in range(int(no/2)))
result = sco.minimize(neg_sharpe_ratio, no*[1./no,], args=args,method='SLSQP', bounds=bounds, constraints=constraints)
return result
######## NEED HELP WITH THE FOLLOWING SNIPPET OF CODE
def neg_return(weights, mean_returns, carry_cov, risk_free_rate):
p_var, p_ret = portfolio_annualised_performance(weights, mean_returns, carry_cov)
return -(p_ret)
def max_carry(mean_returns, carry_cov, risk_free_rate):
args = (mean_returns, carry_cov, risk_free_rate)
no = int(len(mean_returns))
constraints = ({'type': 'eq', 'fun': lambda x: np.sum(x) - 0})
bound1 = (-1.0,0.0)
bound2 = (0.0,1.0)
bounds = tuple(bound2 for asset in range(int(no/2)))+tuple(bound1 for asset in range(int(no/2)))
result = sco.minimize(neg_return, no*[1./no,], args=args,method='SLSQP', bounds=bounds, constraints=constraints)
return result
Я думаю, мне нужно обновить это, чтобы обеспечитьчто p_var = 10% для всего пространства portfgolio, на которое смотрит оптимизатор, но как мне изменить приведенный ниже словарь constrasint?
constraints = ({'type': 'eq', 'fun': lambda x: np.sum(x) - 0})
Также я попробовал следующее, но, похоже, не помогло совсем (Попытка вернуть большое положительное значение возврата, если дисперсия выше или ниже 10,5% или 9,5%, что должно добавить к функции стоимости для оптимизатора):
def neg_return(weights, mean_returns, carry_cov, risk_free_rate):
p_var, p_ret = portfolio_annualised_performance(weights, mean_returns, carry_cov)
if p_var > 0.105 or p_var< 0.095:
p_ret = -p_ret*1000
return -(p_ret)