/// <summary>
        /// Creates synthetic swaps from FX curve for period under 1 year
        /// </summary>
        /// <param name="rateCurve"></param>
        /// <returns></returns>
        public TermPoint[] RemovePoints(IRateCurve rateCurve)
        {
            var fxTermCurve = rateCurve.GetTermCurve();
            var curveId     = GetRateCurveId();
            var termDate    = CutOverTerm.Add(curveId.BaseDate);

            return((from point in fxTermCurve.point
                    let pillarPoint = (DateTime)point.term.Items[0]
                                      where pillarPoint <= termDate
                                      select point).ToArray());
        }
        public NewtonRaphsonSolverFunctions(IPriceableAssetController asset, IPriceableAssetController previousAsset, PricingStructureAlgorithmsHolder algorithmHolder,
                                            IRateCurve baseCurve, DateTime baseDate, SortedDictionary <DateTime, Pair <string, decimal> > items,
                                            double compoundingPeriod, IDictionary <DateTime, double> zeroRateSpreads, IDayCounter dayCounter,
                                            List <DateTime> assetDates)
        {
            _asset           = asset;
            _baseCurve       = baseCurve;
            _zeroRateSpreads = zeroRateSpreads;
            string currency = PropertyHelper.ExtractCurrency(baseCurve.GetPricingStructureId().Properties);

            _algorithm  = algorithmHolder;
            _properties = new NamedValueSet(new Dictionary <string, object>
            {
                { CurveProp.PricingStructureType, "RateCurve" },
                { CurveProp.Market, "DiscountCurveConstruction" },
                { CurveProp.IndexTenor, "0M" },
                { CurveProp.Currency1, currency },
                { "Index", "XXX-XXX" },
                { "Algorithm", "FastLinearZero" },
                { "BaseDate", baseDate },
            });
            _items             = items;
            _compoundingPeriod = compoundingPeriod;
            _dayCounter        = dayCounter;
            _assetDates        = assetDates;
            if (previousAsset != null)
            {
                DateTime previousAssetMaturity = previousAsset.GetRiskMaturityDate();
                DateTime assetMaturity         = asset.GetRiskMaturityDate();
                IEnumerable <KeyValuePair <DateTime, string> > points
                    = from b in baseCurve.GetTermCurve().point
                      where (DateTime)b.term.Items[0] > previousAssetMaturity &&
                      (DateTime)b.term.Items[0] < assetMaturity
                      select new KeyValuePair <DateTime, string>((DateTime)b.term.Items[0], b.id);
                foreach (KeyValuePair <DateTime, string> point in points)
                {
                    _extraPoints.Add(point.Key, point.Value);
                    Pair <string, decimal> pair = new Pair <string, decimal>(point.Value, 0);
                    items.Add(point.Key, pair);
                }
            }
        }
