/// <summary> /// Create a full calibration model.This version uses the volatility grid to generate an engine /// for each swap tenor (row values) /// </summary> /// <param name="volatilityGrid">The vols grid</param> /// <param name="assetGrid">The asset grid</param> /// <param name="settings">The SABR settings</param> /// <param name="calibrationEngineId">The id of this engine</param> /// <param name="optionExpiry">The ATM pointer</param> private static SortedDictionary <SABRKey, SABRCalibrationEngine> BuildEngineCollection(SwaptionDataMatrix volatilityGrid, ForwardRatesMatrix assetGrid, SABRCalibrationSettings settings, string calibrationEngineId, string optionExpiry) { var engineCollection = new SortedDictionary <SABRKey, SABRCalibrationEngine>(new SABRKey()); // Generate a new entry in the engineCollection for each row in the volatility grid foreach (string tenor in volatilityGrid.GetTenors()) { var assetPrice = assetGrid.GetAssetPrice(optionExpiry, tenor); var exerciseTime = (decimal)SABRHelper.GenerateDayValue(optionExpiry, 365.0d); // Generate the Vols and Strikes lists for the engine List <decimal> vols = volatilityGrid.GetVolatility(tenor).ToList(); List <decimal> strikes = volatilityGrid.GetStrikes().Select(strike => assetPrice + strike).ToList(); // Only add a new Calibration Engine (and Calibrate it) if the vols are greater than 0 if (!SABRHelper.ValidateData(vols)) { continue; } // Create a new instance of the engine var calibrationEngine = new SABRCalibrationEngine(calibrationEngineId, settings, strikes, vols, assetPrice, exerciseTime); // Calibrate the engine calibrationEngine.CalibrateSABRModel(); // Add the new engine to our collection var key = new SABRKey(optionExpiry, tenor); engineCollection.Add(key, calibrationEngine); } return(engineCollection); }
/// <summary> /// Create an Interpolated calibration engine. Such an engine is designed for a single value /// derived from a set of base engines. /// </summary> /// <param name="settings">The settings object to use</param> /// <param name="calibrationEngineId">The id of this engine</param> /// <param name="engines">The array of engine handles to use</param> /// <param name="atmVolatility">The ATM volatility</param> /// <param name="assetPrice">Asset Price to use</param> /// <param name="optionExpiry">The ATM pointer</param> /// <param name="tenor">The tenor to create the new engine for. This must be a valid tenor</param> private static SortedDictionary <SABRKey, SABRCalibrationEngine> BuildEngineCollection(SABRCalibrationSettings settings, string calibrationEngineId, IEnumerable <KeyValuePair <SABRKey, SABRCalibrationEngine> > engines, decimal atmVolatility, decimal assetPrice, string optionExpiry, string tenor) { var engineCollection = new SortedDictionary <SABRKey, SABRCalibrationEngine>(new SABRKey()); var exerciseTime = (decimal)SABRHelper.GenerateDayValue(optionExpiry, 365.0d); var indexTenor = (decimal)SABRHelper.GenerateDayValue(tenor, 365.0d); // Create a new instance of the engine var calibrationEngine = new SABRCalibrationEngine(calibrationEngineId, settings, engines, atmVolatility, assetPrice, exerciseTime, indexTenor); // Calibrate the engine calibrationEngine.CalibrateInterpSABRModel(); // Add the new engine to our collection var key = new SABRKey(optionExpiry, tenor); engineCollection.Add(key, calibrationEngine); return(engineCollection); }
/// <summary> /// Calculate the SABR implied volatility for the strike value. /// This method uses the calibration engine indexed by the exerciseTime/assetCode pair /// When an ATM engine is used then the assetCode is ignored. /// </summary> /// <param name="engineHandle">The CalibrationEngine to use</param> /// <param name="exerciseTime">Option Expiry index</param> /// <param name="assetCode">Swap Tenor index</param> /// <param name="strike">The strike to calculate Volatility for</param> /// <returns></returns> public decimal SABRInterpolateVolatility(string engineHandle, string exerciseTime, string assetCode, decimal strike) { decimal result = 0; string errmsg = ""; // Only process if the engine object holder holds the engine for this exercise/asset key if (_sabrEngines.ContainsKey(engineHandle)) { // Extract the information we need from this engine holder var engine = _sabrEngines[engineHandle]; var key = new SABRKey(SABRHelper.GenerateTenorLabel(exerciseTime), SABRHelper.GenerateTenorLabel(assetCode)); // Check that the engine for this exercise/asset key exists if (engine.ContainsKey(key)) { SABRCalibrationEngine calibrationEngine = engine[key]; if (!calibrationEngine.IsSABRModelCalibrated) { throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, "SABR Engine with key: {0}:{1} is not calibrated", new object[] { key.Expiry, key.Tenor })); } // Create SABRImpliedVolatility parameters decimal assetPrice = _engineRatesGrid.ContainsKey(engineHandle) ? _engineRatesGrid[engineHandle].GetAssetPrice(exerciseTime, assetCode) : calibrationEngine.AssetPrice; decimal strikeValue = strike; var expiry = (decimal)SABRHelper.GenerateDayValue(exerciseTime, 365.0d); //decimal strikeValue = strike / 100.0m; // build an ImpliedVolatility object SABRParameters parameters = calibrationEngine.GetSABRParameters; var vol = new SABRImpliedVolatility(parameters, true); // value the strike (interpolate as necessary) if (!vol.SABRInterpolatedVolatility(assetPrice, expiry, strikeValue, ref errmsg, ref result, true)) { throw new ArgumentException(errmsg); } } else { throw new ArgumentException("The Calibration Engine with Key(" + exerciseTime + "," + assetCode + ") not found."); } } else { throw new ArgumentException("Calibration Engine " + engineHandle + " not found."); } return(result); }
/// <summary> /// Create an ATM calibration engine. Such an engine is designed for a single value /// </summary> /// <param name="settings">The settings object to use</param> /// <param name="calibrationEngineId">The id of this engine</param> /// <param name="nu">Nu value</param> /// <param name="rho">Rho value</param> /// <param name="atmVolatility">The ATM volatility</param> /// <param name="assetPrice">Asset Price to use</param> /// <param name="optionExpiry">The ATM pointer</param> /// <param name="assetCode">The ATM identifiier (if used)</param> private static SortedDictionary <SABRKey, SABRCalibrationEngine> BuildEngineCollection(SABRCalibrationSettings settings, string calibrationEngineId, decimal nu, decimal rho, decimal atmVolatility, decimal assetPrice, string optionExpiry, string assetCode) { // basic setup var engineCollection = new SortedDictionary <SABRKey, SABRCalibrationEngine>(new SABRKey()); var exerciseTime = (decimal)SABRHelper.GenerateDayValue(optionExpiry, 365.0d); // Create a new instance of the engine var calibrationEngine = new SABRCalibrationEngine(calibrationEngineId, settings, nu, rho, atmVolatility, assetPrice, exerciseTime); // Calibrate the engine calibrationEngine.CalibrateATMSABRModel(); // Add the new engine to our collection SABRKey key = assetCode != null ? new SABRKey(optionExpiry, assetCode) : new SABRKey(optionExpiry); engineCollection.Add(key, calibrationEngine); return(engineCollection); }