コード例 #1
0
        public void CallNaiveImplemXCheck()
        {
            var maturities     = GridUtils.RegularGrid(0.1, 5.0, 100);
            var vols           = GridUtils.RegularGrid(0.01, 1.0, 10);
            var volMoneynesses = GridUtils.RegularGrid(-3, 3, 100);

            foreach (var mat in maturities)
            {
                foreach (var vol in vols)
                {
                    var sigma = Math.Sqrt(mat) * vol;
                    foreach (var vm in volMoneynesses)
                    {
                        var strike = Math.Exp(vm * sigma);
                        var call   = BlackScholesOption.Price(1.0, strike, vol, mat, 1);

                        //Naive implementation of black-scholes formulae
                        var d_plus      = -(vm * sigma) / sigma + 0.5 * sigma;
                        var d_minus     = d_plus - sigma;
                        var call_xcheck = NormalDistribution.Cumulative(d_plus) - strike * NormalDistribution.Cumulative(d_minus);

                        if (DoubleUtils.EqualZero(call))
                        {
                            Assert.IsTrue(DoubleUtils.EqualZero(call_xcheck));
                        }
                        else
                        {
                            var errRelative = (call - call_xcheck) / call_xcheck;
                            Assert.IsTrue(Math.Abs(errRelative) < 1.0e-11);
                        }
                    }
                }
            }
        }
コード例 #2
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));
        }
コード例 #3
0
        public void CallNaiveImplemXCheck()
        {
            var maturities     = GridUtils.RegularGrid(0.1, 5.0, 100);
            var vols           = GridUtils.RegularGrid(0.001, 0.015, 10);
            var volMoneynesses = GridUtils.RegularGrid(-3, 3, 100);

            foreach (var mat in maturities)
            {
                foreach (var vol in vols)
                {
                    var sigma = Math.Sqrt(mat) * vol;
                    foreach (var vm in volMoneynesses)
                    {
                        var strike = vm * sigma;
                        var call   = BachelierOption.Price(0.0, strike, vol, mat, 1);

                        //Naive implementation of bachelier formulae
                        var d           = strike / sigma;
                        var call_xcheck = -strike *NormalDistribution.Cumulative(-d) + sigma * NormalDistribution.Density(d);

                        if (DoubleUtils.EqualZero(call))
                        {
                            Assert.IsTrue(DoubleUtils.EqualZero(call_xcheck));
                        }
                        else
                        {
                            var errRelative = (call - call_xcheck) / call_xcheck;
                            Assert.IsTrue(Math.Abs(errRelative) < 1.0e-13);
                        }
                    }
                }
            }
        }
コード例 #4
0
 public static RrFunction Affine(double slope, double origin)
 {
     if (DoubleUtils.EqualZero(slope))
     {
         return(Constant(origin));
     }
     return(Constant(slope).Integral(-origin / slope));
 }
コード例 #5
0
 public void TestEqualZero()
 {
     Assert.IsTrue(DoubleUtils.EqualZero(0.0));
     Assert.IsFalse(DoubleUtils.EqualZero(1.0));
     Assert.IsFalse(DoubleUtils.EqualZero(1.0e-28));
     Assert.IsFalse(DoubleUtils.EqualZero(double.Epsilon));
     Assert.IsTrue(DoubleUtils.EqualZero(0.5 * double.Epsilon));
 }
コード例 #6
0
 public static RrFunction Constant(double value)
 {
     if (DoubleUtils.EqualZero(value))
     {
         return(Zero);
     }
     return(new ConstantRrFunction(value));
 }
コード例 #7
0
        public override string ToString()
        {
            var firstNonZeroCoeff = new List <double>(Coeffs).FindIndex(x => !DoubleUtils.EqualZero(x));

            string desc        = "";
            bool   initialized = false;

            //Display constant part
            if (firstNonZeroCoeff == 0)
            {
                desc       += Coeffs[0].ToString(CultureInfo.InvariantCulture);
                initialized = true;
            }

            //Display degree one part
            if (firstNonZeroCoeff <= 1 && Coeffs.Length > 1)
            {
                if (initialized)
                {
                    desc += " + ";
                }

                if (DoubleUtils.MachineEquality(Coeffs[1], 1.0))
                {
                    desc += "X";
                }
                else
                {
                    desc += string.Format("{0} * X", Coeffs[1]);
                }

                initialized = true;
            }

            //Display higher degrees
            for (int i = 2; i < Coeffs.Length; i++)
            {
                if (!DoubleUtils.EqualZero(Coeffs[i]))
                {
                    if (initialized)
                    {
                        desc += " + ";
                    }

                    if (DoubleUtils.MachineEquality(Coeffs[i], 1.0))
                    {
                        desc += string.Format("X^{0}", i);
                    }
                    else
                    {
                        desc += string.Format("{0} * X^{1}", Coeffs[i], i);
                    }

                    initialized = true;
                }
            }
            return(desc);
        }