示例#3
0
        /// <summary>
        /// Bootstraps the specified priceable assets.
        /// </summary>
        /// <param name="priceableAssets">The priceable assets.</param>
        /// <param name="baseZeroCurve">The base Zero Curve</param>
        /// <param name="algorithmHolder">The algorithmHolder</param>
        /// <returns></returns>
        public TermPoint[] Bootstrap(List <IPriceableRateAssetController> priceableAssets,
                                     IRateCurve baseZeroCurve, PricingStructureAlgorithmsHolder algorithmHolder)
        {
            var      items    = new SortedDictionary <DateTime, Pair <string, decimal> >();
            DateTime baseDate = baseZeroCurve.GetBaseDate();

            items.Add(baseDate, new Pair <string, decimal>(null, 1m));
            bool         firstTime         = true;
            const double compoundingPeriod = 0.25;
            IPriceableRateAssetController previousAsset = null;
            IEnumerable <TermPoint>       basePillars   = baseZeroCurve.GetTermCurve().point;
            IDayCounter dayCounter = null;

            foreach (IPriceableRateAssetController priceableAsset in priceableAssets)
            {
                List <DateTime> assetDates;
                if (priceableAsset is PriceableSwapRateAsset swap)
                {
                    dayCounter = DayCounterHelper.Parse(swap.DayCountFraction.Value);
                    assetDates = swap.AdjustedPeriodDates;
                }
                else
                {
                    PriceableDeposit deposit = priceableAsset as PriceableDeposit;
                    if (deposit == null)
                    {
                        throw new ArgumentException(
                                  $"PriceableAsset must be a PriceableSwapRateAsset or PriceableDeposit, '{priceableAsset.GetType()}' is not implemented.");
                    }
                    dayCounter = DayCounterHelper.Parse(deposit.Deposit.dayCountFraction.Value);
                    assetDates = new List <DateTime> {
                        deposit.AdjustedStartDate, deposit.GetRiskMaturityDate()
                    };
                }
                DateTime maturityDate = priceableAsset.GetRiskMaturityDate();
                if (items.Keys.Contains(maturityDate))
                {
                    throw new ArgumentException(
                              $"Duplicate priceable asset on '{maturityDate:yyyy-MM-dd}'", nameof(priceableAssets));
                }
                //The min and max values to use with the solver.
                const int xmin     = -1;
                const int xmax     = 1;
                var       accuracy = 10 ^ -12;
                if (firstTime)
                {
                    firstTime = false;
                    // Solve to find the quarterly compounded zero rate spread
                    var solverFunctions
                        = new NewtonRaphsonSolverFunctions(priceableAsset, null, algorithmHolder, baseZeroCurve,
                                                           baseDate, items, compoundingPeriod, ZeroRateSpreads, dayCounter, assetDates);
                    var solver       = new Newton();
                    var initialGuess = (double)priceableAsset.MarketQuote.value;
                    //var solution = new CenteredFiniteDifferenceDerivative();
                    Func <double, double> f           = solverFunctions.ShortEndTargetFunction;
                    var    derivativeOfTargetFunction = new NumericalDerivative().CreateDerivativeFunctionHandle(f, 1);
                    double zeroRateSpread             = solver.Solve(f, derivativeOfTargetFunction, accuracy, initialGuess, xmin, xmax);
                    // add first point
                    DateTime startDate = assetDates.First();
                    decimal  df        = (decimal)GetAdjustedDiscountFactor(baseDate, startDate, dayCounter, zeroRateSpread, baseZeroCurve);
                    if (startDate != baseDate)
                    {
                        items.Add(startDate, new Pair <string, decimal>(null, df));
                    }
                    ZeroRateSpreads.Add(maturityDate, zeroRateSpread);
                    // add extra points
                    IEnumerable <TermPoint> extraPoints = basePillars.Where(b => (DateTime)b.term.Items[0] > startDate && (DateTime)b.term.Items[0] < maturityDate);
                    // Extrapolate the preceding extra points
                    foreach (TermPoint extraPoint in extraPoints)
                    {
                        DateTime date = (DateTime)extraPoint.term.Items[0];
                        df = (decimal)GetAdjustedDiscountFactor(baseDate, date, dayCounter, zeroRateSpread, baseZeroCurve);
                        items.Add(date, new Pair <string, decimal>(extraPoint.id, df));
                    }
                    // add final point
                    df = (decimal)GetAdjustedDiscountFactor(baseDate, maturityDate, dayCounter, zeroRateSpread, baseZeroCurve);
                    items.Add(maturityDate, new Pair <string, decimal>(priceableAsset.Id, df));
                }
                else
                {
                    items.Add(maturityDate, new Pair <string, decimal>(priceableAsset.Id, 0));
                    ZeroRateSpreads.Add(maturityDate, (double)priceableAsset.MarketQuote.value);
                    // Solve to find the quarterly compounded zero rate spread
                    var solverFunctions
                        = new NewtonRaphsonSolverFunctions(priceableAsset, previousAsset, algorithmHolder, baseZeroCurve,
                                                           baseDate, items, compoundingPeriod, ZeroRateSpreads, dayCounter, assetDates);
                    Func <double, double> f           = solverFunctions.LongEndTargetFunction;
                    var    solver                     = new Newton();
                    var    initialGuess               = (double)priceableAsset.MarketQuote.value;
                    var    derivativeOfTargetFunction = new NumericalDerivative().CreateDerivativeFunctionHandle(f, 1);
                    double zeroRateSpread             = solver.Solve(f, derivativeOfTargetFunction, accuracy, initialGuess, xmin, xmax);
                    // Update discount factor value
                    decimal df = (decimal)GetAdjustedDiscountFactor(baseDate, maturityDate, dayCounter, zeroRateSpread, baseZeroCurve);
                    items[maturityDate].Second    = df;
                    ZeroRateSpreads[maturityDate] = zeroRateSpread;
                    solverFunctions.UpdateDiscountFactors(baseDate);
                }
                previousAsset = priceableAsset;
            }
            // Extrapolate the following extra points
            IEnumerable <TermPoint>         finalPoints         = basePillars.Where(b => (DateTime)b.term.Items[0] > items.Last().Key);
            KeyValuePair <DateTime, double> zeroRateSpreadFinal = ZeroRateSpreads.Last();

            foreach (TermPoint extraPoint in finalPoints)
            {
                DateTime date = (DateTime)extraPoint.term.Items[0];
                decimal  df   = (decimal)GetAdjustedDiscountFactor(baseDate, date, dayCounter, zeroRateSpreadFinal.Value, baseZeroCurve);
                items.Add(date, new Pair <string, decimal>(extraPoint.id, df));
            }
            return(TermPointsFactory.Create(items));
        }