/// <summary> /// Value the fixed and floating legs of the swap. /// </summary> private void ValueFixedAndFloatingLegs(TimeGridIterator tgi, Vector fixedPv, Vector fixedCash, double baseDate, Vector floatPv, Vector floatCash) { using (IntraValuationDiagnosticsHelper.StartCashflowsOnDate(fIntraValuationDiagnosticsWriter, tgi.Date)) { using (IntraValuationDiagnosticsHelper.StartSwaptionCashflows(fIntraValuationDiagnosticsWriter, fFxRate, tgi.T, CashflowType.FixedLeg, fSwaptionDeal.Floating_Margin)) { // Calculate value of fixed side fixedPv.Clear(); fixedCash.Clear(); fFixedCashflowList.Value(fixedPv, fixedCash, null, baseDate, tgi.Date, null, fDiscountRate, null, null, null, fIntraValuationDiagnosticsWriter, 0.0); IntraValuationDiagnosticsHelper.AddCashflowsPV(fIntraValuationDiagnosticsWriter, fixedPv); } using (IntraValuationDiagnosticsHelper.StartSwaptionCashflows(fIntraValuationDiagnosticsWriter, fFxRate, tgi.T, CashflowType.FloatingLeg, fSwaptionDeal.Floating_Margin)) { // Calculate value of floating side floatPv.Clear(); floatCash.Clear(); fFloatCashflowList.ValueSwap(floatPv, floatCash, null, baseDate, tgi.Date, null, 0.0, fDiscountRate, fForecastRate, false, fIntraValuationDiagnosticsWriter); IntraValuationDiagnosticsHelper.AddCashflowsPV(fIntraValuationDiagnosticsWriter, floatPv); } } }
/// <summary> /// Calculate a valuation profile for the deal for the current scenario. /// </summary> public override void Value(ValuationResults valuationResults, PriceFactorList factors, BaseTimeGrid baseTimes) { PreValue(factors); var deal = (CFListBaseDeal <TCashflowList>)fDeal; double baseDate = factors.BaseDate; var tgi = new TimeGridIterator(fT); PVProfiles result = valuationResults.Profile; CashAccumulators cashAccumulators = valuationResults.Cash; double endDate = deal.EndDate(); using (IntraValuationDiagnosticsHelper.StartDeal(fIntraValuationDiagnosticsWriter, fDeal)) { using (var outerCache = Vector.Cache(factors.NumScenarios)) { Vector defaultDate = fCreditRating != null?outerCache.Get(CalcUtils.DateTimeMaxValueAsDouble) : null; var defaultedBeforeBaseDate = CreditRating.DefaultedBeforeBaseDate(fCreditRating, baseDate); bool collectCash = ValueOnCashflowDates(); var saccrResult = SACCRResultFactory.Create(valuationResults, deal.GetDealReferenceProvider().DealReference, () => new SACCROptionResult(factors.NumScenarios)); VectorEngine.For(tgi, () => { using (var cache = Vector.Cache(factors.NumScenarios)) { Vector pv = cache.GetClear(); Vector cash = collectCash ? cache.GetClear() : null; if (!defaultedBeforeBaseDate) { using (IntraValuationDiagnosticsHelper.StartCashflowsOnDate(fIntraValuationDiagnosticsWriter, tgi.Date)) { using (IntraValuationDiagnosticsHelper.StartCashflows(fIntraValuationDiagnosticsWriter, fFxRate, tgi.T, deal)) { Value(pv, cash, baseDate, tgi.Date, saccrResult, fIntraValuationDiagnosticsWriter); IntraValuationDiagnosticsHelper.AddCashflowsPV(fIntraValuationDiagnosticsWriter, pv); } } if (fCreditRating != null) { UpdateDefaultDate(fCreditRating, tgi.Date, tgi.T, defaultDate); GetDefaultValue(baseDate, tgi.Date, defaultDate, fRecoveryRate, pv, cash); } } result.AppendVector(tgi.Date, pv * fFxRate.Get(tgi.T)); if (!cashAccumulators.Ignore && cash != null) { // Realise all value as cash on deal end date if (tgi.Date == endDate) { cash.Assign(pv); } cashAccumulators.Accumulate(fFxRate, tgi.Date, cash); } } }); if (!cashAccumulators.Ignore && !collectCash) { CollectCashflows(cashAccumulators, baseDate, fT.fHorizon); // Consolidate and net in order to avoid getting Net incoming and outgoing cashflows with the same payment date, // e.g. for compounding swaps with both positive and negative rates. cashAccumulators.ConsolidateAndNet(fCurrency, factors); } result.Complete(fT); } } }
/// <summary> /// Calculate valuation profiles. /// </summary> public override void Value(ValuationResults valuationResults, PriceFactorList factors, BaseTimeGrid baseTimes) { PreValue(factors); var result = valuationResults.Profile; var cashAccumulator = valuationResults.Cash; var accruedResults = valuationResults.Results <AccruedInterest>(); var deal = (IInflationCashflowListDeal)Deal; double sign = deal.Buy_Sell == BuySell.Buy ? 1.0 : -1.0; var cashflows = deal.GetCashflows(); var calendar = deal.GetHolidayCalendar(); double baseDate = factors.BaseDate; var tgi = new TimeGridIterator(fT); CalculateMetrics(valuationResults, factors, deal); using (IntraValuationDiagnosticsHelper.StartDeal(fIntraValuationDiagnosticsWriter, fDeal)) { using (var cache = Vector.Cache(factors.NumScenarios)) { Vector defaultDate = null; if (!fIsDefaultNever) { defaultDate = fCreditRating != null?cache.Get(CalcUtils.DateTimeMaxValueAsDouble) : null; } Vector pv = cache.GetClear(); Vector cash = cashAccumulator.Ignore ? null : cache.Get(); Vector accruedInterest = cache.GetClear(); VectorEngine.For(tgi, () => { if (!fIsDefaultNever && CreditRating.DefaultedBeforeBaseDate(fCreditRating, baseDate)) { result.AppendVector(tgi.Date, pv); return(LoopAction.Break); } using (IntraValuationDiagnosticsHelper.StartCashflowsOnDate(fIntraValuationDiagnosticsWriter, tgi.Date)) { using (IntraValuationDiagnosticsHelper.StartCashflows(fIntraValuationDiagnosticsWriter, fFxRate, tgi.T, fDeal)) { cashflows.Value(pv, cash, baseDate, tgi.Date, deal.Settlement_Date, fInflationRate, fIndexVolatility, fDiscountRate, fRepoRate, fSurvivalProb, sign, fIntraValuationDiagnosticsWriter); IntraValuationDiagnosticsHelper.AddCashflowsPV(fIntraValuationDiagnosticsWriter, pv); if (fRecoveryCashflowList != null && fRecoveryCashflowList.Items.Count > 0) { fRecoveryCashflowList.Value(pv, cash, baseDate, tgi.Date, deal.Settlement_Date, fDiscountRate, fRepoRate, fInflationRate, fSurvivalProb, sign); } // Temporary fix up to avoid calculating default when we know the model doesn't support default if (!fIsDefaultNever) { UpdateDefaultDate(fCreditRating, tgi.Date, tgi.T, defaultDate); GetDefaultValue(baseDate, tgi.Date, defaultDate, fInflationRate, fIndexVolatility, fRepoRate, pv, cash); } result.AppendVector(tgi.Date, fFxRate.Get(tgi.T) * pv); if (cash != null) { cashAccumulator.Accumulate(fFxRate, tgi.Date, cash); } if (accruedResults != null) { cashflows.CalculateAccrual(accruedInterest, baseDate, tgi.Date, accruedResults.AccrueFromToday, calendar, fInflationRate, fIndexVolatility, sign); accruedResults.SetValue(tgi.Date, accruedInterest); } else if (fIntraValuationDiagnosticsWriter.Level > IntraValuationDiagnosticsLevel.None) { cashflows.CalculateAccrual(accruedInterest, baseDate, tgi.Date, false, calendar, fInflationRate, fIndexVolatility, sign); } IntraValuationDiagnosticsHelper.AddCashflowsAccruedInterest(fIntraValuationDiagnosticsWriter, accruedInterest); } } return(LoopAction.Continue); }); // On investment horizon or a bond forward's Settlement Date, the deal value is liquidated as cash. double endDate = Deal.EndDate(); if (cash != null && endDate <= fT.fHorizon) { // If endDate on a payment date, cashflow has already been accummulated (as cash), otherwise is 0. // Value liquidated is the value of the pv remaining after accummulating the cashflow. cash.AssignDifference(pv, cash); cashAccumulator.Accumulate(fFxRate, endDate, cash); } } result.Complete(fT); } }