Beispiel #1
0
        public static DiscountCurve LinearRateInterpol(FinancingId financing, DateTime[] pillars, double[] zcs, ITimeMeasure time)
        {
            if (pillars.Length != zcs.Length)
                throw new Exception("LinearRateDiscountProvider : Incompatible size");
            var dates = time[pillars];

            var zcRates = new double[pillars.Length];

            if (DoubleUtils.EqualZero(dates[0]))
            {
                if (!DoubleUtils.MachineEquality(1.0, zcs[0]))
                    throw new Exception("LinearRateInterpol : Discount for refDate must equal to 1.0 ");
                zcRates[0] = 0.0;
            }
            else
            {
                zcRates[0] = -Math.Log(zcs[0]) / dates[0];
            }

            for (int i = 1; i < zcs.Length; i++)
            {
                zcRates[i] = -Math.Log(zcs[i]) / dates[i];
            }

            return new DiscountCurveFromRate(financing, time, RrFunctions.LinearInterpolation(dates, zcRates));
        }
Beispiel #2
0
        public void TestEval()
        {
            var          abs        = new[] { 0.0, 0.5, 0.99, 2.5 };
            var          vals       = new[] { 5.0, 5.4, 3.1, 1.0 };
            const double leftSlope  = 0.0;
            const double rightSlope = 0.98181;

            var stepFunc = RrFunctions.LinearInterpolation(abs, vals, leftSlope, rightSlope);

            foreach (var i in Enumerable.Range(0, abs.Length))
            {
                Assert.AreEqual(stepFunc.Eval(abs[i]), vals[i]);
                if (i < abs.Length - 1)
                {
                    var midPoint = 0.5 * (abs[i] + abs[i + 1]);
                    Assert.AreEqual(stepFunc.Eval(midPoint), 0.5 * (vals[i] + vals[i + 1]));
                }
            }

            double leftExtrapolPoint = abs[0] - 10.0;

            Assert.AreEqual(stepFunc.Eval(leftExtrapolPoint), vals[0] + leftSlope * (leftExtrapolPoint - abs[0]));

            double rightExtrapolPoint = abs[abs.Length - 1] + 10.0;

            Assert.AreEqual(stepFunc.Eval(rightExtrapolPoint), vals[abs.Length - 1] + rightSlope * (rightExtrapolPoint - abs[abs.Length - 1]));
        }
Beispiel #3
0
        public static RrFunction ZcRateCoeffFunction(double maturity, double meanReversion)
        {
            var expMat = Math.Exp(-meanReversion * maturity);

            if (DoubleUtils.MachineEquality(1.0, expMat))
            {
                return(RrFunctions.Affine(1.0, -maturity));
            }

            return((expMat / meanReversion) * RrFunctions.Exp(meanReversion) - (1.0 / meanReversion));
        }
Beispiel #4
0
        public void TestIntegralExp()
        {
            var exp  = RrFunctions.Exp(0.1);
            var step = new StepFunction(new[] { 0.0, 5.0 }, new[] { 0.015, 0.010 }, 0.0);
            var f    = exp * step;

            var integral = f.Integral(0.0);
            var testVal  = integral.Eval(10.0);

            var expintegral = exp.Integral(0.0);
            var refVal      = 0.015 * (expintegral.Eval(5.0) - expintegral.Eval(0.0))
                              + 0.01 * (expintegral.Eval(10.0) - expintegral.Eval(5.0));

            Assert.IsTrue(DoubleUtils.Equality(testVal, refVal, 1.5 * DoubleUtils.MachineEpsilon));
        }
Beispiel #5
0
        private static RrFunction BuildXi(MapRawDatas <DateOrDuration, double> sigma, ITimeMeasure time)
        {
            var matVars = EnumerableUtils.For(0, sigma.Pillars.Length, i =>
            {
                var mat      = time[sigma.Pillars[i].ToDate(time.RefDate)];
                var variance = sigma.Values[i] * sigma.Values[i] * mat;
                return(new { Mat = mat, Variance = variance });
            }).OrderBy(t => t.Mat).ToArray();

            if (!DoubleUtils.EqualZero(matVars.First().Mat))
            {
                matVars = matVars.Concat(new[] { new { Mat = 0.0, Variance = 0.0 } })
                          .OrderBy(t => t.Mat).ToArray();
            }

            var varianceFunc = RrFunctions.LinearInterpolation(matVars.Map(t => t.Mat),
                                                               matVars.Map(t => t.Variance),
                                                               0.0, double.NaN);

            return(varianceFunc.Derivative());
        }
