修正回撤指标的初始净值基线并补充回归测试

This commit is contained in:
boris
2026-09-11 15:00:02 +08:00
parent e0bed38184
commit d847cb5c28
+25 -1
View File
@@ -558,7 +558,9 @@ fn alpha_beta(
} }
fn drawdown_stats(nav: &[f64]) -> (f64, usize) { fn drawdown_stats(nav: &[f64]) -> (f64, usize) {
let mut peak = 0.0_f64; // NAV is measured against the pre-period capital. The first real loss
// must not become a new zero-drawdown baseline.
let mut peak = 1.0_f64;
let mut max_drawdown = 0.0_f64; let mut max_drawdown = 0.0_f64;
let mut duration = 0_usize; let mut duration = 0_usize;
let mut max_duration = 0_usize; let mut max_duration = 0_usize;
@@ -767,6 +769,28 @@ fn safe_div(numerator: f64, denominator: f64, fallback: f64) -> f64 {
mod tests { mod tests {
use super::*; use super::*;
#[test]
fn drawdown_includes_initial_nav_without_adding_a_trading_day() {
let (drawdown, duration) = drawdown_stats(&[0.9, 0.99]);
assert!((drawdown + 0.1).abs() < 1e-12);
assert_eq!(duration, 2);
assert_eq!(drawdown_stats(&[1.0, 1.1, 1.1]), (0.0, 0));
assert_eq!(drawdown_stats(&[0.0]), (-1.0, 1));
assert_eq!(drawdown_stats(&[]), (0.0, 0));
}
#[test]
fn first_day_loss_is_preserved_in_shared_backtest_metrics() {
let curve = vec![
equity_point("2025-01-03", 99.16648349337, 98.81608059815, 100.0),
equity_point("2025-01-06", 99.68551588547, 98.65392198168, 98.81608059815),
];
let metrics = compute_backtest_metrics(&curve, &[], &[], &[], 100.0, None).unwrap();
assert!((metrics.max_drawdown + 0.0083351650663).abs() < 1e-12);
assert_eq!(metrics.total_trade_days, 2);
assert_eq!(metrics.max_drawdown_duration_days, 2);
}
fn equity_point( fn equity_point(
date: &str, date: &str,
total_equity: f64, total_equity: f64,