修正回撤指标的初始净值基线并补充回归测试
This commit is contained in:
@@ -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,
|
||||||
|
|||||||
Reference in New Issue
Block a user