当使用scipy.optimize和“ SLSQP”方法时,最终结果保持为初始值

时间:2019-04-08 03:39:23

标签: python-3.x financial

这是资产分配的金融工程问题。共有四类资产:股票,固定收益,CTA策略和相对价值策略。给出了它们的收益和协方差矩阵。因此,预期分配给固定收益资产的权重更多,分配给股票的权重较小,而不是初始权重。

协方差矩阵(4 * 4矩阵)如下(下面的代码中的C):

sigma = [ [0.019828564,0.002498922,0.003100164,0.001272493],[0.002498922,0.005589884,0.000511829,0.000184773],[0.003100164,0.000511829,0.001559972,0.00019131],[0.001272493,0.000184773,0.00019131,0.0001306]]

sigma_p = np.matrix(sigma)

0、1、2、3分别是'stock_idx','CTA_idx','RelativeValue_idx','bond_idx'

我正在尝试使用“风险-奇偶性”方法找到它们的最佳权重,该方法最终将解决方程:

![风险均等目标方程] https://i.imgur.com/9nxx7xU.png

我在python中使用了scipy.optimize,方法“ SLSQP”是唯一可以在求解过程中应用范围和约束的方法。但是,该机制不起作用,并且无论如何选择初始猜测,总是会返回初始猜测。代码如下:

def calculate_portfolio_var(W,C):
    # function that calculates portfolio risk
    sigma_p = np.sqrt(np.dot(np.dot(W.T,C),W))
    return sigma_p

def calculate_risk_contribution(W,C):
    MRC = np.dot(C,W)# Marginal Risk 
    RC = np.multiply(W,MRC)# Total Risk 
    return RC

def solve_weight(C,N): #C is the covariance matrix, and given as sigma_p before
    def risk_budget_objective(W,C,N):
        W = np.matrix(W).T        
        sig_p =  calculate_portfolio_var(W,C) # portfolio sigma      
        total_RC = calculate_risk_contribution(W,C)       
        risk_target = sig_p / N
        # sum of squared error
        J = sum(np.square(total_RC / sig_p - risk_target)) 

        print("SSE",J[0,0])
        return J[0,0]

    def total_weight_constraint(x):
        return np.sum(x)-1.0

    def long_only_constraint(x):
        return 
    w0 = [0.1, 0.2, 0.3, 0.4]
    w0 = np.matrix(w0).T 
    print('w0',w0,w0.shape)
    b_ = [(0., 1.) for i in range(N)] 
    c_ = ({'type': 'eq', 'fun': lambda W: np.sum(W) - 1.})
    optimized = scipy.optimize.minimize(risk_budget_objective, w0, (C,N), method='SLSQP', constraints=c_, bounds=b_)
    if not optimized.success: raise BaseException(optimized.message)
    w_rb = np.asmatrix(optimized.x)
    return w_rb

1 个答案:

答案 0 :(得分:0)

这似乎是一个数值精度问题,因为所计算的成本函数的值很小。解决此问题的两种方法。要么将成本函数乘以某个标量,以使其返回更大的值。 例如J = sum(np.square(total_RC / sig_p - risk_target))*100或将收敛容差设置为较小的值。默认值为1e-6。

optimized = minimize(risk_budget_objective, w0, (C,N), method='SLSQP', constraints=c_, bounds=b_  , options ={'ftol':1e-8})

更改后,代码将按预期工作。以下是输出

matrix([[0.04780104, 0.12432431, 0.19918203, 0.62869262]])