/// <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> /// A method to generate values for the fast lookup grid /// This is a fire once method /// </summary> private void Populate() { _grid = new Dictionary <SABRKey, GridParameters>(new SABRKey()); foreach (var point in dataPoints.point) { var key = new SABRKey(((Period)point.coordinate[0].expiration[0].Items[0]).ToString(), ((Period)point.coordinate[0].term[0].Items[0]).ToString()); if (!_grid.ContainsKey(key)) { _grid.Add(key, new GridParameters()); } var param = _grid[key]; if (point.measureType.Value == ParameterType.Beta.ToString()) { param.Beta = point.value; } else if (point.measureType.Value == ParameterType.Nu.ToString()) { param.Nu = point.value; } else if (point.measureType.Value == ParameterType.Rho.ToString()) { param.Rho = point.value; } _grid[key] = param; } }
public void ExpiryTest() { SABRKey target = new SABRKey(_expiry, _tenor); string actual; actual = target.Expiry; Assert.AreEqual("6m", actual); }
public void TenorTest() { SABRKey target = new SABRKey(_expiry, _tenor); string actual; actual = target.Tenor; Assert.AreEqual("3yr", actual); }
public void ExpiryAsDoubleTest() { SABRKey target = new SABRKey(_expiry, _tenor); decimal actual = target.ExpiryAsDecimal; Assert.AreEqual(0.5m, actual); }
public void SABRKeyConstructorTest1() { string expiry = _expiry; SABRKey target = new SABRKey(expiry); string expected = _expiry; Assert.AreEqual(expected, target.Expiry); Assert.AreEqual("ATM", target.Tenor); }
public void SABRKeyConstructorTest() { string expiry = _expiry; string tenor = _tenor; SABRKey target = new SABRKey(expiry, tenor); Assert.AreEqual(expiry, target.Expiry); Assert.AreEqual(tenor, target.Tenor); }
public void GetHashCodeTest() { SABRKey target = new SABRKey(); SABRKey obj = target; int expected = obj.GetHashCode(); int actual; actual = target.GetHashCode(obj); Assert.AreEqual(expected, actual); }
public void EqualsTest() { string expiry = "2y"; string tenor = "5y"; string expiry1 = "6m"; string tenor1 = "1y"; SABRKey target = new SABRKey(); // TODO: Initialize to an appropriate value bool expected = true; bool actual; // test ATM keys SABRKey x = new SABRKey(expiry); SABRKey y = new SABRKey(expiry); actual = target.Equals(x, y); Assert.AreEqual(expected, actual); // x will remain constant x = new SABRKey(expiry, tenor); // test full keys y = new SABRKey(expiry, tenor); actual = target.Equals(x, y); Assert.AreEqual(expected, actual); // Each equality test should return false expected = false; // test keys with differing tenors y = new SABRKey(expiry, tenor1); actual = target.Equals(x, y); Assert.AreEqual(expected, actual); // test keys with differing expiries y = new SABRKey(expiry1, tenor); actual = target.Equals(x, y); Assert.AreEqual(expected, actual); // test keys with differing tenors/expiries y = new SABRKey(expiry1, tenor1); actual = target.Equals(x, y); Assert.AreEqual(expected, actual); // test ATM keys with differing expiry x = new SABRKey(expiry); y = new SABRKey(expiry1); actual = target.Equals(x, y); Assert.AreEqual(expected, actual); }
/// <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> /// 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="strikes">The strikes to calculate Volatility for</param> /// <returns></returns> public decimal[] SABRInterpolateVolatilities(string engineHandle, string exerciseTime, string assetCode, decimal[] strikes) { // Only process if the engine object holder holds the engine for this exercise/asset key if (!_sabrEngines.ContainsKey(engineHandle)) { throw new System.Exception("Calibration Engine " + engineHandle + " not found."); } // Extract the information we need from this engine holder SortedDictionary <SABRKey, SABRCalibrationEngine> engine = _sabrEngines[engineHandle]; var key = new SABRKey(GenerateTenorLabel(exerciseTime), GenerateTenorLabel(assetCode)); // Check that the engine for this exercise/asset key exists if (!engine.ContainsKey(key)) { throw new System.Exception("The Calibration Engine with Key(" + exerciseTime + "," + assetCode + ") not found."); } 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 expiry = GenerateDayValue(exerciseTime, 365.0m); // build an ImpliedVolatility object SABRParameters parameters = calibrationEngine.GetSABRParameters; var vol = new SABRImpliedVolatility(parameters, true); // value the strike (interpolate as necessary) var results = new List <decimal>(strikes.Length); foreach (decimal strike in strikes) { string errmsg = ""; decimal result = 0; if (!vol.SABRInterpolatedVolatility(assetPrice, expiry, strike, ref errmsg, ref result, true)) { throw new System.Exception(errmsg); } results.Add(result); } return(results.ToArray()); }
/// <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."); }
/// <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> /// 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 CalibrationError(string engine, string expiry, string tenor) { if (!_sabrEngines.ContainsKey(engine)) { throw new InvalidOperationException("Calibration Engine " + engine + " not found."); } SortedDictionary <SABRKey, SABRCalibrationEngine> engines = _sabrEngines[engine]; var key = new SABRKey(GenerateTenorLabel(expiry), GenerateTenorLabel(tenor)); if (!engines.ContainsKey(key)) { throw new InvalidOperationException("The Calibration Engine with Key(" + expiry + "," + tenor + ") not found."); } SABRCalibrationEngine calibrationEngine = engines[key]; return(calibrationEngine.CalibrationError); }
/// <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 CompareTest() { string expiryLess = "1yr"; string expiry = "3yr"; string expiryGreater = "5yr"; string tenorLess = "6mth"; string tenor = "1yr"; string tenorGreater = "3yr"; SABRKey target = new SABRKey(); // TODO: Initialize to an appropriate value SABRKey x = new SABRKey(expiry, tenor); // Equal tests int expected = 0; // Test that the Expiry/tenor pairs are equal SABRKey y = new SABRKey(expiry, tenor); int actual = target.Compare(x, y); Assert.AreEqual(expected, actual); // Test that the Expiry values (x is the target) expected = -1; y = new SABRKey(expiryGreater, tenor); actual = target.Compare(x, y); Assert.AreEqual(expected, actual); expected = 1; y = new SABRKey(expiryLess, tenor); actual = target.Compare(x, y); Assert.AreEqual(expected, actual); // Test that the Tenor values (x is the target) expected = -1; y = new SABRKey(expiry, tenorGreater); actual = target.Compare(x, y); Assert.AreEqual(expected, actual); expected = 1; y = new SABRKey(expiry, tenorLess); actual = target.Compare(x, y); Assert.AreEqual(expected, actual); }
/// <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> /// 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 SortedDictionary <SABRKey, SABRCalibrationEngine> BuildEngineCollection(SABRCalibrationSettings settings, string calibrationEngineId, ref SortedDictionary <SABRKey, SABRCalibrationEngine> engines, decimal atmVolatility, decimal assetPrice, string optionExpiry, string tenor) { var engineCollection = new SortedDictionary <SABRKey, SABRCalibrationEngine>(new SABRKey()); decimal exerciseTime = GenerateDayValue(optionExpiry, 365.0m); decimal indexTenor = GenerateDayValue(tenor, 365.0m); // Create a new instance of the engine //(string handle, SABRCalibrationSettings calibrationSettings, 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> /// 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"); } }
public void SABRKeyConstructorTest2() { SABRKey target = new SABRKey(); Assert.IsNotNull(target); }