blackscholes_wasm/
implied_volatility.rs

1use crate::{constants::*, Inputs};
2use wasm_bindgen::prelude::*;
3
4#[wasm_bindgen]
5impl Inputs {
6    /// Calculates the implied volatility of the option.
7    /// Tolerance is the max error allowed for the implied volatility,
8    /// the lower the tolerance the more iterations will be required.
9    /// Recommended to be a value between 0.001 - 0.0001 for highest efficiency/accuracy.
10    /// Initializes estimation of sigma using Brenn and Subrahmanyam (1998) method of calculating initial iv estimation.
11    /// Uses Newton Raphson algorithm to calculate implied volatility.
12    /// # Requires
13    /// s, k, r, q, t, p
14    /// # Returns
15    /// f32 of the implied volatility of the option.
16    /// # Example:
17    /// ```
18    /// use blackscholes::{Inputs, OptionType};
19    /// let inputs = Inputs::new(OptionType::Call, 100.0, 100.0, Some(0.2), 0.05, 0.2, 20.0/365.25, None);
20    /// let iv = inputs.calc_iv(0.0001).unwrap();
21    /// ```
22    pub fn calc_iv(&self, tolerance: f32) -> Result<f32, String> {
23        let mut inputs: Inputs = self.clone();
24
25        let p = self
26            .p
27            .ok_or("inputs.p must contain Some(f32), found None".to_string())?;
28        // Initialize estimation of sigma using Brenn and Subrahmanyam (1998) method of calculating initial iv estimation.
29        let mut sigma: f32 = (2.0 * PI / inputs.t).sqrt() * (p / inputs.s);
30        // Initialize diff to 100 for use in while loop
31        let mut diff: f32 = 100.0;
32
33        // Uses Newton Raphson algorithm to calculate implied volatility.
34        // Test if the difference between calculated option price and actual option price is > tolerance,
35        // if so then iterate until the difference is less than tolerance
36        while diff.abs() > tolerance {
37            inputs.sigma = Some(sigma);
38            diff = Inputs::calc_price(&inputs)? - p;
39            sigma -= diff / (Inputs::calc_vega(&inputs)? * 100.0);
40        }
41        Ok(sigma)
42    }
43}