/// <summary> /// Helper function used to set the ATM strike and volatility used in /// the calibration of the SABR engine. /// Preconditions: Methods SetStrikesForSABREngine and /// SetVolatilitiesForSABREngine have been called. /// Post-conditions: data structures that store the strikes and /// volatilities used in the calibration of the SABR engine are each /// expanded by one element and then sorted, and the private field /// _assetPrice is set. /// </summary> /// <param name="logger">The logger.</param> /// <param name="cache">The cache.</param> /// <param name="nameSpace">The clients namespace</param> /// <param name="expiry">Caplet expiry.</param> private void SetATMDataForSABREngine(ILogger logger, ICoreCache cache, string nameSpace, DateTime expiry) { // Set the ATM volatility. var interpType = _capletSmileSettings.ExpiryInterpolationType; var interpObj = new CapletExpiryInterpolatedVolatility (_atmBootstrapEngine, interpType); var volatility = interpObj.ComputeCapletVolatility(expiry); _sabrVolatilities.Add(volatility); _assetPrice = _atmBootstrapEngine.ComputeForwardPrice(logger, cache, nameSpace, expiry); _sabrStrikes.Add(_assetPrice); // Sort the strikes into ascending order, and maintain the // corresponding volatility. var strikeVol = new SortedList <decimal, decimal>(); // temporary container var idx = 0; foreach (var strike in _sabrStrikes) { strikeVol.Add(strike, _sabrVolatilities[idx]); ++idx; } _sabrStrikes = new List <decimal>(); _sabrVolatilities = new List <decimal>(); foreach (var key in strikeVol.Keys) { _sabrStrikes.Add(key); _sabrVolatilities.Add(strikeVol[key]); } }
/// <summary> /// Helper function used to set the volatilities used in the /// calibration of the SABR engine. /// Post-condition: private field _sabrVolatilities is set. /// </summary> /// <param name="expiry">The expiry.</param> private void SetVolatilitiesForSABREngine(DateTime expiry) { _sabrVolatilities = new List <decimal>(); var interpType = _capletSmileSettings.ExpiryInterpolationType; // Retrieve the volatility at the given expiry. foreach (var eng in _fixedStrikeBootstrapEngines) { var obj = new CapletExpiryInterpolatedVolatility(eng, interpType); var volatility = obj.ComputeCapletVolatility(expiry); _sabrVolatilities.Add(volatility); } }
/// <summary> /// Process a CapFloor ATM parvVols structure. /// The process Bootstraps the parVols using the supplied ratecurve /// </summary> /// <param name="logger">The logger</param> /// <param name="cache">The cache.</param> /// <param name="nameSpace"></param> /// <param name="rateCurve"></param> /// <param name="capFloor"></param> /// <returns></returns> private static Market ProcessCapFloorATM(ILogger logger, ICoreCache cache, string nameSpace, Market rateCurve, CapFloorATMMatrix capFloor) { var id = capFloor.id; var expiry = capFloor.GetExpiries(); var vols = capFloor.GetVolatilities(); var mkt = rateCurve; var curve = new SimpleRateCurve(mkt); var discountFactorDates = curve.GetDiscountFactorDates(); var discountFactors = curve.GetDiscountFactors(); var volType = capFloor.GetVolatilityTypes(); var atmVols = new Dictionary <string, decimal>(); var settings = CreateCapFloorProperties(capFloor.GetVolatilitySettings()); // Create an internal matrix object from the raw data var matrix = new CapFloorVolatilityMatrix(id, expiry, volType, vols, null, discountFactorDates, ArrayUtilities.ArrayToDecimal(discountFactors)); // Create an ATM engine from the matrix var engines = CreateEngines(logger, cache, nameSpace, id, matrix, settings); // Add the default interpolation to use const ExpiryInterpolationType volatilityInterpolation = ExpiryInterpolationType.Linear; if (engines != null) { var vol = new CapletExpiryInterpolatedVolatility(engines[0], volatilityInterpolation); // List the values so we can build our ATM vols var keys = ExpiryKeys.Split(','); // Create a calendar to use to modify the date var businessCalendar = settings.GetValue("BusinessCalendar", "AUSY"); var bc = BusinessCenterHelper.ToBusinessCalendar(cache, new[] { businessCalendar }, nameSpace); // Use some logic to get the spot date to use // LPM Spot lag is 2 days (modfollowing) var spotDate = curve.GetSpotDate(); var rollConvention = settings.GetValue("RollConvention", BusinessDayConventionEnum.FOLLOWING); spotDate = spotDate == curve.GetBaseDate() ? bc.Roll(spotDate.Add(new TimeSpan(2, 0, 0, 0)), rollConvention) : spotDate; //// Extract each surface and build an ATM engine therefrom //// Build a list of all possible engines foreach (var key in keys) { // Calculate the volatility for each target key var tv = PeriodHelper.Parse(key); var target = tv.period == PeriodEnum.D ? bc.Roll(spotDate.AddDays(Convert.ToInt32(tv.periodMultiplier)), rollConvention) : bc.Roll(spotDate.AddMonths(Convert.ToInt32(tv.periodMultiplier)), rollConvention); atmVols.Add(key, vol.ComputeCapletVolatility(target)); } } var outputVols = new object[atmVols.Count + 1, 2]; var i = 1; //Expiry 0 outputVols[0, 0] = "Expiry"; outputVols[0, 1] = "0"; foreach (var key in atmVols.Keys) { outputVols[i, 0] = key; outputVols[i, 1] = atmVols[key]; i++; } DateTime buildDateTime = rateCurve.Items1[0].buildDateTime; var volSurface = new VolatilitySurface(outputVols, new VolatilitySurfaceIdentifier(id), curve.BaseDate, buildDateTime); return(CreateMarketDocument(volSurface.GetFpMLData())); }