Beispiel #6
0
        private static double[][] VarSwapDeformation(Bergomi2FModel b2F, double[] fwdVolStart, double[] fwdVolEnd)
        {
            Debug.Assert(fwdVolStart.Length == fwdVolEnd.Length);

            var initCurve = b2F.Xi.Integral(0.0);
            var factor1   = (b2F.Xi * RrFunctions.Exp(-b2F.K1)).Integral(0.0);
            var factor2   = (b2F.Xi * RrFunctions.Exp(-b2F.K2)).Integral(0.0);

            var alpha = Alpha(b2F);

            return(EnumerableUtils.For(0, fwdVolStart.Length, i =>
            {
                double volMatStart = fwdVolStart[i];
                double volMatEnd = fwdVolEnd[i];

                double initFwdVariance = initCurve.Eval(volMatEnd) - initCurve.Eval(volMatStart);
                double def1 = factor1.Eval(volMatEnd) - factor1.Eval(volMatStart);
                double def2 = factor2.Eval(volMatEnd) - factor2.Eval(volMatStart);

                return new[] { (1.0 - b2F.Theta) * def1, b2F.Theta * def2 }.Mult(b2F.Nu * alpha / initFwdVariance);
            }));
        }
        public static RrFunction IntegratedCovariance(RrFunction instantCovariance, double meanReversion1, double meanReversion2, double startDate = 0.0)
        {
            var integratedExpCov = (instantCovariance * RrFunctions.Exp(meanReversion1 + meanReversion2)).Integral(startDate);

            return(integratedExpCov * RrFunctions.Exp(-(meanReversion1 + meanReversion2)));
        }
        public static RrFunction IntegratedDrift(RrFunction instantDrift, double meanReversion, double startDate = 0.0)
        {
            var integratedExpDrift = (instantDrift * RrFunctions.Exp(meanReversion)).Integral(startDate);

            return(integratedExpDrift * RrFunctions.Exp(-meanReversion));
        }
        public double[] CalibrateVol(double[] maturities, double[] targetPrices, double[] strikes, double[] optionTypes)
        {
            Contract.Requires(EnumerableUtils.IsSorted(maturities));
            Contract.Requires(maturities.Length == strikes.Length &&
                              strikes.Length == targetPrices.Length &&
                              targetPrices.Length == optionTypes.Length);

            double[] variances = new double[maturities.Length + 1];
            double[] varPillars = new[] { 0.0 }.Concat(maturities).ToArray();

            double[] calibVols = new double[maturities.Length];
            for (int step = 0; step < maturities.Length; step++)
            {
                var maturity    = maturities[step];
                var strike      = strikes[step];
                var targetPrice = targetPrices[step];
                var q           = optionTypes[step];

                //Proxy using Lehman Formula
                double proxyFwd, proxyDk;
                affineDivUtils.LehmanProxy(maturity, spot, out proxyFwd, out proxyDk);
                double lehmanTargetVol = BlackScholesOption.ImpliedVol(targetPrice, proxyFwd, strike + proxyDk, maturity, q);

                var pricer = new BsDivPrice(maturities[step], strikes[step], spot, affineDivUtils, quadPoints, quadWeights);
                Func <double, double> volToLehmanVolErr = v =>
                {
                    variances[1 + step] = v * v * maturity;
                    var varFunc = RrFunctions.LinearInterpolation(varPillars, variances);

                    Func <double, double> volFunc = t => Math.Sqrt(varFunc.Eval(t) / t);
                    var price = pricer.Price(volFunc, q);
                    return(BlackScholesOption.ImpliedVol(price, proxyFwd, strike + proxyDk, maturity, q) - lehmanTargetVol);
                };//TODO use a cache


                //Bracket & Solve
                double v1 = lehmanTargetVol;
                double v2;
                if (step == 0)
                {
                    v2 = lehmanTargetVol - volToLehmanVolErr(lehmanTargetVol);
                }
                else
                {
                    var volIfZeroVolOnStep = Math.Sqrt(calibVols[step - 1] * calibVols[step - 1] * maturities[step - 1] / maturities[step]);
                    var minError           = volToLehmanVolErr(volIfZeroVolOnStep);
                    if (minError > 0.0) //saturation case
                    {
                        calibVols[step]     = volIfZeroVolOnStep;
                        variances[1 + step] = volIfZeroVolOnStep * volIfZeroVolOnStep * maturity;
                        continue;
                    }
                    v2 = volIfZeroVolOnStep;
                }

                if (!RootUtils.Bracket(volToLehmanVolErr, v1, v2, out v1, out v2))
                {
                    throw new Exception("Failed to inverse vol");
                }
                var impliedVol = RootUtils.Brenth(volToLehmanVolErr, v1, v2, 1.0e-10, 2.0 * DoubleUtils.MachineEpsilon, 10);

                calibVols[step]     = impliedVol;
                variances[1 + step] = impliedVol * impliedVol * maturity;
            }

            return(calibVols);
        }