コード例 #8
0
        public override RrFunction Integral(double basePoint)
        {
            if (DoubleUtils.EqualZero(slope))
            {
                return(RrFunctions.Constant(weight).Integral(basePoint));
            }

            var zeroBaseIntegral = Create(weight / slope, slope);

            return(zeroBaseIntegral - zeroBaseIntegral.Eval(basePoint));
        }
コード例 #9
0
        public static RrFunction Add(StepFunction step, ConstantRrFunction cst)
        {
            if (DoubleUtils.EqualZero(cst.Value))
            {
                return(step);
            }

            var shiftedValues = step.values.Map(v => v + cst.Value);

            return(new StepFunction(step.abscissae, shiftedValues, step.leftValue + cst.Value));
        }
コード例 #10
0
        public void CheckSymmetry()
        {
            var rand = new Random(1468);

            for (int i = 0; i < 10000; i++)
            {
                var x           = rand.NextDouble() * 30.0; // random in [0, 30]
                var norm_x      = NormalDistribution.Cumulative(x);
                var norm_minusx = NormalDistribution.Cumulative(-x);
                var err         = Math.Abs((norm_x + norm_minusx) - 1.0);
                Assert.IsTrue(DoubleUtils.EqualZero(err));
            }
        }
コード例 #11
0
        public static RrFunction Mult(LinearCombinationRrFunction lc, ConstantRrFunction cst)
        {
            if (DoubleUtils.MachineEquality(1.0, cst.Value))
            {
                return(lc);
            }

            if (DoubleUtils.EqualZero(cst.Value))
            {
                return(RrFunctions.Zero);
            }

            return(LinearCombinationRrFunction.Create(lc.Weights.Map(w => w * cst.Value), lc.Functions));
        }
コード例 #12
0
        public static RrFunction Create(double weight, double slope)
        {
            if (DoubleUtils.EqualZero(weight))
            {
                return(RrFunctions.Zero);
            }

            if (DoubleUtils.EqualZero(slope))
            {
                return(RrFunctions.Constant(weight));
            }

            return(new ExpRrFunction(weight, slope));
        }
コード例 #13
0
        public override RnRFunction Mult(RnRFunction right)
        {
            var cst = right as ConstantRnRFunction;

            if (cst != null)
            {
                if (DoubleUtils.EqualZero(cst.Value))
                {
                    return(RnRFunctions.Constant(0.0, cst.Dim));
                }

                return(new ExpAffineRnRFunction(cst.Value * add, mults.Map(m => m * cst.Value)));
            }

            return(base.Mult(right));
        }
コード例 #14
0
        public static RrFunction Mult(StepFunction step, ConstantRrFunction cst)
        {
            if (DoubleUtils.MachineEquality(cst.Value, 1.0))
            {
                return(step);
            }

            if (DoubleUtils.EqualZero(cst.Value))
            {
                return(RrFunctions.Zero);
            }

            var multValues = step.values.Map(v => v * cst.Value);

            return(new StepFunction(step.abscissae, multValues, step.leftValue * cst.Value));
        }
コード例 #15
0
        public static double rational_cubic_control_parameter_to_fit_second_derivative_at_right_side(double x_l, double x_r, double y_l, double y_r,
                                                                                                     double d_l, double d_r, double second_derivative_r)
        {
            double h = (x_r - x_l), numerator = 0.5 * h * second_derivative_r + (d_r - d_l);

            if ((DoubleUtils.EqualZero(numerator)))
            {
                return(0);
            }
            double denominator = d_r - (y_r - y_l) / h;

            if ((DoubleUtils.EqualZero(denominator)))
            {
                return(numerator > 0 ? MaximumRationalCubicControlParameterValue : MinimumRationalCubicControlParameterValue);
            }
            return(numerator / denominator);
        }
