Esempio n. 1
0
        public void recalibration(List <Period> swapLengths, List <double> beta, Period swapTenor)
        {
            Utils.QL_REQUIRE(beta.Count == swapLengths.Count, () =>
                             "beta size (" + beta.Count + ") must be equal to number of swap lenghts ("
                             + swapLengths.Count + ")");

            List <double> betaTimes = new List <double>();

            for (int i = 0; i < beta.Count; i++)
            {
                betaTimes.Add(timeFromReference(optionDateFromTenor(swapLengths[i])));
            }

            LinearInterpolation betaInterpolation = new LinearInterpolation(betaTimes, betaTimes.Count, beta);

            List <double> cubeBeta = new List <double>();

            for (int i = 0; i < optionTimes().Count; i++)
            {
                double t = optionTimes()[i];
                // flat extrapolation ensures admissable values
                if (t < betaTimes.First())
                {
                    t = betaTimes.First();
                }
                if (t > betaTimes.Last())
                {
                    t = betaTimes.Last();
                }
                cubeBeta.Add(betaInterpolation.value(t));
            }

            recalibration(cubeBeta, swapTenor);
        }
Esempio n. 2
0
        public void applyTo(object o, double t)
        {
            Vector a     = (Vector)o;
            Vector aCopy = new Vector(a);

            int iterIndex = dividendTimes_.BinarySearch(t);

            if (iterIndex >= 0)
            {
                double dividend = dividends_[iterIndex];

                if (mesher_.layout().dim().Count == 1)
                {
                    LinearInterpolation interp = new LinearInterpolation(x_, x_.Count, aCopy);
                    for (int k = 0; k < x_.size(); ++k)
                    {
                        a[k] = interp.value(Math.Max(x_[0], x_[k] - dividend), true);
                    }
                }
                else
                {
                    Vector tmp      = new Vector(x_.size());
                    int    xSpacing = mesher_.layout().spacing()[equityDirection_];

                    for (int i = 0; i < mesher_.layout().dim().Count; ++i)
                    {
                        if (i != equityDirection_)
                        {
                            int ySpacing = mesher_.layout().spacing()[i];
                            for (int j = 0; j < mesher_.layout().dim()[i]; ++j)
                            {
                                for (int k = 0; k < x_.size(); ++k)
                                {
                                    int index = j * ySpacing + k * xSpacing;
                                    tmp[k] = aCopy[index];
                                }
                                LinearInterpolation interp = new LinearInterpolation(x_, x_.Count, tmp);
                                for (int k = 0; k < x_.size(); ++k)
                                {
                                    int index = j * ySpacing + k * xSpacing;
                                    a[index] = interp.value(
                                        Math.Max(x_[0], x_[k] - dividend), true);
                                }
                            }
                        }
                    }
                }
            }
        }
        protected override double volatilityImpl(double length, double strike)
        {
            calculate();

            List <double> vol = new InitializedList <double>(nInterpolations_);

            for (int i = 0; i < nInterpolations_; ++i)
            {
                vol[i] = strikeInterpolations_[i].value(strike, true);
            }

            List <double>       optionletTimes   = new List <double>(optionletStripper_.optionletFixingTimes());
            LinearInterpolation timeInterpolator = new LinearInterpolation(optionletTimes, optionletTimes.Count, vol);

            return(timeInterpolator.value(length, true));
        }
        public double k(double t, List <double> xBegin, int size)
        {
            LinearInterpolation li = new LinearInterpolation(xBegin, size, coeffs_.k_);

            return(li.value(t));
        }
        public double k(double t)
        {
            LinearInterpolation li = new LinearInterpolation(this.xBegin_, this.size_, this.yBegin_);

            return(li.value(t));
        }
