Пример #1
0
        public void Build(DateTime originDate, double[][] strikes, DateTime[] expiries, double[][] vols, Func <double, double> forwardCurve)
        {
            OriginDate     = originDate;
            Expiries       = expiries;
            ExpiriesDouble = Expiries.Select(t => TimeBasis.CalculateYearFraction(originDate, t)).ToArray();

            if (Expiries.Length != strikes.Length)
            {
                throw new InvalidOperationException("Expiries and first dimension of Strikes must of same length");
            }
            if (Expiries.Length != vols.Length)
            {
                throw new InvalidOperationException("Expiries and first dimension of Vols must of same length");
            }

            Alphas = new double[Expiries.Length];
            Betas  = new double[Expiries.Length];
            Nus    = new double[Expiries.Length];
            Rhos   = new double[Expiries.Length];


            for (var i = 0; i < expiries.Length; i++)
            {
                var vs  = vols[i];
                var ks  = strikes[i];
                var t   = ExpiriesDouble[i];
                var fwd = forwardCurve(t);
                Betas[i] = 1.0;
                Func <double[], double[]> errorFunc = (x =>
                {
                    var err = ks.Select((k, ix) => vs[ix] - SABR.CalcImpVol_Beta1(fwd, k, t, x[0], x[1], x[2]));
                    return(err.ToArray());
                });

                var n2Sol = new Math.Solvers.GaussNewton
                {
                    ObjectiveFunction = errorFunc,
                    InitialGuess      = new double[] { vs.Average(), 0.1, 0.1 },
                    Tollerance        = 1e-8,
                    JacobianBump      = 0.0000001
                };

                var paramArr = n2Sol.Solve();

                Alphas[i] = paramArr[0];
                Rhos[i]   = paramArr[1];
                Nus[i]    = paramArr[2];
            }

            var fwds = ExpiriesDouble.Select(x => forwardCurve(x)).ToArray();

            _alphaInterp = InterpolatorFactory.GetInterpolator(ExpiriesDouble, Alphas, TimeInterpolatorType);
            _betaInterp  = InterpolatorFactory.GetInterpolator(ExpiriesDouble, Betas, TimeInterpolatorType);
            _rhoInterp   = InterpolatorFactory.GetInterpolator(ExpiriesDouble, Rhos, TimeInterpolatorType);
            _nuInterp    = InterpolatorFactory.GetInterpolator(ExpiriesDouble, Nus, TimeInterpolatorType);
            _fwdsInterp  = InterpolatorFactory.GetInterpolator(ExpiriesDouble, fwds, TimeInterpolatorType);
        }
Пример #2
0
        private double GetDeltaStrikeForAbs(double fwd, double strike, double maturity)
        {
            var cp = strike < 0 ? OptionType.Put : OptionType.Call;
            Func <double, double> testFunc = (deltaK =>
            {
                var interpForStrike = InterpolatorFactory.GetInterpolator(ExpiriesDouble, ExpiriesDouble.Select(e => GetVolForDeltaStrike(deltaK, e, fwd)).ToArray(), TimeInterpolatorType);
                var vol2 = interpForStrike.Interpolate(maturity);
                var absK = BlackFunctions.AbsoluteStrikefromDeltaKAnalytic(fwd, deltaK, 0, maturity, vol2);
                return(absK - strike);
            });

            var solvedStrike = -Math.Solvers.Brent.BrentsMethodSolve(testFunc, -0.99999999999, -0.00000000001, 1e-8);

            if (solvedStrike == 0.00000000001 || solvedStrike == 0.99999999999) //out of bounds
            {
                var upperK = testFunc(-0.00000000001);
                var lowerK = testFunc(-0.99999999999);
                if (Abs(upperK - fwd) < Abs(lowerK - fwd))
                {
                    solvedStrike = 0.00000000001;
                }
                else
                {
                    solvedStrike = 0.99999999999;
                }
            }

            return(solvedStrike);
        }
Пример #3
0
        private double GetAbsStrikeForDelta(double fwd, double deltaStrike, double maturity)
        {
            var cp = deltaStrike < 0 ? OptionType.Put : OptionType.Call;
            Func <double, double> testFunc = (absK =>
            {
                var interpForStrike = InterpolatorFactory.GetInterpolator(ExpiriesDouble, ExpiriesDouble.Select(e => GetVolForAbsoluteStrike(absK, e, fwd)).ToArray(), TimeInterpolatorType);
                var vol2 = interpForStrike.Interpolate(maturity);
                var deltaK = BlackFunctions.BlackDelta(fwd, absK, 0, maturity, vol2, cp);
                return(deltaK - deltaStrike);
            });

            var solvedStrike = Math.Solvers.Brent.BrentsMethodSolve(testFunc, 0.000000001, 50 * fwd, 1e-8);

            return(solvedStrike);
        }