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