3 votos

Cómo entender este método de optimización convexa para encontrar la cartera con presupuesto de riesgo

Ambos el material del curso corto codificado por los desarrolladores de CVXPY y una respuesta en Quant SE sugieren que dado un presupuesto de riesgo deseado $b$ podemos encontrar la cartera de inversión completa con ponderaciones $w$ que tiene el presupuesto de riesgo (como se define en esos materiales) igual a $b$ realizando la siguiente optimización convexa:

$$\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}$$

Sin embargo, habiendo hecho esto yo mismo en Python con CVXPY, encontré los presupuestos de riesgo resultantes no eran los mismos que los deseados $b$ .

Luego traté de calcular esta minimización a mano, y encontré que la solución $w$ tiene

$$(\Sigma w)_i - \frac{b_i}{w_i} = \lambda\;\;\;\text{for all }i$$

donde $\lambda$ es el multiplicador lagrangiano.

En otras palabras, ya que podemos demostrar que el $i$ -el presupuesto de riesgo ${b_w}_i$ por definición es igual a $\frac{w_i(\Sigma w)_i}{w'\Sigma w}$ la solución a ese problema de optimización tiene:

$${b_w}_i = \dfrac{b_i+\lambda w_i}{w'\Sigma w} = \dfrac{b_i+\lambda w_i}{1 + \lambda}$$

y esto en general no es igual a $b_i$ (por lo demás, $w_i=b_i$ ). Esto ha sido verificado por la optimización que he ejecutado en Python.

Pero estoy seguro de que este método no está mal -hay un trabajo académico escrito para explicarlo por Spinu (2013), que está más allá de mis capacidades. Así que, ¡realmente agradecería a quien pueda explicar esta formulación!

Actualización:

Aquí está el código Python que escribí. Es un ejercicio que forma parte del curso corto 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)

Y los resultados impresos son:

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]

2voto

Corey Goldberg Puntos 15625

Creo que el problema debería resolverse en dos pasos: la optimización sin la condición de que la suma sea igual a 1, seguida de un paso de normalización que divide w entre sum(w) para producir la solución deseada.

Aquí está el código modificado:

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)

El resultado

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]

Los valores marginales son iguales (dentro del error numérico).

Finanhelp.com

FinanHelp es una comunidad para personas con conocimientos de economía y finanzas, o quiere aprender. Puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X