/// <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.");
 }
        /// <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>
        /// 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);
        }