/// <summary> /// Gets the forward rate. /// </summary> /// <returns></returns> public decimal EvaluateForwardRate(DateTime valuationDate, DateTime startDate, DateTime forwardDate, decimal yearFraction, IRateCurve forecastCurve) { var forwardRate = 0.0d; if (forecastCurve != null) { var startDiscountFactor = forecastCurve.GetDiscountFactor(valuationDate, startDate); var endDiscountFactor = forecastCurve.GetDiscountFactor(valuationDate, forwardDate); if (yearFraction != 0) { forwardRate = (startDiscountFactor / endDiscountFactor - 1) / (double)yearFraction; } } return((decimal)forwardRate); }
/// <summary> /// /// </summary> /// <param name="fxCurve"></param> /// <param name="usdCurve"></param> /// <param name="currency"></param> /// <param name="baseDate"></param> /// <param name="algorithmHolder"></param> /// <returns></returns> public static RateCurve CreateBasisAdjustedDiscountCurve(FxCurve fxCurve, IRateCurve usdCurve, string currency, DateTime baseDate, PricingStructureAlgorithmsHolder algorithmHolder) { string quoteCurrency = ((FxCurveIdentifier)fxCurve.GetPricingStructureId()).QuoteCurrency.Value; double power = quoteCurrency == currency ? -1 : 1; double fxRate0 = Math.Pow(fxCurve.GetForward(baseDate), power); var newPoints = new Dictionary <DateTime, Pair <string, decimal> >(); foreach (TermPoint point in fxCurve.GetTermCurve().point) { var pillarPoint = (DateTime)point.term.Items[0]; double fxRateN = Math.Pow(fxCurve.GetForward(pillarPoint), power); double discountFactorN = usdCurve.GetDiscountFactor(pillarPoint); var quoteBasisAdjustedDiscountFactor = (decimal)(discountFactorN * fxRateN / fxRate0); newPoints.Add(pillarPoint, new Pair <string, decimal>(point.id, quoteBasisAdjustedDiscountFactor)); } var newProperties = new Dictionary <string, object> { { CurveProp.PricingStructureType, "RateCurve" }, { CurveProp.Market, "DiscountCurveConstruction" }, { CurveProp.IndexTenor, "0M" }, { CurveProp.Currency1, currency }, { CurveProp.IndexName, "XXX-XXX" }, { CurveProp.Algorithm, "FastLinearZero" }, { CurveProp.BaseDate, baseDate }, }; var namedValueSet = new NamedValueSet(newProperties); return(new RateCurve(namedValueSet, algorithmHolder, newPoints));//There is no compounding frequency propertty }
/// <summary> /// This assumes that the rest dates are consistent with the curve. /// </summary> /// <param name="valuationDate"></param> /// <param name="paymentDate">The payment date. The same rest period is assumed as with the spot date.</param> /// <param name="indexCurve">The index curve should be already in the correct form for the fx.</param> /// <param name="currency2">Normally the foreign rate curve.</param> /// <param name="currency2PerCurrency1">The currency2PerCurrency1 flag. </param> /// <param name="currency1">Normally the domestic rate curve. </param> /// <param name="indexVolatilitySurface">The index volatility surface. </param> /// <param name="expiryTime">The expiry time. </param> /// <param name="timeToIndex">The time to reset or expiry. </param> /// <param name="strike">The strike. </param> /// <param name="fxOptionType">The option type. </param> public FxOptionLegAnalytic(DateTime valuationDate, DateTime paymentDate, IFxCurve indexCurve, IRateCurve currency1, IRateCurve currency2, bool currency2PerCurrency1, decimal strike, decimal expiryTime, decimal timeToIndex, IVolatilitySurface indexVolatilitySurface, FxOptionType fxOptionType) { //ToReportingCurrencyRate = EvaluateReportingCurrencyFxRate(valuationDate, reportingCurrencyFxCurve); var todayRate = indexCurve.GetForward(valuationDate, valuationDate); //TODO The spot rate may not be the same due to the carry effect, but the evolution works. var df1 = currency1.GetDiscountFactor(valuationDate, paymentDate); var df2 = currency2.GetDiscountFactor(valuationDate, paymentDate); var forward = df1 / df2; if (!currency2PerCurrency1) { forward = df2 / df1; } ForwardFxRate = (decimal)(todayRate * forward); OptionType = fxOptionType; Strikes = new List <decimal> { strike }; ExpiryTimes = new List <decimal> { expiryTime }; TimeToIndices = new List <decimal> { timeToIndex }; Volatilities = new List <decimal> { (decimal)indexVolatilitySurface.GetValue((double)timeToIndex, (double)strike) }; }
private static decimal GetForecastRate(CalculationPeriod calculationPeriod, IRateCurve forecastCurve, DayCountFraction dayCountFraction) { double startOfPeriodDiscount = forecastCurve.GetDiscountFactor(calculationPeriod.adjustedStartDate); double endOfPeriodDiscount = forecastCurve.GetDiscountFactor(calculationPeriod.adjustedEndDate); IDayCounter dayCounter = DayCounterHelper.Parse(dayCountFraction.Value); double accrualPeriod = dayCounter.YearFraction(calculationPeriod.adjustedStartDate, calculationPeriod.adjustedEndDate); if (0 == accrualPeriod) { string message = $"Accrual period is 0 days. calculationPeriod.adjustedStartDate = '{calculationPeriod.adjustedStartDate}', calculationPeriod.adjustedEndDate = '{calculationPeriod.adjustedEndDate}'"; throw new System.Exception(message); } double forecastContinuouslyCompoundingRate = (startOfPeriodDiscount / endOfPeriodDiscount - 1.0) / accrualPeriod; return((decimal)forecastContinuouslyCompoundingRate); }
private static void CalculateForecastPaymentAmount(PrincipalExchange principleExchange, IRateCurve discountCurve, DateTime valuationDate) { principleExchange.discountFactor = (decimal)discountCurve.GetDiscountFactor(valuationDate, principleExchange.adjustedPrincipalExchangeDate); principleExchange.discountFactorSpecified = true; principleExchange.presentValuePrincipalExchangeAmount = MoneyHelper.Mul(MoneyHelper.GetAmount(principleExchange.principalExchangeAmount), principleExchange.discountFactor); }
/// <summary> /// Evaluating the discount factor rate. /// </summary> /// <returns>The discount factor</returns> protected decimal EvaluateDiscountFactor(DateTime valuationDate, DateTime date, IRateCurve discountCurve) { var result = 1.0m; if (discountCurve != null) { result = (decimal)discountCurve.GetDiscountFactor(valuationDate, date); } return(result); }
public double ShortEndTargetFunction(double guess) { DateTime baseDate = _baseCurve.GetBaseDate(); DateTime date0 = _assetDates.First(); DateTime date1 = _assetDates.Last(); double d0 = _baseCurve.GetDiscountFactor(date0); double d1 = _baseCurve.GetDiscountFactor(date1); double y = _dayCounter.YearFraction(date0, date1); double y0 = _dayCounter.YearFraction(baseDate, date0); double y1 = _dayCounter.YearFraction(baseDate, date1); double z0 = RateAnalytics.DiscountFactorToZeroRate(d0, y0, _compoundingPeriod); double z1 = RateAnalytics.DiscountFactorToZeroRate(d1, y1, _compoundingPeriod); double projectedRate = 1 / y * (d0 / d1 - 1); double basisSpread = (double)_asset.MarketQuote.value; double term1 = Math.Pow(1 + 0.25 * (z0 + guess), -4 * y0); double term2 = Math.Pow(1 + 0.25 * (z1 + guess), -4 * y1); double term3 = y * term2 * (projectedRate + basisSpread); double result = -term1 + term2 + term3; return(result); }
/// <summary> /// Creates synthetic swaps from FX curve for period under 1 year /// </summary> /// <param name="cache">The cache.</param> /// <param name="logger">The logger.</param> /// <param name="fixingCalendar">The fixingCalendar.</param> /// <param name="rollCalendar">The rollCalendar.</param> /// <param name="nameSpace">THe client namespace</param> /// <param name="baseCurve"></param> /// <param name="basisAdjustedDiscountCurve"></param> /// <param name="currency"></param> /// <param name="baseDate"></param> /// <param name="swapsRequired">Array of the names of the swaps required</param> /// <returns></returns> public static List <IPriceableRateAssetController> CreateSyntheticSwaps(ILogger logger, ICoreCache cache, string nameSpace, IRateCurve baseCurve, RateCurve basisAdjustedDiscountCurve, string currency, DateTime baseDate, string[] swapsRequired, IBusinessCalendar fixingCalendar, IBusinessCalendar rollCalendar) { var dummyRates = new decimal[5]; string[] swapIds = swapsRequired.Select(a => currency + "-XccySwap-" + a).ToArray(); List <IPriceableRateAssetController> priceableRateAssets = PriceableAssetFactory.CreatePriceableRateAssets(logger, cache, nameSpace, baseDate, swapIds, dummyRates, null, fixingCalendar, rollCalendar); foreach (var priceableRateAssetController in priceableRateAssets) { var swap = (PriceableSimpleIRSwap)priceableRateAssetController; DateTime date0 = swap.AdjustedStartDate; DateTime date1 = swap.GetRiskMaturityDate(); IDayCounter dayCounter = DayCounterHelper.Parse(swap.DayCountFraction.Value); double adjustedDiscountFactorStart = basisAdjustedDiscountCurve.GetDiscountFactor(date0); double adjustedDiscountFactorEnd = basisAdjustedDiscountCurve.GetDiscountFactor(date1); double term3 = 0; double term4 = 0; for (int i = 0; i < swap.AdjustedPeriodDates.Count - 1; i++) { DateTime startDate = swap.AdjustedPeriodDates[i]; DateTime endDate = swap.AdjustedPeriodDates[i + 1]; if (startDate == endDate) { throw new InvalidOperationException("StartDate and EndDate cannot be the same"); } double adjustedDiscountFactor = basisAdjustedDiscountCurve.GetDiscountFactor(endDate); double baseDiscountFactorStart = baseCurve.GetDiscountFactor(startDate); double baseDiscountFactorEnd = baseCurve.GetDiscountFactor(endDate); double yearFraction = dayCounter.YearFraction(startDate, endDate); double baseForwardRate = (1 / yearFraction) * (baseDiscountFactorStart / baseDiscountFactorEnd - 1); term3 += yearFraction * adjustedDiscountFactor * baseForwardRate; term4 += yearFraction * adjustedDiscountFactor; } swap.MarketQuote.value = (decimal)((adjustedDiscountFactorStart - adjustedDiscountFactorEnd - term3) / term4); swap.BasicAssetValuation.quote[0].value = swap.MarketQuote.value; } return(priceableRateAssets); }
/// <summary> /// Initiates a new model. /// </summary> /// <param name="valuationDate">The valuation date.</param> /// <param name="paymentDate">The payment date of the cash flow.</param> /// <param name="reportingCurrencyFxCurve">THe fx curve. It must already be normalised.</param> /// <param name="indexCurve">The rate curve to use for calculating the forward index.</param> /// <param name="discountCurve">The rate curve to use for discounting.</param> public FxRateCashflowAnalytic(DateTime valuationDate, DateTime paymentDate, IFxCurve reportingCurrencyFxCurve, ICurve indexCurve, IRateCurve discountCurve) { ToReportingCurrencyRate = EvaluateReportingCurrencyFxRate(valuationDate, reportingCurrencyFxCurve); if (indexCurve != null) { FloatingIndex = (decimal)indexCurve.GetValue(new DateTimePoint1D(valuationDate, paymentDate)).Value; } if (discountCurve != null) { PaymentDiscountFactor = (decimal)discountCurve.GetDiscountFactor(valuationDate, paymentDate); } }
/// <summary> /// This assumes that the rest dates are consistent with the curve. /// </summary> /// <param name="valuationDate"></param> /// <param name="paymentDate">The payment date. The same rest period is assumed as with the spot date.</param> /// <param name="indexCurve">The index curve should be already in the correct form for the fx.</param> /// <param name="currency2">Normally the foreign rate curve.</param> /// <param name="currency2PerCurrency1">The currency2PerCurrency1 flag. </param> /// <param name="currency1">Normally the domestic rate curve. </param> /// <param name="currency1Settlement">Does settlement occur in currency1. If not, then it must be currency2. </param> /// <param name="reportingCurrencyFxCurve">The reporting current fx curve from settlement currency to reporting currency. It must already be normalised.</param> public FxRateCashflowAnalytic(DateTime valuationDate, DateTime paymentDate, IFxCurve indexCurve, IRateCurve currency1, IRateCurve currency2, bool currency2PerCurrency1, bool currency1Settlement, IFxCurve reportingCurrencyFxCurve) { ToReportingCurrencyRate = EvaluateReportingCurrencyFxRate(valuationDate, reportingCurrencyFxCurve); var todayRate = indexCurve.GetForward(valuationDate, valuationDate); //TODO The spot rate may not be the same due to the carry effect, but the evolution works. var df1 = currency1.GetDiscountFactor(valuationDate, paymentDate); var df2 = currency2.GetDiscountFactor(valuationDate, paymentDate); var forward = df1 / df2; if (!currency2PerCurrency1) { forward = df2 / df1; } FloatingIndex = (decimal)(todayRate * forward); if (currency1Settlement) { PaymentDiscountFactor = (decimal)currency1.GetDiscountFactor(valuationDate, paymentDate); } else { PaymentDiscountFactor = (decimal)currency2.GetDiscountFactor(valuationDate, paymentDate); } }
public override AssetValuation Calculate(IInstrumentControllerData modelData) { ModelData = modelData; AnalyticModelParameters = new FuturesAssetParameters(); AnalyticsModel = new FuturesTransactionAnalytic(); var marketEnvironment = modelData.MarketEnvironment; var metrics = ResolveModelMetrics(AnalyticsModel.Metrics); var metricsAsArray = metrics.Select(metric => metric).ToArray(); IExchangeTradedCurve futuresCurve = null; IRateCurve discountCurve = null; //1. instantiate curve if (marketEnvironment.GetType() == typeof(SimpleMarketEnvironment)) { discountCurve = (IRateCurve)((ISimpleMarketEnvironment)marketEnvironment).GetPricingStructure(); DiscountCurveName = discountCurve.GetPricingStructureId().UniqueIdentifier; futuresCurve = (IExchangeTradedCurve)((ISimpleMarketEnvironment)marketEnvironment).GetPricingStructure(); FuturesCurveName = futuresCurve.GetPricingStructureId().UniqueIdentifier; } if (marketEnvironment.GetType() == typeof(MarketEnvironment)) { futuresCurve = (IExchangeTradedCurve)modelData.MarketEnvironment.GetPricingStructure(FuturesCurveName); discountCurve = (IRateCurve)modelData.MarketEnvironment.GetPricingStructure(DiscountCurveName); } var settlementDF = 1.0; if (discountCurve != null) { settlementDF = discountCurve.GetDiscountFactor(SettlementDate); } //var interval = FuturesTypeInfo.; AnalyticModelParameters.SettlementDiscountFactor = Convert.ToDecimal(settlementDF); AnalyticModelParameters.Multiplier = Multiplier; AnalyticModelParameters.AccrualPeriod = 0.25m; AnalyticModelParameters.NumberOfContracts = NumberOfContracts; AnalyticModelParameters.TradePrice = PurchasePrice.amount; AnalyticModelParameters.ContractNotional = Convert.ToDecimal(FuturesTypeInfo.Future.multiplier); //Get the discountfactor to the settlemetn date if (futuresCurve != null) { AnalyticModelParameters.Quote = Convert.ToDecimal(futuresCurve.GetForward(LastTradeDate)); } AnalyticResults = AnalyticsModel.Calculate <IFuturesAssetResults, FuturesAssetResults>(AnalyticModelParameters, metricsAsArray); // store inputs and results from this run CalculationPerfomedIndicator = true; return(GetValue(CalculationResults, modelData.ValuationDate)); }
internal static double GetAdjustedDiscountFactor(DateTime baseDate, DateTime baseCurveDate, IDayCounter dayCounter, double zeroRateSpread, IRateCurve baseCurve) { const double compoundingPeriod = 0.25; // Convert to Zero Rate double yearFraction = dayCounter.YearFraction(baseDate, baseCurveDate); double df0 = baseCurve.GetDiscountFactor(baseCurveDate); double z0 = RateAnalytics.DiscountFactorToZeroRate(df0, yearFraction, compoundingPeriod); // Add the spread double z = z0 + zeroRateSpread; // Change back double discountFactor = RateAnalytics.ZeroRateToDiscountFactor(z, yearFraction, compoundingPeriod); return(discountFactor); }
public static void UpdatePaymentsAmounts(IBusinessCalendar paymentCalendar, CapFloor capFloor, CapFloorLegParametersRange capFloorLeg, IRateCurve discountCurve, DateTime valuationDate) { foreach (Payment payment in capFloor.additionalPayment) { var date = AdjustedDateHelper.GetAdjustedDate(paymentCalendar, payment.paymentDate); if (date != null) { payment.discountFactor = (decimal)discountCurve.GetDiscountFactor(valuationDate, (DateTime)date); payment.discountFactorSpecified = true; payment.presentValueAmount = MoneyHelper.Mul(payment.paymentAmount, payment.discountFactor); } } }
/// <summary> /// Set discount from a yield curve ID /// </summary> /// <param name="rateCurve"></param> /// <returns></returns> public string SetDiscountFactors(IRateCurve rateCurve) { const int length = 123; string temp; try { var discount = new double[length]; DateTime today = DateTime.Now; for (int i = 0; i < length; i++) { discount[i] = rateCurve.GetDiscountFactor(today, today.AddMonths(i * 3)); } _usd.CurDiscount = discount; _usd.DiscountStatus = "User Defined"; temp = String.Format("Discount factors were set."); } catch (Exception e) { temp = e.ToString(); } return(temp); }
/// <summary> /// Gets the bucketed discount factors. /// </summary> /// <param name="curve">The curve.</param> /// <param name="valuationDate">The valuation date.</param> /// <param name="bucketDates">The bucket dates.</param> /// <returns></returns> protected static Decimal[] GetBucketedDiscountFactors(IRateCurve curve, DateTime valuationDate, IList <DateTime> bucketDates) { // Bucketed Delta return(Array.ConvertAll(bucketDates.Select((t, index) => index == 0 ? 1.0 : curve.GetDiscountFactor(valuationDate, t)).ToArray(), Convert.ToDecimal)); }
private static void CalculateForecastPaymentAmount(Calculation calculation, FloatingRateCalculation floatingRateCalculation, PaymentCalculationPeriod paymentCalculationPeriod, IRateCurve forecastCurve, IRateCurve discountCurve, DateTime valuationDate) { var amountAccruedPerPaymentPeriod = new List <Money>(); decimal interestFromPreviousPeriods = 0; Notional notionalSchedule = XsdClassesFieldResolver.CalculationGetNotionalSchedule(calculation); Currency notionalCurrency = notionalSchedule.notionalStepSchedule.currency; // Cashflows // foreach (CalculationPeriod calculationPeriod in XsdClassesFieldResolver.GetPaymentCalculationPeriodCalculationPeriodArray(paymentCalculationPeriod)) { decimal notional = XsdClassesFieldResolver.CalculationPeriodGetNotionalAmount(calculationPeriod); decimal finalRate = 0.0m; // If has a fixed rate (fixed rate coupon) // if (XsdClassesFieldResolver.CalculationPeriodHasFixedRate(calculationPeriod)) { finalRate = XsdClassesFieldResolver.CalculationPeriodGetFixedRate(calculationPeriod); } else if (XsdClassesFieldResolver.CalculationPeriodHasFloatingRateDefinition(calculationPeriod)) { if (null != forecastCurve) { FloatingRateDefinition floatingRateDefinition = XsdClassesFieldResolver.CalculationPeriodGetFloatingRateDefinition(calculationPeriod); // Apply spread from schedule if it hasn't been specified yet. // if (!floatingRateDefinition.spreadSpecified) { floatingRateDefinition.spread = floatingRateCalculation.spreadSchedule[0].initialValue; floatingRateDefinition.spreadSpecified = true; } ForecastRateHelper.UpdateFloatingRateDefinition(floatingRateDefinition, floatingRateCalculation, calculation.dayCountFraction, calculationPeriod, forecastCurve); calculationPeriod.Item1 = floatingRateDefinition; decimal calculatedRate = floatingRateDefinition.calculatedRate; // final rate after application of Cap/Floor rates // finalRate = calculatedRate; // If has a Cap rate, finalRate = MAX(0, FinalRate - CapRate) // if (null != floatingRateDefinition.capRate) { Strike strike = floatingRateDefinition.capRate[0]; finalRate = System.Math.Max(0, finalRate - strike.strikeRate); } // If has a Floor rate, finalRate = MAX(0, FloorRate - FinalRate) // if (null != floatingRateDefinition.floorRate) { Strike strike = floatingRateDefinition.floorRate[0]; finalRate = System.Math.Max(0, strike.strikeRate - finalRate); } } } else { throw new System.Exception("CalculationPeriod has neither fixedRate nor floatngRateDefinition."); } // Compound interest accrued during previos calculation periods in this payment period. // decimal notionalAdjustedForInterestFromPreviousPeriods = notional + interestFromPreviousPeriods; if (calculation.discounting == null) { interestFromPreviousPeriods = notionalAdjustedForInterestFromPreviousPeriods * finalRate * calculationPeriod.dayCountYearFraction; } else if (calculation.discounting.discountingType == DiscountingTypeEnum.FRA || calculation.discounting.discountingType == DiscountingTypeEnum.Standard) { interestFromPreviousPeriods = notionalAdjustedForInterestFromPreviousPeriods * (1.0m - 1.0m / (1.0m + finalRate * calculationPeriod.dayCountYearFraction)); } else { throw new NotSupportedException("The specified discountingType is not supported."); } Money amountAccruedPerCalculationPeriod = MoneyHelper.GetAmount(interestFromPreviousPeriods, notionalCurrency); amountAccruedPerPaymentPeriod.Add(amountAccruedPerCalculationPeriod); } paymentCalculationPeriod.forecastPaymentAmount = MoneyHelper.Sum(amountAccruedPerPaymentPeriod); paymentCalculationPeriod.discountFactor = (decimal)discountCurve.GetDiscountFactor(valuationDate, paymentCalculationPeriod.adjustedPaymentDate); paymentCalculationPeriod.discountFactorSpecified = true; paymentCalculationPeriod.presentValueAmount = MoneyHelper.Mul(paymentCalculationPeriod.forecastPaymentAmount, paymentCalculationPeriod.discountFactor); }
/// <summary> /// This assumes that the rest dates are consistent with the curve. /// </summary> /// <param name="valuationDate"></param> /// <param name="paymentDate">The payment date. The same rest period is assumed as with the spot date.</param> /// <param name="indexCurve">The index curve should be already in the correct form for the fx.</param> /// <param name="currency1">Normally the domestic rate curve. </param> public CommoditySwapLegAnalytic(DateTime valuationDate, DateTime paymentDate, ICommodityCurve indexCurve, IRateCurve currency1) { //ToReportingCurrencyRate = EvaluateReportingCurrencyFxRate(valuationDate, reportingCurrencyFxCurve); var todayRate = indexCurve.GetForward(valuationDate, valuationDate); //TODO The spot rate may not be the same due to the carry effect, but the evolution works. var df1 = currency1.GetDiscountFactor(valuationDate, paymentDate); }