/// <summary>
        /// Calculates the specified model data.
        /// </summary>
        /// <param name="modelData">The model data.</param>
        /// <returns></returns>
        public override AssetValuation Calculate(IInstrumentControllerData modelData)
        {
            ModelData = modelData;
            AnalyticModelParameters = null;
            CalculationResults      = null;
            UpdateBucketingInterval(ModelData.ValuationDate, PeriodHelper.Parse(CDefaultBucketingInterval));
            // 1. First derive the analytics to be evaluated via the stream controller model
            // NOTE: These take precendence of the child model metrics
            if (AnalyticsModel == null)
            {
                AnalyticsModel = new SimpleIRSwaptionInstrumentAnalytic();
            }
            var swaptionControllerMetrics = ResolveModelMetrics(AnalyticsModel.Metrics);
            var quotes = ModelData.AssetValuation.quote.ToList();

            if (AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.BreakEvenRate.ToString()) == null)
            {
                var quote = QuotationHelper.Create(0.0m, InstrumentMetrics.BreakEvenRate.ToString(), "DecimalValue");
                quotes.Add(quote);
            }
            if (AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.NPV.ToString()) == null)
            {
                var quote = QuotationHelper.Create(0.0m, InstrumentMetrics.NPV.ToString(), "DecimalValue");
                quotes.Add(quote);
            }
            ModelData.AssetValuation.quote = quotes.ToArray();
            AssetValuation swaptionValuation;

            //Sets the evolution type for calculations.
            Swap.PricingStructureEvolutionType = PricingStructureEvolutionType;
            Swap.BucketedDates = BucketedDates;
            if (PremiumPayments != null)
            {
                foreach (var payment in PremiumPayments)
                {
                    payment.PricingStructureEvolutionType = PricingStructureEvolutionType;
                    payment.BucketedDates = BucketedDates;
                }
            }
            //The assetValuation list.
            var childValuations = new List <AssetValuation>();

            // 2. Now evaluate only the child specific metrics (if any)
            if (PremiumPayments != null)
            {
                var paymentControllers = new List <InstrumentControllerBase>(PremiumPayments);
                childValuations.AddRange(paymentControllers.Select(payment => payment.Calculate(modelData)));
            }
            var swapMetrics = Swap.Calculate(modelData);
            //We assume the fixed leg is always the first leg!
            var fixedLeg      = Swap.GetLegs()[0].Calculate(modelData);
            var breakEvenRate = AssetValuationHelper.GetQuotationByMeasureType(swapMetrics, InstrumentMetrics.BreakEvenRate.ToString()).value;
            var timeToIndex   = (Swap.EffectiveDate - ModelData.ValuationDate).Days / 365.0;
            //This is European only.
            var expiryTime = (ExerciseDates[0] - ModelData.ValuationDate).Days / 365.0;
            IVolatilitySurface indexVolSurface = null;

            if (modelData.MarketEnvironment is ISwapLegEnvironment streamMarket1)
            {
                indexVolSurface = streamMarket1.GetVolatilitySurface();
                indexVolSurface.PricingStructureEvolutionType = PricingStructureEvolutionType;
                VolatilitySurfaceName = indexVolSurface.GetPricingStructureId().UniqueIdentifier;
            }
            else
            {
                if (!string.IsNullOrEmpty(VolatilitySurfaceName))
                {
                    indexVolSurface = (IVolatilitySurface)modelData.MarketEnvironment.GetPricingStructure(VolatilitySurfaceName);
                }
            }
            //Calculate the delta
            var delta = SimpleIRSwaptionInstrumentAnalytic.CalculateOptionDelta(IsCall, breakEvenRate, StrikeRate, expiryTime, timeToIndex, indexVolSurface);

            //Set the multiplier using the delta of the option.
            //Multiplier = delta;?
            Swap.Multiplier = System.Math.Abs(delta);
            //New function that converts the metrics by multiplying be the delta.
            var swapCalculations = Swap.Calculate(modelData);
            //childValuations.Add(swapCalculations);
            var childControllerValuations = AssetValuationHelper.AggregateMetrics(childValuations, new List <string>(Metrics), PaymentCurrencies); // modelData.ValuationDate);
            var streamAccrualFactor       = AssetValuationHelper.GetQuotationByMeasureType(fixedLeg, InstrumentMetrics.AccrualFactor.ToString());  //TODO This is not correct!
            var npv = AssetValuationHelper.GetQuotationByMeasureType(childControllerValuations, InstrumentMetrics.NPV.ToString());

            childValuations.Add(swapCalculations);
            // Child metrics have now been calculated so we can now evaluate the stream model metrics
            if (swaptionControllerMetrics.Count > 0)
            {
                //Get the market data.
                IFxCurve fxCurve = null;
                ISwaptionInstrumentParameters analyticModelParameters = new SwaptionInstrumentParameters
                {
                    IsBought          = IsBasePartyBuyer,
                    IsCall            = IsCall,
                    SwapAccrualFactor = System.Math.Abs(streamAccrualFactor.value),
                    Strike            = StrikeRate,
                    OtherNPV          = npv.value,
                    TimeToExpiry      = (decimal)expiryTime,
                    SwapBreakEvenRate = breakEvenRate,
                    //OtherNPV =
                };
                // Curve Related
                if (modelData.MarketEnvironment is ISwapLegEnvironment streamMarket)
                {
                    analyticModelParameters.VolatilitySurface = indexVolSurface;
                    //Check for currency.
                    if (ModelData.ReportingCurrency != null)
                    {
                        if (ModelData.ReportingCurrency.Value != PaymentCurrencies[0])//This is an interest rate swap and so only has one currency.
                        {
                            fxCurve = streamMarket.GetReportingCurrencyFxCurve();
                            fxCurve.PricingStructureEvolutionType = PricingStructureEvolutionType;
                        }
                    }
                }
                var analyticsModel = new SimpleIRSwaptionInstrumentAnalytic(ModelData.ValuationDate, (decimal)timeToIndex,
                                                                            StrikeRate, fxCurve, indexVolSurface);
                AnalyticsModel          = analyticsModel;
                Volatility              = analyticsModel.Volatility;
                AnalyticModelParameters = analyticModelParameters;
                CalculationResults      = AnalyticsModel.Calculate <ISwaptionInstrumentResults, SwaptionInstrumentResults>(analyticModelParameters, swaptionControllerMetrics.ToArray());
                // Now merge back into the overall stream valuation
                var swapControllerValuation = GetValue(CalculationResults, modelData.ValuationDate);
                //childValuations.Add(swapControllerValuation);
                childControllerValuations = AssetValuationHelper.AggregateMetrics(childValuations, new List <string>(Metrics), PaymentCurrencies);// modelData.ValuationDate);
                swaptionValuation         = AssetValuationHelper.UpdateValuation(swapControllerValuation,
                                                                                 childControllerValuations, ConvertMetrics(swaptionControllerMetrics), new List <string>(Metrics));
                //swaptionValuation = AssetValuationHelper.AggregateMetrics(childValuations, new List<string>(Metrics), modelData.ValuationDate);
            }
            else
            {
                swaptionValuation = childControllerValuations;
            }
            CalculationPerfomedIndicator = true;
            swaptionValuation.id         = Id;
            return(swaptionValuation);
        }