コード例 #16
0
        public static double minimum_rational_cubic_control_parameter(double d_l, double d_r, double s, bool preferShapePreservationOverSmoothness)
        {
            bool monotonic = d_l * s >= 0 && d_r * s >= 0, convex = d_l <= s && s <= d_r, concave = d_l >= s && s >= d_r;

            if (!monotonic && !convex && !concave) // If 3==r_non_shape_preserving_target, this means revert to standard cubic.
            {
                return(MinimumRationalCubicControlParameterValue);
            }
            double d_r_m_d_l = d_r - d_l, d_r_m_s = d_r - s, s_m_d_l = s - d_l;
            double r1 = -double.MaxValue, r2 = r1;

            // If monotonicity on this interval is possible, set r1 to satisfy the monotonicity condition (3.8).
            if (monotonic)
            {
                if (!DoubleUtils.EqualZero(s)) // (3.8), avoiding division by zero.
                {
                    r1 = (d_r + d_l) / s;      // (3.8)
                }
                else if (preferShapePreservationOverSmoothness)
                {
                    // If division by zero would occur, and shape preservation is preferred, set value to enforce linear interpolation.
                    r1 = MaximumRationalCubicControlParameterValue; // This value enforces linear interpolation.
                }
            }
            if (convex || concave)
            {
                if (!(DoubleUtils.EqualZero(s_m_d_l) || DoubleUtils.EqualZero(d_r_m_s))) // (3.18), avoiding division by zero.
                {
                    r2 = Math.Max(Math.Abs(d_r_m_d_l / d_r_m_s), Math.Abs(d_r_m_d_l / s_m_d_l));
                }
                else if (preferShapePreservationOverSmoothness)
                {
                    r2 = MaximumRationalCubicControlParameterValue; // This value enforces linear interpolation.
                }
            }
            else if (preferShapePreservationOverSmoothness)
            {
                r2 = MaximumRationalCubicControlParameterValue;
            }
            // This enforces linear interpolation along segments that are inconsistent with the slopes on the boundaries, e.g., a perfectly horizontal segment that has negative slopes on either edge.
            return(Math.Max(MinimumRationalCubicControlParameterValue, Math.Max(r1, r2)));
        }
コード例 #17
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());
        }
コード例 #18
0
        public Polynomial(bool simplify, params double[] coeffs)
        {
            Contract.Requires(coeffs.Length > 0);

            if (simplify)
            {
                int degree = coeffs.Length - 1;
                while (degree > 0)
                {
                    if (!DoubleUtils.EqualZero(coeffs[degree]))
                    {
                        break;
                    }
                    --degree;
                }
                Coeffs = new double[degree + 1];
                Array.Copy(coeffs, Coeffs, Coeffs.Length);
            }
            else
            {
                Coeffs = coeffs;
            }
        }
コード例 #19
0
        /// <summary>
        /// Brenth algorithm from scipy
        /// </summary>
        public static double Brenth(Func <double, double> f,
                                    double xa, double fa, double xb, double fb,
                                    double xtol, double rtol, int maxIter,
                                    out int funcalls, out int iterations)
        {
            double xpre = xa;
            double xcur = xb;
            double fpre = fa;
            double fcur = fb;

            funcalls   = 0;
            iterations = 0;

            if (fpre * fcur > 0)
            {
                throw new Exception("Brent : root must be bracketed");
            }

            if (DoubleUtils.EqualZero(fpre))
            {
                return(xpre);
            }
            if (DoubleUtils.EqualZero(fcur))
            {
                return(xcur);
            }

            double xblk = 0.0, fblk = 0.0, spre = 0.0, scur = 0.0;

            for (int i = 0; i < maxIter; i++)
            {
                iterations++;
                if (fpre * fcur < 0)
                {
                    xblk = xpre;
                    fblk = fpre;
                    spre = scur = xcur - xpre;
                }
                if (Math.Abs(fblk) < Math.Abs(fcur))
                {
                    xpre = xcur;
                    xcur = xblk;
                    xblk = xpre;
                    fpre = fcur;
                    fcur = fblk;
                    fblk = fpre;
                }

                double tol  = xtol + rtol * Math.Abs(xcur);
                double sbis = (xblk - xcur) / 2.0;
                if (DoubleUtils.EqualZero(fcur) || Math.Abs(sbis) < tol)
                {
                    return(xcur);
                }

                if (Math.Abs(spre) > tol && Math.Abs(fcur) < Math.Abs(fpre))
                {
                    double stry;
                    if (DoubleUtils.MachineEquality(xpre, xblk))
                    {
                        // interpolate
                        stry = -fcur * (xcur - xpre) / (fcur - fpre);
                    }
                    else
                    {
                        // extrapolate
                        double dpre = (fpre - fcur) / (xpre - xcur);
                        double dblk = (fblk - fcur) / (xblk - xcur);

                        stry = -fcur * (fblk - fpre) / (fblk * dpre - fpre * dblk);
                    }

                    if (2.0 * Math.Abs(stry) < Math.Min(Math.Abs(spre), 3.0 * Math.Abs(sbis) - tol))
                    {
                        // accept step
                        spre = scur;
                        scur = stry;
                    }
                    else
                    {
                        // bisect
                        spre = sbis;
                        scur = sbis;
                    }
                }
                else
                {
                    // bisect
                    spre = sbis;
                    scur = sbis;
                }

                xpre = xcur;
                fpre = fcur;
                if (Math.Abs(scur) > tol)
                {
                    xcur += scur;
                }
                else
                {
                    xcur += (sbis > 0.0 ? tol : -tol);
                }

                fcur = f(xcur);
                funcalls++;
            }
            throw new Exception("Brent : max iteration excedeed");
        }