/// <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); }
private static string SabrCalibrationSettings(string swaption) { const string instrumentType = "Swaption"; const string currency = "AUD"; const double beta = 1; return(SABRHelper.AddSabrCalibrationSettings(swaption, instrumentType, currency, beta)); }
public void SabrInterpolateVolatilityTest() { const string expiry = "3m"; const string tenor = "0.25y"; string handle = SabrAtmCalibrationWithTenor(); const double strike = 2; double actual = (double)SABRHelper.SabrImpliedVolatility(handle, expiry, tenor, strike); const double expected = 0.31687; Assert.AreEqual(expected, actual, 0.00001); }
public void SabrInterpolateVolatilitiesTest() { const string expiry = "3m"; const string tenor = "0.25y"; string handle = SabrAtmCalibrationWithTenor(); double[] strikes = { 0.02, 0.03 }; decimal[] actuals = SABRHelper.SabrInterpolateVolatilities(handle, expiry, tenor, strikes); const double expected = 0.31687; Assert.AreEqual(expected, (double)actuals[0], 0.00001); }
public void SabrInterpolateVolatilityLegacyInputsTest() { const string calibrationHandle = "SABR Full Settings 20y1y"; const string calibrationInstrument = "Swaption"; const string calibrationCurrency = "AUD"; const double beta = 1; string result = SABRHelper.AddSabrCalibrationSettings(calibrationHandle, calibrationInstrument, calibrationCurrency, beta); Assert.AreEqual(calibrationHandle, result); object[,] vols = { { "Swap Tenor", "ATM - 193.810720549067", "ATM - 93.8107205490671", "ATM - 43.8107205490671", "ATM - 18.8107205490671", "ATM", "ATM + 6.18927945093288", "ATM + 31.1892794509329", "ATM + 56.1892794509329", "ATM + 106.189279450933", "ATM + 206.189279450933" }, { "1y", 18.55, 16.32, 15.60, 15.35, 15.20, 15.16, 15.01, 14.91, 14.80, 14.83 } }; object[,] assets = { { null, null, null, null, null, null, null, null, null, null, null, null, null, null, null }, { "Option Expiry", 1d, 2d, 3d, 4d, 5d, 6d, 7d, 8d, 9d, 10d, 12d, 15d, 20d, 30d }, { "0m", 7.23, 7.10, 7.12, 7.16, 7.15, 7.13, 7.12, 7.11, 7.11, 7.10, 7.10, 7.00, 7.00, 7.00 }, { "1m", 7.23, 7.10, 7.12, 7.16, 7.15, 7.13, 7.12, 7.11, 7.11, 7.10, 7.10, 7.00, 7.00, 7.00 }, { "2m", 7.23, 7.10, 7.12, 7.16, 7.15, 7.13, 7.12, 7.11, 7.11, 7.10, 7.10, 7.00, 7.00, 7.00 }, { "3m", 7.23, 7.10, 7.12, 7.16, 7.15, 7.13, 7.12, 7.11, 7.11, 7.10, 7.10, 7.00, 7.00, 7.00 }, { "6m", 7.23, 7.10, 7.12, 7.16, 7.15, 7.13, 7.12, 7.11, 7.11, 7.10, 7.10, 7.00, 7.00, 7.00 }, { "1y", 7.01, 7.01, 7.08, 7.11, 7.11, 7.09, 7.09, 7.08, 7.08, 7.06, 7.06, 6.97, 6.97, 6.97 }, { "2y", 7.00, 7.10, 7.09, 7.12, 7.10, 7.10, 7.09, 7.08, 7.07, 7.05, 7.05, 6.92, 6.92, 6.92 }, { "3y", 7.21, 7.13, 7.10, 7.12, 7.11, 7.10, 7.09, 7.07, 7.05, 7.02, 7.02, 6.87, 6.87, 6.87 }, { "4y", 7.02, 7.03, 7.01, 7.06, 7.06, 7.05, 7.03, 7.01, 6.98, 6.96, 6.96, 6.79, 6.79, 6.79 }, { "5y", 7.01, 7.00, 7.01, 7.05, 7.04, 7.02, 7.00, 6.97, 6.94, 6.92, 6.92, 6.71, 6.71, 6.71 }, { "6y", 7.01, 7.00, 7.01, 7.05, 7.04, 7.02, 7.00, 6.97, 6.94, 6.92, 6.92, 6.71, 6.71, 6.71 }, { "7y", 7.02, 7.01, 7.00, 7.01, 6.97, 6.94, 6.91, 6.87, 6.82, 6.78, 6.92, 6.50, 6.71, 6.71 }, { "8y", 6.71, 6.71, 6.71, 6.71, 6.71, 6.71, 6.71, 6.71, 6.71, 6.71, 6.92, 6.71, 6.71, 6.71 }, { "9y", 6.71, 6.71, 6.71, 6.71, 6.71, 6.71, 6.71, 6.71, 6.71, 6.71, 6.92, 6.71, 6.71, 6.71 }, { "10y", 6.83, 6.79, 6.76, 6.77, 6.74, 6.68, 6.62, 6.56, 6.50, 6.45, 6.92, 6.08, 6.71, 6.71 }, { "12y", 6.69, 6.65, 6.61, 6.58, 6.51, 6.45, 6.38, 6.31, 6.22, 6.14, 6.92, 5.78, 6.71, 6.71 }, { "15y", 6.26, 6.23, 6.16, 6.12, 6.04, 5.94, 5.84, 5.75, 5.67, 5.59, 6.92, 5.25, 6.71, 6.71 }, { "20y", 6.71, 6.71, 6.71, 6.71, 6.71, 6.71, 6.71, 6.71, 6.71, 6.71, 6.71, 6.71, 6.71, 6.71 }, { "30y", 6.71, 6.71, 6.71, 6.71, 6.71, 6.71, 6.71, 6.71, 6.71, 6.71, 6.71, 6.71, 6.71, 6.71 }, }; const string expiry = "20y"; const string tenor = "1y"; const string engineHandle = "Full Calibration 20y1y"; const double strike = 7; string handle2 = SABRHelper.CalibrateSabrModel(engineHandle, calibrationHandle, vols, assets, expiry); decimal actual = SABRHelper.SabrImpliedVolatility(handle2, expiry, tenor, strike); const double expected = 0.149766076068191;// 0.14976614 Assert.AreEqual(expected, (double)actual, 0.00000001); }
private static string SabrAtmCalibrationWithTenor() { const string expiry = "3m"; const string tenor = "0.25y"; const string swaption = "VOLGRID " + expiry + tenor; const double atmVolatility = 20; const double assetPrice = 3.44; const double nu = 0.7561; const double rho = -0.3702; string handle = Handle(expiry, tenor); SabrCalibrationSettings(swaption); return(SABRHelper.CalibrateSabrAtmModelWithTenor(handle, swaption, nu, rho, atmVolatility, assetPrice, expiry, tenor)); }
/// <summary> /// Get the Calibration status for the calibration engine using /// the expiry/tenor pair /// </summary> /// <param name="engine">The calibration engine handle</param> /// <param name="expiry">The exercise time of the option</param> /// <param name="tenor">The asset Code of the swap (tenor)</param> /// <returns></returns> public bool IsSABRModelCalibrated(string engine, string expiry, string tenor) { if (_sabrEngines.ContainsKey(engine)) { //SABREngineCollection SABREngines = _SABREngines[engine]; SortedDictionary <SABRKey, SABRCalibrationEngine> sabrEngines = _sabrEngines[engine]; var key = new SABRKey(SABRHelper.GenerateTenorLabel(expiry), SABRHelper.GenerateTenorLabel(tenor)); if (sabrEngines.ContainsKey(key)) { SABRCalibrationEngine calibrationEngine = sabrEngines[key]; return(calibrationEngine.IsSABRModelCalibrated); } } return(false); }
/// <summary> /// Get the Calibration Engine Calibration Error the expiry/tenor pair /// </summary> /// <param name="engine">The calibration engine handle</param> /// <param name="expiry">The exercise time of the option</param> /// <param name="tenor">The asset Code of the swap (tenor)</param> /// <returns></returns> public decimal SABRCalibrationError(string engine, string expiry, string tenor) { if (_sabrEngines.ContainsKey(engine)) { //SABREngineCollection SABREngines = _SABREngines[engine]; SortedDictionary <SABRKey, SABRCalibrationEngine> sabrEngines = _sabrEngines[engine]; var key = new SABRKey(SABRHelper.GenerateTenorLabel(expiry), SABRHelper.GenerateTenorLabel(tenor)); if (sabrEngines.ContainsKey(key)) { SABRCalibrationEngine calibrationEngine = sabrEngines[key]; return(calibrationEngine.CalibrationError); } throw new ArgumentException("The Calibration Engine with Key(" + expiry + "," + tenor + ") not found."); } throw new ArgumentException("Calibration Engine " + engine + " not found."); }
public void SabrInterpolateVolatilityStandardInputsTest2() { const string calibrationHandle = "SABR Full Settings 6m1y"; const string calibrationInstrument = "Swaption"; const string calibrationCurrency = "AUD"; const double beta = 1; object[,] vols = { { "Swap Tenor", "ATM - 199.054193939524", "ATM - 99.0541939395239", "ATM - 49.0541939395239", "ATM - 24.0541939395239", "ATM", "ATM + 0.945806060476073", "ATM + 25.9458060604761", "ATM + 50.9458060604761", "ATM + 100.945806060476", "ATM + 200.945806060476" }, { "1y", 39.10, 33.00, 31.10, 30.43, 29.93, 29.91, 29.50, 29.21, 28.96, 29.28 } }; object[,] assets = { { "Option Expiry", 1d, 2d, 3d, 4d, 5d, 6d, 7d, 8d, 9d, 10d }, { "0m", 7.23, 7.10, 7.12, 7.16, 7.15, 7.13, 7.12, 7.11, 7.11, 7.10 }, { "1m", 7.23, 7.10, 7.12, 7.16, 7.15, 7.13, 7.12, 7.11, 7.11, 7.10 }, { "2m", 7.23, 7.10, 7.12, 7.16, 7.15, 7.13, 7.12, 7.11, 7.11, 7.10 }, { "3m", 7.23, 7.10, 7.12, 7.16, 7.15, 7.13, 7.12, 7.11, 7.11, 7.10 }, { "6m", 7.23, 7.10, 7.12, 7.16, 7.15, 7.13, 7.12, 7.11, 7.11, 7.10 }, { "1y", 7.01, 7.01, 7.08, 7.11, 7.11, 7.09, 7.09, 7.08, 7.08, 7.06 }, { "2y", 7.00, 7.10, 7.09, 7.12, 7.10, 7.10, 7.09, 7.08, 7.07, 7.05 }, { "3y", 7.21, 7.13, 7.10, 7.12, 7.11, 7.10, 7.09, 7.07, 7.05, 7.02 }, { "4y", 7.02, 7.03, 7.01, 7.06, 7.06, 7.05, 7.03, 7.01, 6.98, 6.96 }, { "5y", 7.01, 7.00, 7.01, 7.05, 7.04, 7.02, 7.00, 6.97, 6.94, 6.92 }, { "6y", 7.01, 7.00, 7.01, 7.05, 7.04, 7.02, 7.00, 6.97, 6.94, 6.92 }, { "7y", 7.02, 7.01, 7.00, 7.01, 6.97, 6.94, 6.91, 6.87, 6.82, 6.78 }, { "8y", 6.71, 6.71, 6.71, 6.71, 6.71, 6.71, 6.71, 6.71, 6.71, 6.71 }, { "9y", 6.71, 6.71, 6.71, 6.71, 6.71, 6.71, 6.71, 6.71, 6.71, 6.71 }, { "10y", 6.83, 6.79, 6.76, 6.77, 6.74, 6.68, 6.62, 6.56, 6.50, 6.45 }, }; const string expiry = "6m"; const string tenor = "1y"; const string engineHandle = "Full Calibration 6m1y"; const double strike = 2.5; string result = SABRHelper.AddSabrCalibrationSettings(calibrationHandle, calibrationInstrument, calibrationCurrency, beta); Assert.AreEqual(calibrationHandle, result); string handle2 = SABRHelper.CalibrateSabrModel(engineHandle, calibrationHandle, vols, assets, expiry); Assert.AreEqual(engineHandle, handle2); decimal actual = SABRHelper.SabrImpliedVolatility(handle2, expiry, tenor, strike); Assert.AreEqual(0.6210, (double)actual, 0.0001); }
/// <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); }
public void SabrInterpolateVolatilityTest2() { const string expiry = "6m"; const double strike = 0.03; const double assetCode = 5.0587; const double nu = 0.9211; const double rho = -0.2823; const double atmVol = 23.18; const string tenor = "1y"; const string handle = "6m1y ATM VOLGRID Calibration"; string swaption = SABRHelper.AddSabrCalibrationSettings("VOLGRID 6m1y", "Swaption", "AUD", 1); string handle2 = SABRHelper.CalibrateSabrAtmModelWithTenor(handle, swaption, nu, rho, atmVol, assetCode, expiry, tenor); decimal actual = SABRHelper.SabrImpliedVolatility(handle2, expiry, tenor, strike); const double expected = 1.3829; Assert.AreEqual(expected, (double)actual, 0.0001); }
/// <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); }
/// <summary> /// Get the SABR Calibration engine parameter for the provided options /// The exercise/tenor pair form the key to the correct calibration engine /// from an underlying store. /// </summary> /// <param name="param">The parameter type to return</param> /// <param name="engine">The engine to use</param> /// <param name="pExercise">The exercise (option expiry) part of the key</param> /// <param name="pTenor">The tenor (asset code) part of the key</param> /// <returns></returns> public decimal GetSABRParameter(CalibrationParameter param, string engine, string pExercise, string pTenor) { string exercise = SABRHelper.GenerateTenorLabel(pExercise); string tenor = SABRHelper.GenerateTenorLabel(pTenor); if (!_sabrEngines.ContainsKey(engine)) { throw new ArgumentException("Calibration Engine " + engine + " not found."); } SortedDictionary <SABRKey, SABRCalibrationEngine> sabrEngines = _sabrEngines[engine]; var key = new SABRKey(exercise, tenor); if (!sabrEngines.ContainsKey(key)) { throw new ArgumentException("The Calibration Engine with Key(" + exercise + "," + tenor + ") not found."); } SABRCalibrationEngine calibrationEngine = sabrEngines[key]; SABRParameters parameters = calibrationEngine.GetSABRParameters; switch (param) { case CalibrationParameter.Alpha: return(parameters.Alpha); case CalibrationParameter.Beta: return(parameters.Beta); case CalibrationParameter.Nu: return(parameters.Nu); case CalibrationParameter.Rho: return(parameters.Rho); default: throw new ArgumentException("Unknown Calibration Parameter request"); } }
/// <summary> /// Generate a new set of full calibration engines for the supplied data. /// Add or overwrite the engine store for the new engine. /// Each engineId will point to a set of engines indexed by swap tenor and option expiry /// Calibration assumes that the format of the grid data is as follows: /// /// + XXXX | lbl0 | lbl1 | ... | lbln + /// | lbl0 | d[0,0] | d[0,1] | ... | d[0,n] | /// | lbl1 | d[1,0] | d[1,1] | ... | d[1,n] | /// | ... | ... | ... | ... | ... | /// + lbln | d[n,0] | d[n,1] | ... | d[n,n] + /// /// </summary> /// <param name="engineHandle">Calibration Engine handle</param> /// <param name="settingsHandle">Calibartion settings handle</param> /// <param name="strikes">An array of strikes.</param> /// <param name="rawVols">A grid of volatilities (with row/column labels)</param> /// <param name="rawAssets">A grid of asset values</param> /// <param name="assetExpiry">An array of asset expiries.</param> /// <param name="optionEx">The ption expiry to index against</param> /// <param name="tenors">An array of expiry tenors.</param> /// <param name="assetTenors">An array of asset tenors.</param> /// <returns></returns> public string SABRCalibrateModel(string engineHandle, string settingsHandle, String[] tenors, decimal[] strikes, Decimal[,] rawVols, Decimal[,] rawAssets, String[] assetTenors, String[] assetExpiry, string optionEx) { // Create the asset and volatility data grids SwaptionDataMatrix volatilityGrid = ParseVolatilityInput(tenors, strikes, rawVols, optionEx); ForwardRatesMatrix assetGrid = ParseAssetInputWithInterpolation(assetTenors, assetExpiry, rawAssets); // Retrieve the calibration settings to use with this calibration engine SABRCalibrationSettings settings = _sabrSettings[settingsHandle]; // Generate the CalibrationEngine Id string calibrationEngineId = engineHandle; string optionExpiry = SABRHelper.GenerateTenorLabel(optionEx); // Create a new engine holder object SortedDictionary <SABRKey, SABRCalibrationEngine> sabrEngine = BuildEngineCollection(volatilityGrid, assetGrid, settings, calibrationEngineId, optionExpiry); // We have an asset grid (forward rates) with this engine type so we should keep it // for future reference (that is during the lifetime of this session) if (_engineRatesGrid.ContainsKey(engineHandle)) { _engineRatesGrid[engineHandle] = assetGrid; } else { _engineRatesGrid.Add(engineHandle, assetGrid); } // Add the SABREngine to the persistent store if (_sabrEngines.ContainsKey(calibrationEngineId)) { _sabrEngines[calibrationEngineId] = sabrEngine; } else { _sabrEngines.Add(calibrationEngineId, sabrEngine); } return(engineHandle); }
/// <summary> /// Generate an ATM (At-The-Money) Swaption Calibration engine using the supplied parameters /// This form of engine creates a single cell engine that does not support asset/volatility grid data. /// </summary> /// <param name="engineHandle">The engine identifier</param> /// <param name="settingsHandle">The settings identifier</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="exerciseTime">Exercise time for the option</param> /// <param name="assetCode">The asset code.</param> /// <returns></returns> public string SABRCalibrateATMModel(string engineHandle, string settingsHandle, decimal nu, decimal rho, decimal atmVolatility, decimal assetPrice, string exerciseTime, string assetCode) { // Create the parameters used in this engine SABRCalibrationSettings settings = _sabrSettings[settingsHandle]; // Create the engine SortedDictionary <SABRKey, SABRCalibrationEngine> sabrEngine = BuildEngineCollection(settings, engineHandle, nu, rho, atmVolatility, assetPrice, SABRHelper.GenerateTenorLabel(exerciseTime), SABRHelper.GenerateTenorLabel(assetCode)); // Add the SABREngine to the persistent store if (_sabrEngines.ContainsKey(engineHandle)) { _sabrEngines[engineHandle] = sabrEngine; } else { _sabrEngines.Add(engineHandle, sabrEngine); } return(engineHandle); }
public void SabrInterpolateVolatilityMultipleTenorsTest() { const string calibrationHandle = "SABR Full 6m Settings"; const string calibrationInstrument = "Swaption"; const string calibrationCurrency = "AUD"; const double beta = 1; string result = SABRHelper.AddSabrCalibrationSettings(calibrationHandle, calibrationInstrument, calibrationCurrency, beta); Assert.AreEqual(calibrationHandle, result); object[,] assets = { { "Option Expiry", "Swap Tenor", 1d, 2d, 3d, 4d, 5d, 7d, 10d }, { "1m", null, 6.8000, 6.8000, 6.8000, 6.8000, 6.8000, 6.7000, 6.6000 }, { "2m", null, 6.8000, 6.8000, 6.8000, 6.8000, 6.8000, 6.7000, 6.6000 }, { "3m", "Years to E", 6.8000, 6.8000, 6.8000, 6.8000, 6.8000, 6.7000, 6.6000 }, { "6m", 0.5, 6.8000, 6.8000, 6.8000, 6.8000, 6.8000, 6.7000, 6.6000 }, { "1yr", 1, 6.8000, 6.8000, 6.9000, 6.9000, 6.8000, 6.7000, 6.6000 }, { "2yr", 2, 6.8500, 6.8000, 6.8000, 6.7750, 6.7000, 6.6000, 6.5500 }, { "3yr", 3, 6.9000, 6.8000, 6.7000, 6.6500, 6.6000, 6.5000, 6.5000 }, { "4yr", 4, 6.7000, 6.6000, 6.5500, 6.5250, 6.5000, 6.4500, 6.4000 }, { "5yr", 5, 6.4000, 6.4000, 6.4000, 6.4000, 6.4000, 6.4000, 6.3000 }, { "7yr", 7, 6.4000, 6.4000, 6.3000, 6.4000, 6.3500, 6.4000, 6.2000 }, { "10yr", 10, 6.4000, 6.4000, 6.3000, 6.4000, 6.3000, 6.4000, 6.1000 }, }; object[,] vols = { { "Swap Tenor", "ATM - 100", "ATM - 75", "ATM - 50", "ATM - 25", "ATM", "ATM + 25", "ATM + 50", "ATM + 75", "ATM + 100" }, { "1yr", 10.50, 10.30, 10.04, 9.87, 9.77, 9.65, 9.61, 9.61, 9.69 }, { "2yr", 10.68, 10.40, 10.16, 10.03, 9.94, 9.83, 9.79, 9.78, 9.83 }, { "3yr", 10.86, 10.60, 10.40, 10.25, 10.14, 10.05, 10.01, 10.01, 10.06 }, { "4yr", 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00 }, { "5yr", 10.82, 10.60, 10.39, 10.26, 10.16, 10.02, 9.99, 10.00, 10.07 }, { "7yr", 10.94, 10.81, 10.56, 10.41, 10.31, 10.15, 10.12, 10.13, 10.20 }, { "10yr", 11.15, 10.92, 10.74, 10.62, 10.52, 10.31, 10.27, 10.29, 10.38 }, }; const string expiry = "6M"; const string tenor = "1y"; const string engineHandle = "Full Calibration 20y1y"; string handle2 = SABRHelper.CalibrateSabrModel(engineHandle, calibrationHandle, vols, assets, expiry); decimal actual = SABRHelper.SabrImpliedVolatility(handle2, expiry, tenor, 5.8); Assert.AreEqual(.1052, (double)actual, 0.0001); actual = SABRHelper.SabrImpliedVolatility(handle2, expiry, tenor, 6.05); Assert.AreEqual(.1027, (double)actual, 0.0001); actual = SABRHelper.SabrImpliedVolatility(handle2, expiry, tenor, 6.3); Assert.AreEqual(.1006, (double)actual, 0.0001); actual = SABRHelper.SabrImpliedVolatility(handle2, expiry, tenor, 6.55); Assert.AreEqual(.0989, (double)actual, 0.0001); actual = SABRHelper.SabrImpliedVolatility(handle2, expiry, tenor, 6.8); Assert.AreEqual(.0977, (double)actual, 0.0001); actual = SABRHelper.SabrImpliedVolatility(handle2, expiry, tenor, 7.05); Assert.AreEqual(.0969, (double)actual, 0.0001); actual = SABRHelper.SabrImpliedVolatility(handle2, expiry, tenor, 7.30); Assert.AreEqual(.0964, (double)actual, 0.0001); actual = SABRHelper.SabrImpliedVolatility(handle2, expiry, tenor, 7.55); Assert.AreEqual(.0963, (double)actual, 0.0001); actual = SABRHelper.SabrImpliedVolatility(handle2, expiry, tenor, 7.80); Assert.AreEqual(.0966, (double)actual, 0.0001); }