(
returns: &DMatrix<f64>,
cov: &DMatrix<f64>,
confidence_level: f64,
indices: &[usize],
)
| 406 | } |
| 407 | |
| 408 | fn cluster_expected_shortfall( |
| 409 | returns: &DMatrix<f64>, |
| 410 | cov: &DMatrix<f64>, |
| 411 | confidence_level: f64, |
| 412 | indices: &[usize], |
| 413 | ) -> Result<f64, HcaaError> { |
| 414 | let w = inverse_variance_weights(cov, indices)?; |
| 415 | let mut portfolio_returns = Vec::with_capacity(returns.nrows()); |
| 416 | for r in 0..returns.nrows() { |
| 417 | let mut v = 0.0; |
| 418 | for (ii, &idx) in indices.iter().enumerate() { |
| 419 | v += returns[(r, idx)] * w[ii]; |
| 420 | } |
| 421 | portfolio_returns.push(v); |
| 422 | } |
| 423 | let threshold = quantile(portfolio_returns.clone(), confidence_level); |
| 424 | let tail: Vec<f64> = portfolio_returns.into_iter().filter(|x| *x <= threshold).collect(); |
| 425 | if tail.is_empty() { |
| 426 | return Ok(0.0); |
| 427 | } |
| 428 | Ok(-tail.iter().sum::<f64>() / tail.len() as f64) |
| 429 | } |
| 430 | |
| 431 | fn cluster_conditional_drawdown( |
| 432 | returns: &DMatrix<f64>, |
no test coverage detected