use rust_decimal::Decimal;
use rust_decimal_macros::dec;
use super::*;
use crate::MetricsError;
#[test]
fn var_95_picks_5th_percentile() {
let returns: Vec<Decimal> = (0..20)
.map(|i| Decimal::from(i) * dec!(0.01) - dec!(0.10))
.collect();
let v = var(&returns, 95);
assert_eq!(v, dec!(-0.09), "VaR(95%) = {v}");
}
#[test]
fn cvar_95_is_mean_below_var() {
let returns: Vec<Decimal> = (0..20)
.map(|i| Decimal::from(i) * dec!(0.01) - dec!(0.10))
.collect();
let c = cvar(&returns, 95);
assert_eq!(c, dec!(-0.10), "CVaR(95%) = {c}");
}
#[test]
fn cvar_always_gte_var_in_magnitude() {
let returns: Vec<Decimal> = (0..100)
.map(|i| {
if i < 5 {
dec!(-0.10)
} else if i < 10 {
dec!(-0.05)
} else {
Decimal::from(i) * dec!(0.001)
}
})
.collect();
let v = var(&returns, 95);
let c = cvar(&returns, 95);
assert!(
c <= v,
"CVaR({c}) should be <= VaR({v}) (more negative = more extreme)"
);
}
#[test]
fn try_var_rejects_insufficient_data() {
let returns = vec![dec!(0.01); 5];
let result = try_var(&returns, 99);
assert!(result.is_err());
let err = result.unwrap_err();
assert!(matches!(err, MetricsError::InsufficientData { .. }));
}