/// <summary> /// Gets the discount rate used in the option valuation formula. /// </summary> protected override void GetDiscountRate(Vector r, IInterestRate discountRate, double t, double tPay) { Double date = fBaseDate + CalcUtils.YearsToDays(t); Double payDate = fBaseDate + CalcUtils.YearsToDays(tPay); r.Assign(VectorMath.Log(discountRate.Get(t, tPay)) / CalcUtils.DayCountFraction(payDate, date, DayCount.BUS_252, ((IDIOptionDeal)Deal).Calendar())); }
/// <summary> /// Get price factors. /// </summary> private void PreValue(PriceFactorList factors) { var deal = (CalendarSpreadOption)Deal; // Get forward price samples. fForwardSample = factors.Get <ForwardPriceSample>(deal.Sampling_Type); // Get ReferencePrice price factors. fReferencePrice1 = factors.GetInterface <IReferencePrice>(deal.Reference_Type); fReferencePrice2 = factors.GetInterface <IReferencePrice>(deal.Reference_Type); // Get ReferenceVol price factors. // Default to Reference Type if Reference Vol Type is not set. if (string.IsNullOrEmpty(deal.Reference_Vol_Type)) { fReferenceVol1 = factors.Get <ReferenceVol>(deal.Reference_Type); fReferenceVol2 = factors.Get <ReferenceVol>(deal.Reference_Type); } else { fReferenceVol1 = factors.Get <ReferenceVol>(deal.Reference_Vol_Type); fReferenceVol2 = factors.Get <ReferenceVol>(deal.Reference_Vol_Type); } // Get correlation price factor based on the ID of the forward price. fCorrelations = factors.Get <ForwardPriceCorrelations>(fReferencePrice1.GetForwardPrice()); // Get FX rate price factors. fFxRate = factors.GetInterface <IFxRate>(deal.Currency); fFxPayoffRate = factors.GetInterface <IFxRate>(deal.DealCurrency()); fPriceFactorFxRate = factors.GetInterface <IFxRate>(fReferencePrice1.DomesticCurrency()); // Get discount rate price factor. fDiscountRate = factors.GetInterface <IInterestRate>(InterestRateUtils.GetRateId(deal.Discount_Rate, deal.Currency)); }
/// <summary> /// Value cashflow list with standard payoff, standard LIBOR cashflows without options. /// </summary> private void ValueSwap(Vector pv, Vector cash, double baseDate, double valueDate, Vector settlementDate, IInterestRate discount, IInterestRate forecast, IIntraValuationDiagnosticsWriter intraValuationDiagnosticsWriter) { if (fCharacteristics.IsOIS && OIS_Cashflow_Group_Size <= 1 && settlementDate == null) { fCashflows.ValueOIS(pv, cash, baseDate, valueDate, fCutoffDate, discount, forecast, intraValuationDiagnosticsWriter); } else { fCashflows.ValueSwap(pv, cash, null, baseDate, valueDate, settlementDate, fCutoffDate, discount, forecast, fCharacteristics.IsVanillaSwap, intraValuationDiagnosticsWriter); } }
/// <summary> /// Constructor. /// </summary> public CreditValuationParameters(DealCreditBase deal, CreditBaseValuation valuation, PriceFactorList factors, VectorScopedCache.Scope cache) { DF = DiscountRate.Get(factors, InterestRateUtils.GetRateId(deal.Discount_Rate, deal.Currency)); X = factors.GetInterface <IFxRate>(deal.Currency); SP = factors.GetInterface <ISurvivalProb>(string.IsNullOrEmpty(deal.Survival_Probability) ? deal.Name : deal.Survival_Probability); RR = null; CR = null; DefaultTime = null; Weights = null; NamesDefaultedBeforeBaseDate = null; if (valuation.Respect_Default == YesNo.Yes) { List <string> names = new List <string>(); if (deal.ProtectionReferenceType() == DealCreditBase.ReferenceType.Single_Name) { names.Add(deal.Name); Weights = new double[] { 1.0 }; } else { IndexCDSPool indexCds = factors.Get <IndexCDSPool>(deal.Name); Weights = new double[indexCds.Names.Count]; for (int i = 0; i < indexCds.Names.Count; ++i) { names.Add(indexCds.Names[i].Name); Weights[i] = indexCds.Names[i].Weight; } } if (valuation.RequiresRecoveryOnDefault()) { RR = new RecoveryRate[names.Count]; for (int i = 0; i < names.Count; ++i) { RR[i] = factors.Get <RecoveryRate>(string.IsNullOrEmpty(deal.Recovery_Rate) ? names[i] : deal.Recovery_Rate); } } CR = new CreditRating[names.Count]; NamesDefaultedBeforeBaseDate = new bool[names.Count]; DefaultTime = new Vector[names.Count]; for (int i = 0; i < names.Count; ++i) { DefaultTime[i] = cache.Get(); CR[i] = factors.Get <CreditRating>(names[i]); NamesDefaultedBeforeBaseDate[i] = CreditRating.DefaultedBeforeBaseDate(CR[i], factors.BaseDate); CR[i].DefaultTime(DefaultTime[i]); } } }
/// <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; }
public Account(ICustomer customer, AccountType type = AccountType.Normal, float balance = 0.0F, DateTime closeDate = default(DateTime), IInterestRate state = null, float allowedDebit = 250.00F) { AccountId = customer.NewAccountId(); CustomerId = customer.CustomerId; Balance = balance; OpenDate = DateTime.Now; CloseDate = closeDate; History = new List<IOperationHistory>(); AllowedDebit = allowedDebit; Debits = 0.0F; Type = type; State = state ?? new Normal(this); State.Check(); }
/// <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); }
/// <inheritdoc /> public void PreValue(PriceFactorList factors) { var deal = (SwaptionDeal)Deal; var discountId = InterestRateUtils.GetRateId(deal.Discount_Rate, deal.Currency); var forecastId = InterestRateUtils.GetRateId(deal.Forecast_Rate, discountId); fModelParameters = factors.Get <HullWhite1FactorModelParameters>(fModelParametersId); fFxRate = factors.GetInterface <IFxRate>(deal.Currency); fDiscountRate = DiscountRate.Get(factors, discountId); fForecastRate = factors.GetInterface <IInterestRate>(forecastId); fQuadrature = new Lazy <GaussHermiteNormalQuadrature>(() => new GaussHermiteNormalQuadrature(30)); }
/// <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> /// This method Adjusts the bond price vector by taking the default into account give the default time vector. /// </summary> public static void AdjustForDefault(double baseDate, double valueDate, Vector bondPrice, TDate expiryDate, bool respectDefault, Vector underlyingIsAlive, Vector historicalRecovery, Vector defaultTime, IInterestRate discountRate, RecoveryRate recoveryRate) { // Adjust the bond price for default: check scenario by scenario for defaults, overwriting bondPrice as necessary if (!respectDefault) { return; } double currentTime = CalcUtils.DaysToYears(valueDate - baseDate); double tExpiry = CalcUtils.DaysToYears(expiryDate - baseDate); BondOptionValuation.AdjustBondValueForDefault(1.0, tExpiry, bondPrice, underlyingIsAlive, historicalRecovery, defaultTime, currentTime, discountRate, recoveryRate); }
/// <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> /// This method check scenario by scenario for defaults, overwriting bondValue as necessary /// </summary> public static void AdjustBondValueForDefault(double notional, double expiryTime, Vector bondValue, Vector bondIsAlive, Vector historicalRecovery, Vector defaultTime, double currentTime, IInterestRate discountRate, RecoveryRate recoveryRate) { using (var cache = Vector.CacheLike(bondValue)) { Vector recoveryValue = cache.Get(); Vector expiryDf = cache.Get(); discountRate.GetValue(expiryDf, currentTime, expiryTime); recoveryRate.GetValue(recoveryValue, currentTime); // If this is the period when the bond defaults fill in the historical recovery amount. historicalRecovery.AssignConditional((defaultTime <= currentTime).And(bondIsAlive), recoveryValue * notional, historicalRecovery); bondValue.AssignConditional((defaultTime <= currentTime), expiryDf * historicalRecovery, bondValue); bondIsAlive.AssignConditional((defaultTime <= currentTime), 0.0, bondIsAlive); } }
/// <summary> /// Value the deal from given base date, price factors and time grid. /// </summary> public void Value(PVProfiles pvResults, CashAccumulators cashResults, double baseDate, IInterestRate discountRate, IInterestRate forecastRate1, IInterestRate forecastRate2, IFxRate fxRate, TimeGrid timeGrid, int numScenarios) { var tgi = new TimeGridIterator(timeGrid); var deal = (FloatingInterestCashflowInterpolatedDeal)Deal; bool hasRate1 = deal.HasRate1(); bool hasRate2 = deal.HasRate2(); double scale = deal.Buy_Sell == BuySell.Buy ? +deal.Principal : -deal.Principal; double tPay = CalcUtils.DaysToYears(fPaymentDate - baseDate); double tReset = CalcUtils.DaysToYears(deal.Reset_Date - baseDate); double tRateStart = CalcUtils.DaysToYears(deal.Rate_Start_Date - baseDate); double tRateEnd1 = hasRate1 ? CalcUtils.DaysToYears(fRate1EndDate - baseDate) : 0.0; double tRateEnd2 = hasRate2 ? CalcUtils.DaysToYears(fRate2EndDate - baseDate) : 0.0; double tRateEnd12 = tRateEnd2 - tRateEnd1; // Time from rate 1 end date to rate 2 end date. double tAccrualEnd = CalcUtils.DaysToYears(deal.Accrual_End_Date - baseDate); double interpCoefficient = Math.Abs(tRateEnd12) >= CalcUtils.MinTime ? (tAccrualEnd - tRateEnd1) / tRateEnd12 : 0.0; // Coefficient used to calculate interpolated rate. VectorEngine.For(tgi, () => { using (var cache = Vector.Cache(numScenarios)) { Vector pv = cache.Get(); if (tgi.Date <= fPaymentDate && fPaymentDate > fCutoffDate) { Vector interpRate = cache.GetClear(); Vector rate1 = cache.GetClear(); Vector rate2 = cache.GetClear(); if (hasRate1) { if (fKnownResetRate1.HasValue) { rate1.Assign(fKnownResetRate1.Value); } else { InterestRateUtils.LiborRate(rate1, forecastRate1, tgi.T, tReset, tRateStart, tRateEnd1, fRate1YearFraction); } } if (hasRate2) { if (fKnownResetRate2.HasValue) { rate2.Assign(fKnownResetRate2.Value); } else { InterestRateUtils.LiborRate(rate2, forecastRate2, tgi.T, tReset, tRateStart, tRateEnd2, fRate2YearFraction); } } if (hasRate1 && hasRate2) { if (Math.Abs(tRateEnd12) >= CalcUtils.MinTime) { interpRate.Assign(rate1 + interpCoefficient * (rate2 - rate1)); } else { interpRate.Assign(0.5 * rate1 + 0.5 * rate2); } } else { interpRate.Assign(hasRate1 ? rate1 : rate2); } // Round the calculated rate, regardless whether the valuation date is before or after the reset date. CFFloatingInterestList.RoundRateTo(deal.Interpolated_Rate_Rounding, interpRate); pv.Assign(scale * (interpRate + deal.Margin) * fAccrualYearFraction); CFFixedList.RoundCashflow(pv, Cashflow_Rounding); if (tgi.Date < fPaymentDate) { pv.MultiplyBy(discountRate.Get(tgi.T, tPay)); } else if (tgi.Date == fPaymentDate) { cashResults.Accumulate(fxRate, fPaymentDate, pv); } } else { pv.Clear(); } pvResults.AppendVector(tgi.Date, pv * fxRate.Get(tgi.T)); } }); // After maturity pvResults.Complete(timeGrid); }
/// <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> /// 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); } } } }