Оптимизация среднего отклонения + Python + ограничения настройки - PullRequest
0 голосов
/ 21 января 2019

Я пытаюсь провести Оптимизацию портфеля среднего отклонения, используя встроенный оптимизатор 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)

1 Ответ

0 голосов
/ 06 июня 2019

вам нужно обновить ограничения:

constraints = ({'type': 'eq', 'fun': lambda x: np.sum(x) - 0},
{'type':'eq','fun': const_vol,'args':[mean_return, carry_cov]})

def const_vol(weights, *args):
        curr_vol = portfolio_annualised_performance(weights, args[0], args[1])[0]
        return 0.1 - curr_vol
...