use super::super::*;
use crate::types::Value;
fn approx(a: Value, b: f64, tol: f64) -> bool {
if let Value::Number(n) = a { (n - b).abs() < tol } else { false }
}
#[test]
fn pricedisc_6month_tbill() {
let args = [
Value::Number(44927.0), Value::Number(45108.0), Value::Number(0.05),
Value::Number(100.0),
Value::Number(2.0), ];
assert!(approx(pricedisc_fn(&args), 97.4861, 1e-4));
}
#[test]
fn pricedisc_default_basis() {
let args = [
Value::Number(44927.0), Value::Number(45108.0), Value::Number(0.05),
Value::Number(100.0),
];
assert!(approx(pricedisc_fn(&args), 97.5, 1e-4));
}
#[test]
fn disc_recovers_known_rate() {
let args = [
Value::Number(44927.0), Value::Number(45108.0), Value::Number(97.4861111111111),
Value::Number(100.0),
Value::Number(2.0),
];
assert!(approx(disc_fn(&args), 0.05, 1e-4));
}
#[test]
fn disc_basic_30_360() {
let args = [
Value::Number(44927.0), Value::Number(45108.0), Value::Number(97.5),
Value::Number(100.0),
];
assert!(approx(disc_fn(&args), 0.05, 1e-4));
}
#[test]
fn tbillprice_5pct_6month() {
let args = [
Value::Number(44927.0), Value::Number(45108.0), Value::Number(0.05),
];
assert!(approx(tbillprice_fn(&args), 97.4861, 1e-4));
}
#[test]
fn coupdays_semiannual_actual() {
let args = [
Value::Number(44927.0), Value::Number(45658.0), Value::Number(2.0), Value::Number(1.0), ];
assert!(approx(coupdays_fn(&args), 181.0, 1e-4));
}
#[test]
fn coupdays_semiannual_30_360() {
let args = [
Value::Number(44927.0), Value::Number(45658.0), Value::Number(2.0), Value::Number(0.0), ];
assert!(approx(coupdays_fn(&args), 180.0, 1e-4));
}
#[test]
fn price_rate_equals_yield_returns_near_par() {
let args = [
Value::Number(45292.0),
Value::Number(46022.0),
Value::Number(0.05),
Value::Number(0.05),
Value::Number(100.0),
Value::Number(2.0),
];
let result = price_fn(&args);
if let Value::Number(p) = result {
assert!((p - 100.0).abs() < 0.1, "price {} should be near 100", p);
} else {
panic!("expected Number, got {:?}", result);
}
}
#[test]
fn basis_0_is_valid() {
assert_eq!(validate_basis(0.0), Ok(0));
}
#[test]
fn basis_4_is_valid() {
assert_eq!(validate_basis(4.0), Ok(4));
}
#[test]
fn frequency_1_annual_valid() {
assert_eq!(validate_frequency(1.0), Ok(1));
}
#[test]
fn frequency_2_semiannual_valid() {
assert_eq!(validate_frequency(2.0), Ok(2));
}
#[test]
fn frequency_4_quarterly_valid() {
assert_eq!(validate_frequency(4.0), Ok(4));
}