Example #1
0
        public virtual double CalculateQuoteError()
        {
            var curve        = new SimpleDiscountFactorCurve(BaseDate, InterpolationMethod, Extrapolation, Dfs);
            var impliedQuote = PriceableAsset.CalculateImpliedQuote(curve);

            return((double)(Quote - impliedQuote));
        }
Example #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(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));
        }
Example #3
0
        /// <summary>
        /// Create a series of CapFloor engines from a raw volatility grid and a DF curve
        /// </summary>
        /// <param name="logger">The logger.</param>
        /// <param name="cache">The cache.</param>
        /// <param name="nameSpace">The client namespace</param>
        /// <param name="properties">The properties of the engine, including the reference handle to access this engine collection</param>
        /// <param name="instruments">An array of instrument types.</param>
        /// <param name="rawVolatilityGrid">The raw grid used to build the engines. Assume that all volatility and strike values are 100x true</param>
        /// <param name="dfDataTimeGrid">The discount factor dates array.</param>
        /// <param name="dfGrid">The discount factors required for bootstrapping</param>
        /// <returns>The engine handle or an error message</returns>
        public string CreateCapFloorATMCurve(ILogger logger, ICoreCache cache, string nameSpace, NamedValueSet properties,
                                             String[] instruments, Decimal[] rawVolatilityGrid, DateTime[] dfDataTimeGrid, Decimal[] dfGrid)
        {
            var volatilityCheck = CheckVolatilities(rawVolatilityGrid);

            if (volatilityCheck != null)
            {
                throw new ArgumentException(volatilityCheck);
            }
            var id            = properties.GetString("EngineHandle", true);
            var baseDate      = properties.GetValue <DateTime>("BaseDate", true);
            var valuationDate = properties.GetValue("ValuationDate", DateTime.MinValue);

            if (valuationDate == DateTime.MinValue)
            {
                properties.Set("ValuationDate", baseDate);
            }
            properties.Set("PricingStructureType", PricingStructureTypeEnum.CapVolatilityCurve.ToString());
            var strikeQuoteUnits = properties.GetString("StrikeQuoteUnits", null);

            if (strikeQuoteUnits == null)
            {
                properties.Set("StrikeQuoteUnits", StrikeQuoteUnitsEnum.ATMFlatMoneyness.ToString());
            }
            var measureType = properties.GetString("MeasureType", null);

            if (measureType == null)
            {
                properties.Set("MeasureType", MeasureTypesEnum.Volatility.ToString());
            }
            var quoteUnits = properties.GetString("QuoteUnits", null);

            if (quoteUnits == null)
            {
                properties.Set("QuoteUnits", QuoteUnitsEnum.LogNormalVolatility.ToString());
            }
            var algorithm = properties.GetString("Algorithm", null);

            if (algorithm == null)
            {
                properties.Set("Algorithm", "Default");
            }
            InterpolationMethod interp = InterpolationMethodHelper.Parse("LogLinearInterpolation");
            // Check there are valid strikes
            IRateCurve discountCurve =
                new SimpleDiscountFactorCurve(baseDate, interp, true, dfDataTimeGrid, dfGrid);

            // Create the engines and either add to, or overwrite the existing, collection
            if (_capFloorEngine.ContainsKey(id))
            {
                _capFloorEngine[id] = CreateCurves(logger, cache, nameSpace, properties, discountCurve, discountCurve, instruments, rawVolatilityGrid);
            }
            else
            {
                _capFloorEngine.Add(id, CreateCurves(logger, cache, nameSpace, properties, discountCurve, discountCurve, instruments, rawVolatilityGrid));
            }
            return(id);
        }
        /// <summary>
        /// An inital test to see if the guess was good..
        /// </summary>
        /// <returns></returns>
        public Boolean InitialValue()
        {
            var curve        = new SimpleDiscountFactorCurve(_baseDate, _interpolationMethod, _extrapolation, _dates, _dfs);
            var impliedQuote = _priceableAsset.CalculateImpliedQuote(curve);
            var marketQuote  = MarketQuoteHelper.NormalisePriceUnits(_priceableAsset.MarketQuote, "DecimalRate").value;
            var quoteError   = (double)(marketQuote - impliedQuote);

            return(Math.Abs(quoteError) < _cTolerance);
        }
        static public IMarketEnvironment CreateSimpleInflationCurve(string curveName, DateTime baseDate, Double[] times, Double[] dfs)
        {
            var market       = new MarketEnvironment();
            var interpMethod = InterpolationMethodHelper.Parse("LinearInterpolation");
            var curve        = new SimpleDiscountFactorCurve(baseDate, interpMethod, true, times, dfs);

            market.AddPricingStructure(curveName, curve);
            return(market);
        }
        /// <summary>
        /// Values the specified discount factor.
        /// </summary>
        /// <param name="discountFactor">The discount factor.</param>
        /// <returns></returns>
        public double Value(double discountFactor)
        {
            _dfs[_dfs.Length - 1] = discountFactor;
            var curve        = new SimpleDiscountFactorCurve(_baseDate, _interpolationMethod, _extrapolation, _dates, _dfs);
            var impliedQuote = _priceableAsset.CalculateImpliedQuote(curve);
            var marketQuote  = MarketQuoteHelper.NormalisePriceUnits(_priceableAsset.MarketQuote, "DecimalRate").value;
            var quoteError   = (double)(marketQuote - impliedQuote);

            return(quoteError);
        }
        static public ISimpleRateMarketEnvironment CreateSimpleRateMarketEnvironment(DateTime baseDate, Double[] times, Double[] dfs)
        {
            var market       = new SimpleRateMarketEnvironment();
            var interpMethod = InterpolationMethodHelper.Parse("LogLinearInterpolation");
            var curve        = new SimpleDiscountFactorCurve(baseDate, interpMethod, true, times, dfs);

            market.AddPricingStructure("DiscountCurve", curve);
            market.PricingStructureIdentifier = "DiscountCurve";
            return(market);
        }
        static public ISwapLegEnvironment CreateInterestRateStreamEnvironment(DateTime baseDate, Double[] times, Double[] dfs)
        {
            var market       = new SwapLegEnvironment();
            var interpMethod = InterpolationMethodHelper.Parse("LogLinearInterpolation");
            var curve        = new SimpleDiscountFactorCurve(baseDate, interpMethod, true, times, dfs);

            market.AddPricingStructure("DiscountCurve", curve);
            market.AddPricingStructure("ForecastCurve", curve);
            return(market);
        }
        static public IMarketEnvironment CreateDFandVolCurves(string curveName, string volcurveName, DateTime baseDate, Double[] times, Double[] dfs, Double[] voltimes, Double[] volstrikes, Double[,] vols)
        {
            var market       = new MarketEnvironment();
            var interpMethod = InterpolationMethodHelper.Parse("LinearInterpolation");
            var curve        = new SimpleDiscountFactorCurve(baseDate, interpMethod, true, times, dfs);
            var volcurve     = new SimpleVolatilitySurface(baseDate, interpMethod, true, voltimes, volstrikes, vols);

            market.AddPricingStructure(curveName, curve);
            market.AddPricingStructure(volcurveName, volcurve);
            return(market);
        }
