Esempio n. 1
0
        /// <summary>
        /// Bootstraps the specified priceable assets.
        /// </summary>
        /// <param name="priceableAssets">The priceable assets.</param>
        /// <param name="baseDate">The base date.</param>
        /// <param name="extrapolationPermitted">The extrapolationPermitted flag.</param>
        /// <param name="interpolationMethod">The interpolationMethod.</param>
        /// <param name="tolerance">Solver tolerance to use.</param>
        /// <returns></returns>
        public static TermPoint[] Bootstrap(IEnumerable <IPriceableRateAssetController> priceableAssets,
                                            DateTime baseDate, Boolean extrapolationPermitted,
                                            InterpolationMethod interpolationMethod, 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;

            // Add the rest
            foreach (IPriceableRateAssetController 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);
                    var curve = 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.
                    var curve = 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));
                }
                var objectiveFunction = new RateAssetQuote(priceableAsset, baseDate, interpolationMethod,
                                                           extrapolationPermitted, points, tolerance);
                // Check whether the guess was close enough
                if (!objectiveFunction.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));
        }
Esempio n. 2
0
        /// <summary>
        /// Bootstraps the specified priceable assets.
        /// </summary>
        /// <param name="priceableAssets">The priceable assets.</param>
        /// <param name="baseDate">The base date.</param>
        /// <param name="extrapolationPermitted">The extrapolationPermitted flag.</param>
        /// <param name="interpolationMethod">The interpolationMethod.</param>
        /// <param name="tolerance">Solver tolerance to use.</param>
        /// <returns></returns>
        public static TermPoint[] Bootstrap(List <IPriceableFxAssetController> priceableAssets,
                                            DateTime baseDate, Boolean extrapolationPermitted,
                                            InterpolationMethod interpolationMethod, Double tolerance)
        {
            const Double        solveRateGap     = 0.015d;//should we need more precising perhaps???
            const Decimal       dfamMinThreshold = 0.0m;
            const Decimal       defaultGuess     = 0.9m;
            const Double        accuracy         = 0.000001d;
            InterpolationMethod interp           = InterpolationMethodHelper.Parse("LinearInterpolation"); //only works for linear on zero.

            priceableAssets = priceableAssets.OrderBy(a => a.GetRiskMaturityDate()).ToList();
            var  dates           = new List <DateTime>();
            var  discountFactors = new List <double>();
            var  items           = new Dictionary <DateTime, Pair <string, decimal> >();
            bool firstTime       = true;

            foreach (var asset in priceableAssets)
            {
                DateTime assetMaturityDate = asset.GetRiskMaturityDate();
                //check if the maturity date is already in the list. If not contimue.
                if (items.ContainsKey(assetMaturityDate))
                {
                    continue;
                }
                decimal guess = asset.ForwardAtMaturity > dfamMinThreshold ? asset.ForwardAtMaturity : defaultGuess;
                decimal dfam;
                if (firstTime)
                {
                    firstTime = false;
                    dates.Add(assetMaturityDate);
                    discountFactors.Add(Convert.ToDouble(guess));
                    dfam = asset.CalculateImpliedQuote(new SimpleFxCurve(baseDate, interp, extrapolationPermitted, dates, discountFactors));
                    discountFactors[0] = (double)dfam;
                }
                else
                {
                    //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.
                    dfam = asset.CalculateImpliedQuote(new SimpleFxCurve(baseDate, interp, extrapolationPermitted, dates, discountFactors));
                    discountFactors.Add((double)dfam);
                    dates.Add(assetMaturityDate);
                }
                //Add a check on the dfam so that the solver is only called if outside the tolerance.
                var objectiveFunction = new FxAssetQuote(asset, baseDate, interpolationMethod,
                                                         extrapolationPermitted, dates, discountFactors, tolerance);
                if (!objectiveFunction.InitialValue())
                {
                    var timeInterval  = Actual365.Instance.YearFraction(baseDate, assetMaturityDate);
                    var solveInterval = Math.Exp(-solveRateGap * timeInterval);
                    var min           = Math.Max(0, (double)dfam * solveInterval);
                    var max           = (double)dfam / solveInterval;
                    var solver        = new Brent();
                    dfam = (decimal)solver.Solve(objectiveFunction, accuracy, (double)dfam, min, max);
                }
                items.Add(assetMaturityDate, new Pair <string, decimal>(asset.Id, dfam));
            }
            return(TermPointsFactory.Create(items));
        }
