/// <summary> /// Value the deal using the cashflow list. /// </summary> /// <param name="pv">Present value to be updated.</param> /// <param name="cash">Realised cash to be updated.</param> public void Value(Vector pv, Vector cash, double baseDate, double valueDate, Vector settlementDate, IInterestRate discount, IInterestRate forecast, IInterestRate repo, IInterestRateVol interestRateVol, IInterestYieldVol interestYieldVol, ISurvivalProb survivalProb, ISACCRResult saccrResult, IIntraValuationDiagnosticsWriter intraValuationDiagnosticsWriter) { CFFixedListDeal deal = (CFFixedListDeal)Deal; pv.Clear(); if (cash != null) { cash.Clear(); } deal.Cashflows.Value(pv, cash, baseDate, valueDate, settlementDate, discount, survivalProb, intraValuationDiagnosticsWriter, fCutoffDate); ApplySign(pv, cash, fBuySellSign); }
/// <summary> /// Single date valuation function. /// </summary> public void Value(Vector pv, Vector cash, double baseDate, double valueDate, Vector settlementDate, IInterestRate discount, IInterestRate forecast, IInterestRate repo, IInterestRateVol interestRateVol, IInterestYieldVol interestYieldVol, ISurvivalProb survivalProb, ISACCRResult saccrResult, IIntraValuationDiagnosticsWriter intraValuationDiagnosticsWriter) { FixedCashflowBaseDeal deal = (FixedCashflowBaseDeal)fDeal; double payDate = deal.Payment_Date; if (payDate < valueDate) { return; } using (var cache = Vector.CacheLike(pv)) { Vector amount = cache.Get(fAmount); if (settlementDate != null) { amount.MultiplyBy(settlementDate < payDate); } if (payDate == valueDate) { pv.Assign(amount); if (cash != null) { cash.Assign(amount); } } else { double t = CalcUtils.DaysToYears(valueDate - baseDate); double tPay = CalcUtils.DaysToYears(payDate - baseDate); if (survivalProb != null) { pv.Assign(amount * discount.Get(t, tPay) * survivalProb.Get(t, tPay)); } else { pv.Assign(amount * discount.Get(t, tPay)); } } } }
/// <summary> /// Value the deal. /// </summary> /// <param name="pv">Present value to be updated.</param> /// <param name="cash">Realised cash to be updated.</param> public override void Value(Vector pv, Vector cash, double baseDate, double valueDate, ISACCRResult saccrResult, IIntraValuationDiagnosticsWriter intraValuationDiagnosticsWriter) { var deal = (CFEquityFloatingInterestListDeal)Deal; pv.Clear(); if (cash != null) { cash.Clear(); } var equityParams = new EquityCashflowParams((IEquityPrice)fEquity, (EquityPriceVol)fEquityVol, fEquityFXRate, fEquityPayoffFXRate, deal.GetEquityPayoffType(), fEquityQuantoCompo, null, null); if (!fForecastIsForeign && fCharacteristics.fIsStandardLibor) { // standard swap leg deal.Cashflows.ValueSwap(pv, cash, baseDate, valueDate, fDiscountRate, fForecastRate, equityParams, fFxRate, intraValuationDiagnosticsWriter, fCutoffDate); } else { using (var cache = Vector.CacheLike(pv)) { // Use general equity cashflow list valuation for quanto or convexity corrections. var irParams = new IRCashflowParams(fForecastRate, fDiscountRate, fForecastRateVol, fDiscountRateVol, fForecastFXVol, fForecastFXCorrel, fForecastDiscountCorrel, cache.Get(1.0), ReferenceEquals(fForecastRate, fDiscountRate), fForecastRate.GetCurrency() != fDiscountRate.GetCurrency(), Convexity_Correction == YesNo.Yes, Quanto_Correction == YesNo.Yes); deal.Cashflows.Value(pv, cash, baseDate, valueDate, irParams, equityParams, fFxRate, intraValuationDiagnosticsWriter, fCutoffDate); } } pv.Assign(fBuySellSign * pv); if (cash != null) { cash.AssignProduct(fBuySellSign, cash); } }
/// <summary> /// Value a caplet or floorlet under the 1 factor Hull-White model. /// </summary> public override void Value(Vector pv, Vector cash, double baseDate, double valueDate, ISACCRResult saccrResult, IIntraValuationDiagnosticsWriter intraValuationDiagnosticsWriter) { int count = fCashflows.Count(); bool forecastIsDiscount = ReferenceEquals(fForecastRate, fDiscountRate); // time of dfStart and dfEnd double tDfStart = double.NegativeInfinity; double tDfEnd = double.NegativeInfinity; using (var cache = Vector.CacheLike(pv)) { // Shared between loops Vector dfStart = cache.Get(); Vector dfEnd = cache.Get(); VectorEngine.For(0, count, LoopDirection.Backwards, i => { using (var innerCache = Vector.CacheLike(pv)) { CFFloatingInterest cashflow = fCashflows[i]; if (cashflow.Payment_Date < valueDate || cashflow.Payment_Date <= fCutoffDate) { return(LoopAction.Break); } Vector rate = innerCache.Get(); Vector dfPay = innerCache.Get(); Vector stdDev = innerCache.GetClear(); Vector amount = innerCache.GetClear(); GeneralCashflowProperties properties = fCashflows.GetCashflowProperties(i); double tPay = CalcUtils.DaysToYears(cashflow.Payment_Date - baseDate); bool haveDfPay = false; if (forecastIsDiscount && tPay == tDfStart) { dfPay.Assign(dfStart); haveDfPay = true; } using (IntraValuationDiagnosticsHelper.StartCashflow(intraValuationDiagnosticsWriter)) using (var volatilitiesAtDateStore = IntraValuationDiagnosticsHelper.CreateVolatilitiesAtDateStore(intraValuationDiagnosticsWriter, pv.Count)) { cashflow.AddPropertiesToIntraValuationDiagnostics(intraValuationDiagnosticsWriter); // Standard Libor implies single reset. var reset = cashflow.Resets.Single(); if (reset.IsKnown(baseDate)) { rate.Assign(reset.Known_Rate); } else { double tValue = CalcUtils.DaysToYears(valueDate - baseDate); double tReset = CalcUtils.DaysToYears(reset.Reset_Date - baseDate); double tStart = CalcUtils.DaysToYears(reset.Rate_Start_Date - baseDate); double tEnd = CalcUtils.DaysToYears(reset.Rate_End_Date - baseDate); // Reset is a historical or forward Libor rate. InterestRateUtils.LiborRate(rate, fForecastRate, tValue, tReset, tStart, tEnd, reset.Rate_Year_Fraction, dfStart, ref tDfStart, dfEnd, ref tDfEnd); if (tReset > tValue) { GetStandardDeviation(stdDev, tValue, tReset, tStart, tEnd); volatilitiesAtDateStore.Add(valueDate, reset.Reset_Date, stdDev); } } if (!haveDfPay && forecastIsDiscount && tPay == tDfEnd) { dfPay.Assign(dfEnd); haveDfPay = true; } // Add swaplet value amount.AddProduct(properties.Swap_Multiplier, rate); double tau = reset.Rate_Year_Fraction; rate.Assign(1.0 + rate * tau); // Add cap and floor option values. AddOptionValue(amount, OptionType.Call, rate, properties.Cap_Strike, stdDev, tau, properties.Cap_Multiplier); AddOptionValue(amount, OptionType.Put, rate, properties.Floor_Strike, stdDev, tau, properties.Floor_Multiplier); amount.Assign(fBuySellSign * (cashflow.Fixed_Amount + cashflow.Notional * (amount + cashflow.Margin) * cashflow.Accrual_Year_Fraction)); IntraValuationDiagnosticsHelper.AddImpliedVolatilities(intraValuationDiagnosticsWriter, volatilitiesAtDateStore); CFFixedList.RoundCashflow(amount, Cashflow_Rounding); CFFixedList.UpdatePvAndCash(cashflow, baseDate, valueDate, haveDfPay ? null : fDiscountRate, null, amount, dfPay, pv, cash, intraValuationDiagnosticsWriter); } } return(LoopAction.Continue); }); } }
/// <summary> /// Value the deal using the cashflow list. /// </summary> /// <param name="pv">Present value to be updated.</param> /// <param name="cash">Realised cash to be updated.</param> public void Value(Vector pv, Vector cash, double baseDate, double valueDate, Vector settlementDate, IInterestRate discount, IInterestRate forecast, IInterestRate repo, IInterestRateVol interestRateVol, IInterestYieldVol interestYieldVol, ISurvivalProb survivalProb, ISACCRResult saccrResult, IIntraValuationDiagnosticsWriter intraValuationDiagnosticsWriter) { CFFixedInterestListDeal deal = (CFFixedInterestListDeal)Deal; pv.Clear(); if (cash != null) { cash.Clear(); } deal.Cashflows.Value(pv, cash, null, baseDate, valueDate, settlementDate, discount, survivalProb, fFxRate, fRateFxRate, intraValuationDiagnosticsWriter, fCutoffDate); using (var cache = Vector.CacheLike(pv)) { Vector sp = cache.Get(1.0); double dealSettlementDate = deal.Settlement_Date; double t = CalcUtils.DaysToYears(valueDate - baseDate); double tSettle = CalcUtils.DaysToYears(dealSettlementDate - baseDate); if (Use_Survival_Probability == YesNo.Yes && survivalProb != null) { survivalProb.GetValue(sp, t, tSettle); fRecoveryList.Value(pv, baseDate, valueDate, discount, survivalProb, intraValuationDiagnosticsWriter); } if (valueDate < dealSettlementDate) { // Forward deal before settlement date if (deal.Is_Defaultable == YesNo.No) { pv.Assign((pv / discount.Get(t, tSettle) - fSettlementAmount) * repo.Get(t, tSettle)); } else { pv.Subtract(fAccruedInterest * discount.Get(t, tSettle) * sp + (fSettlementAmount - fAccruedInterest) * repo.Get(t, tSettle)); } } else if (valueDate == dealSettlementDate) { // Forward deal at settlement date pv.Subtract(fSettlementAmount); if (cash != null) { if (deal.Settlement_Style == SettlementType.Cash) { cash.Assign(pv); } else { cash.Subtract(fSettlementAmount); } } } } pv.AssignProduct(fBuySellSign, pv); if (cash != null) { cash.AssignProduct(fBuySellSign, cash); } }
/// <summary> /// Value the deal. /// </summary> /// <param name="pv">Present value to be updated.</param> /// <param name="cash">Realised cash to be updated.</param> public override void Value(Vector pv, Vector cash, double baseDate, double valueDate, ISACCRResult saccrResult, IIntraValuationDiagnosticsWriter intraValuationDiagnosticsWriter) { Value(pv, cash, baseDate, valueDate, null, fDiscountRate, null, fRepoRate, null, null, fSurvivalProb, saccrResult, intraValuationDiagnosticsWriter); // Add accruedInterest to Intra-valuation diagnostics if (intraValuationDiagnosticsWriter.Level > IntraValuationDiagnosticsLevel.None) { CFFixedInterestListDeal deal = (CFFixedInterestListDeal)Deal; using (var cache = Vector.CacheLike(pv)) { Vector accruedInterest = cache.Get(deal.Cashflows.CalculateAccrual(valueDate, false, deal.GetHolidayCalendar())); IntraValuationDiagnosticsHelper.AddCashflowsAccruedInterest(fIntraValuationDiagnosticsWriter, accruedInterest); } } }
/// <summary> /// Value the deal. /// </summary> /// <param name="pv">Present value to be updated.</param> /// <param name="cash">Realised cash to be updated.</param> /// <param name="baseDate">Base date of the calculation.</param> /// <param name="valueDate">Valuation date.</param> /// <param name="intraValuationDiagnosticsWriter">Cashflow writer.</param> public override void Value(Vector pv, Vector cash, double baseDate, double valueDate, ISACCRResult saccrResult, IIntraValuationDiagnosticsWriter intraValuationDiagnosticsWriter) { // pv -> fBuySellSign * (fBuySellSign * pv + cashflowListPv) = pv + fBuySellSign * cashflowListPv ApplySign(pv, cash, fBuySellSign); fCashflows.Value(pv, cash, baseDate, valueDate, fDiscountRate, fForecastRate, fForecastRate2, fDiscountRateVol, fDiscountYieldVol, fForecast1RateVol, fForecast1YieldVol, fForecast2RateVol, fForecast2YieldVol, fFx1Vol, fFx2Vol, fForecast1Fx1Correl, fForecast2Fx2Correl, fForecast1DiscountCorrel, fForecast2DiscountCorrel, fForecast1Forecast2Correl, fForecast1Forecast2Correls, fCutoffDate); ApplySign(pv, cash, fBuySellSign); }
/// <summary> /// Value the deal using the cashflow list. /// </summary> public void Value(Vector pv, Vector cash, double baseDate, double valueDate, Vector settlementDate, IInterestRate discount, IInterestRate forecast, IInterestRate repo, IInterestRateVol interestRateVol, IInterestYieldVol interestYieldVol, ISurvivalProb survivalProb, ISACCRResult saccrResult, IIntraValuationDiagnosticsWriter intraValuationDiagnosticsWriter) { var deal = (CFFloatingInterestListDeal)Deal; pv.Clear(); if (cash != null) { cash.Clear(); } bool valued = false; if (Use_Survival_Probability == YesNo.Yes && survivalProb != null) { fRecoveryList.Value(pv, baseDate, valueDate, discount, survivalProb, intraValuationDiagnosticsWriter); } else if (!fForecastIsForeign && fCharacteristics.IsStandardPayoff && fCharacteristics.IsStandardLibor && fCashflows.Compounding_Method != CompoundingMethod.Exponential) { if (fCharacteristics.HasSwaplet && !fCharacteristics.HasOptionlet) { ValueSwap(pv, cash, baseDate, valueDate, settlementDate, discount, forecast, intraValuationDiagnosticsWriter); valued = true; } else if (fCharacteristics.HasOptionlet && !fCharacteristics.HasSwaplet && fCashflows.Compounding_Method == CompoundingMethod.None) { fCashflows.ValueCap(pv, cash, baseDate, valueDate, settlementDate, discount, forecast, fForecastRateVol, saccrResult, intraValuationDiagnosticsWriter, fCutoffDate); valued = true; } } if (!valued) { // Use general cashflow list valuation if (fCashflows.Averaging_Method == AveragingMethod.Average_Rate) { fCashflows.ValueAverageRate(pv, cash, baseDate, valueDate, settlementDate, discount, forecast, fForecastRateVol, fForecastYieldVol, fFxRate, fForecastFxRate, fForecastFxVol, fForecastFxCorrel, survivalProb, intraValuationDiagnosticsWriter, fCutoffDate); } else { fCashflows.Value(pv, cash, baseDate, valueDate, settlementDate, discount, forecast, fDiscountRateVol, fDiscountYieldVol, interestRateVol, interestYieldVol, fFxRate, fForecastFxRate, fForecastFxVol, fForecastFxCorrel, fForecastDiscountCorrel, survivalProb, intraValuationDiagnosticsWriter, fCutoffDate); } } double dealSettlementDate = deal.Settlement_Date; if (valueDate <= dealSettlementDate) { using (var cache = Vector.CacheLike(pv)) { Vector accruedInterest = cache.Get(); fCashflows.CalculateAccrual(accruedInterest, baseDate, dealSettlementDate, false, deal.AccrualHolidayCalendar(), forecast); Vector settlementAmount = cache.Get(deal.Settlement_Amount); if (deal.Settlement_Amount_Is_Clean == YesNo.Yes) { settlementAmount.Add(accruedInterest); } if (valueDate < dealSettlementDate) { // Forward deal before settlement date double t = CalcUtils.DaysToYears(valueDate - baseDate); double tSettle = CalcUtils.DaysToYears(dealSettlementDate - baseDate); if (deal.Is_Defaultable == YesNo.No) { pv.Assign((pv / discount.Get(t, tSettle) - settlementAmount) * repo.Get(t, tSettle)); } else { pv.Subtract(accruedInterest * discount.Get(t, tSettle) + (settlementAmount - accruedInterest) * repo.Get(t, tSettle)); } } else if (valueDate == dealSettlementDate) { // Forward deal at settlement date pv.Subtract(settlementAmount); if (cash != null) { if (deal.Settlement_Style == SettlementType.Cash) { cash.Assign(pv); } else { cash.Subtract(settlementAmount); } } } } } pv.AssignProduct(fBuySellSign, pv); if (cash != null) { cash.AssignProduct(fBuySellSign, cash); } }
/// <summary> /// Value the deal. /// </summary> /// <param name="pv">Present value to be updated.</param> /// <param name="cash">Realised cash to be updated.</param> public override void Value(Vector pv, Vector cash, double baseDate, double valueDate, ISACCRResult saccrResult, IIntraValuationDiagnosticsWriter intraValuationDiagnosticsWriter) { Value(pv, cash, baseDate, valueDate, null, fDiscountRate, null, fRepoRate, null, null, fSurvivalProb, saccrResult, intraValuationDiagnosticsWriter); }
/// <summary> /// Value the deal. /// </summary> public abstract void Value(Vector pv, Vector cash, double baseDate, double valueDate, ISACCRResult saccrResult, IIntraValuationDiagnosticsWriter intraValuationDiagnosticsWriter);