/// <summary> /// Prepare for valuation anything that is not dependent upon the scenario. /// </summary> public override void PreCloneInitialize(PriceFactorList factors, BaseTimeGrid baseTimes, RequiredResults requiredResults) { base.PreCloneInitialize(factors, baseTimes, requiredResults); IInflationCashflowListDeal deal = (IInflationCashflowListDeal)Deal; // Set up cashflow list IInflationRate inflationRate = deal.NeedInflationRate() ? factors.GetInterface <IInflationRate>(deal.Index) : null; deal.GetCashflows().PreCloneInitialize(factors.BaseDate, inflationRate, deal.GetHolidayCalendar()); // Add to valuation time grid deal.AddPayDates(fT); if (deal.Investment_Horizon > 0.0) { fT.AddPayDate(deal.Investment_Horizon, requiredResults.CashRequired()); } if (deal.Settlement_Date > 0.0) { fT.AddPayDate(deal.Settlement_Date, requiredResults.CashRequired()); } // Recovery cashflows are created on the fly to respect customized cashflows if (NeedRecoveryCashflows()) { fRecoveryCashflowList = new CFRecoveryInflationList(); fRecoveryCashflowList.PopulateRecoveryCashflowList(factors.BaseDate, deal.Settlement_Date, deal.GetCashflows()); } }
/// <summary> /// Register price factors. /// </summary> public override void RegisterFactors(PriceFactorList factors, ErrorList errors) { base.RegisterFactors(factors, errors); IInflationCashflowListDeal deal = (IInflationCashflowListDeal)Deal; if (deal.NeedInflationRate()) { factors.RegisterInterface <IInflationRate>(deal.Index); } if (NeedCreditRating()) { factors.Register <CreditRating>(deal.Issuer); } if (NeedRecoveryRate()) { factors.Register <RecoveryRate>(GetRecoveryRateID()); } if (NeedSurvivalProb()) { factors.RegisterInterface <ISurvivalProb>(GetSurvivalProbID()); } if (!string.IsNullOrEmpty(deal.Repo_Rate)) { factors.RegisterInterface <IInterestRate>(deal.Repo_Rate); } }
/// <summary> /// Modify the pv and cash taking the date of default into account. /// </summary> protected void GetDefaultValue(double baseDate, double valueDate, Vector defaultDate, IInflationRate inflationRate, IPriceIndexVolatility indexVolatility, IInterestRate repo, Vector pv, Vector cash) { IInflationCashflowListDeal deal = (IInflationCashflowListDeal)Deal; double settlementDate = deal.Settlement_Date; double t = CalcUtils.DaysToYears(valueDate - baseDate); double buySellSign = deal.Buy_Sell == BuySell.Buy ? 1.0 : -1.0; if (repo == null) { repo = fDiscountRate; } using (var cache = Vector.CacheLike(pv)) { Vector principal = cache.Get(); GetCurrentExposure(principal, t, valueDate, inflationRate); // Approximation: recover only principal, neglecting accrued interest. Vector recovery = cache.Get(buySellSign * principal * fRecoveryRate.Get(t)); if (valueDate <= settlementDate) { // Set the pv to (recovery - |settlementAmount|) * df when defaultDate <= valueDate <= settlementDate. // Set cash to (recovery - |settlementAmount|) when defaultDate <= valueDate = settlementDate (cash is always zero before settlementDate). // Note that GetSettlementAmount(...) will return a negative value for a long bond position, indicating an outgoing cashflow. double tSettle = CalcUtils.DaysToYears(settlementDate - baseDate); Vector settlementAmount = cache.Get(); GetSettlementAmount(settlementAmount, valueDate, baseDate, inflationRate, indexVolatility); settlementAmount.MultiplyBy(buySellSign); Vector hasDefaulted = cache.Get(defaultDate <= valueDate); pv.AssignConditional(hasDefaulted, repo.Get(t, tSettle) * (recovery + settlementAmount), pv); if (cash != null && valueDate == settlementDate) { cash.AssignConditional(hasDefaulted, pv, cash); } } else { // after settlement date recovery.MultiplyBy(defaultDate >= valueDate); // set to zero if already defaulted Vector notDefaulted = cache.Get(defaultDate > valueDate); pv.AssignConditional(notDefaulted, pv, recovery); if (cash != null) { cash.AssignConditional(notDefaulted, cash, recovery); } } } }
/// <summary> /// Prepare for valuation anything that is dependent upon the scenario. /// </summary> /// <param name="factors">Price factors.</param> public override void PreValue(PriceFactorList factors) { base.PreValue(factors); IInflationCashflowListDeal deal = (IInflationCashflowListDeal)Deal; fIsDefaultNever = !NeedCreditRating(); fCreditRating = NeedCreditRating() ? factors.Get <CreditRating>(deal.Issuer) : null; fRecoveryRate = NeedRecoveryRate() ? factors.Get <RecoveryRate>(GetRecoveryRateID()) : null; fSurvivalProb = NeedSurvivalProb() ? factors.GetInterface <ISurvivalProb>(GetSurvivalProbID()) : null; fInflationRate = !string.IsNullOrEmpty(deal.Index) ? factors.GetInterface <IInflationRate>(deal.Index) : null; fRepoRate = !string.IsNullOrEmpty(deal.Repo_Rate) ? factors.GetInterface <IInterestRate>(deal.Repo_Rate) : fDiscountRate; fIndexVolatility = deal is InflationOptionCashflowListDeal?factors.GetInterface <IPriceIndexVolatility>(GetPriceIndexVolatility()) : null; }
/// <summary> /// Calculate valuation metrics requested by the Base Valuation calculation. /// </summary> private void CalculateMetrics(ValuationResults valuationResults, PriceFactorList factors, IInflationCashflowListDeal deal) { var results = valuationResults.Results <ValuationMetrics>(); if (results == null) { return; } if (results.IsMetricRequested(ValuationMetricConstants.AccruedInterest)) { using (var cache = Vector.Cache(factors.NumScenarios)) { double?parameter = results.GetMetricParameter(ValuationMetricParameterConstants.AccrueFromToday); bool accrueFromToday = parameter.HasValue && parameter.Value == 1.0; Vector accruedInterest = cache.GetClear(); double buySellSign = deal.Buy_Sell == BuySell.Buy ? 1.0 : -1.0; deal.GetCashflows().CalculateAccrual(accruedInterest, factors.BaseDate, factors.BaseDate, accrueFromToday, deal.GetHolidayCalendar(), fInflationRate, fIndexVolatility, buySellSign); results.SetMetricValue(ValuationMetricConstants.AccruedInterest, new ValuationId(this), accruedInterest[0]); } } }
protected virtual bool DealHasIssuer() { IInflationCashflowListDeal deal = (IInflationCashflowListDeal)Deal; return(!string.IsNullOrEmpty(deal.Issuer)); }