/// <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> /// Calibrates the SABR engine for the Caplet smile at the particular /// expiry. /// Exception: System.Exception /// </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 CalibrateSABREngine(ILogger logger, ICoreCache cache, string nameSpace, DateTime expiry) { // Set the inputs for the SABR calibration engine. SetStrikesForSABREngine(); SetVolatilitiesForSABREngine(expiry); SetExerciseTimeForSABREngine(expiry); SetATMDataForSABREngine(logger, cache, nameSpace, expiry); // Calibrate the SABR engine. _sabrEngine = new SABRCalibrationEngine (SABREngineHandle, _sabrSettings, _sabrStrikes, _sabrVolatilities, _assetPrice, _excerciseTime); _sabrEngine.CalibrateSABRModel(); // Check the status of the SABR calibration. if (_sabrEngine.IsSABRModelCalibrated) { } else { var errorMessage = "SABR calibration failed at Caplet expiry: " + expiry; throw new Exception(errorMessage); } }
/// <summary> /// Values at. /// </summary> /// <param name="axisValue">The axis value.</param> /// <param name="extrapolation">if set to <c>true</c> [extrapolation].</param> /// <returns></returns> public double ValueAt(double axisValue, bool extrapolation) { string engineHandle = SettingsHandle; decimal time = Convert.ToDecimal(ExpiryTime); const decimal tenor = 0; var calibrationEngine = new SABRCalibrationEngine(engineHandle, CalibrationSettings, EngineHandles, AtmVolatility, AssetPrice, time, tenor ); calibrationEngine.CalibrateInterpSABRModel(); var sabrParameters = new SABRParameters(calibrationEngine.GetSABRParameters.Alpha, calibrationEngine.GetSABRParameters.Beta, calibrationEngine.GetSABRParameters.Nu, calibrationEngine.GetSABRParameters.Rho); var sabrImpliedVol = new SABRImpliedVolatility(sabrParameters, false); var value = Convert.ToDecimal(axisValue) * AssetPrice; string errMsg = "Error interpolating"; decimal result = 0.0m; sabrImpliedVol.SABRInterpolatedVolatility(AssetPrice, time, value, ref errMsg, ref result, true); return(Convert.ToDouble(result)); }
/// <summary> /// Initialises the specified strikes. /// </summary> /// <param name="strikes">The strikes.</param> /// <param name="volatilities">The volatilities.</param> public void Initialize(double[] strikes, double[] volatilities) { // Convert the x-array to the Decimal data type. var strikeValues = new List <decimal>(); InitHandles(ExpiryTime); decimal expiry = Convert.ToDecimal(ExpiryTime); var vols = new List <Decimal>(); int n = volatilities.Length; for (int jdx = 0; jdx < n; jdx++) { if (volatilities[jdx] > 0) { strikeValues.Add((decimal)strikes[jdx] * AssetPrice); vols.Add(Convert.ToDecimal(volatilities[jdx])); } } // Calibrate and cache SABR handle for each expiry. CalibrationEngine = new SABRCalibrationEngine(SettingsHandle, CalibrationSettings, strikeValues, vols, AssetPrice, expiry); CalibrationEngine.CalibrateSABRModel(); string expiryTime = ExpiryTime + "Y"; EngineHandles.Add(new SABRKey(expiryTime, Tenor), CalibrationEngine); IsCalibrated = CalibrationEngine.IsSABRModelCalibrated; }
/// <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); }
public void TestCalibrateATMSABRModel() { // Override some variable set in the SetUp method. _assetPrice = 1352; _exerciseTime = 3.0m; // Initialise information required specifically for an ATM // calibration.. decimal atmVolatility = 0.2884m; decimal nu = 1.23498996m; decimal rho = -0.2724164m; _calibrationEngine = new SABRCalibrationEngine(_engineHandle, _calibrationSettings, nu, rho, atmVolatility, _assetPrice, _exerciseTime); _calibrationEngine.CalibrateATMSABRModel(); // Test: calibration status. Assert.IsTrue(_calibrationEngine.IsSABRModelCalibrated); // Test: SABR parameter alpha. _expected = 0.65869806m; _actual = _calibrationEngine.GetSABRParameters.Alpha; Assert.AreEqual(decimal.ToDouble(_expected), decimal.ToDouble(_actual), decimal.ToDouble(_tolerance)); // Test: SABR parameter beta. _expected = 0.85m; _actual = _calibrationEngine.GetSABRParameters.Beta; Assert.AreEqual(_expected, _actual); // Test: SABR parameter nu. _expected = 1.23498996m; _actual = _calibrationEngine.GetSABRParameters.Nu; Assert.AreEqual(_expected, _actual); // Test: SABR parameter rho. _expected = -0.2724164m; _actual = _calibrationEngine.GetSABRParameters.Rho; Assert.AreEqual(_expected, _actual); }
/// <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); }
/// <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"); } }
// // Use TestInitialize to run code before running each test // [TestInitialize()] // public void MyTestInitialize() { } // // Use TestCleanup to run code after each test has run // [TestCleanup()] // public void MyTestCleanup() { } // #endregion #region Setup public void Initialisation() { // Initialise the SABR calibration settings object. _settingsHandle = "SABR Calibration Engine Unit Test."; _currency = "AUD"; _instrument = InstrumentType.Instrument.CallPut; _beta = 0.85m; //_calibrationError = 0.0m; _calibrationSettings = new SABRCalibrationSettings(_settingsHandle, _instrument, _currency, _beta); // Initialise the SABR calibration engine object. _assetPrice = 1350.00m; _engineHandle = _settingsHandle; _exerciseTime = 5.0m; decimal[] tempStrikes = { 1242.00m, 1269.00m, 1283.00m, 1296.00m, 1323.00m, 1350.00m, 1377.00m, 1404.00m, 1418.00m, 1431.00m, 1458.00m, 1485.00m, 1519.00m }; _strikes = new List <decimal>(); foreach (decimal strike in tempStrikes) { _strikes.Add(strike); } decimal[] tempVolatilities = { 0.3108m, 0.3012m, 0.2966m, 0.2925m, 0.2847m, 0.2784m, 0.2738m, 0.2709m, 0.2700m, 0.2696m, 0.2697m, 0.2710m, 0.2744m }; _volatilities = new List <decimal>(); foreach (decimal volatility in tempVolatilities) { _volatilities.Add(volatility); } _calibrationEngine = new SABRCalibrationEngine(_engineHandle, _calibrationSettings, _strikes, _volatilities, _assetPrice, _exerciseTime); // Initialise the collection of SABR calibration engine objects. //_engineHandles = null; }