use super::*;
use rust_decimal_macros::dec;
#[test]
fn max_drawdown_simple() {
let equity = vec![dec!(100), dec!(110), dec!(90), dec!(105)];
let dd = max_drawdown(&equity).expect("max_drawdown should succeed with valid equity curve");
assert!(dd < dec!(-18));
assert!(dd > dec!(-19));
}
#[test]
fn max_drawdown_no_drawdown() {
let equity = vec![dec!(100), dec!(110), dec!(120), dec!(130)];
let dd = max_drawdown(&equity)
.expect("max_drawdown should succeed for monotonically increasing equity");
assert_eq!(dd, dec!(0));
}
#[test]
fn max_drawdown_multiple_drawdowns() {
let equity = vec![dec!(100), dec!(90), dec!(120), dec!(80), dec!(100)];
let dd = max_drawdown(&equity).expect("max_drawdown should succeed with multiple drawdowns");
assert!(dd < dec!(-33));
assert!(dd > dec!(-34));
}
#[test]
fn max_drawdown_insufficient_data() {
let equity = vec![dec!(100)];
assert_eq!(
max_drawdown(&equity),
Err(MetricsError::InsufficientData {
required: 2,
actual: 1
})
);
}
#[test]
fn drawdown_series_tracks_peak() {
let equity = vec![dec!(100), dec!(110), dec!(100), dec!(120), dec!(110)];
let dd =
drawdown_series(&equity).expect("drawdown_series should succeed with valid equity curve");
assert_eq!(dd[0], dec!(0)); assert_eq!(dd[1], dec!(0)); assert!(dd[2] < dec!(0)); assert_eq!(dd[3], dec!(0)); assert!(dd[4] < dec!(0)); }
#[test]
fn max_drawdown_duration_simple() {
let equity = vec![dec!(100), dec!(90), dec!(95), dec!(105)];
let duration = max_drawdown_duration(&equity)
.expect("max_drawdown_duration should succeed with simple drawdown");
assert_eq!(duration, 2);
}
#[test]
fn max_drawdown_duration_not_recovered() {
let equity = vec![dec!(100), dec!(90), dec!(85), dec!(88), dec!(87)];
let duration = max_drawdown_duration(&equity)
.expect("max_drawdown_duration should succeed for unrecovered drawdown");
assert_eq!(duration, 4);
}
#[test]
fn max_drawdown_duration_multiple() {
let equity = vec![
dec!(100),
dec!(90),
dec!(95),
dec!(110), dec!(100), dec!(95), dec!(98), dec!(105), ];
let duration = max_drawdown_duration(&equity)
.expect("max_drawdown_duration should succeed with multiple drawdown periods");
assert_eq!(duration, 4); }
#[test]
fn max_drawdown_duration_no_drawdown() {
let equity = vec![dec!(100), dec!(110), dec!(120)];
let duration = max_drawdown_duration(&equity)
.expect("max_drawdown_duration should succeed with no drawdown");
assert_eq!(duration, 0);
}
#[test]
fn recovery_time_recovered() {
let equity = vec![dec!(100), dec!(110), dec!(90), dec!(100), dec!(115)];
let recovery =
recovery_time(&equity).expect("recovery_time should succeed for recovered drawdown");
assert_eq!(recovery, Some(2)); }
#[test]
fn recovery_time_not_recovered() {
let equity = vec![dec!(100), dec!(110), dec!(90), dec!(95), dec!(100)];
let recovery =
recovery_time(&equity).expect("recovery_time should succeed for unrecovered drawdown");
assert_eq!(recovery, None);
}
#[test]
fn recovery_time_no_drawdown() {
let equity = vec![dec!(100), dec!(110), dec!(120)];
let recovery = recovery_time(&equity).expect("recovery_time should succeed with no drawdown");
assert_eq!(recovery, Some(0));
}