Esempio n. 3
0
        /// <summary>
        /// Bootstraps the specified priceable assets, where the assets
        /// are simple commodity asset with single cash flows on a
        /// single index observation.
        /// </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>
        /// <param name="spreadXArray">THe spread interpolator produced in the bootstrapper</param>
        /// <param name="spreadYArray">THe spread interpolator produced in the bootstrapper</param>
        /// <returns></returns>
        public static TermPoint[] Bootstrap(IEnumerable <IPriceableCommoditySpreadAssetController> priceableAssets,
                                            ICommodityCurve referenceCurve, DateTime baseDate, bool extrapolationPermitted, double tolerance, ref IList <double> spreadXArray, ref IList <double> spreadYArray)
        {
            //only works for linear on zero.
            //InterpolationMethod interp = InterpolationMethodHelper.Parse("LinearInterpolation");
            //  Add the first element (date : discount factor) to the list
            var points = new Dictionary <DateTime, double>();
            var items
                = new SortedDictionary <DateTime, Pair <string, decimal> >();
            var dayCounter = new Actual365();

            foreach (var priceableAsset in priceableAssets)
            {
                DateTime assetMaturityDate = priceableAsset.GetRiskMaturityDate();
                if (points.Keys.Contains(assetMaturityDate))
                {
                    continue;
                }
                //This now should automatically extrapolate the required discount factor on a flat rate basis.
                if (IsSpreadAsset(priceableAsset))
                {
                    //These are simple assts so the solver is unnecessary.
                    var value    = (double)priceableAsset.CalculateImpliedQuoteWithSpread(referenceCurve);
                    var dayCount = dayCounter.YearFraction(baseDate, assetMaturityDate);
                    spreadXArray.Add(dayCount);
                    spreadYArray.Add((double)priceableAsset.MarketQuote.value);  //TODO Get the marketquote
                    points.Add(assetMaturityDate, value);
                    items.Add(assetMaturityDate,
                              new Pair <string, decimal>(priceableAsset.Id, (decimal)points[assetMaturityDate]));
                }
            }
            if (spreadXArray.Count > 2)
            {
                var spreadCurveInterpolator = new LinearInterpolation(spreadXArray.ToArray(),
                                                                      spreadYArray.ToArray());
                var index = 0;
                foreach (var assetMaturityDate in referenceCurve.GetTermCurve().GetListTermDates())
                {
                    if (points.Keys.Contains(assetMaturityDate))
                    {
                        continue;
                    }
                    var    dayCount    = dayCounter.YearFraction(baseDate, assetMaturityDate);
                    double spreadValue = spreadCurveInterpolator.ValueAt(dayCount, true);
                    var    value       = referenceCurve.GetForward(baseDate, assetMaturityDate);
                    points.Add(assetMaturityDate, value + spreadValue);
                    items.Add(assetMaturityDate,
                              new Pair <string, decimal>("RefCurvePillar_" + index, (decimal)points[assetMaturityDate]));
                    index++;
                }
                return(TermPointsFactory.Create(items));
            }
            return(null);
        }
Esempio n. 4
0
        public void LoadInterestRateVolCurveTest()
        {
            CreateATMRateVolCurve("AUD", "3M", IrVolInstruments, IrVolValues, IrStrikes);
            var curve = (CapVolatilityCurve)CurveEngine.LoadVolatilityCurve(Market, "AUD", "3M", null);

            Assert.IsNotNull(curve);
            // 3M does exist
            Assert.AreEqual("3M", curve.GetPricingStructureId().Properties.GetString("IndexTenor", true));
            //var baseDate = curve.GetBaseDate();
            var expiration = VolatilitySurfaceHelper.GetDimensionValues(curve.GetVolatilityMatrix().dataPoints?.point,
                                                                        CubeDimension.Expiration);
            var volatilities = VolatilitySurfaceHelper.GetDimensionValues(curve.GetVolatilityMatrix().dataPoints?.point,
                                                                          CubeDimension.Volatility);
            var valArray = new List <Decimal>();

            foreach (var vol in volatilities)
            {
                valArray.Add((decimal)vol);
            }
            var expiryArray = new List <TimeDimension>();

            //var valArray = new List<Decimal>();
            //Debug.Print(baseDate.ToString(CultureInfo.InvariantCulture));
            foreach (var expiry in expiration)
            {
                //Temporary
                if (expiry is TimeDimension timeDimension)
                {
                    expiryArray.Add(timeDimension);
                }
                //var date = expiry as DateTime? ?? baseDate.AddDays(1);
                //expiryArray.Add(date);
                //Debug.Print(expiry.ToString());
            }
            var termPoints = TermPointsFactory.Create(expiryArray, valArray);
            var termCurve  = new TermCurve {
                point = termPoints
            };
            var output = XmlSerializerHelper.SerializeToString(termCurve);

            Debug.Print(output);
        }
Esempio n. 5
0
        /// <summary>
        /// Bootstraps the specified priceable assets.
        /// </summary>
        /// <param name="priceableAssets">The priceable assets.</param>
        /// <param name="baseDate">The base date.</param>
        /// <param name="extrapolationPermitted">The extrapolationPermitted flag.</param>
        /// <param name="interpolationMethod">The interpolationMethod.</param>
        /// <param name="tolerance">Solver tolerance to use.</param>
        /// <returns></returns>
        public static TermPoint[] Bootstrap(IEnumerable <IPriceableFuturesAssetController> priceableAssets,
                                            DateTime baseDate, Boolean extrapolationPermitted,
                                            InterpolationMethod interpolationMethod, Double tolerance)
        {
            //  Add the first element (date : discount factor) to the list
            var points = new Dictionary <DateTime, double>();
            var items  = new Dictionary <DateTime, Pair <string, decimal> >();

            // Add the rest
            foreach (IPriceableFuturesAssetController priceableAsset in priceableAssets)
            {
                DateTime assetMaturityDate = priceableAsset.LastTradeDate;
                if (points.Keys.Contains(assetMaturityDate))
                {
                    continue;
                }
                points.Add(assetMaturityDate, (double)priceableAsset.IndexAtMaturity);
                items.Add(assetMaturityDate, new Pair <string, decimal>(priceableAsset.Id, (decimal)points[assetMaturityDate]));
            }
            return(TermPointsFactory.Create(items));
        }
