如何理解這種尋找風險預算組合的凸優化方法
CVXPY開發人員編寫的短期課程材料和Quant SE 上的答案都表明,給定所需的風險預算b $ b $ ,我們可以找到具有權重的全投資組合在 $ w $ 風險預算(在這些材料中定義)等於b $ b $ 通過執行以下凸優化:
最小化12在′Σ在−∑一世b一世日誌在一世受制於1′在=1$$ \begin{align}\text{Minimize};&\frac{1}{2}w’\Sigma w - \sum_i b_i,\text{log}w_i \ \text{subject to} ;& 1’w=1\end{align} $$
然而,我自己在 Python 中使用 CVXPY 完成了這項工作,我發現由此產生的風險預算與預期的不一樣b $ b $ .
然後我嘗試手動計算這個最小化,我發現解決方案在 $ w $ 有
(Σ在)一世−b一世在一世=λ對所有人 一世$$ (\Sigma w)_i - \frac{b_i}{w_i} = \lambda;;;\text{for all }i $$
在哪裡λ $ \lambda $ 是拉格朗日乘數。
換句話說,因為我們可以證明一世 $ i $ -th 風險預算b在一世 $ {b_w}_i $ 根據定義等於在一世(Σ在)一世在′Σ在 $ \frac{w_i(\Sigma w)_i}{w’\Sigma w} $ ,該優化問題的解決方案有:
b在一世=b一世+λ在一世在′Σ在=b一世+λ在一世1+λ$$ {b_w}_i = \dfrac{b_i+\lambda w_i}{w’\Sigma w} = \dfrac{b_i+\lambda w_i}{1 + \lambda} $$
這通常不等於b一世 $ b_i $ (否則,在一世=b一世 $ w_i=b_i $ )。這已通過我在 Python 中執行的優化得到驗證。
但我確信這種方法沒有錯——Spinu (2013) 寫了一篇學術論文來解釋它,這超出了我的能力範圍。所以,我真的很感激任何能解釋這個公式的人!
更新:
這是我編寫的 Python 程式碼。這是一個練習,是 CVXPY 短期課程的一部分。
import numpy as np import cvxpy as cp #input data Sigma = np.array([[6.1, 2.9, -0.8, 0.1], [2.9, 4.3, -0.3, 0.9], [-0.8, -0.3, 1.2, -0.7], [0.1, 0.9, -0.7, 2.3]]) b = np.ones(4)/4 #risk parity # optimization w = cp.Variable(4) #portfolio weight obj = 0.5 * cp.quad_form(w, Sigma) - cp.sum(cp.multiply(b, cp.log(w))) #objective constr = [cp.sum(w) == 1, w >= 0] # constraint prob = cp.Problem(cp.Minimize(obj), constr) prob.solve() # print the solution weight and solution risk budget b_w = cp.multiply(w, Sigma @ w) / cp.quad_form(w, Sigma) #solution risk budget print("The solution weight is", w.value) print("The solution risk budget is", b_w.value)
列印輸出為:
The solution weight is [0.16073365 0.14918463 0.42056612 0.2695156 ]
The solution risk budget is [0.32355772 0.33307394 0.10944985 0.23391849]
我相信這個問題應該分兩步解決:在總和等於 1 的條件下進行優化**,**然後是標準化步驟,將 w 除以 sum(w) 以產生所需的解決方案。
這是修改後的程式碼:
import numpy as np import cvxpy as cp #input data Sigma = np.array([[6.1, 2.9, -0.8, 0.1], [2.9, 4.3, -0.3, 0.9], [-0.8, -0.3, 1.2, -0.7], [0.1, 0.9, -0.7, 2.3]]) b = np.ones(4)/4 #risk parity # optimization w = cp.Variable(4) #portfolio weight obj = 0.5 * cp.quad_form(w, Sigma) - cp.sum(cp.multiply(b, cp.log(w))) #objective constr = [w >= 0] # constraint prob = cp.Problem(cp.Minimize(obj), constr) prob.solve() # normalize w = w/cp.sum(w) # print the solution weight and solution risk budget b_w = cp.multiply(w, Sigma @ w) / cp.quad_form(w, Sigma) #solution risk budget print("The solution weight is", w.value) print("The solution risk budget is", b_w.value)
結果
The solution weight is [0.13765302 0.11336252 0.4758825 0.27310195] The solution risk budget is [0.25000012 0.25000013 0.24999967 0.25000007]
邊際值相等(在數值誤差範圍內)。