/// <summary> /// Initializes a new instance of the <see cref="FxSingleLegPricer"/> class. All the cashfloews must be signed. /// </summary> /// <param name="fxLeg">The fxLeg.</param> /// <param name="baseParty">The the base party.</param> /// <param name="productType">THe product type: This should only be FxSpot or FxForward.</param> public FxSingleLegPricer(FxSingleLeg fxLeg, string baseParty, ProductTypeSimpleEnum productType) { Multiplier = 1.0m; OrderedPartyNames = new List <string>(); Id = fxLeg.id; AnalyticsModel = new FxLegAnalytic(); ProductType = productType; ExchangeRate = fxLeg.exchangeRate; HybridValuation = true; //Get the currency. PaymentCurrencies = new List <string>(); Currency1 = fxLeg.exchangedCurrency1.paymentAmount.currency; Currency2 = fxLeg.exchangedCurrency2.paymentAmount.currency; if (!PaymentCurrencies.Contains(Currency1.Value)) { PaymentCurrencies.Add(Currency1.Value); } if (!PaymentCurrencies.Contains(Currency2.Value)) { PaymentCurrencies.Add(Currency2.Value); } //Set the default discount curve name. Currency1DiscountCurveName = CurveNameHelpers.GetDiscountCurveName(Currency1.Value, true); //Set the default discount curve name. Currency2DiscountCurveName = CurveNameHelpers.GetDiscountCurveName(Currency2.Value, true); //TODO //Set the appropraiet cross //if the quotebasis is : Currency1PerCurrency2 the currency curve is: currency1-currency2 if (ExchangeRate.quotedCurrencyPair.quoteBasis == QuoteBasisEnum.Currency2PerCurrency1) { FxIndexCurveName = MarketEnvironmentHelper.ResolveFxCurveNames(Currency1.Value, Currency2.Value); } //Otherwise it is Currency2-Currency1 else { FxIndexCurveName = MarketEnvironmentHelper.ResolveFxCurveNames(Currency2.Value, Currency1.Value); } if (fxLeg.nonDeliverableSettlement != null)//TODO Not implemented yet. { IsNonDeliverableForward = true; SettlementCurrency = fxLeg.nonDeliverableSettlement.settlementCurrency; SettlementCurrencyDiscountCurveName = CurveNameHelpers.GetDiscountCurveName(SettlementCurrency.Value, true); } //Build the coupons and principal exchanges. Payments = PriceableInstrumentsFactory.CreatePriceableFxLegPayment(baseParty, fxLeg); //TODO: add extra cashflowss. RiskMaturityDate = fxLeg.Items1ElementName[0] == Items1ChoiceType.valueDate ? fxLeg.Items1[0] : LastDate(); }
/// <summary> /// Initializes a new instance of the <see cref="PriceableFxRateCashflow"/> class. /// </summary> /// <param name="cashflowId">The stream id.</param> /// <param name="startIndex">The start Index. If null then the cash flow is not a differenctial.</param> /// <param name="observedIndex">The observed Index. If null then the cash flow is not a differenctial. </param> /// <param name="isCurrency1Base">The isCurrency1Base flag. </param> /// <param name="currency2PayerIsBase">The currency2PayerIsBase lag.</param> /// <param name="isSettlementInCurrency1">The isSettlementInCurrency1 flag</param> /// <param name="hybridValuation">Is hybrid valuation used, or the base fa curve. </param> /// <param name="currency1NotionalAmount">The currency1 notional amount.</param> /// <param name="fixingDateRelativeOffset">The fixingDateRelativeOffset.</param> /// <param name="paymentDate">The payment date.</param> /// <param name="fixingCalendar">The fixingCalendar.</param> /// <param name="paymentCalendar">The paymentCalendar.</param> protected PriceableFxRateCashflow ( string cashflowId , FxRate startIndex , FxRate observedIndex , bool isCurrency1Base , bool currency2PayerIsBase , bool isSettlementInCurrency1 , bool hybridValuation , Money currency1NotionalAmount , AdjustableOrAdjustedDate paymentDate , RelativeDateOffset fixingDateRelativeOffset , IBusinessCalendar fixingCalendar , IBusinessCalendar paymentCalendar) : base ( cashflowId , FloatingIndexType.Fx , startIndex.rate , IsObserved(observedIndex) , currency2PayerIsBase , currency1NotionalAmount , paymentDate , fixingDateRelativeOffset , fixingCalendar , paymentCalendar) { ModelIdentifier = "FloatingFxRateCashflowModel"; StartFxRate = startIndex; IsSettlementInCurrency1 = isSettlementInCurrency1; HybridValuation = hybridValuation; if (StartFxRate.quotedCurrencyPair.quoteBasis == QuoteBasisEnum.Currency1PerCurrency2) { InvertFxRate = true; } IsCurrency1Base = isCurrency1Base; Currency1 = StartFxRate.quotedCurrencyPair.currency1; Currency2 = StartFxRate.quotedCurrencyPair.currency2; //Set the default discount curve name. Currency1DiscountCurveName = CurveNameHelpers.GetDiscountCurveName(Currency1.Value, true); //Set the default discount curve name. Currency2DiscountCurveName = CurveNameHelpers.GetDiscountCurveName(Currency2.Value, true); ForecastCurveName = MarketEnvironmentHelper.ResolveFxCurveNames(StartFxRate.quotedCurrencyPair.currency1.Value, StartFxRate.quotedCurrencyPair.currency2.Value); }
/// <summary> /// Calculates the specified model data. /// </summary> /// <param name="modelData">The model data.</param>//TODO the floating delta? /// <returns></returns> public override AssetValuation Calculate(IInstrumentControllerData modelData) { ModelData = modelData; AnalyticModelParameters = null; AnalyticsModel = new FxRateCashflowAnalytic(); CalculationResults = null; YearFractionToCashFlowPayment = Convert.ToDecimal(CDefaultDayCounter.YearFraction(ModelData.ValuationDate, PaymentDate)); //Make sure there are some bucket dates even if not set previously. if (BucketedDates.Length < 1) { UpdateBucketingInterval(ModelData.ValuationDate, PeriodHelper.Parse(CDefaultBucketingInterval)); } IsRealised = HasBeenRealised(ModelData.ValuationDate); //Add the extra metrics required var quotes = ModelData.AssetValuation.quote.ToList(); if (AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, FloatingCashflowMetrics.NPV.ToString()) == null) { var quote = QuotationHelper.Create(0.0m, FloatingCashflowMetrics.LocalCurrencyNPV.ToString(), "DecimalValue", ModelData.ValuationDate); quotes.Add(quote); } if (AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, FloatingCashflowMetrics.LocalCurrencyNPV.ToString()) == null) { var quote = QuotationHelper.Create(0.0m, FloatingCashflowMetrics.LocalCurrencyNPV.ToString(), "DecimalValue", ModelData.ValuationDate); quotes.Add(quote); } if (AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.RiskNPV.ToString()) == null) { var quote = QuotationHelper.Create(0.0m, InstrumentMetrics.NPV.ToString(), "DecimalValue", ModelData.ValuationDate); quotes.Add(quote); } if (AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, FloatingCashflowMetrics.LocalCurrencyExpectedValue.ToString()) == null) { var quote = QuotationHelper.Create(0.0m, FloatingCashflowMetrics.LocalCurrencyExpectedValue.ToString(), "DecimalValue", ModelData.ValuationDate); quotes.Add(quote); } //Check if risk calc are required. bool delta1PDH = AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.LocalCurrencyDelta1PDH.ToString()) != null || AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.Delta1PDH.ToString()) != null; //Check if risk calc are required. bool delta0PDH = AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.LocalCurrencyDelta0PDH.ToString()) != null || AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.Delta0PDH.ToString()) != null; ModelData.AssetValuation.quote = quotes.ToArray(); var metrics = ResolveModelMetrics(AnalyticsModel.Metrics); IFxCurve fxCurve = null; IRateCurve discountCurve = null; IFxCurve currencyCurve = null; var reportingCurrency = ModelData.ReportingCurrency == null ? PaymentCurrency.Value : ModelData.ReportingCurrency.Value; //Set the basic model. var analyticModelParameters = new FxRateCashflowParameters { Multiplier = Multiplier, ValuationDate = ModelData.ValuationDate, PaymentDate = PaymentDate, Currency = PaymentCurrency.Value, ReportingCurrency = reportingCurrency, NotionalAmount = PaymentAmount.amount, StartIndex = StartIndex, IsRealised = IsRealised, CurveYearFraction = YearFractionToCashFlowPayment, PeriodAsTimesPerYear = 0.25m, BucketingRate = 0.05m }; if (modelData.MarketEnvironment is ISwapLegEnvironment environment) { var marketEnvironment = environment; //The discount curve. discountCurve = marketEnvironment.GetDiscountRateCurve(); discountCurve.PricingStructureEvolutionType = PricingStructureEvolutionType; analyticModelParameters.DiscountCurve = discountCurve; //Check if it is our of currency. if (ModelData.ReportingCurrency != null && ModelData.ReportingCurrency.Value != PaymentCurrency.Value) { fxCurve = marketEnvironment.GetReportingCurrencyFxCurve(); fxCurve.PricingStructureEvolutionType = PricingStructureEvolutionType; analyticModelParameters.ReportingCurrencyFxCurve = fxCurve; } } else if (modelData.MarketEnvironment.GetType() == typeof(MarketEnvironment)) { var market = (MarketEnvironment)modelData.MarketEnvironment; discountCurve = (IRateCurve)market.SearchForPricingStructureType(DiscountCurveName); discountCurve.PricingStructureEvolutionType = PricingStructureEvolutionType; analyticModelParameters.DiscountCurve = discountCurve; var currencyCurveName = MarketEnvironmentHelper.ResolveFxCurveNames(StartFxRate.quotedCurrencyPair.currency1.Value, StartFxRate.quotedCurrencyPair.currency2.Value); currencyCurve = (IFxCurve)market.SearchForPricingStructureType(currencyCurveName); currencyCurve.PricingStructureEvolutionType = PricingStructureEvolutionType; if (delta1PDH) { var riskMarket = market.SearchForPerturbedPricingStructures(DiscountCurveName, "delta1PDH"); analyticModelParameters.Delta1PDHCurves = riskMarket; analyticModelParameters.Delta1PDHPerturbation = 10; } if (delta0PDH) { var riskMarket = market.SearchForPerturbedPricingStructures(DiscountCurveName, "delta0PDH");//TODO The fx deltas analyticModelParameters.Delta1PDHCurves = riskMarket; analyticModelParameters.Delta1PDHPerturbation = 10; } if (modelData.ReportingCurrency.Value != PaymentCurrency.Value) { string curveName = MarketEnvironmentHelper.ResolveFxCurveNames(PaymentCurrency.Value, modelData.ReportingCurrency.Value); fxCurve = (IFxCurve)market.SearchForPricingStructureType(curveName); fxCurve.PricingStructureEvolutionType = PricingStructureEvolutionType; analyticModelParameters.ReportingCurrencyFxCurve = fxCurve; } if (HybridValuation) { var currency1RateCurve = (IRateCurve)market.SearchForPricingStructureType(Currency1DiscountCurveName); currency1RateCurve.PricingStructureEvolutionType = PricingStructureEvolutionType; var currency2RateCurve = (IRateCurve)market.SearchForPricingStructureType(Currency2DiscountCurveName); currency2RateCurve.PricingStructureEvolutionType = PricingStructureEvolutionType; AnalyticsModel = new FxRateCashflowAnalytic(ModelData.ValuationDate, PaymentDate, currencyCurve, currency1RateCurve, currency2RateCurve, !InvertFxRate, IsSettlementInCurrency1, fxCurve); } } // store inputs and results from this run AnalyticModelParameters = analyticModelParameters; if (!HybridValuation) { AnalyticsModel = new FxRateCashflowAnalytic(ModelData.ValuationDate, PaymentDate, fxCurve, currencyCurve, discountCurve); } //TODO Fix this with a generic index curve. //AnalyticsModel = analyticsModel; CalculationResults = AnalyticsModel.Calculate <IFloatingCashflowResults, FloatingCashflowResults>(AnalyticModelParameters, metrics.ToArray()); CalculationPerformedIndicator = true; PaymentDiscountFactor = ((FxRateCashflowAnalytic)AnalyticsModel).PaymentDiscountFactor; ForecastAmount = MoneyHelper.GetAmount(CalculationResults.LocalCurrencyExpectedValue, PaymentAmount.currency); NPV = MoneyHelper.GetAmount(CalculationResults.LocalCurrencyNPV, PaymentAmount.currency); AssetValuation valuation = GetValue(CalculationResults, modelData.ValuationDate); valuation.id = Id; return(valuation); }
/// <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; AnalyticsModel = new FloatingRateCouponAnalytic(); RequiresReset = modelData.ValuationDate > ResetDate; IsRealised = HasBeenRealised(ModelData.ValuationDate); //Make sure there are some bucket dates even if not set previously. if (BucketedDates.Length < 1) { UpdateBucketingInterval(ModelData.ValuationDate, PeriodHelper.Parse(CDefaultBucketingInterval)); } //Add the extra metrics required 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", ModelData.ValuationDate); quotes.Add(quote); } if (AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.AccrualFactor.ToString()) == null) { var quote = QuotationHelper.Create(0.0m, InstrumentMetrics.AccrualFactor.ToString(), "DecimalValue", ModelData.ValuationDate); quotes.Add(quote); } if (AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.FloatingNPV.ToString()) == null) { var quote = QuotationHelper.Create(0.0m, InstrumentMetrics.FloatingNPV.ToString(), "DecimalValue", ModelData.ValuationDate); quotes.Add(quote); } if (AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.NPV.ToString()) == null) { var quote = QuotationHelper.Create(0.0m, InstrumentMetrics.NPV.ToString(), "DecimalValue", ModelData.ValuationDate); quotes.Add(quote); } if (AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.RiskNPV.ToString()) == null) { var quote = QuotationHelper.Create(0.0m, InstrumentMetrics.RiskNPV.ToString(), "DecimalValue", ModelData.ValuationDate); quotes.Add(quote); } if (AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.LocalCurrencyNPV.ToString()) == null) { var quote = QuotationHelper.Create(0.0m, InstrumentMetrics.LocalCurrencyNPV.ToString(), "DecimalValue", ModelData.ValuationDate); quotes.Add(quote); } if (AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.LocalCurrencyExpectedValue.ToString()) == null) { var quote = QuotationHelper.Create(0.0m, InstrumentMetrics.LocalCurrencyExpectedValue.ToString(), "DecimalValue", ModelData.ValuationDate); quotes.Add(quote); } //Check if risk calc are required. bool delta1PDH = AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.LocalCurrencyDelta1PDH.ToString()) != null || AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.Delta1PDH.ToString()) != null; //Check if risk calc are required. bool delta0PDH = AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.LocalCurrencyDelta0PDH.ToString()) != null || AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.Delta0PDH.ToString()) != null; ModelData.AssetValuation.quote = quotes.ToArray(); var metrics = ResolveModelMetrics(AnalyticsModel.Metrics); IFxCurve fxCurve = null; IRateCurve discountCurve = null; IRateCurve forecastCurve = null; //// Determine if DFAM has been requested - if so thats all we evaluate - every other metric is ignored //if (metrics.Contains(InstrumentMetrics.DiscountFactorAtMaturity)) //{ // metrics.RemoveAll(metricItem => metricItem != InstrumentMetrics.DiscountFactorAtMaturity); //} //Set the forrecast rate dates. The ForecastRateInterpolation shhould have been set. ForwardStartDate = AccrualStartDate; ForwardEndDate = ForecastRateInterpolation ? AccrualEndDate : AdjustedDateHelper.ToAdjustedDate(FixingCalendar, ForecastRateIndex.indexTenor.Add(ForwardStartDate), AccrualBusinessDayAdjustments); //var metricsToEvaluate = metrics.ToArray(); if (metrics.Count > 0) { YearFractionToCashFlowPayment = GetPaymentYearFraction(ModelData.ValuationDate, PaymentDate); var reportingCurrency = ModelData.ReportingCurrency == null ? PaymentCurrency.Value : ModelData.ReportingCurrency.Value; var amount = NotionalAmount.amount; IRateCouponParameters analyticModelParameters = new RateCouponParameters { Multiplier = Multiplier, ValuationDate = modelData.ValuationDate, PaymentDate = PaymentDate, Currency = PaymentCurrency.Value, ReportingCurrency = reportingCurrency, DiscountType = DiscountType, IsRealised = IsRealised, HasReset = RequiresReset, NotionalAmount = amount, Spread = Margin, YearFraction = CouponYearFraction, CurveYearFraction = YearFractionToCashFlowPayment }; decimal?discountRate = null; // Curve Related if (modelData.MarketEnvironment is ISwapLegEnvironment environment) { var streamMarket = environment; discountCurve = streamMarket.GetDiscountRateCurve(); discountCurve.PricingStructureEvolutionType = PricingStructureEvolutionType; forecastCurve = streamMarket.GetForecastRateCurve(); forecastCurve.PricingStructureEvolutionType = PricingStructureEvolutionType; DiscountCurveName = discountCurve.GetPricingStructureId().UniqueIdentifier; analyticModelParameters.DiscountCurve = discountCurve; ForecastCurveName = forecastCurve.GetPricingStructureId().UniqueIdentifier; analyticModelParameters.ForecastCurve = forecastCurve; // Bucketed Delta if (BucketedDates.Length > 1) { analyticModelParameters.PeriodAsTimesPerYear = GetPaymentYearFraction(BucketedDates[0], BucketedDates[1]); analyticModelParameters.BucketedDiscountFactors = GetBucketedDiscountFactors(discountCurve, ModelData. ValuationDate, BucketedDates); } //Check for currency. if (ModelData.ReportingCurrency != null) { if (ModelData.ReportingCurrency.Value != PaymentCurrency.Value) { fxCurve = streamMarket.GetReportingCurrencyFxCurve(); fxCurve.PricingStructureEvolutionType = PricingStructureEvolutionType; analyticModelParameters.ReportingCurrencyFxCurve = fxCurve; } } AnalyticModelParameters = analyticModelParameters; } else if (modelData.MarketEnvironment.GetType() == typeof(MarketEnvironment)) { var market = (MarketEnvironment)modelData.MarketEnvironment; discountCurve = (IRateCurve)market.SearchForPricingStructureType(DiscountCurveName); discountCurve.PricingStructureEvolutionType = PricingStructureEvolutionType; forecastCurve = (IRateCurve)market.SearchForPricingStructureType(ForecastCurveName); forecastCurve.PricingStructureEvolutionType = PricingStructureEvolutionType; analyticModelParameters.DiscountCurve = discountCurve; analyticModelParameters.ForecastCurve = forecastCurve; // Bucketed Delta if (BucketedDates.Length > 1) { analyticModelParameters.PeriodAsTimesPerYear = GetPaymentYearFraction(BucketedDates[0], BucketedDates[1]); analyticModelParameters.BucketedDiscountFactors = GetBucketedDiscountFactors(discountCurve, ModelData. ValuationDate, BucketedDates); } if (delta1PDH) { var riskMarket = market.SearchForPerturbedPricingStructures(DiscountCurveName, "delta1PDH"); analyticModelParameters.Delta1PDHCurves = riskMarket; analyticModelParameters.Delta1PDHPerturbation = 10; } if (delta0PDH) { var riskMarket = market.SearchForPerturbedPricingStructures(ForecastCurveName, "delta0PDH"); analyticModelParameters.Delta0PDHCurves = riskMarket; analyticModelParameters.Delta0PDHPerturbation = 10; } //Check for currency. if (ModelData.ReportingCurrency != null) { if (ModelData.ReportingCurrency.Value != PaymentCurrency.Value) { string curveName = MarketEnvironmentHelper.ResolveFxCurveNames(PaymentCurrency.Value, modelData.ReportingCurrency.Value); fxCurve = (IFxCurve)market.SearchForPricingStructureType(curveName); fxCurve.PricingStructureEvolutionType = PricingStructureEvolutionType; analyticModelParameters.ReportingCurrencyFxCurve = fxCurve; } } AnalyticModelParameters = analyticModelParameters; } //Set the base rate. Default is zero if (AnalyticModelParameters != null) { AnalyticModelParameters.BaseRate = BaseRate; } if (UseObservedRate) { AnalyticsModel = new FixedRateCouponAnalytic(ModelData.ValuationDate, AccrualStartDate, AccrualEndDate, PaymentDate, Rate, analyticModelParameters.YearFraction, DiscountType, fxCurve, discountCurve, forecastCurve); if (Rate != null) { analyticModelParameters.Rate = (decimal)Rate; } } else { if (Rate != null) { discountRate = Rate; } if (DiscountRate != null) { discountRate = DiscountRate; } AnalyticsModel = new FloatingRateCouponAnalytic(ModelData.ValuationDate, AccrualStartDate, AccrualEndDate, PaymentDate, discountRate, analyticModelParameters.YearFraction, DiscountType, fxCurve, discountCurve, forecastCurve); } CalculationResults = AnalyticsModel.Calculate <IRateInstrumentResults, RateInstrumentResults>(AnalyticModelParameters, metrics.ToArray()); CalculationPerfomedIndicator = true; PaymentDiscountFactor = ((FixedRateCouponAnalytic)AnalyticsModel).PaymentDiscountFactor; if (!UseObservedRate) { Rate = CalculationResults.BreakEvenRate; } ForecastAmount = MoneyHelper.GetAmount(CalculationResults.LocalCurrencyExpectedValue, PaymentAmount.currency); NPV = MoneyHelper.GetAmount(CalculationResults.LocalCurrencyNPV, PaymentAmount.currency); } AssetValuation valuation = GetValue(CalculationResults, modelData.ValuationDate); valuation.id = Id; return(valuation); }
/// <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; AnalyticsModel = new FxOptionAnalytic(); CalculationResults = null; YearFractionToCashFlowPayment = Convert.ToDecimal(CDefaultDayCounter.YearFraction(ModelData.ValuationDate, PaymentDate)); //Make sure there are some bucket dates even if not set previously. if (BucketedDates.Length < 1) { UpdateBucketingInterval(ModelData.ValuationDate, PeriodHelper.Parse(CDefaultBucketingInterval)); } IsRealised = HasBeenRealised(ModelData.ValuationDate); //Add the extra metrics required var quotes = ModelData.AssetValuation.quote.ToList(); if (AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, FloatingCashflowMetrics.NPV.ToString()) == null) { var quote = QuotationHelper.Create(0.0m, FloatingCashflowMetrics.LocalCurrencyNPV.ToString(), "DecimalValue", ModelData.ValuationDate); quotes.Add(quote); } if (AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, FloatingCashflowMetrics.LocalCurrencyNPV.ToString()) == null) { var quote = QuotationHelper.Create(0.0m, FloatingCashflowMetrics.LocalCurrencyNPV.ToString(), "DecimalValue", ModelData.ValuationDate); quotes.Add(quote); } if (AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.RiskNPV.ToString()) == null) { var quote = QuotationHelper.Create(0.0m, InstrumentMetrics.NPV.ToString(), "DecimalValue", ModelData.ValuationDate); quotes.Add(quote); } if (AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, FloatingCashflowMetrics.LocalCurrencyExpectedValue.ToString()) == null) { var quote = QuotationHelper.Create(0.0m, FloatingCashflowMetrics.LocalCurrencyExpectedValue.ToString(), "DecimalValue", ModelData.ValuationDate); quotes.Add(quote); } //Check if risk calc are required. bool delta1PDH = AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.LocalCurrencyDelta1PDH.ToString()) != null || AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.Delta1PDH.ToString()) != null; //Check if risk calc are required. bool delta0PDH = AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.LocalCurrencyDelta0PDH.ToString()) != null || AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.Delta0PDH.ToString()) != null; ModelData.AssetValuation.quote = quotes.ToArray(); //Set the cash flowdetails. HasReset = modelData.ValuationDate > ResetDate; IsRealised = HasBeenRealised(ModelData.ValuationDate); TimeToExpiry = GetPaymentYearFraction(ModelData.ValuationDate, AdjustedFixingDate); var volatilityCurveNodeTime = GetPaymentYearFraction(ModelData.ValuationDate, PaymentDate); IFxCurve fxCurve = null; IRateCurve discountCurve = null; IFxCurve currencyCurve = null; IVolatilitySurface volSurface = null; var metrics = ResolveModelMetrics(AnalyticsModel.Metrics); //var metricsToEvaluate = metrics.ToArray(); //if (metricsToEvaluate.Length > 0) //{ YearFractionToCashFlowPayment = GetPaymentYearFraction(ModelData.ValuationDate, PaymentDate); var reportingCurrency = ModelData.ReportingCurrency == null ? PaymentCurrency.Value : ModelData.ReportingCurrency.Value; decimal?premium = null; if (Premium != null) { premium = Premium; } IFxRateCashflowParameters analyticModelParameters = new FxRateCashflowParameters { ValuationDate = modelData.ValuationDate, PaymentDate = PaymentDate, Currency = PaymentCurrency.Value, ReportingCurrency = reportingCurrency, IsRealised = IsRealised, IsReset = HasReset, NotionalAmount = NotionalAmount.amount, CurveYearFraction = YearFractionToCashFlowPayment, ExpiryYearFraction = TimeToExpiry, Premium = premium }; // Curve Related if (modelData.MarketEnvironment.GetType() == typeof(MarketEnvironment)) { var market = (MarketEnvironment)modelData.MarketEnvironment; discountCurve = (IRateCurve)market.SearchForPricingStructureType(DiscountCurveName); discountCurve.PricingStructureEvolutionType = PricingStructureEvolutionType; volSurface = (IVolatilitySurface)market.SearchForPricingStructureType(VolatilitySurfaceName); volSurface.PricingStructureEvolutionType = PricingStructureEvolutionType; var currencyCurveName = MarketEnvironmentHelper.ResolveFxCurveNames(StartFxRate.quotedCurrencyPair.currency1.Value, StartFxRate.quotedCurrencyPair.currency2.Value); currencyCurve = (IFxCurve)market.SearchForPricingStructureType(currencyCurveName); currencyCurve.PricingStructureEvolutionType = PricingStructureEvolutionType; analyticModelParameters.DiscountCurve = discountCurve; if (delta1PDH) { var riskMarket = market.SearchForPerturbedPricingStructures(DiscountCurveName, "delta1PDH"); analyticModelParameters.Delta1PDHCurves = riskMarket; analyticModelParameters.Delta1PDHPerturbation = 10; } if (delta0PDH)//TODO Do this for the fxrate { //var riskMarket = market.SearchForPerturbedPricingStructures(DiscountCurveName, "delta0PDH"); // //TODO The fx deltas //analyticModelParameters.Delta1PDHCurves = riskMarket; //analyticModelParameters.Delta1PDHPerturbation = 10; } if (modelData.ReportingCurrency.Value != PaymentCurrency.Value) { string curveName = MarketEnvironmentHelper.ResolveFxCurveNames(PaymentCurrency.Value, modelData.ReportingCurrency.Value); fxCurve = (IFxCurve)market.SearchForPricingStructureType(curveName); fxCurve.PricingStructureEvolutionType = PricingStructureEvolutionType; analyticModelParameters.ReportingCurrencyFxCurve = fxCurve; } if (HybridValuation) { var currency1RateCurve = (IRateCurve)market.SearchForPricingStructureType(Currency1DiscountCurveName); currency1RateCurve.PricingStructureEvolutionType = PricingStructureEvolutionType; var currency2RateCurve = (IRateCurve)market.SearchForPricingStructureType(Currency2DiscountCurveName); currency2RateCurve.PricingStructureEvolutionType = PricingStructureEvolutionType; AnalyticsModel = new FxOptionAnalytic(ModelData.ValuationDate, PaymentDate, currencyCurve, currency1RateCurve, currency2RateCurve, IsSettlementInCurrency1, !InvertFxRate, Strike, TimeToExpiry, volatilityCurveNodeTime, volSurface, FxOptionType, fxCurve); } } // store inputs and results from this run AnalyticModelParameters = analyticModelParameters; if (!HybridValuation) { AnalyticsModel = new FxOptionAnalytic(ModelData.ValuationDate, PaymentDate, Strike, TimeToExpiry, volatilityCurveNodeTime, fxCurve, currencyCurve, discountCurve, volSurface, FxOptionType); } //TODO Fix this with a generic index curve. //AnalyticsModel = analyticsModel; CalculationResults = AnalyticsModel.Calculate <IFloatingCashflowResults, FloatingCashflowResults>( AnalyticModelParameters, metrics.ToArray()); CalculationPerfomedIndicator = true; PaymentDiscountFactor = ((FxRateCashflowAnalytic)AnalyticsModel).PaymentDiscountFactor; ForecastAmount = MoneyHelper.GetAmount(CalculationResults.LocalCurrencyExpectedValue, PaymentAmount.currency); NPV = MoneyHelper.GetAmount(CalculationResults.LocalCurrencyNPV, PaymentAmount.currency); AssetValuation valuation = GetValue(CalculationResults, modelData.ValuationDate); valuation.id = Id; return(valuation); }
/// <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 SimpleXccySwapInstrumentAnalytic(); } var swapControllerMetrics = ResolveModelMetrics(AnalyticsModel.Metrics); AssetValuation swapValuation; 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); } ModelData.AssetValuation.quote = quotes.ToArray(); //Sets the evolution type for calculations. foreach (var leg in Legs) { leg.PricingStructureEvolutionType = PricingStructureEvolutionType; leg.BucketedDates = BucketedDates; leg.Multiplier = Multiplier; } if (AdditionalPayments != null) { foreach (var payment in AdditionalPayments) { payment.PricingStructureEvolutionType = PricingStructureEvolutionType; payment.BucketedDates = BucketedDates; payment.Multiplier = Multiplier; } } var legControllers = new List <InstrumentControllerBase> { PayLeg, ReceiveLeg }; //The assetValuation list. var childValuations = new List <AssetValuation>(); // 2. Now evaluate only the child specific metrics (if any) if (modelData.MarketEnvironment is ISwapLegEnvironment) { var market = (SwapLegEnvironment)modelData.MarketEnvironment; IRateCurve discountCurve = null; IRateCurve forecastCurve = null; IFxCurve currencyCurve = null; foreach (var leg in legControllers) { var stream = (PriceableInterestRateStream)leg; if (modelData.ReportingCurrency == null) { modelData.ReportingCurrency = stream.Currency; } if (stream.DiscountCurveName != null) { discountCurve = market.GetDiscountRateCurve(); } if (stream.ForecastCurveName != null) { forecastCurve = market.GetForecastRateCurve(); } if (modelData.ReportingCurrency.Value != stream.Currency.Value) { //stream.ReportingCurrencyFxCurveName = // MarketEnvironmentHelper.ResolveFxCurveNames(stream.Currency.Value, modelData.ReportingCurrency.Value); currencyCurve = market.GetReportingCurrencyFxCurve(); } modelData.MarketEnvironment = MarketEnvironmentHelper.CreateInterestRateStreamEnvironment(modelData.ValuationDate, discountCurve, forecastCurve, currencyCurve); childValuations.Add(leg.Calculate(modelData)); } if (GetAdditionalPayments() != null) { var paymentControllers = new List <InstrumentControllerBase>(GetAdditionalPayments()); childValuations.AddRange(paymentControllers.Select(payment => payment.Calculate(modelData))); } } else { childValuations = EvaluateChildMetrics(legControllers, modelData, Metrics); } var childControllerValuations = AssetValuationHelper.AggregateMetrics(childValuations, new List <string>(Metrics), PaymentCurrencies);// modelData.ValuationDate); childControllerValuations.id = Id + ".InterestRateStreams"; // Child metrics have now been calculated so we can now evaluate the stream model metrics if (swapControllerMetrics.Count > 0) { //TODO need to fix this calculation. var payStreamAccrualFactor = AssetValuationHelper.GetQuotationByMeasureType(childValuations[0], InstrumentMetrics.AccrualFactor.ToString()); //AggregateMetric(InstrumentMetrics.AccrualFactor, childValuations); var payStreamNPV = AssetValuationHelper.GetQuotationByMeasureType(childValuations[0], InstrumentMetrics.NPV.ToString()); //AggregateMetric(InstrumentMetrics.NPV, childValuations); var payStreamFloatingNPV = AssetValuationHelper.GetQuotationByMeasureType(childValuations[0], InstrumentMetrics.FloatingNPV.ToString()); //AggregateMetric(InstrumentMetrics.FloatingNPV, childValuations); var receiveStreamAccrualFactor = AssetValuationHelper.GetQuotationByMeasureType(childValuations[1], InstrumentMetrics.AccrualFactor.ToString()); //AggregateMetric(InstrumentMetrics.AccrualFactor, childValuations); var receiveStreamNPV = AssetValuationHelper.GetQuotationByMeasureType(childValuations[1], InstrumentMetrics.NPV.ToString()); //AggregateMetric(InstrumentMetrics.NPV, childValuations); var receiveStreamFloatingNPV = AssetValuationHelper.GetQuotationByMeasureType(childValuations[1], InstrumentMetrics.FloatingNPV.ToString()); IIRSwapInstrumentParameters analyticModelParameters = new SwapInstrumentParameters { IsPayFixedInd = true, PayStreamAccrualFactor = payStreamAccrualFactor.value, PayStreamFloatingNPV = payStreamFloatingNPV.value, PayStreamNPV = payStreamNPV.value, ReceiveStreamFloatingNPV = receiveStreamFloatingNPV.value, ReceiveStreamNPV = receiveStreamNPV.value, ReceiveStreamAccrualFactor = receiveStreamAccrualFactor.value, NPV = payStreamNPV.value + receiveStreamNPV.value }; CalculationResults = AnalyticsModel.Calculate <IIRSwapInstrumentResults, SwapInstrumentResults>(analyticModelParameters, swapControllerMetrics.ToArray()); // Now merge back into the overall stream valuation var swapControllerValuation = GetValue(CalculationResults, modelData.ValuationDate); swapValuation = AssetValuationHelper.UpdateValuation(swapControllerValuation, childControllerValuations, ConvertMetrics(swapControllerMetrics), new List <string>(Metrics)); } else { swapValuation = childControllerValuations; } CalculationPerfomedIndicator = true; swapValuation.id = Id; return(swapValuation); }
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 FxLegAnalytic(); } AssetValuation streamValuation; //Check if risk calc are required. bool delta0PDH = AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.LocalCurrencyDelta0PDH.ToString()) != null || AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.Delta0PDH.ToString()) != null; bool delta1PDH = AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.LocalCurrencyDelta1PDH.ToString()) != null || AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.Delta1PDH.ToString()) != null; var streamControllerMetrics = ResolveModelMetrics(AnalyticsModel.Metrics); var childValuations = new List <AssetValuation>(); foreach (var payment in Payments) { payment.PricingStructureEvolutionType = PricingStructureEvolutionType; payment.BucketedDates = BucketedDates; payment.Multiplier = Multiplier; } if (modelData.MarketEnvironment is IFxLegEnvironment marketEnvironment)//TODO need to look at PricingStructureEvolutionType. { //Modify the second market. var curveName1 = marketEnvironment.GetExchangeCurrencyPaymentEnvironment1(); var modelData1 = new InstrumentControllerData(modelData.AssetValuation, curveName1, modelData.ValuationDate, modelData.ReportingCurrency); var curveName2 = marketEnvironment.GetExchangeCurrencyPaymentEnvironment2(); var modelData2 = new InstrumentControllerData(modelData.AssetValuation, curveName2, modelData.ValuationDate, modelData.ReportingCurrency); childValuations.Add(Currency1Payment.Calculate(modelData1)); childValuations.Add(Currency2Payment.Calculate(modelData2)); } else if (modelData.MarketEnvironment.GetType() == typeof(MarketEnvironment)) { var market = (MarketEnvironment)modelData.MarketEnvironment; if (delta0PDH) { //Force building of the risk curves. //market.SearchForPerturbedPricingStructures(FxIndexCurveName, "delta0PDH");//TODO Need to add this perturbation to fxCurve. } if (delta1PDH) { //Force building of the risk curves. market.SearchForPerturbedPricingStructures(Currency1DiscountCurveName, "delta1PDH"); market.SearchForPerturbedPricingStructures(Currency2DiscountCurveName, "delta1PDH"); } //This defines the cross cureves from the payment currency to the reporting //currency for each leg of the fx trade. // if (modelData.ReportingCurrency.Value != Currency1.Value) { ReportingCurrencyFxCurveName1 = MarketEnvironmentHelper.ResolveFxCurveNames(Currency1.Value, modelData.ReportingCurrency.Value); } if (modelData.ReportingCurrency.Value != Currency2.Value) { ReportingCurrencyFxCurveName2 = MarketEnvironmentHelper.ResolveFxCurveNames(Currency2.Value, modelData.ReportingCurrency.Value); } childValuations.Add(Currency1Payment.Calculate(modelData)); childValuations.Add(Currency2Payment.Calculate(modelData)); } var paymentValuation = AssetValuationHelper.AggregateMetrics(childValuations, new List <string>(Metrics), PaymentCurrencies); var childControllerValuations = new List <AssetValuation> { paymentValuation }; // Child metrics have now been calculated so we can now evaluate the stream model metrics if (streamControllerMetrics.Count > 0) { var rate = ExchangeRate.rate; if (modelData.MarketEnvironment is MarketEnvironment market) { var fxCurve = (IFxCurve)market.SearchForPricingStructureType(FxIndexCurveName); if (HybridValuation) { var curve1 = (IRateCurve)market.SearchForPricingStructureType(Currency1DiscountCurveName); var curve2 = (IRateCurve)market.SearchForPricingStructureType(Currency2DiscountCurveName); var flag = ExchangeRate.quotedCurrencyPair.quoteBasis == QuoteBasisEnum.Currency2PerCurrency1; AnalyticsModel = new FxLegAnalytic(modelData.ValuationDate, RiskMaturityDate, fxCurve, curve1, curve2, flag); } else { AnalyticsModel = new FxLegAnalytic(modelData.ValuationDate, RiskMaturityDate, fxCurve); } } IFxLegParameters analyticModelParameters = new FxLegParameters { Multiplier = Multiplier, MarketQuote = rate, }; CalculationResults = AnalyticsModel.Calculate <IFxLegInstrumentResults, FxLegInstrumentResults>( 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); } else { streamValuation = paymentValuation; } CalculationPerfomedIndicator = true; streamValuation.id = Id; return(streamValuation); }