use rust_decimal::Decimal;
use rust_decimal_macros::dec;
use super::*;
#[test]
fn full_kelly_standard_case() {
let frac = compute_kelly_fraction(dec!(0.6), dec!(2.0), KellyMode::Full);
assert_eq!(frac.as_decimal(), dec!(0.4));
}
#[test]
fn half_kelly_halves_fraction() {
let frac = compute_kelly_fraction(dec!(0.6), dec!(2.0), KellyMode::Half);
assert_eq!(frac.as_decimal(), dec!(0.2));
}
#[test]
fn quarter_kelly_quarters_fraction() {
let frac = compute_kelly_fraction(dec!(0.6), dec!(2.0), KellyMode::Quarter);
assert_eq!(frac.as_decimal(), dec!(0.1));
}
#[test]
fn no_edge_returns_zero() {
let frac = compute_kelly_fraction(dec!(0.3), dec!(1.0), KellyMode::Full);
assert!(frac.is_zero());
assert_eq!(frac.as_decimal(), Decimal::ZERO);
}
#[test]
fn perfect_system_capped_at_one() {
let frac = compute_kelly_fraction(dec!(1.0), dec!(5.0), KellyMode::Full);
assert_eq!(frac.as_decimal(), Decimal::ONE);
}
#[test]
fn zero_win_rate_returns_zero() {
let frac = compute_kelly_fraction(dec!(0.0), dec!(1.0), KellyMode::Full);
assert!(frac.is_zero());
}
#[test]
fn zero_ratio_returns_zero() {
let frac = compute_kelly_fraction(dec!(0.6), Decimal::ZERO, KellyMode::Full);
assert!(frac.is_zero());
}
#[test]
fn negative_ratio_returns_zero() {
let frac = compute_kelly_fraction(dec!(0.6), dec!(-1.0), KellyMode::Full);
assert!(frac.is_zero());
}
#[test]
fn breakeven_system_returns_zero() {
let frac = compute_kelly_fraction(dec!(0.5), dec!(1.0), KellyMode::Full);
assert!(frac.is_zero());
}
#[test]
fn kelly_mode_display() {
assert_eq!(KellyMode::Full.to_string(), "Full");
assert_eq!(KellyMode::Half.to_string(), "Half");
assert_eq!(KellyMode::Quarter.to_string(), "Quarter");
}
#[test]
fn kelly_fraction_display() {
let frac = compute_kelly_fraction(dec!(0.6), dec!(2.0), KellyMode::Full);
let display = format!("{frac}");
assert!(
display.contains("0.4"),
"Display should show 0.4, got: {display}"
);
}
#[test]
fn inputs_from_pnls() {
let pnls = [dec!(100), dec!(-50), dec!(75), dec!(-25), dec!(80)];
let (wr, ratio, count) = compute_kelly_inputs(&pnls).expect("should succeed");
assert_eq!(wr, dec!(0.6), "win_rate should be fraction, not percentage");
assert_eq!(count, 5);
let expected_ratio = dec!(85) / dec!(37.5);
assert_eq!(ratio, expected_ratio);
}
#[test]
fn inputs_empty_pnls_errors() {
let result = compute_kelly_inputs(&[]);
assert_eq!(
result,
Err(crate::MetricsError::InsufficientData {
required: 1,
actual: 0,
})
);
}
#[test]
fn inputs_all_wins_errors() {
let result = compute_kelly_inputs(&[dec!(100), dec!(200)]);
assert!(
matches!(result, Err(crate::MetricsError::DivisionByZero { .. })),
"expected DivisionByZero, got: {result:?}"
);
}
#[test]
fn inputs_all_losses_errors() {
let result = compute_kelly_inputs(&[dec!(-100), dec!(-200)]);
assert!(
matches!(result, Err(crate::MetricsError::InsufficientData { .. })),
"expected InsufficientData, got: {result:?}"
);
}