surface_lib/models/bs/
mod.rs1#[allow(non_snake_case)]
6fn norm_cdf(x: f64) -> f64 {
7 0.5 * (1.0 + libm::erf(x / (2.0_f64).sqrt()))
9}
10
11#[allow(non_snake_case)]
13pub fn bs_call_price(S: f64, K: f64, r: f64, q: f64, T: f64, sigma: f64) -> f64 {
14 if T <= 0.0 || sigma <= 0.0 {
15 return (S * (-q * T).exp() - K * (-r * T).exp()).max(0.0);
16 }
17 let d1 = ((S / K).ln() + (r - q + 0.5 * sigma.powi(2)) * T) / (sigma * T.sqrt());
18 let d2 = d1 - sigma * T.sqrt();
19 S * (-q * T).exp() * norm_cdf(d1) - K * (-r * T).exp() * norm_cdf(d2)
20}
21
22#[allow(non_snake_case)]
24pub fn bs_put_price(S: f64, K: f64, r: f64, q: f64, T: f64, sigma: f64) -> f64 {
25 if T <= 0.0 || sigma <= 0.0 {
26 return (K * (-r * T).exp() - S * (-q * T).exp()).max(0.0);
27 }
28 let d1 = ((S / K).ln() + (r - q + 0.5 * sigma.powi(2)) * T) / (sigma * T.sqrt());
29 let d2 = d1 - sigma * T.sqrt();
30 let nd1m = 1.0 - norm_cdf(d1);
31 let nd2m = 1.0 - norm_cdf(d2);
32 K * (-r * T).exp() * nd2m - S * (-q * T).exp() * nd1m
33}