Esempio n. 6
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));
        }
Esempio n. 7
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));
        }
        /// <summary>
        /// Bootstraps the specified priceable assets.
        /// </summary>
        /// <param name="priceableAssets">The priceable assets.</param>
        /// <param name="baseDate">The base date.</param>
        /// <param name="extrapolationPermitted">The extrapolationPermitted flag.</param>
        /// <param name="interpolationMethod">The interpolationMethod.</param>
        /// <param name="tolerance">Solver tolerance to use.</param>
        /// <returns></returns>
        public static TermPoint[] Bootstrap(List <IPriceableCreditAssetController> priceableAssets,
                                            DateTime baseDate, Boolean extrapolationPermitted,
                                            InterpolationMethod interpolationMethod, Double tolerance)
        {
            const Double  cSolveRateGap     = 0.015d;//should be need more precise perhaps???
            const Decimal cDfamMinThreshold = 0.0m;
            const Decimal cDefaultGuess     = 0.9m;
            const Double  accuracy          = 0.000001d;

            priceableAssets.Sort
            (
                (priceableAssetController1, priceableAssetController2) =>
                priceableAssetController1.GetRiskMaturityDate().CompareTo(priceableAssetController2.GetRiskMaturityDate())
            );
            //  Add the first element (date : discount factor) to the list
            //
            IList <DateTime> dates = new List <DateTime> {
                baseDate
            };
            IList <double> discountFactors = new List <double> {
                1.0
            };
            var index = 0;

            foreach (var priceableAsset in priceableAssets)
            {
                //TODO check if the maturity date is already in the list. If not contimue.
                var assetMaturityDate = priceableAsset.GetRiskMaturityDate();
                if (dates.Contains(assetMaturityDate))
                {
                    continue;
                }
                // do we really need that guess step??? I don't think so...
                //
                var guess = priceableAsset.SurvivalProbabilityAtMaturity;
                if (guess <= cDfamMinThreshold)
                {
                    guess = cDefaultGuess;
                }
                //dates.Add(priceableAsset.GetRiskMaturityDate());
                decimal  dfam;
                double[] values;
                //var position = dates.IndexOf(priceableAsset.GetRiskMaturityDate());
                //discountFactors.CopyTo(values, 0);
                //only works for linear on zero.
                var interp = InterpolationMethodHelper.Parse("LogLinearInterpolation");
                if (index == 0)
                {
                    dates.Add(priceableAsset.GetRiskMaturityDate());
                    values = new double[dates.Count];
                    var position = dates.IndexOf(priceableAsset.GetRiskMaturityDate());
                    discountFactors.CopyTo(values, 0);
                    values[position] = Convert.ToDouble(guess);
                    dfam             = priceableAsset.CalculateImpliedQuote(new SimpleDiscountFactorCurve(baseDate, interp, extrapolationPermitted, dates, values));
                    values[position] = (double)dfam;
                    index++;
                }
                else
                {
                    //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.
                    var tempvalues = new List <double>(discountFactors);
                    dfam = priceableAsset.CalculateImpliedQuote(new SimpleDiscountFactorCurve(baseDate, interp, extrapolationPermitted, dates, tempvalues.ToArray()));
                    tempvalues.Add((double)dfam);
                    dates.Add(priceableAsset.GetRiskMaturityDate());
                    values = new double[dates.Count];
                    tempvalues.CopyTo(values, 0);
                    index++;
                }
                //Add a check on the dfam so that the solver is only called if outside tyhe tolerance.
                var objectiveFunction = new CreditAssetQuote(priceableAsset, baseDate, interpolationMethod,
                                                             extrapolationPermitted, dates, values, tolerance);
                if (objectiveFunction.InitialValue())
                {
                    discountFactors.Add((double)dfam);
                }
                else
                {
                    var timeInterval         = Actual365.Instance.YearFraction(baseDate, assetMaturityDate);
                    var cSolveInterval       = Math.Exp(-cSolveRateGap * timeInterval);
                    var min                  = Math.Max(0, (double)dfam * cSolveInterval);
                    var max                  = (double)dfam / cSolveInterval;
                    var solver2              = new Brent();
                    var solvedFiscountFactor = solver2.Solve(objectiveFunction, accuracy, (double)dfam, min, max);
                    //TODO check that this is the correct usage of the optimizer.
                    discountFactors.Add(solvedFiscountFactor);
                }
            }
            return(TermPointsFactory.Create(dates, discountFactors));
        }