Ejemplo n.º 1
0
        /// <summary>
        /// Bootstraps the specified priceable assets.
        /// </summary>
        /// <param name="priceableAssets">The priceable assets.</param>
        /// <param name="referenceCurve">The reference curve.</param>
        /// <param name="baseDate">The base date.</param>
        /// <param name="termCurve">The term Curve with pre-existing points. This will not work if there are no points.</param>
        /// <param name="tolerance">Solver tolerance to use.</param>
        /// <returns></returns>
        public static TermPoint[] Bootstrap(IList <IPriceableRateSpreadAssetController> priceableAssets,
                                            IRateCurve referenceCurve, DateTime baseDate, TermCurve termCurve,
                                            Double tolerance)
        {
            const double min = 0.000000001;
            const double max = 1;
            Dictionary <DateTime, Pair <string, decimal> > items
                = new Dictionary <DateTime, Pair <string, decimal> > ();
            //  Add the elements (date : discount factor) to the list
            IDictionary <DateTime, double> dfs = new Dictionary <DateTime, double>();

            foreach (var point in termCurve.point)
            {
                dfs.Add((DateTime)point.term.Items[0], (double)point.mid);
                items.Add((DateTime)point.term.Items[0], new Pair <string, decimal>(point.id, point.mid));
            }
            var solver = new Brent();

            foreach (var priceableAsset in priceableAssets)
            {
                var assetMaturityDate = priceableAsset.GetRiskMaturityDate();
                if (dfs.ContainsKey(assetMaturityDate))
                {
                    continue;
                }
                //The first guess, which should be correct for all priceable assets with analytical solutions that have been implemented.
                //So far this is only wrt Depos and Futures...This now should automatically extrapolate the required discount factor on a flat rate basis.
                dfs.Add(assetMaturityDate, (double)priceableAsset.CalculateDiscountFactorAtMaturity(referenceCurve));
                var objectiveFunction = new RateSpreadAssetQuote(priceableAsset, referenceCurve, baseDate,
                                                                 termCurve.extrapolationPermitted, dfs, tolerance);
                // check accuracy so that solver is only called if outside the tolerance.
                if (!objectiveFunction.InitialValue())
                {
                    dfs[assetMaturityDate] = solver.Solve(objectiveFunction, tolerance, dfs[assetMaturityDate], min, max);
                }
                items.Add(assetMaturityDate, new Pair <string, decimal>(priceableAsset.Id, (decimal)dfs[assetMaturityDate]));
            }
            return(TermPointsFactory.Create(items));
        }
        /// <summary>
        /// Bootstraps the specified priceable assets.
        /// </summary>
        /// <param name="priceableAssets">The priceable assets.</param>
        /// <param name="referenceCurve">The reference curve.</param>
        /// <param name="baseDate">The base date.</param>
        /// <param name="extrapolationPermitted">The extrapolationPermitted flag.</param>
        /// <param name="tolerance">The tolerance for the solver</param>
        /// <returns></returns>
        public static TermPoint[] Bootstrap(IEnumerable <IPriceableRateSpreadAssetController> priceableAssets,
                                            IRateCurve referenceCurve, DateTime baseDate, bool extrapolationPermitted, double tolerance)
        {
            const double defaultGuess = 0.9;
            const double min          = 0.000000001;
            const double max          = 2;
            //only works for linear on zero.
            InterpolationMethod interp = InterpolationMethodHelper.Parse("LogLinearInterpolation");
            //  Add the first element (date : discount factor) to the list
            var points = new Dictionary <DateTime, double> {
                { baseDate, 1d }
            };
            var items
                = new Dictionary <DateTime, Pair <string, decimal> > {
                { baseDate, new Pair <string, decimal>("", 1m) }
                };
            var  solver = new Brent();
            bool first  = true;

            foreach (var priceableAsset in priceableAssets)
            {
                DateTime assetMaturityDate = priceableAsset.GetRiskMaturityDate();
                if (points.Keys.Contains(assetMaturityDate))
                {
                    continue;
                }
                if (assetMaturityDate < points.Keys.Last())
                {
                    throw new InvalidOperationException("The maturity dates of the assets must be consecutive order");
                }
                if (first)
                {
                    first = false;
                    // Add the first point
                    points.Add(assetMaturityDate, defaultGuess);
                    IRateCurve curve = IsSpreadAsset(priceableAsset) ? referenceCurve : new SimpleDiscountFactorCurve(baseDate, interp, extrapolationPermitted, points);
                    points[assetMaturityDate] = (double)priceableAsset.CalculateDiscountFactorAtMaturity(curve);
                }
                else
                {
                    //This now should automatically extrapolate the required discount factor on a flat rate basis.
                    IRateCurve curve = IsSpreadAsset(priceableAsset) ? referenceCurve : new SimpleDiscountFactorCurve(baseDate, interp, extrapolationPermitted, points);
                    //The first guess, which should be correct for all priceable assets with analytical solutions that have been implemented.
                    points.Add(assetMaturityDate, (double)priceableAsset.CalculateDiscountFactorAtMaturity(curve));
                }
                IObjectiveFunction objectiveFunction;
                bool initialValue;
                if (IsSpreadAsset(priceableAsset))
                {
                    objectiveFunction = new RateSpreadAssetQuote(priceableAsset, referenceCurve, baseDate,
                                                                 extrapolationPermitted, points, tolerance);
                    initialValue = ((RateSpreadAssetQuote)objectiveFunction).InitialValue();
                }
                else
                {
                    objectiveFunction = new RateAssetQuote(priceableAsset, baseDate, interp, extrapolationPermitted,
                                                           points, tolerance);
                    initialValue = ((RateAssetQuote)objectiveFunction).InitialValue();
                }
                // Check whether the guess was close enough
                if (!initialValue)
                {
                    double guess = Math.Max(min, points[assetMaturityDate]);
                    points[assetMaturityDate] = solver.Solve(objectiveFunction, tolerance, guess, min, max);
                }
                items.Add(assetMaturityDate, new Pair <string, decimal>(priceableAsset.Id, (decimal)points[assetMaturityDate]));
            }
            return(TermPointsFactory.Create(items));
        }