Example #10
0
        private static IRateCurve GetDiscountFactorCurveFromObject(object discountFactorCurveObject, string paramName)
        {
            IRateCurve curve;

            if (discountFactorCurveObject is IRateCurve o)
            {
                curve = o;
            }
            else
            {
                if (discountFactorCurveObject is object[,] array)
                {
                    //  extract from [ , ]
                    //               [ , ]
                    //               [ , ]
                    //               [ , ] array
                    var discountFactorCurveObjectAsArray = array;
                    int dim0LowerBound = (discountFactorCurveObjectAsArray).GetLowerBound(0);
                    int dim1LowerBound = (discountFactorCurveObjectAsArray).GetLowerBound(1);
                    int dim0UpperBound = (discountFactorCurveObjectAsArray).GetUpperBound(0);
                    var listDt         = new List <DateTime>();
                    var listDf         = new List <double>();
                    for (int i = dim0LowerBound; i <= dim0UpperBound; ++i)
                    {
                        var dt = (DateTime)discountFactorCurveObjectAsArray[i, dim1LowerBound];
                        var df = (double)discountFactorCurveObjectAsArray[i, dim1LowerBound + 1];
                        listDt.Add(dt);
                        listDf.Add(df);
                    }

                    DateTime            baseDate = listDt[0];
                    InterpolationMethod interp   = InterpolationMethodHelper.Parse("LinearInterpolation");
                    //SimpleDFToZeroRateCurve curve = new SimpleDFToZeroRateCurve(baseDate, interp, false, dates, dfs);
                    curve = new SimpleDiscountFactorCurve(baseDate, interp, false, listDt.ToArray(), listDf.ToArray());
                }
                else
                {
                    var message = $"{paramName} is invalid";
                    throw new ArgumentException(message, paramName);
                }
            }
            return(curve);
        }
