public static double inv_m1_beta_black_cxv(double beta, double f, double sigma) { var s2 = sigma * sigma; var igb = inv_g(beta, f); var fac = -0.5 * s2; var rf = FS.fun((double cxv) => { var mu = igb + fac * cxv; var f0 = m1_beta_black(beta, mu, sigma); return(f - f0); }); var alpha = 0.5 * beta * s2; var guess = alpha == 0.0 ? 1.0 : Math.Min(1.0, Math.Max(0.0, (f + alpha) / alpha)); var lo = guess - 1e-3; var hi = guess + 1e-3; var tGuess = rf(alpha); if (DoubleUtils.ApproximatelyEqual(tGuess, 0.0, 100.0 * DoubleUtils.DoubleEpsilon)) { return(igb + fac * alpha); } NumericalRecipes.zbrac(rf, ref lo, ref hi); var cxvRoot = Brent.FindRoot(rf, lo, hi); return(igb + fac * cxvRoot); }
public static double beta_black_break_even_to_sigma(double beta, double f, double t, double breakEven, double dt = 1.0 / 365.0) { var rf = FS.fun((double sigma) => beta_black_break_even(beta, f, t, sigma, dt) - breakEven); var x1 = 1.0; var x2 = 5.0; NumericalRecipes.zbrac(rf, ref x1, ref x2); return(Brent.FindRoot(rf, x1, x2)); }
public static double ibeta_black(double beta, OptionType optType, double F, double K, double T, double premium) { var rf = FS.fun((double sigma) => beta_black(beta, optType, F, K, T, sigma) - premium); var lo = 1.0; var hi = 5.0; // If very deep in-out of the money, will fail. f(lo) = f(hi), zbrac only moves low NumericalRecipes.zbrac(rf, ref lo, ref hi); return(Brent.FindRoot(rf, lo, hi)); }