/// <summary>
        /// The constructor
        /// </summary>
        /// <param name="logger">The logger</param>
        /// <param name="surfaceId">The id to use with this matrix</param>
        /// <param name="nameSpace">The namespace</param>
        /// <param name="expiryTenors">An array of expiry definitions</param>
        /// <paparam name="strike">An array of strike descriptions</paparam>
        /// <param name="strikes">The strike array.</param>
        /// <param name="volSurface">A 2d array of volatilities.
        /// This must be equal to (expiry.Count x (1 &lt;= y &lt;= term.Count) x strike.Count </param>
        /// <param name="cache">The cache</param>
        protected ExpiryTermStrikeVolatilitySurface(ILogger logger, ICoreCache cache, String nameSpace, String[] expiryTenors, Double[] strikes, Double[,] volSurface,
                                                    VolatilitySurfaceIdentifier surfaceId)
        {
            Algorithm = surfaceId.Algorithm;
            PricingStructureIdentifier = surfaceId;
            var holder = new PricingStructureAlgorithmsHolder(logger, cache, nameSpace, surfaceId.PricingStructureType, surfaceId.Algorithm);
            var curveInterpolationMethod = InterpolationMethodHelper.Parse(holder.GetValue("CurveInterpolation"));

            _matrixIndexHelper = new SortedList <ExpiryTenorStrikeKey, int>(new ExpiryTenorStrikeKey());
            var points = ProcessRawSurface(expiryTenors, strikes, volSurface, surfaceId.StrikeQuoteUnits, surfaceId.UnderlyingAssetReference);

            PricingStructure          = CreateVolatilityRepresentation(surfaceId);
            PricingStructureValuation = CreateDataPoints(points, surfaceId);
            var expiries = new double[expiryTenors.Length];
            var index    = 0;

            foreach (var term in expiryTenors)//TODO include business day holidays and roll conventions.
            {
                expiries[index] = PeriodHelper.Parse(term).ToYearFraction();
                index++;
            }
            // Record the row/column sizes of the inputs
            _matrixRowCount = expiryTenors.Length;
            // Columns includes expiry and term (tenor) if it exists.
            _matrixColumnCount = strikes.Length + 1;
            // Generate an interpolator to use
            Interpolator = new VolSurfaceInterpolator(expiries, strikes, new Matrix(volSurface), curveInterpolationMethod, true);
        }
        /// <summary>
        /// Create a surface from an FpML
        /// </summary>
        /// <param name="logger"></param>
        /// <param name="cache"></param>
        /// <param name="nameSpace"></param>
        /// <param name="fpmlData"></param>
        /// <param name="properties"></param>
        public ExpiryTermTenorStrikeVolatilityCube(ILogger logger, ICoreCache cache, String nameSpace, Pair <PricingStructure, PricingStructureValuation> fpmlData, NamedValueSet properties)
        {
            var surfaceId = new VolatilitySurfaceIdentifier(properties);

            Algorithm = surfaceId.Algorithm;
            PricingStructureIdentifier = surfaceId;
            var holder = new PricingStructureAlgorithmsHolder(logger, cache, nameSpace, surfaceId.PricingStructureType, surfaceId.Algorithm);

            Algorithm = "Linear"; //Add as a propert in the id.
            var      curveInterpolationMethod = InterpolationMethodHelper.Parse(holder.GetValue("CurveInterpolation"));
            var      data     = (VolatilityMatrix)fpmlData.Second;
            DateTime baseDate = data.baseDate.Value;

            Interpolator = new VolSurfaceInterpolator(data.dataPoints, curveInterpolationMethod, true, baseDate);
            SetFpMLData(fpmlData);
        }
        /// <summary>
        /// Create a surface from an FpML
        /// </summary>
        /// <param name="logger">The logger.</param>
        /// <param name="cache">The cache.</param>
        /// <param name="nameSpace">The nameSpace</param>
        /// <param name="fpmlData">The data.</param>
        /// <param name="properties">The properties.</param>
        protected ExpiryTermStrikeVolatilitySurface(ILogger logger, ICoreCache cache, String nameSpace, Pair <PricingStructure, PricingStructureValuation> fpmlData, NamedValueSet properties)
        {
            var data = (VolatilityMatrix)fpmlData.Second;

            Algorithm = "Linear";//Add as a property in the id.
            //Creates the property collection. This should be backward compatable with V1.
            var surfaceId = new VolatilitySurfaceIdentifier(properties);

            PricingStructureIdentifier = surfaceId;
            var holder = new PricingStructureAlgorithmsHolder(logger, cache, nameSpace, surfaceId.PricingStructureType, surfaceId.Algorithm);
            var curveInterpolationMethod = InterpolationMethodHelper.Parse(holder.GetValue("CurveInterpolation"));

            Interpolator = new VolSurfaceInterpolator(data.dataPoints, curveInterpolationMethod, true, PricingStructureIdentifier.BaseDate);
            SetFpmlData(fpmlData);
            _matrixIndexHelper = new SortedList <ExpiryTenorStrikeKey, int>(new ExpiryTenorStrikeKey());
            ProcessVolatilityRepresentation();
        }
        /// <summary>
        /// Takes a range of volatilities, an array of tenor expiries and an
        /// array of strikes to create a VolatilitySurface
        /// </summary>
        /// <param name="logger"></param>
        /// <param name="cache"></param>
        /// <param name="nameSpace"></param>
        /// <param name="expiryTenors"></param>
        /// <param name="strikes"></param>
        /// <param name="volSurface"></param>
        /// <param name="surfaceId"></param>
        public ExpiryTermTenorStrikeVolatilityCube(ILogger logger, ICoreCache cache, String nameSpace, String[] expiryTenors, Double[] strikes, Double[,] volSurface,
                                                   VolatilitySurfaceIdentifier surfaceId)
        {
            Algorithm = surfaceId.Algorithm;
            var holder = new PricingStructureAlgorithmsHolder(logger, cache, nameSpace, surfaceId.PricingStructureType, surfaceId.Algorithm);
            var curveInterpolationMethod = InterpolationMethodHelper.Parse(holder.GetValue("CurveInterpolation"));
            var points = ProcessRawSurface(expiryTenors, strikes, volSurface);

            PricingStructure = new VolatilityRepresentation {
                name  = surfaceId.Name,
                id    = surfaceId.Id,
                asset = new AnyAssetReference {
                    href = "Unknown"
                },
            };
            var datapoints = new MultiDimensionalPricingData {
                point = points
            };

            PricingStructureValuation = new VolatilityMatrix
            {
                dataPoints        = datapoints
                , objectReference = new AnyAssetReference {
                    href = PricingStructure.id
                }
                ,
                baseDate = new IdentifiedDate {
                    Value = surfaceId.BaseDate
                }
                , buildDateTime          = DateTime.Now
                , buildDateTimeSpecified = true
            };
            var expiries = new double[expiryTenors.Length];
            var index    = 0;

            foreach (var term in expiryTenors)//TODO include business day holidays and roll conventions.
            {
                expiries[index] = PeriodHelper.Parse(term).ToYearFraction();
                index++;
            }
            // Generate an interpolator to use
            Interpolator = new VolSurfaceInterpolator(expiries, strikes, new Matrix(volSurface), curveInterpolationMethod, true);
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="logger"></param>
        /// <param name="cache"></param>
        /// <param name="nameSpace"></param>
        /// <param name="properties"></param>
        /// <param name="expiries"></param>
        /// <param name="vols"></param>
        /// <param name="inputInstruments"></param>
        /// <param name="inputSwapRates"></param>
        /// <param name="inputBlackVolRates"></param>
        protected ExpiryTermStrikeVolatilitySurface(ILogger logger, ICoreCache cache, String nameSpace, NamedValueSet properties, DateTime[] expiries, double[] vols,
                                                    string[] inputInstruments, double[] inputSwapRates, double[] inputBlackVolRates)
        {
            Algorithm = PropertyHelper.ExtractAlgorithm(properties);
            PricingStructureIdentifier = new VolatilitySurfaceIdentifier(properties);
            var surfaceId    = (VolatilitySurfaceIdentifier)PricingStructureIdentifier;
            var expiryLength = expiries.Length;
            var pointIndex   = 0;
            var points       = new PricingStructurePoint[expiryLength];

            _matrixIndexHelper = new SortedList <ExpiryTenorStrikeKey, int>(new ExpiryTenorStrikeKey());
            for (var expiryIndex = 0; expiryIndex < expiryLength; expiryIndex++)
            {
                // extract the current expiry
                var expiryKeyPart = expiries[expiryIndex];
                var key           = new ExpiryTenorStrikeKey(expiryKeyPart.ToString(CultureInfo.InvariantCulture), 0);
                _matrixIndexHelper.Add(key, pointIndex);
                // Add the value to the points array (dataPoints entry in the matrix)
                var coordinates = new PricingDataPointCoordinate[1];
                coordinates[0] = new PricingDataPointCoordinate {
                    expiration = new TimeDimension[1]
                };
                coordinates[0].expiration[0] = new TimeDimension {
                    Items = new object[] { expiries[expiryIndex] }
                };
                var pt = new PricingStructurePoint
                {
                    value          = (decimal)vols[expiryIndex],
                    valueSpecified = true,
                    coordinate     = coordinates,
                };
                points[pointIndex++] = pt;
            }
            // Record the row/column sizes of the inputs
            _matrixRowCount           = expiries.Length;
            _matrixColumnCount        = 1;
            PricingStructure          = CreateVolatilityRepresentation(surfaceId);
            PricingStructureValuation = CreateDataPoints(points, surfaceId);
            if (inputInstruments != null)
            {
                int inputCount  = inputInstruments.GetUpperBound(0);
                var assetQuotes = new List <BasicAssetValuation>();
                var assetSet    = new List <Asset>();
                var itemsList   = new List <ItemsChoiceType19>();
                for (int i = 0; i <= inputCount; i++)
                {
                    var assetProperties = new PriceableAssetProperties(inputInstruments[i]);
                    assetSet.Add(new SimpleIRSwap {
                        id = inputInstruments[i], term = assetProperties.TermTenor
                    });
                    var rateQuote = BasicQuotationHelper.Create((decimal)inputSwapRates[i], AssetMeasureEnum.MarketQuote, PriceQuoteUnitsEnum.DecimalRate);
                    var volQuote  = BasicQuotationHelper.Create((decimal)inputBlackVolRates[i], AssetMeasureEnum.Volatility, PriceQuoteUnitsEnum.LogNormalVolatility);
                    assetQuotes.Add(new BasicAssetValuation
                    {
                        objectReference = new AnyAssetReference {
                            href = inputInstruments[i]
                        },
                        definitionRef = assetProperties.TermTenor.ToString(),
                        quote         = new[] { rateQuote, volQuote }
                    });
                    itemsList.Add(ItemsChoiceType19.simpleIrSwap);//TODO NOt actually correct.
                }
                var instrumentSet = new InstrumentSet {
                    Items = assetSet.ToArray(), ItemsElementName = itemsList.ToArray()
                };
                ((VolatilityMatrix)PricingStructureValuation).inputs
                    = new QuotedAssetSet {
                    assetQuote = assetQuotes.ToArray(), instrumentSet = instrumentSet
                    };
            }
            // Generate an interpolator to use
            double[] expiryTerms = expiries.Select(a => (surfaceId.BaseDate - a).TotalDays / 365d).ToArray();
            var      holder      = new PricingStructureAlgorithmsHolder(logger, cache, nameSpace, surfaceId.PricingStructureType, surfaceId.Algorithm);
            var      curveInterpolationMethod = InterpolationMethodHelper.Parse(holder.GetValue("CurveInterpolation"));

            Interpolator = new VolSurfaceInterpolator(expiryTerms, new double[] { 1 }, new Matrix(vols), curveInterpolationMethod, true);
        }
        /// <summary>
        /// Takes a range of volatilities, an array of tenor expiries and an
        /// array of strikes to create a VolatilitySurface
        /// </summary>
        /// <param name="logger">The logger.</param>
        /// <param name="cache">The cache.</param>
        /// <param name="nameSpace"></param>
        /// <param name="expiryTenors"></param>
        /// <param name="tenors"></param>
        /// <param name="volSurface"></param>
        /// <param name="surfaceId"></param>
        /// <param name="baseDate"></param>
        /// <param name="algorithm">The algorithm for interpolation.</param>
        protected ExpiryTermTenorATMVolatilitySurface(ILogger logger, ICoreCache cache, String nameSpace, String[] expiryTenors, String[] tenors, Double[,]
                                                      volSurface, VolatilitySurfaceIdentifier surfaceId, DateTime baseDate,
                                                      string algorithm)
        {
            Algorithm = algorithm;
            PricingStructureIdentifier = surfaceId;
            var holder = new PricingStructureAlgorithmsHolder(logger, cache, nameSpace, surfaceId.PricingStructureType, surfaceId.Algorithm);
            var curveInterpolationMethod = InterpolationMethodHelper.Parse(holder.GetValue("CurveInterpolation"));

            _matrixIndexHelper = new SortedList <ExpiryTenorStrikeKey, int>(new ExpiryTenorStrikeKey());
            var points = ProcessRawSurface(expiryTenors, tenors, volSurface, surfaceId.UnderlyingAssetReference);

            PricingStructure = new VolatilityRepresentation
            {
                name     = surfaceId.Name,
                id       = surfaceId.Id,
                currency = surfaceId.Currency,
                asset    = new AnyAssetReference {
                    href = surfaceId.Instrument
                },
            };
            var datapoints = new MultiDimensionalPricingData {
                point = points
            };

            PricingStructureValuation = new VolatilityMatrix
            {
                dataPoints = datapoints
                ,
                objectReference = new AnyAssetReference {
                    href = surfaceId.Instrument
                }
                , baseDate = new IdentifiedDate {
                    Value = baseDate
                }
                , buildDateTime          = DateTime.Now
                , buildDateTimeSpecified = true
            };
            var expiries = new double[expiryTenors.Length];
            var index    = 0;

            foreach (var term in expiryTenors)//TODO include business day holidays and roll conventions.
            {
                expiries[index] = PeriodHelper.Parse(term).ToYearFraction();
                index++;
            }
            var tenor = new double[tenors.Length];

            index = 0;
            foreach (var term in tenors)//TODO include business day holidays and roll conventions.
            {
                tenor[index] = PeriodHelper.Parse(term).ToYearFraction();
                index++;
            }
            // Record the row/column sizes of the inputs
            _matrixRowCount  = expiryTenors.Length;
            _matrixRowCount *= tenors.Length;
            // Columns includes expiry and term (tenor) if it exists.
            _matrixColumnCount = 1;
            // Generate an interpolator to use
            Interpolator = new VolSurfaceInterpolator(expiries, tenor, new Matrix(volSurface), curveInterpolationMethod, true);
        }
        /// <summary>
        /// Takes a range of volatilities, an array of tenor expiries and an
        /// array of strikes to create a VolatilitySurface
        /// </summary>
        /// <param name="logger">The logger.</param>
        /// <param name="cache">The cache.</param>
        /// <param name="expiryTenors">the expiry tenors.</param>
        /// <param name="tenors">The tenors.</param>
        /// <param name="volSurface">The vol surface.</param>
        /// <param name="nameSpace">The namespace</param>
        /// <param name="properties">The properties.</param>
        protected ExpiryTermTenorATMVolatilitySurface(ILogger logger, ICoreCache cache, String nameSpace, NamedValueSet properties, String[] expiryTenors, String[] tenors, Double[,] volSurface)
        {
            Algorithm = PropertyHelper.ExtractAlgorithm(properties);
            PricingStructureIdentifier = new VolatilitySurfaceIdentifier(properties);
            var surfaceId = (VolatilitySurfaceIdentifier)PricingStructureIdentifier;
            var holder    = new PricingStructureAlgorithmsHolder(logger, cache, nameSpace, surfaceId.PricingStructureType, surfaceId.Algorithm);
            var curveInterpolationMethod = InterpolationMethodHelper.Parse(holder.GetValue("CurveInterpolation"));

            _matrixIndexHelper = new SortedList <ExpiryTenorStrikeKey, int>(new ExpiryTenorStrikeKey());
            var points = ProcessRawSurface(expiryTenors, tenors, volSurface, surfaceId.UnderlyingAssetReference);

            PricingStructure = new VolatilityRepresentation
            {
                name     = surfaceId.Name,
                id       = surfaceId.Id,
                currency = surfaceId.Currency,
                asset    = new AnyAssetReference {
                    href = surfaceId.Instrument
                },
            };
            var datapoints = new MultiDimensionalPricingData {
                point             = points,
                businessCenter    = surfaceId.BusinessCenter,
                timing            = surfaceId.QuoteTiming,
                currency          = surfaceId.Currency,
                cashflowType      = surfaceId.CashflowType,
                informationSource = surfaceId.InformationSources,
                measureType       = surfaceId.MeasureType,
                quoteUnits        = surfaceId.QuoteUnits
            };

            if (surfaceId.ExpiryTime != null)
            {
                datapoints.expiryTime          = (DateTime)surfaceId.ExpiryTime;
                datapoints.expiryTimeSpecified = true;
            }
            if (surfaceId.ValuationDate != null)
            {
                datapoints.valuationDate          = (DateTime)surfaceId.ValuationDate;
                datapoints.valuationDateSpecified = true;
            }
            if (surfaceId.Time != null)
            {
                datapoints.time          = (DateTime)surfaceId.Time;
                datapoints.timeSpecified = true;
            }
            if (surfaceId.QuotationSide != null)
            {
                datapoints.side          = (QuotationSideEnum)surfaceId.QuotationSide;
                datapoints.sideSpecified = true;
            }
            PricingStructureValuation = new VolatilityMatrix
            {
                dataPoints      = datapoints,
                objectReference = new AnyAssetReference {
                    href = surfaceId.Instrument
                },
                baseDate = new IdentifiedDate {
                    Value = surfaceId.BaseDate
                },
                buildDateTime          = surfaceId.BuildDateTime,
                buildDateTimeSpecified = true
            };
            var expiries = new double[expiryTenors.Length];
            var index    = 0;

            foreach (var term in expiryTenors)//TODO include business day holidays and roll conventions.
            {
                expiries[index] = PeriodHelper.Parse(term).ToYearFraction();
                index++;
            }
            var tenor = new double[tenors.Length];

            index = 0;
            foreach (var term in tenors)//TODO include business day holidays and roll conventions.
            {
                tenor[index] = PeriodHelper.Parse(term).ToYearFraction();
                index++;
            }
            // Record the row/column sizes of the inputs
            _matrixRowCount  = expiryTenors.Length;
            _matrixRowCount *= tenors.Length;
            // Columns includes expiry and term (tenor) if it exists.
            _matrixColumnCount = 1;
            // Generate an interpolator to use
            Interpolator = new VolSurfaceInterpolator(expiries, tenor, new Matrix(volSurface), curveInterpolationMethod, true);
        }