/// <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> /// Returns the payment amount on settlement date based on the cashflowlist. /// </summary> /// <remarks> /// The payment amount on settlement date will be either the dirty price of the bond or the clean price of the bond plus /// the accrued interest (two cashflows). Note that for a long position in a bond forward, this value is negative /// (indicating outgoing cashflow). /// </remarks> protected virtual void GetSettlementAmount(Vector amount, double valueDate, double baseDate, IInflationRate inflationRate, IPriceIndexVolatility indexVolatility) { amount.Clear(); using (var cache = Vector.CacheLike(amount)) { var deal = (IInflationCashflowListDeal)Deal; var cashflows = deal.GetCashflows(); Vector settlementPay = cache.Get(); for (int i = 0; i < cashflows.Count(); ++i) { if (cashflows.GetCashflow(i).Payment_Date < deal.Settlement_Date) { continue; } else if (cashflows.GetCashflow(i).Payment_Date == deal.Settlement_Date) { cashflows.GetCashflow(i).ExpectedAmount(settlementPay, CalcUtils.DaysToYears(valueDate - baseDate), inflationRate, indexVolatility, IntraValuationDiagnosticsWriterFactory.GetOrCreate(IntraValuationDiagnosticsLevel.None)); amount.Add(settlementPay); } else { break; } } } }
/// <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); } } } }