Example #11
0
        /// <summary>
        /// Create a Sortedlist of bootstrap engines from the data matrix
        /// </summary>
        /// <param name="logger">The logger</param>
        /// <param name="cache">The cache.</param>
        /// <param name="nameSpace"></param>
        /// <param name="engineHandle">The engine collection name</param>
        /// <param name="matrix">The internal data structure used in conversion</param>
        /// <param name="properties">The properties object to use</param>
        /// <returns></returns>
        private static SortedList <decimal, CapVolatilityCurve> CreateEngines(ILogger logger, ICoreCache cache,
                                                                              string nameSpace, string engineHandle, CapFloorVolatilityMatrix matrix, NamedValueSet properties)
        {
            var engines = new SortedList <decimal, CapVolatilityCurve>();

            //  Check there is a valid settings object
            if (properties == null)
            {
                return(null);
            }
            var currency = properties.GetString("Currency", true);
            var baseDate = properties.GetValue("Calculation Date", DateTime.MinValue);

            properties.Set("EngineHandle", engineHandle);
            matrix.ValuationDate = baseDate;
            var valuationDate = properties.GetValue("ValuationDate", DateTime.MinValue);

            if (valuationDate == DateTime.MinValue)
            {
                properties.Set("ValuationDate", baseDate);
            }
            properties.Set("PricingStructureType", PricingStructureTypeEnum.CapVolatilityCurve.ToString());
            var strikeQuoteUnits = properties.GetString("StrikeQuoteUnits", null);

            if (strikeQuoteUnits == null)
            {
                properties.Set("StrikeQuoteUnits", StrikeQuoteUnitsEnum.ATMFlatMoneyness.ToString());
            }
            var measureType = properties.GetString("MeasureType", null);

            if (measureType == null)
            {
                properties.Set("MeasureType", MeasureTypesEnum.Volatility.ToString());
            }
            var quoteUnits = properties.GetString("QuoteUnits", null);

            if (quoteUnits == null)
            {
                properties.Set("QuoteUnits", QuoteUnitsEnum.LogNormalVolatility.ToString());
            }
            var algorithm = properties.GetString("Algorithm", null);

            if (algorithm == null)
            {
                properties.Set("Algorithm", "Default");
            }
            InterpolationMethod interp = InterpolationMethodHelper.Parse("LogLinearInterpolation");
            var dfs = matrix.DiscountFactorsAsDoubles();
            // Check there are valid strikes
            IRateCurve discountCurve =
                new SimpleDiscountFactorCurve(baseDate, interp, true, dfs);
            //TODO
            //The quoted asset set
            var volTypes    = matrix.CapVolatilities();
            var instruments = new List <string>();
            var volatilties = new List <decimal>();

            foreach (var volType in volTypes)
            {
                string tempName;
                string tenor;
                var    type = volType.VolatilityType;
                if (type == VolatilityDataType.ETO)
                {
                    tempName = currency + "-Caplet-";
                    tenor    = volType.Expiry + "D-90D";
                }
                else
                {
                    tempName = currency + "-IRCap-";
                    tenor    = volType.Expiry + "Y";
                }
                instruments.Add(tempName + tenor);
                volatilties.Add(volType.Volatility);
            }
            var qas = AssetHelper.Parse(instruments.ToArray(), volatilties.ToArray());
            //The volatilities
            // Create a new ATM CapletBootstrap engine. The default decimal should be 0
            var engine = new CapVolatilityCurve(logger, cache, nameSpace, properties, qas, discountCurve, discountCurve,
                                                null, null);

            // Add engine
            engines.Add(0, engine);
            return(engines);
        }