/// <summary> /// Helper function used by the master function that validates all /// constructor arguments. /// Exceptions: ArgumentNullException, ArgumentException. /// </summary> /// <param name="atmBootstrapEngine">An existing At-the-Money (ATM) /// Caplet bootstrap engine. /// </param> private static void ValidateATMBootstrapEngine (CapVolatilityCurve atmBootstrapEngine) { // Check for a correct engine type. if (atmBootstrapEngine.Equals(null) || !atmBootstrapEngine.IsATMBootstrap) { // Invalid engine type. const string errorMessage = "Invalid engine passed as an ATM Caplet Bootstrap engine"; throw new ArgumentException (errorMessage, nameof(atmBootstrapEngine)); } // Check that the Caplet Bootstrap engine is in a calibrated state. if (atmBootstrapEngine.IsBootstrapSuccessful) { } else { // Engine is not in a calibrated state. const string errorMessage = "ATM Caplet Bootstrap engine is not calibrated"; throw new ArgumentException (errorMessage, nameof(atmBootstrapEngine)); } }
/// <summary> /// Constructor for <see cref="CapletExpiryInterpolatedVolatility"/> /// class. /// </summary> /// <param name="capletBootstrapEngine">The Caplet Bootstrap Engine /// that contains the results of the bootstrap. /// Precondition: IsCapletBootstrapSuccessful method applied to the /// Caplet bootstrap engine returns "true".</param> /// <param name="expiryInterpolationType">Type of one dimensional /// interpolation that will be applied to the expiry.</param> public CapletExpiryInterpolatedVolatility (CapVolatilityCurve capletBootstrapEngine, ExpiryInterpolationType expiryInterpolationType) { ValidateConstructorArguments(capletBootstrapEngine); InitialisePrivateFields (capletBootstrapEngine, expiryInterpolationType); }
/// <summary> /// Master function used to validate all constructor arguments. /// </summary> /// /// <param name="atmBootstrapEngine">An existing At-the-Money (ATM) /// Caplet bootstrap engine. /// </param> /// <param name="capletSmileSettings">An existing Caplet Smile settings /// object that will be used in the calibration of the Caplet smile. /// </param> /// <param name="fixedStrikeBootstrapEngines">List of existing fixed /// strike Caplet bootstrap engines. /// when applied to each Caplet bootstrap engine in the list.</param> /// <param name="handle">Unique name that will identify the object /// that will be instantiated.</param> private static void ValidateConstructorArguments (CapVolatilityCurve atmBootstrapEngine, CapletSmileCalibrationSettings capletSmileSettings, ICollection <CapVolatilityCurve> fixedStrikeBootstrapEngines, string handle) { ValidateATMBootstrapEngine(atmBootstrapEngine); ValidateCapletSmileSettings(capletSmileSettings); ValidateFixedStrikeBootstrapEngines(fixedStrikeBootstrapEngines); ValidateHandle(handle); }
/// <summary> /// Helper function used to initialise the private fields. /// </summary> /// <param name="capletCurve">The Caplet Bootstrap engine /// that contains the results of the bootstrap.</param> /// <param name="expiryInterpolationType">Type of the expiry /// interpolation. /// Example: Linear interpolation.</param> private void InitialisePrivateFields (CapVolatilityCurve capletCurve, ExpiryInterpolationType expiryInterpolationType) { // Initialise the Calculation Date. _calculationDate = capletCurve.GetBaseDate(); // Set the x and y arrays for the one dimensional interpolation. var results = capletCurve.BootstrapResults.Results; IDayCounter dayCountObj = Actual365.Instance; var tempXArray = new List <double>(); var tempYArray = new List <double>(); var count = 1; foreach (var expiry in results.Keys) { var timeToExpiry = dayCountObj.YearFraction (_calculationDate, expiry); tempXArray.Add(timeToExpiry); tempYArray.Add(decimal.ToDouble(results[expiry])); // Record the first and last time to expiry and available // bootstrap Caplet volatility. if (count == 1) { _firstExpiry = (decimal)timeToExpiry; _firstCapletVolatility = results[expiry]; } _lastCapletVolatility = results[expiry]; _lastExpiry = (decimal)timeToExpiry; ++count; } double[] xArray = tempXArray.ToArray(); double[] yArray = tempYArray.ToArray(); // Initialise the one dimensional interpolation object. switch (expiryInterpolationType) { case ExpiryInterpolationType.CubicHermiteSpline: _expiryInterpolationObj = new CubicHermiteSplineInterpolation(); _expiryInterpolationObj.Initialize(xArray, yArray); break; default: // Linear interpolation _expiryInterpolationObj = new LinearInterpolation(); _expiryInterpolationObj.Initialize(xArray, yArray); break; } }
/// <summary> /// Create a Sorted list of bootstrap engines from the data matrix /// </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, including the engine handle.</param> /// <param name="forecastCurve">The forecast rate curve.</param> /// <param name="discountCurve">The discount rate curve.</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> /// <returns></returns> private SortedList <decimal, CapVolatilityCurve> CreateCurves(ILogger logger, ICoreCache cache, string nameSpace, NamedValueSet properties, IRateCurve discountCurve, IRateCurve forecastCurve, String[] instruments, Decimal[] rawVolatilityGrid) { var clonedProperties = properties.Clone(); // Create engine var quotedAssetSet = AssetHelper.Parse(instruments, rawVolatilityGrid, null); var engines = new SortedList <decimal, CapVolatilityCurve>(); // Create a new ATM CapletBootstrap engine. The default decimal should be 0 var engine = new CapVolatilityCurve(logger, cache, nameSpace, clonedProperties, quotedAssetSet, discountCurve, forecastCurve, null, null); // Add engine engines.Add(0, engine); return(engines); }
/// <summary> /// Constructor for the class <see cref="CapletSmileCalibrationEngine"/> /// </summary> /// <param name="atmBootstrapEngine">An existing At-the-Money (ATM) /// Caplet bootstrap engine. /// Precondition: Method IsCapletBootstrapSuccessful returns true. /// </param> /// <param name="capletSmileSettings">An existing Caplet Smile settings /// object that will be used in the calibration of the Caplet smile. /// </param> /// <param name="fixedStrikeBootstrapEngines">List of existing fixed /// strike Caplet bootstrap engines. /// Precondition: Method IsCapletBootstrapSuccessful returns true /// when applied to each Caplet bootstrap engine in the list.</param> /// <param name="handle">Unique name that will identify the object /// that will be instantiated. /// Precondition: Non empty string.</param> public CapletSmileCalibrationEngine (CapVolatilityCurve atmBootstrapEngine, CapletSmileCalibrationSettings capletSmileSettings, List <CapVolatilityCurve> fixedStrikeBootstrapEngines, string handle) { ValidateConstructorArguments (atmBootstrapEngine, capletSmileSettings, fixedStrikeBootstrapEngines, handle); InitialisePrivateFields (atmBootstrapEngine, capletSmileSettings, fixedStrikeBootstrapEngines, handle); }
/// <summary> /// Master function used to initialise all private fields. /// </summary> /// <param name="atmBootstrapEngine">An existing At-the-Money (ATM) /// Caplet bootstrap engine.</param> /// <param name="capletSmileSettings">An existing Caplet Smile settings /// object that will be used in the calibration of the Caplet smile. /// </param> /// <param name="fixedStrikeBootstrapEngines">List of existing fixed /// strike Caplet bootstrap engines.</param> /// <param name="handle">Unique name that will identify the object /// that will be instantiated.</param> private void InitialisePrivateFields (CapVolatilityCurve atmBootstrapEngine, CapletSmileCalibrationSettings capletSmileSettings, List <CapVolatilityCurve> fixedStrikeBootstrapEngines, string handle) { _atmBootstrapEngine = atmBootstrapEngine; _capletSmileSettings = capletSmileSettings; _fixedStrikeBootstrapEngines = fixedStrikeBootstrapEngines; Handle = handle; InitialiseSABRSettings(); // Initialise the remaining private fields to an appropriate // default. _assetPrice = -1.0m; _excerciseTime = -1.0m; _sabrEngine = null; _sabrStrikes = null; _sabrVolatilities = null; }
/// <summary> /// Helper function used to validate the arguments to the constructor. /// Exception: ArgumentException. /// </summary> /// <param name="capletCurve">The Caplet bootstrap engine /// that contains the results of the bootstrap. /// Precondition: IsCapletBootstrapSuccessful method applied to the /// Caplet bootstrap engine returns "true".</param> private static void ValidateConstructorArguments (CapVolatilityCurve capletCurve) { // Check for a valid Caplet Bootstrap Engine. if (capletCurve == null) { const string errorMessage = "Caplet expiry interpolation found a NULL calibration engine"; throw new ArgumentException(errorMessage); } if (capletCurve.IsBootstrapSuccessful) { } else { const string errorMessage = "Caplet expiry interpolation requires a successful bootstrap"; throw new ArgumentException(errorMessage); } }
/// <summary> /// Create a Sorted list of bootstrap engines from the data matrix /// </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, including the engine handle.</param> /// <param name="forecastCurve">The forecast rate curve.</param> /// <param name="discountCurve">The discount rate curve.</param> /// <param name="instruments">An array of instrument types.</param> /// <param name="strikes">The strike array.</param> /// <param name="rawVolatilityGrid">The raw grid used to build the engines. Assume that all volatility and strike values are 100x true</param> /// <returns></returns> private SortedList <decimal, CapVolatilityCurve> CreateCurves(ILogger logger, ICoreCache cache, string nameSpace, NamedValueSet properties, IRateCurve discountCurve, IRateCurve forecastCurve, String[] instruments, Decimal[] strikes, Decimal[,] rawVolatilityGrid) { var clonedProperties = properties.Clone(); // Check there are valid strikes if (strikes != null && rawVolatilityGrid != null) { //The matrix is zero based, but the upper bound returns the last column index. var volColumns = rawVolatilityGrid.GetUpperBound(1) + 1; var columns = Math.Min(strikes.Length, volColumns); var engines = new SortedList <decimal, CapVolatilityCurve>(); // Loop through the strikes to create each new engine for (var i = 0; i < columns; i++) { decimal[] adjustedRates = GenerateVolatilityMatrix(instruments, i, rawVolatilityGrid); clonedProperties.Set("Strike", strikes[i]); clonedProperties.Set("StrikeQuoteUnits", StrikeQuoteUnitsEnum.DecimalRate.ToString()); // Create engine var quotedAssetSet = AssetHelper.Parse(instruments, adjustedRates, null); var engine = new CapVolatilityCurve(logger, cache, nameSpace, clonedProperties, quotedAssetSet, discountCurve, forecastCurve, null, null); // Add engine engines.Add(strikes[i], engine); } return(engines); } { var engines = new SortedList <decimal, CapVolatilityCurve>(); // Create a new ATM CapletBootstrap engine. The default decimal should be 0 var engine = PricingStructureFactory.CreateCurve(logger, cache, nameSpace, null, null, clonedProperties, instruments, null, null) as CapVolatilityCurve; // Add engine engines.Add(0, engine); return(engines); } }
/// <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); }