Esempio n. 6
0
        public Concentrating1dMesher(double start, double end, int size,
                                     Pair <double?, double?> cPoints = null,
                                     bool requireCPoint = false)
            : base(size)
        {
            Utils.QL_REQUIRE(end > start, () => "end must be larger than start");
            if (cPoints == null)
            {
                cPoints = new Pair <double?, double?>();
            }

            double?cPoint  = cPoints.first;
            double?density = cPoints.second == null ? null : cPoints.second * (end - start);

            Utils.QL_REQUIRE(cPoint == null || (cPoint >= start && cPoint <= end),
                             () => "cPoint must be between start and end");
            Utils.QL_REQUIRE(density == null || density > 0.0,
                             () => "density > 0 required");
            Utils.QL_REQUIRE(cPoint == null || density != null,
                             () => "density must be given if cPoint is given");
            Utils.QL_REQUIRE(!requireCPoint || cPoint != null,
                             () => "cPoint is required in grid but not given");

            double dx = 1.0 / (size - 1);

            if (cPoint != null)
            {
                List <double> u         = new List <double>();
                List <double> z         = new List <double>();
                Interpolation transform = null;
                double        c1        = Utils.Asinh((start - cPoint.Value) / density.GetValueOrDefault());
                double        c2        = Utils.Asinh((end - cPoint.Value) / density.GetValueOrDefault());
                if (requireCPoint)
                {
                    u.Add(0.0);
                    z.Add(0.0);
                    if (!Utils.close(cPoint.Value, start) && !Utils.close(cPoint.Value, end))
                    {
                        double z0 = -c1 / (c2 - c1);
                        double u0 =
                            Math.Max(
                                Math.Min(Convert.ToInt32(z0 * (size - 1) + 0.5),
                                         Convert.ToInt32(size) - 2),
                                1) / (Convert.ToDouble(size - 1));
                        u.Add(u0);
                        z.Add(z0);
                    }
                    u.Add(1.0);
                    z.Add(1.0);
                    transform = new LinearInterpolation(u, u.Count, z);
                }

                for (int i = 1; i < size - 1; ++i)
                {
                    double li = requireCPoint ? transform.value(i * dx) : i * dx;
                    locations_[i] = cPoint.Value
                                    + density.GetValueOrDefault() * Math.Sinh(c1 * (1.0 - li) + c2 * li);
                }
            }
            else
            {
                for (int i = 1; i < size - 1; ++i)
                {
                    locations_[i] = start + i * dx * (end - start);
                }
            }

            locations_[0] = start;
            locations_[locations_.Count - 1] = end;

            for (int i = 0; i < size - 1; ++i)
            {
                dplus_[i] = dminus_[i + 1] = locations_[i + 1] - locations_[i];
            }
            dplus_[dplus_.Count - 1] = null;
            dminus_[0] = null;
        }
Esempio n. 7
0
        public Concentrating1dMesher(double start, double end, int size,
                                     List <Tuple <double?, double?, bool> > cPoints,
                                     double tol = 1e-8)
            : base(size)
        {
            Utils.QL_REQUIRE(end > start, () => "end must be larger than start");

            List <double?> points = new List <double?>(), betas = new List <double?>();

            foreach (Tuple <double?, double?, bool> iter in cPoints)
            {
                points.Add(iter.Item1);
                betas.Add((iter.Item2 * (end - start)) * (iter.Item2 * (end - start)));
            }

            // get scaling factor a so that y(1) = end
            double aInit = 0.0;

            for (int i = 0; i < points.Count; ++i)
            {
                double c1 = Utils.Asinh((start - points[i].GetValueOrDefault()) / betas[i].GetValueOrDefault());
                double c2 = Utils.Asinh((end - points[i].GetValueOrDefault()) / betas[i].GetValueOrDefault());
                aInit += (c2 - c1) / points.Count;
            }

            OdeIntegrationFct fct = new OdeIntegrationFct(points, betas, tol);
            double            a   = new Brent().solve(
                new OdeSolver(fct, start, 0.0, 1.0, end),
                tol, aInit, 0.1 * aInit);

            // solve ODE for all grid points
            Vector x = new Vector(size), y = new Vector(size);

            x[0] = 0.0;
            y[0] = start;
            double dx = 1.0 / (size - 1);

            for (int i = 1; i < size; ++i)
            {
                x[i] = i * dx;
                y[i] = fct.solve(a, y[i - 1], x[i - 1], x[i]);
            }

            // eliminate numerical noise and ensure y(1) = end
            double dy = y[y.Count - 1] - end;

            for (int i = 1; i < size; ++i)
            {
                y[i] -= i * dx * dy;
            }

            LinearInterpolation odeSolution = new LinearInterpolation(x, x.Count, y);

            // ensure required points are part of the grid
            List <Pair <double?, double?> > w =
                new InitializedList <Pair <double?, double?> > (1, new Pair <double?, double?>(0.0, 0.0));

            for (int i = 0; i < points.Count; ++i)
            {
                if (cPoints[i].Item3 && points[i] > start && points[i] < end)
                {
                    int j = y.distance(y[0], y.BinarySearch(points[i].Value));

                    double e = new Brent().solve(
                        new OdeSolver2(odeSolution.value, points[i].Value),
                        Const.QL_EPSILON, x[j], 0.5 / size);

                    w.Add(new Pair <double?, double?>(Math.Min(x[size - 2], x[j]), e));
                }
            }
            w.Add(new Pair <double?, double?>(1.0, 1.0));
            w = w.OrderBy(xx => xx.first).Distinct(new equal_on_first()).ToList();

            List <double> u = new List <double>(w.Count), z = new List <double>(w.Count);

            for (int i = 0; i < w.Count; ++i)
            {
                u[i] = w[i].first.GetValueOrDefault();
                z[i] = w[i].second.GetValueOrDefault();
            }
            LinearInterpolation transform = new LinearInterpolation(u, u.Count, z);

            for (int i = 0; i < size; ++i)
            {
                locations_[i] = odeSolution.value(transform.value(i * dx));
            }

            for (int i = 0; i < size - 1; ++i)
            {
                dplus_[i] = dminus_[i + 1] = locations_[i + 1] - locations_[i];
            }
            dplus_[dplus_.Count] = null;
            dminus_[0]           = null;
        }
 public interpolated_volatility(List <double> pGrid,
                                List <double> vGrid)
 {
     variance = new LinearInterpolation(pGrid, pGrid.Count, vGrid);
 }