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 precedence of the child model metrics
            if (AnalyticsModel == null)
            {
                AnalyticsModel = new BondStreamAnalytic();
            }
            var            streamControllerMetrics = ResolveModelMetrics(AnalyticsModel.Metrics);
            AssetValuation streamValuation;

            // 2. Now evaluate only the child specific metrics (if any)
            foreach (var coupon in Coupons)
            {
                coupon.PricingStructureEvolutionType = PricingStructureEvolutionType;
                coupon.BucketedDates = BucketedDates;
                coupon.Multiplier    = Multiplier;
            }
            var childControllers = new List <InstrumentControllerBase>(Coupons.ToArray());
            //Now the stream analytics can be completed.
            var childValuations           = EvaluateChildMetrics(childControllers, modelData, Metrics);
            var couponValuation           = AssetValuationHelper.AggregateMetrics(childValuations, new List <string>(Metrics), PaymentCurrencies);
            var childControllerValuations = new List <AssetValuation> {
                couponValuation
            };

            // Child metrics have now been calculated so we can now evaluate the stream model metrics
            if (streamControllerMetrics.Count > 0)
            {
                var reportingCurrency = ModelData.ReportingCurrency == null ? Currency : ModelData.ReportingCurrency.Value;
                var notionals         = GetCouponNotionals();
                var accrualFactors    = GetCouponAccrualFactors();
                var discountFactors   = GetPaymentDiscountFactors();
                var floatingNPV       = AggregateMetric(InstrumentMetrics.FloatingNPV, childControllerValuations);
                var accrualFactor     = AggregateMetric(InstrumentMetrics.AccrualFactor, childControllerValuations);
                //TODO need to  set the notional amount and the weighting. Also amortisation??
                IBondStreamParameters analyticModelParameters = new BondStreamParameters
                {
                    Multiplier        = Multiplier,
                    CouponNotionals   = notionals,
                    Currency          = Currency,
                    ReportingCurrency = reportingCurrency,
                    AccrualFactor     = accrualFactor,
                    FloatingNPV       = floatingNPV,
                    NPV = AggregateMetric(InstrumentMetrics.NPV, childControllerValuations),
                    CouponYearFractions    = accrualFactors,
                    PaymentDiscountFactors = discountFactors,
                    TargetNPV = floatingNPV
                };
                CalculationResults = AnalyticsModel.Calculate <IBondStreamInstrumentResults, BondStreamInstrumentResults>(analyticModelParameters, streamControllerMetrics.ToArray());
                // Now merge back into the overall stream valuation
                var streamControllerValuation = GetValue(CalculationResults, modelData.ValuationDate);
                streamValuation = AssetValuationHelper.UpdateValuation(streamControllerValuation,
                                                                       childControllerValuations, ConvertMetrics(streamControllerMetrics), new List <string>(Metrics), PaymentCurrencies);
                AnalyticModelParameters = analyticModelParameters;
            }
            else
            {
                streamValuation = AssetValuationHelper.AggregateMetrics(childControllerValuations, new List <string>(Metrics), PaymentCurrencies);
            }
            CalculationPerformedIndicator = true;
            streamValuation.id            = Id;
            return(streamValuation);
        }
        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 CapFloorStreamAnalytic();
            }
            var            streamControllerMetrics = ResolveModelMetrics(AnalyticsModel.Metrics);
            AssetValuation streamValuation;

            // 2. Now evaluate only the child specific metrics (if any)
            foreach (var coupon in Coupons)
            {
                coupon.PricingStructureEvolutionType = PricingStructureEvolutionType;
                coupon.BucketedDates = BucketedDates;
                coupon.Multiplier    = 1.0m;//TODO this will have to be fixed eventually.
            }
            var childControllers = new List <InstrumentControllerBase>(Coupons.ToArray());
            //Add the extra metrics required
            var quotes = ModelData.AssetValuation.quote.ToList();

            if (AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.AccrualFactor.ToString()) == null)
            {
                var quote = QuotationHelper.Create(0.0m, InstrumentMetrics.AccrualFactor.ToString(), "DecimalValue");
                quotes.Add(quote);
            }
            if (AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.FloatingNPV.ToString()) == null)
            {
                var quote = QuotationHelper.Create(0.0m, InstrumentMetrics.FloatingNPV.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);
            }
            if (AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.LocalCurrencyNPV.ToString()) == null)
            {
                var quote = QuotationHelper.Create(0.0m, InstrumentMetrics.LocalCurrencyNPV.ToString(), "DecimalValue");
                quotes.Add(quote);
            }
            if (AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.LocalCurrencyExpectedValue.ToString()) == null)
            {
                var quote = QuotationHelper.Create(0.0m, InstrumentMetrics.LocalCurrencyExpectedValue.ToString(), "DecimalValue");
                quotes.Add(quote);
            }
            ModelData.AssetValuation.quote = quotes.ToArray();
            var childValuations           = EvaluateChildMetrics(childControllers, modelData, Metrics);
            var couponValuation           = AssetValuationHelper.AggregateMetrics(childValuations, new List <string>(Metrics), PaymentCurrencies);// modelData.ValuationDate);
            var childControllerValuations = new List <AssetValuation> {
                couponValuation
            };

            if (Exchanges != null && Exchanges.Count > 0)
            {
                foreach (var exchange in Exchanges)
                {
                    exchange.PricingStructureEvolutionType = PricingStructureEvolutionType;
                    exchange.BucketedDates = BucketedDates;
                    exchange.Multiplier    = 1.0m;//TODO this will have to be fixed eventually.
                }
                // Roll-Up and merge child valuations into parent Valuation
                var childPrincipalControllers = new List <InstrumentControllerBase>(Exchanges.ToArray());
                var childPrincipalValuations  = EvaluateChildMetrics(childPrincipalControllers, modelData, Metrics);
                var principalValuation        = AssetValuationHelper.AggregateMetrics(childPrincipalValuations, new List <string>(Metrics), PaymentCurrencies);// modelData.ValuationDate);
                childControllerValuations.Add(principalValuation);
            }
            // Child metrics have now been calculated so we can now evaluate the stream model metrics
            if (streamControllerMetrics.Count > 0)
            {
                var reportingCurrency = ModelData.ReportingCurrency == null
                                            ? Currency.Value
                                            : ModelData.ReportingCurrency.Value;
                ICapFloorStreamParameters analyticModelParameters = new CapFloorStreamParameters
                {
                    Multiplier        = 1.0m,
                    Currency          = Currency.Value,
                    ReportingCurrency = reportingCurrency,
                    AccrualFactor     = AggregateMetric(InstrumentMetrics.AccrualFactor, childControllerValuations),
                    FloatingNPV       = AggregateMetric(InstrumentMetrics.FloatingNPV, childControllerValuations),
                    NPV = AggregateMetric(InstrumentMetrics.NPV, childControllerValuations)                                                          //,
                };
                CalculationResults = AnalyticsModel.Calculate <ICapFloorStreamInstrumentResults, CapFloorStreamInstrumentResults>(analyticModelParameters, streamControllerMetrics.ToArray());
                // Now merge back into the overall stream valuation
                var streamControllerValuation = GetValue(CalculationResults, modelData.ValuationDate);
                streamValuation = AssetValuationHelper.UpdateValuation(streamControllerValuation,
                                                                       childControllerValuations, ConvertMetrics(streamControllerMetrics), new List <string>(Metrics), PaymentCurrencies);// modelData.ValuationDate);
            }
            else
            {
                streamValuation = AssetValuationHelper.AggregateMetrics(childControllerValuations, new List <string>(Metrics), PaymentCurrencies);// modelData.ValuationDate);
            }
            CalculationPerfomedIndicator = true;
            streamValuation.id           = Id;
            return(streamValuation);
        }