public static double[][] ComputeLocalVarianceOnGridFromCalls(this IVolSurface VanillaSurface, double[][] strikes, double[] timeSteps, Func <double, double> forwardFunc) { var numberOfTimesteps = timeSteps.Length; var deltaK = 0.001 * forwardFunc(timeSteps[0]); var lvGrid = new double[numberOfTimesteps - 1][]; var fwds = timeSteps.Select(t => forwardFunc(t)).ToArray(); //ParallelUtils.Instance.For(1, numberOfTimesteps, 1, it => for (var it = 1; it < numberOfTimesteps; it++) { var T = timeSteps[it]; var T1 = timeSteps[it - 1]; var fwd = fwds[it]; var fwdtm1 = fwds[it - 1]; var rmq = Log(fwd / fwdtm1) / (T - T1); var numberOfStrikes = strikes[it - 1].Length; var cInterp = VanillaSurface.GeneratePremiumInterpolator(numberOfStrikes * 2, T, fwd, OptionType.C); lvGrid[it - 1] = new double[numberOfStrikes]; if (numberOfStrikes > 1) { for (var ik = 0; ik < numberOfStrikes; ik++) { var K = strikes[it][ik]; var V = VanillaSurface.GetVolForAbsoluteStrike(K, T, fwd); var C = BlackFunctions.BlackPV(fwd, K, 0.0, T, V, OptionType.C); var Vtm1 = VanillaSurface.GetVolForAbsoluteStrike(K, T1, fwdtm1); //var dcdt = -BlackFunctions.BlackTheta(fwd, K, 0.0, T, V, OptionType.C); var dcdt = -(BlackFunctions.BlackPV(fwdtm1, K, 0.0, T1, Vtm1, OptionType.C) - C) / (T - T1); var dcdk = cInterp.FirstDerivative(K); var d2cdk2 = cInterp.SecondDerivative(K); var localVariance = d2cdk2 == 0 ? V * V : (dcdt - rmq * (C - K * dcdk)) / (0.5 * K * K * d2cdk2); lvGrid[it - 1][ik] = localVariance; } } else { var K = strikes[it][0]; var V = VanillaSurface.GetVolForAbsoluteStrike(K, T, fwd); lvGrid[it - 1][0] = V * V; } }//, false).Wait(); return(lvGrid); }
public static double AmericanFutureOptionPV(double forward, double strike, double riskFree, double expTime, double volatility, OptionType CP) { var blackPV = BlackFunctions.BlackPV(forward, strike, riskFree, expTime, volatility, CP); if (riskFree == 0) { return(blackPV); } var n = System.Math.Max(32, (int)System.Math.Round(365.0 / 2.0 * expTime)); var PV = AmericanPV(expTime, forward, strike, riskFree, volatility, CP, riskFree, n); return(PV.SafeMax(blackPV)); }
public static double AmericanFutureOptionPV(double forward, double strike, double RiskFree, double expTime, double Volatility, OptionType CP) { var n = (int)System.Math.Round(365 * expTime); var blackPV = BlackFunctions.BlackPV(forward, strike, RiskFree, expTime, Volatility, CP); if (RiskFree == 0) //american option under zero rates has no benefit to ever exercise early { return(blackPV); } var PV = AmericanPV(expTime, forward, strike, RiskFree, Volatility, CP, RiskFree, n); return(PV.SafeMax(blackPV)); }