hayden4r4 / blackscholes-rust

A Black-Scholes pricing model built in Rust
MIT License
11 stars 6 forks source link

Correct negative IV with Let's be rational IV calculation #14

Closed hayden4r4 closed 4 months ago

hayden4r4 commented 4 months ago

Issue found by @day01 with negative IV from the Let's be rational IV calculation. We should either fix this or handle it properly.

In stochastic tests I get an issue


        #[test]
        fn test_implied_volatility_random(f in 50.0_f64..150.0_f64, k in 50.0_f64..150.0_f64, price in 0.01_f64..100.0_f64, t in 0.1_f64..2.0_f64, q in any::<u8>().prop_map(|x| if x % 2 == 0 { OptionType::Call } else { OptionType::Put })) {
            let iv = implied_volatility_from_a_transformed_rational_guess(price, f, k, t, q);

            let a = f64::total_cmp(&iv, &0.0);
            println!("Comparison result: {:?}", a);
            println!("Random Test - Implied Volatility: {:?}, f {:?}, k {:?} price {:?} t {:?} q {:?}", iv, f, k, price, t, q);
            assert!(!iv.is_sign_negative(), "Implied Volatility is negative");
            assert!(iv >= 0.0, "Implied Volatility is {}", iv);
        }

with parameters like:

Comparison result: Less
Random Test - Implied Volatility: -1.7976931348623157e308, f 145.23533118406826, k 50.0 price 0.01 t 0.1 q Call
thread 'lets_be_rational::tests::test_implied_volatility_random' panicked at src/lets_be_rational.rs:290:13:
Implied Volatility is negative

Based on my knowledge IV cannot be negative. Probably algorithm in cpp has a bug in numeric calculation, somewhere we should round to zero or we got underflow unchecked...

Suggestions?

Originally posted by @day01 in https://github.com/hayden4r4/blackscholes-rust/issues/8#issuecomment-2196153081