예제 #1
0
        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);
        }
예제 #2
0
        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));
        }
예제 #3
0
        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));
        }