Scenario-Based Risk Parity Using Finite-Difference Risk Contributions
Summary
The document explores constructing a risk parity portfolio directly from simulated asset return scenarios. It defines an objective that seeks similar behavior in each asset’s marginal contribution to portfolio risk across scenarios, then considers adding penalties for trading away from current holdings and for departing from equal weights. It also proposes combining those preferences with a conventional covariance-based risk parity target.
The answer explains that marginal risk contributions can be estimated by perturbing one weight at a time and measuring the resulting change in a chosen portfolio risk function. A simulation with five assets and twenty scenarios compares these finite-difference estimates with covariance-based calculations and reports matching values. For optimization, the author favors derivative-free local search, including Threshold Accepting, because it can handle flexible scenario-based objectives. The document does not establish convexity or prescribe a single best solver; finite differences and local search may require substantial computation, and the example is small.
Key ideas
- Marginal risk contributions can be estimated by perturbing one portfolio weight and recalculating risk.
- Scenario-based finite differences allow risk functions beyond standard deviation to be used.
- The example’s finite-difference contributions match covariance-based contributions for standard deviation.
- The answer recommends derivative-free local search, including Threshold Accepting, for flexible objectives.
- The document does not settle the convexity question or compare optimization methods systematically.
Tags
Full text
# risk parity portfolio from scenario optimization
# risk parity portfolio from scenario optimization
would like to ask how we could use simulated asset returns (a matrix $R\in\mathbb{R}^{s\times d}$ from scenarios, row per sample and col per asset) to construct a risk parity portfolio (RPP).
by definition, RPP minimize the std.dev.(variance) of derivative of portfolio return std.dev.(variance) w.r.t. asset weights
$$ \underset{\mathbf{w}}{\min} \mathbb{V}_d[ \frac{\partial \sqrt{(\mathbb{V}_s[\mathbf{R}\mathbf{w}])}}{\partial \mathbf{w}} ] $$
where $\mathbf{w}$ is a col vector of portfolio weights, $\sqrt{\mathbb{V}_s[\mathbf{Rw}]}$ is std.dev. of portfolio returns in sampled scenarios, the external $\mathbb{V}_d$ is the std.dev. of derivatives (w.r.t. portfolio weights); overall this objective function aims to let each weight contribute equally towards risk in various scenarios.
the objective function is:
```
R = MatrixSymbol["R", {s, d}, Reals];
w = VectorSymbol["w", d, Reals];
StandardDeviation[D[StandardDeviation[R . w], w]] // Normal //
Rationalize // FullSimplify
```
1. is this objective function convex? what are suitable optimization algorithms? SGD/ADAM/etc.?
2. For application we may further add regularization terms to let weights be penalized for transaction cost and benchmarked upon, for example, equal weight (Talmud):
$$ \underset{\mathbf{w}}{\min} \mathbb{V}_d[ \frac{\partial \sqrt{(\mathbb{V}_s[\mathbf{R}\mathbf{w}])}}{\partial \mathbf{w}} ] + c\|\mathbf{w}-\mathbf{w}_0\|_1 + \lambda\|\mathbf{w}-\frac{1}{d}\|_1 $$
here $c$ is transaction cost (0.0015), $\mathbf{w}_0$ as portfolio weights prior to rebalancing, $\lambda=0.001$ a regularization constant, and $\frac{1}{d}$ as the equal weight.
would those 1-norm affect convexity? what are suitable optimization algorithms in this case?
3. since we can use the "classical" risk parity from the least square (from wiki https://en.wikipedia.org/wiki/Risk_parity), using covmat from scenario simulated returns directly, say the solution is $\mathbf{w}_{rp}$ $$ {\displaystyle {\underset {w}{\arg \min }}\sum _{i=1}^{N}\left[w_{i}-{\frac {\sigma (w)^{2}}{(\Sigma w)_{i}N}}\right]^{2}} $$
can we merge those into one obj fun to reach a trade-off among transaction cost, risk-parity style, and equal weight style? $$ \underset{\mathbf{w}}{\min} ~ c\|\mathbf{w}-\mathbf{w}_0\|_1 + \lambda_1\|\mathbf{w}-\mathbf{w}_{rp}\|_1 + \lambda_2\|\mathbf{w}-\frac{1}{d}\|_1 $$
## Answer by Enrico Schumann (score 2)
https://quant.stackexchange.com/a/80453
Expanding my comment on non-standard risk measures: under risk parity/ERC, you look at the marginal contributions to risk, which means the first derivatives of a function $f$ that maps weights (and data) into a single number, the risk. If $f$ is the standard deviation, it can be conveniently and efficiently computed from the covariance matrix. But after all, you look for first derivatives, which you can approximate by finite differences. The downside, of course, is a higher computational cost, but there might be no other alternative way to compute those contributions, and you gain flexibility. Specifically, if $R$ is the returns matrix, and $w$ are the weights, then the $i$-th weight's derivative can be approximated as $(f(R(w^*_i)) - f(Rw))/ h$. The symbol $h$ is a small number: for a forward difference, as here, typically of the order of $10^{-8}$ or similar; when in doubt, use a larger number. $w^*_i$ is the weights vector with the $i$-th weight increased by $h$.
Computational 'proof': I use R to simulate 20 return scenarios for 5 assets.
```
library("FRAPO") ## for function 'mrc'
library("NMOF") ## for function 'randomReturns'
na <- 5
R <- randomReturns(na = na, ns = 20, sd = 0.02, rho = 0.5)
## [,1] [,2] [,3] [,4] [,5]
## [1,] 0.0381 0.0320 0.0126 0.0161 0.015
## [2,] 0.0117 0.0028 0.0367 -0.0100 -0.004
## [3,] -0.0258 -0.0006 -0.0124 0.0017 -0.005
## [4,] 0.0309 0.0182 0.0064 0.0197 0.014
## [5,] -0.0202 -0.0259 -0.0457 0.0064 -0.023
## [6,] -0.0036 0.0018 -0.0345 -0.0149 -0.019
## ....
## equal-weight portfolio
w <- rep(1/na, na)
## risk function: input is a vector of _portfolio_
## returns under the scenarios
risk <- function(Rw, ...) {
sqrt(var(c(Rw)))
}
risk(R %*% w)
## [1] 0.01432615 ## vol of the equal-weight portfolio
```
The function `mrc_fd` implements the above formula for a finite difference:
```
## approximate first-derivatives of risk with respect
## to weights via forward difference
mrc_fd <- function(w, R, risk, ..., h = 1e-8) {
Rw <- R %*% w
dR <- R*h
ans <- numeric(length(w))
for (i in seq_along(w)) {
ans[i] <- w[i] * ( risk(Rw + dR[, i]) - risk(Rw) ) / h
}
ans
}
```
Compare the results with the implementation of marginal risk contribution in package `FRAPO`:
```
FRAPO::mrc(w, var(R), FALSE)
## [1] 0.00301 0.00200 0.00349 0.00240 0.00343
mrc_fd(w = w, R = R, risk = risk)
## [1] 0.00301 0.00200 0.00349 0.00240 0.00343
```
The numbers are the same. But where `mrc` computes them off the covariance matrix, function `mrc_fd` directly works with the scenarios, and so would work with other definitions of `risk` as well.
Concerning methods: I like local-search methods, which (like scenario optimization) are extremely flexible. Essentially, these method start with random solution, and then iteratively change this solution by increasing/decreasing weights in small steps, until they have arrived at a good solution (or some computational limit is reached, such as a fixed number of iterations). Threshold Accepting (TA), for instance, is such a method, and it is also implemented in the `NMOF` package. TA is also an early, perhaps the earliest derivative-free method that was used for portfolio selection, as described in
```
@ARTICLE{Dueck1992,
author = {Gunter Dueck and Peter Winker},
title = {New Concepts and Algorithms for Portfolio Choice},
journal = {Applied Stochastic Models and Data Analysis},
year = 1992,
volume = 8,
pages = {159--178},
number = 3
}
```
(Disclosure: I am the maintainer of package NMOF.)Shown in full with attribution under the source's licence. Licence: CC BY-SA 4.0 (Stack Exchange)
This summary was written by Stratmill's research agent from the original; it is not a copy of the source.