/// <summary> /// Calculates the number of days between the two dates. /// </summary> /// <param name="startDate">The start date.</param> /// <param name="endDate">The end Date.</param> /// <param name="dayCounter">THe dayCounter.</param> /// <returns></returns> public int AcccrualDays(DateTime startDate, DateTime endDate, string dayCounter) { IDayCounter dc = DayCounterHelper.Parse(dayCounter); int days = dc.DayCount(startDate, endDate); return(days); }
/// <summary> /// /// </summary> /// <param name="logger"></param> /// <param name="cache"></param> /// <param name="fixingCalendar"></param> /// <param name="paymentCalendar"></param> /// <param name="isBuyer"></param> /// <param name="fraFpML"></param> /// <param name="nameSpace"></param> public FraPricer(ILogger logger, ICoreCache cache, IBusinessCalendar fixingCalendar, IBusinessCalendar paymentCalendar, bool isBuyer, Fra fraFpML, String nameSpace) { OrderedPartyNames = new List <string>(); Multiplier = 1.0m; FraDiscounting = fraFpML.fraDiscounting; FixingOffSet = fraFpML.fixingDateOffset; FloatingRateIndex = fraFpML.floatingRateIndex; DayCountFraction = fraFpML.dayCountFraction; Notional = fraFpML.notional; IndexTenor = fraFpML.indexTenor; AdjustablePaymentDate = fraFpML.paymentDate; FixedRate = fraFpML.fixedRate; AddCashFlows(logger, cache, fixingCalendar, paymentCalendar, fraFpML, isBuyer, nameSpace); BasePartyPayingFixed = !isBuyer; RiskMaturityDate = TerminationDate; NumberOfDays = (DayCounterHelper.Parse(DayCountFraction.Value)).DayCount(EffectiveDate, TerminationDate); //Set the product type. ProductType = ProductTypeSimpleEnum.FRA; PaymentCurrencies = new List <string> { Notional.currency.Value }; //Set the default discount curve name. DiscountCurveName = CurveNameHelpers.GetDiscountCurveName(Notional.currency.Value, true); ForecastCurveName = CurveNameHelpers.GetForecastCurveName(fraFpML.floatingRateIndex, fraFpML.indexTenor); }
/// <summary> /// Caculates the number of business days between two dates given a list of public holidays /// </summary> public static double BusinessDaysBetweenTwoDates(DateTime firstDate, DateTime secondDate, IList <DateTime> publicHolidays) { //Compare supplied dates if (ValidateInputDates(firstDate, secondDate)) { return(0); } //Get the date range between the two dates excluding firstDate and secondDate var dateRange = DayCounterHelper.GetDateRangeBetweenTwoDates(firstDate, secondDate); //Count the number of dates that are a business day //A business day is a week day that is either a full day or a half day //A public holiday is either defined as a full public holiday or a half public holiday //When comparing Hour, it uses the 24 format therefore it is safe to assume that 12 means 12pm otherwise it would be 0 //A half public holidays is defined as a date with the time set to 12PM var halfDayPublicHolidays = publicHolidays.Where(d => d.Hour == 12); var fullDayPublicHolidays = publicHolidays.Where(d => d.Hour != 12); //First get the true full business days (a half day is not a full business day, so we need to pass the half day list) var fullBusinessDays = DayCounterHelper.GetFullBusinessDays(dateRange, fullDayPublicHolidays, halfDayPublicHolidays); //Then get the true half business days var halfBusinessDays = DayCounterHelper.GetHalfBusinessDays(dateRange, fullDayPublicHolidays, halfDayPublicHolidays); //Return the count return((double)fullBusinessDays.Count() + ((double)halfBusinessDays.Count() / 2)); }
/// <summary> /// /// </summary> /// <param name="logger"></param> /// <param name="cache"></param> /// <param name="isCollateralised"></param> /// <param name="collateralCurrency"></param> /// <param name="fixingCalendar"></param> /// <param name="paymentCalendar"></param> /// <param name="isPayer"></param> /// <param name="commodityForwardFpML"></param> /// <param name="nameSpace"></param> public CommodityForwardPricer(ILogger logger, ICoreCache cache, bool isCollateralised, string collateralCurrency, IBusinessCalendar fixingCalendar, IBusinessCalendar paymentCalendar, bool isPayer, CommodityForward commodityForwardFpML, String nameSpace) { IsCollateralised = isCollateralised; CollateralCurrency = collateralCurrency; OrderedPartyNames = new List <string>(); Multiplier = 1.0m; ValueDate = commodityForwardFpML.valueDate; FixedLeg = commodityForwardFpML.fixedLeg; BullionPhysicalLeg = commodityForwardFpML.Item; if (commodityForwardFpML.commonPricingSpecified) { CommonPricing = commodityForwardFpML.commonPricing; } AddCashFlows(logger, cache, fixingCalendar, paymentCalendar, commodityForwardFpML, isPayer, nameSpace); BasePartyPayingFixed = !isPayer; RiskMaturityDate = TerminationDate; NumberOfDays = (DayCounterHelper.Parse(DayCountFraction.Value)).DayCount(EffectiveDate, TerminationDate); //Set the product type. ProductType = ProductTypeSimpleEnum.FRA; PaymentCurrencies = new List <string> { Notional.currency.Value }; //Set the default discount curve name. DiscountCurveName = CurveNameHelpers.GetDiscountCurveName(CollateralCurrency, !IsCollateralised); ForecastCurveName = CurveNameHelpers.GetForecastCurveName(commodityForwardFpML.floatingRateIndex, commodityForwardFpML.indexTenor); }
/// <summary> /// Creates a fixed coupon calculation period. /// </summary> /// <param name="accrualStartDate"></param> /// <param name="accrualEndDate"></param> /// <param name="notionalAmount"></param> /// <param name="calculation"></param> /// <returns></returns> public static CalculationPeriod[] CreateSimpleCouponItem(DateTime accrualStartDate, DateTime accrualEndDate, Money notionalAmount, Calculation calculation) { IDayCounter dayCounter = DayCounterHelper.Parse(calculation.dayCountFraction.Value); var calculationPeriod = new CalculationPeriod(); int numDays = dayCounter.DayCount(accrualStartDate, accrualEndDate); calculationPeriod.adjustedStartDate = accrualStartDate; calculationPeriod.adjustedStartDateSpecified = true; calculationPeriod.adjustedEndDate = accrualEndDate; calculationPeriod.adjustedEndDateSpecified = true; calculationPeriod.dayCountYearFraction = (decimal)dayCounter.YearFraction(accrualStartDate, accrualEndDate); calculationPeriod.dayCountYearFractionSpecified = true; calculationPeriod.calculationPeriodNumberOfDays = numDays.ToString(CultureInfo.InvariantCulture); calculationPeriod.Item = notionalAmount.amount; calculationPeriod.unadjustedEndDateSpecified = false; calculationPeriod.unadjustedStartDateSpecified = false; calculationPeriod.Item1 = calculation; var rate = ((Schedule)calculation.Items[0]).initialValue; calculationPeriod.forecastRate = rate; calculationPeriod.forecastRateSpecified = true; calculationPeriod.forecastAmount = MoneyHelper.Mul(notionalAmount, calculationPeriod.dayCountYearFraction * calculationPeriod.forecastRate); var calculationPeriods = new List <CalculationPeriod> { calculationPeriod }; return(calculationPeriods.ToArray()); }
public static double GetEffectiveFrequency(List <AmortisingResultItem> cashflowsSchedule, BillsSwapPricer2TermsRange terms) { IDayCounter dayCounter = DayCounterHelper.Parse(terms.DayCountConvention); double effectiveFrequency = GetEffectiveFrequency(cashflowsSchedule, dayCounter); return(effectiveFrequency); }
[InlineData(2021, 13, DayOfWeek.Monday, 1, 0)] //1st Monday in the 13th month of 2021 12AM public void GetDateByOccurrence_WithInvalidInput(int year, int month, DayOfWeek dayOfWeek, int hour, int dayOfWeekOccurrence) { //Given a date defined by invalid occurrence //When I create the date Action act = () => DayCounterHelper.GetDateByOccurrence(year, month, dayOfWeek, dayOfWeekOccurrence, 0); //Then I should not be able to create the date Assert.Throws <ArgumentOutOfRangeException>(act); }
[InlineData(2021, 3, DayOfWeek.Wednesday, 5, 0, "31/03/2021")] //5th Wednesday of March 2021 AM public void GetDateByOccurrence_WithValidInput(int year, int month, DayOfWeek dayOfWeek, int dayOfWeekOccurrence, int hour, string expectedDateTime) { //Given a date defined by valid occurrence //When I create the date DateTime actualDateTime = DayCounterHelper.GetDateByOccurrence(year, month, dayOfWeek, dayOfWeekOccurrence, hour); //Then I should create the correct date Assert.Equal(DateTime.ParseExact(expectedDateTime, "d/M/yyyy", CultureInfo.InvariantCulture).Date, actualDateTime.Date); }
/// <summary> /// Gets the year fraction. /// </summary> /// <returns></returns> public override decimal[] GetYearFractions() { return (new[] { (decimal) DayCounterHelper.Parse(UnderlyingRateIndex.dayCountFraction.Value).YearFraction( AdjustedStartDate, GetRiskMaturityDate()) }); }
/// <summary> /// Helper function used to set the expiry used in the calibration of /// the SABR engine. /// Postcondition: _excerciseTime is set. /// </summary> /// <param name="expiry">Caplet expiry.</param> private void SetExerciseTimeForSABREngine(DateTime expiry) { // Set the exercise time. var obj = _atmBootstrapEngine; var calculationDate = obj.GetBaseDate();//This was calculation date. var dayCountObj = DayCounterHelper.Parse(VolatilityDayCount); _excerciseTime = (decimal)dayCountObj.YearFraction (calculationDate, expiry); }
/// <summary> /// Gets the year fraction. /// </summary> /// <returns></returns> public decimal GetYearFraction(string dayCountFraction, DateTime adjustedStartDate, DateTime maturityDate) { IDayCounter dayCounter = DayCounterHelper.Parse(dayCountFraction); decimal yearFraction = (decimal)dayCounter.YearFraction(adjustedStartDate, maturityDate); if (yearFraction == 0) { throw new NotSupportedException("YearFraction cannot be zero"); } return(yearFraction); }
public static Trade CreateFraTrade(FraInputRange2 fraInputRange) { var trade = new Trade(); var fra = new Fra { adjustedEffectiveDate = DateTypesHelper.ToRequiredIdentifierDate(fraInputRange.AdjustedEffectiveDate), adjustedTerminationDate = fraInputRange.AdjustedTerminationDate, adjustedTerminationDateSpecified = true, paymentDate = DateTypesHelper.ToAdjustableDate(fraInputRange.UnadjustedPaymentDate, fraInputRange.PaymentDateBusinessDayConvention, fraInputRange.PaymentDateBusinessCenters), Items = new object[] { new ProductType { Value = ProductTypeSimpleEnum.FRA.ToString() } }, ItemsElementName = new[] { ItemsChoiceType2.productType } }; if ("resetDate" != fraInputRange.FixingDayOffsetDateRelativeTo) { throw new ArgumentException("The fixing date must be specified as 'resetDate'-relative!", nameof(fraInputRange)); } var fixingDayType = EnumHelper.Parse <DayTypeEnum>(fraInputRange.FixingDayOffsetDayType); fra.fixingDateOffset = RelativeDateOffsetHelper.Create(fraInputRange.FixingDayOffsetPeriod, fixingDayType, fraInputRange.FixingDayOffsetBusinessDayConvention, fraInputRange.FixingDayOffsetBusinessCenters, fraInputRange.FixingDayOffsetDateRelativeTo); fra.dayCountFraction = DayCountFractionHelper.Parse(fraInputRange.DayCountFraction); IDayCounter dayCounter = DayCounterHelper.Parse(fra.dayCountFraction.Value); fra.calculationPeriodNumberOfDays = dayCounter.DayCount(fra.adjustedEffectiveDate.Value, fra.adjustedTerminationDate).ToString(CultureInfo.InvariantCulture); fra.notional = MoneyHelper.GetAmount(fraInputRange.NotionalAmount, fraInputRange.NotionalCurrency); fra.fixedRate = (decimal)fraInputRange.FixedRate; fra.fixedRateSpecified = true; fra.floatingRateIndex = FloatingRateIndexHelper.Parse(fraInputRange.FloatingRateIndex); fra.indexTenor = new[] { PeriodHelper.Parse(fraInputRange.IndexTenor) }; fra.fraDiscounting = fraInputRange.FraDiscounting; fra.fraDiscountingSpecified = true; PartyReference party1 = PartyReferenceFactory.Create("party1"); PartyReference party2 = PartyReferenceFactory.Create("party2"); fra.sellerPartyReference = party1; fra.buyerPartyReference = party2; if (bool.Parse(fraInputRange.IsParty1Buyer)) { fra.sellerPartyReference = party2; fra.buyerPartyReference = party1; } XsdClassesFieldResolver.TradeSetFra(trade, fra); trade.id = fraInputRange.TradeId; return(trade); }
public void GetDateRange_Between_TwoInvalidDates(string startDate, string endDate) { //Given two dates with the startDate greater than the endDate var testStartDate = DateTime.ParseExact(startDate, "d/M/yyyy", CultureInfo.InvariantCulture); var testEndtDate = DateTime.ParseExact(endDate, "d/M/yyyy", CultureInfo.InvariantCulture); //When I generate a range of dates Action act = () => DayCounterHelper.GetDateRangeBetweenTwoDates(testStartDate, testEndtDate); //Then I should not be able to generate a date range Assert.Throws <ArgumentException>(act); }
public void GetDateRange_Between_TwoValidDates(string startDate, string endDate, int expectedCount) { //Given two dates var testStartDate = DateTime.ParseExact(startDate, "d/M/yyyy", CultureInfo.InvariantCulture); var testEndDate = DateTime.ParseExact(endDate, "d/M/yyyy", CultureInfo.InvariantCulture); //When I generate a range of dates between the two dates var actualCount = DayCounterHelper.GetDateRangeBetweenTwoDates(testStartDate, testEndDate).Count(); //Then the count should exclude the two dates Assert.Equal(expectedCount, actualCount); }
/// <summary> /// Gets the year fractions for dates. /// </summary> /// <param name="periodDates">The period dates.</param> /// <param name="dayCountFraction">The day count fraction.</param> /// <returns></returns> protected static decimal[] GetYearFractionsForDates(IList <DateTime> periodDates, DayCountFraction dayCountFraction) { var yearFractions = new List <decimal>(); IDayCounter dayCounter = DayCounterHelper.Parse(dayCountFraction.Value); for (int i = 0; i < periodDates.Count - 1; i++) { double yearFraction = dayCounter.YearFraction(periodDates[i], periodDates[i + 1]); yearFractions.Add((decimal)yearFraction); } return(yearFractions.ToArray()); }
///<summary> ///</summary> ///<param name="valuationDate"></param> ///<param name="floatMargin"></param> ///<param name="fixedRate"></param> ///<param name="payTerms"></param> ///<param name="payRolls"></param> ///<param name="receiveTerms"></param> ///<param name="receiveRolls"></param> ///<param name="rateCurve"></param> ///<param name="bulletPaymentDate"></param> ///<param name="bulletPaymentValue"></param> ///<returns></returns> public static double CalculateFixedSidePV(DateTime valuationDate, double floatMargin, double fixedRate, BillsSwapPricer2TermsRange payTerms, List <AmortisingResultItem> payRolls, BillsSwapPricer2TermsRange receiveTerms, List <AmortisingResultItem> receiveRolls, RateCurve rateCurve, DateTime bulletPaymentDate, double bulletPaymentValue) { // pay == fixed. // IDayCounter dayCounter = DayCounterHelper.Parse(payTerms.DayCountConvention); double fixedSidePV = GetFixedSidePV(valuationDate, payRolls, receiveRolls, dayCounter, rateCurve, floatMargin, fixedRate, bulletPaymentDate, bulletPaymentValue); return(fixedSidePV); }
public void TestGetDayCounterTypes() { IDayCounter dc = DayCounterHelper.Parse("Actual365"); Assert.IsNotNull(dc); // No longer supported //dc = DayCounterHelper.Parse("ActualMY"); //Assert.IsNotNull(dc); //dc = DayCounterHelper.Parse("ActualQuarters"); //Assert.IsNotNull(dc); }
/// <summary> /// Helper function used by the function that computes the swap price. /// The function generates the accrual factors for each swap period. /// Precondition: method GenerateSwapSchedule has been called. /// Post-condition: private field _accrualFactors is set. /// </summary> private void GenerateAccrualFactors() { // Flush the container that will store the accrual factors. _accrualFactors = new List <double>(); // Generate the accrual factors. var dayCountObj = DayCounterHelper.Parse(_dayCount); var numSwapDates = _swapSchedule.Count; for (var i = 1; i < numSwapDates; ++i) { var accrualFactor = dayCountObj.YearFraction(_swapSchedule[i - 1], _swapSchedule[i]); _accrualFactors.Add(accrualFactor); } }
///<summary> ///</summary> ///<param name="valuationDate"></param> ///<param name="floatMargin"></param> ///<param name="fixedRate"></param> ///<param name="payTerms"></param> ///<param name="payRolls"></param> ///<param name="receiveTerms"></param> ///<param name="receiveRolls"></param> ///<param name="originalReceiveCurve"></param> ///<param name="bulletPaymentDate"></param> ///<param name="bulletPaymentValue"></param> ///<param name="listInstrumentIdAndQuotes"></param> ///<param name="listPerturbations"></param> ///<param name="filterByInstruments"></param> ///<returns></returns> public static double CalculateFixedSideDelta(DateTime valuationDate, double floatMargin, double fixedRate, BillsSwapPricer2TermsRange payTerms, List <AmortisingResultItem> payRolls, BillsSwapPricer2TermsRange receiveTerms, List <AmortisingResultItem> receiveRolls, RateCurve originalReceiveCurve, DateTime bulletPaymentDate, double bulletPaymentValue, List <InstrumentIdAndQuoteRangeItem> listInstrumentIdAndQuotes, List <DoubleRangeItem> listPerturbations, string filterByInstruments) { if (null == listPerturbations) { listPerturbations = new List <DoubleRangeItem>(); foreach (InstrumentIdAndQuoteRangeItem item in listInstrumentIdAndQuotes) { item.InstrumentId = RemoveExtraInformationFromInstrumentId(item.InstrumentId); var defaultPerturbationAmount = new DoubleRangeItem { Value = GetDefaultPerturbationAmount(item.InstrumentId) }; listPerturbations.Add(defaultPerturbationAmount); } } var perturbationArray = new List <Pair <string, decimal> >(); for (int i = 0; i < listInstrumentIdAndQuotes.Count; i++) { InstrumentIdAndQuoteRangeItem item = listInstrumentIdAndQuotes[i]; item.InstrumentId = RemoveExtraInformationFromInstrumentId(item.InstrumentId); DoubleRangeItem perturbItem = listPerturbations[i]; if (!String.IsNullOrEmpty(filterByInstruments)) { if (item.InstrumentId.StartsWith(filterByInstruments, true, null)) { perturbationArray.Add(new Pair <string, decimal>(item.InstrumentId, (decimal)perturbItem.Value)); } } else { perturbationArray.Add(new Pair <string, decimal>(item.InstrumentId, (decimal)perturbItem.Value)); } } //var perturbedCurveId = originalReceiveCurve.PerturbCurve(perturbationArray); // Perturb the curve // //Curves.RateCurve perturbedReceiveCurve = RateCurveInMemoryCollection.Instance.Get(perturbedCurveId); var perturbedReceiveCurve = (RateCurve)originalReceiveCurve.PerturbCurve(perturbationArray); //ObjectCacheHelper.GetPricingStructureFromSerialisable(perturbedCurveId); // pay == fixed. // IDayCounter dayCounter = DayCounterHelper.Parse(payTerms.DayCountConvention); double sensitivity = GetFixedSideSensitivity(valuationDate, payRolls, receiveRolls, dayCounter, originalReceiveCurve, perturbedReceiveCurve, floatMargin, fixedRate, bulletPaymentDate, bulletPaymentValue); return(sensitivity); }
/// <summary> /// Sets the interpolator. /// </summary> private void SetInterpolator(DateTime baseDate) { // The underlying curve and associated compounding frequency (compounding frequency required when underlying curve is a ZeroCurve) InterpolationMethod curveInterpolationMethod = InterpolationMethodHelper.Parse(Holder.GetValue("CurveInterpolation")); IDayCounter dayCounter = DayCounterHelper.Parse(Holder.GetValue("DayCounter")); UnderlyingInterpolatedCurve = Holder.GetValue("UnderlyingCurve"); // Retrieve the Discount factor curve and assign the curve interpolation we want to initiate // This dependends on the underyling curve type (i.e. rate or discount factor) TermCurve termCurve = GetEquityCurveValuation().fxForwardCurve; termCurve.interpolationMethod = curveInterpolationMethod; // interpolate the DiscountFactor curve based on the respective curve interpolation Interpolator = new FxCurveInterpolator(termCurve, baseDate, dayCounter); }
/// <summary> /// Initializes a new instance of the <see cref="PriceableSimpleInflationAsset"/> class. /// </summary> /// <param name="baseDate">The base date.</param> /// <param name="nodeStruct"></param> /// <param name="fixingCalendar"></param> /// <param name="paymentCalendar"></param> /// <param name="fixedRate">The fixed rate.</param> public PriceableSimpleZeroCouponInflationSwap(DateTime baseDate, SimpleIRSwapNodeStruct nodeStruct, IBusinessCalendar fixingCalendar, IBusinessCalendar paymentCalendar, BasicQuotation fixedRate) : base(baseDate, XsdClassesFieldResolver.CalculationGetNotionalSchedule(nodeStruct.Calculation).notionalStepSchedule.initialValue, nodeStruct.DateAdjustments, fixedRate) { Id = nodeStruct.SimpleIRSwap.id; SimpleInflationSwap = nodeStruct.SimpleIRSwap; SpotDateOffset = nodeStruct.SpotDate; Calculation = nodeStruct.Calculation; UnderlyingRateIndex = nodeStruct.UnderlyingRateIndex; DayCounter = DayCounterHelper.Parse(Calculation.dayCountFraction.Value); AdjustedStartDate = GetSpotDate(baseDate, fixingCalendar, SpotDateOffset); RiskMaturityDate = GetEffectiveDate(AdjustedStartDate, paymentCalendar, SimpleInflationSwap.term, nodeStruct.DateAdjustments.businessDayConvention); YearFraction = GetYearFractions()[0]; }
/// <summary> /// Sets the interpolator. /// </summary> /// <param name="baseDate">The base date.</param> /// <param name="holder">The holder.</param> private void SetInterpolator(DateTime baseDate, PricingStructureAlgorithmsHolder holder) { // The underlying curve and associated compounding frequency (compounding frequency required when underlying curve is a ZeroCurve) var curveInterpolationMethod = InterpolationMethodHelper.Parse(holder.GetValue("CurveInterpolation")); var dayCounter = DayCounterHelper.Parse(holder.GetValue("DayCounter")); UnderlyingInterpolatedCurve = holder.GetValue("UnderlyingCurve"); //TODO this redundant. // Retrieve the Discount factor curve and assign the curve interpolation we want to initiate // This dependends on the underyling curve type (i.e. rate or discount factor) var termCurve = GetFxCurveValuation().fxForwardCurve; termCurve.interpolationMethod = curveInterpolationMethod; // interpolate the DiscountFactor curve based on the respective curve interpolation Interpolator = new CommodityCurveInterpolator(termCurve, baseDate, dayCounter); }
private static void UpdateNumberOfDaysAndYearFraction(IEnumerable <PaymentCalculationPeriod> paymentCalculationPeriods, Calculation calculation) { foreach (PaymentCalculationPeriod pcp in paymentCalculationPeriods) { // set the calculationPeriodNumberOfDays and dayCountYearFraction fields // foreach (CalculationPeriod calculationPeriod in XsdClassesFieldResolver.GetPaymentCalculationPeriodCalculationPeriodArray(pcp)) { IDayCounter dayCounter = DayCounterHelper.Parse(calculation.dayCountFraction.Value); calculationPeriod.calculationPeriodNumberOfDays = dayCounter.DayCount(calculationPeriod.adjustedStartDate, calculationPeriod.adjustedEndDate).ToString(CultureInfo.InvariantCulture); calculationPeriod.dayCountYearFraction = (decimal)dayCounter.YearFraction(calculationPeriod.adjustedStartDate, calculationPeriod.adjustedEndDate); calculationPeriod.dayCountYearFractionSpecified = true; } } }
/// <summary> /// Helper method used by the Caplet Bootstrap Engine to compute the /// forward rate for a period. /// </summary> /// <param name="capletBootstrapSettings">The Caplet Bootstrap Settings /// object that stores the Calculation Date and Day Count.</param> /// <param name="offsets">Array of offsets (number of days) from /// the Calculation Date.</param> /// <param name="discountFactors">Array of discount factors.</param> /// <param name="startDate">The start date for the period.</param> /// <param name="endDate">The end date for the period.</param> /// <returns> /// Simple forward rate (in the day count) for the given period. /// Note: if the start and end date of the period are equal, then the /// function returns the value 0.0. /// </returns> public static decimal ComputeForwardRate (NamedValueSet capletBootstrapSettings, double[] offsets, double[] discountFactors, DateTime startDate, DateTime endDate) { // Check that the End Date is not before the Start Date. var dateDiff = endDate - startDate; const string dateErrorMessage = "End date cannot be before start date for a forward rate"; DataQualityValidator.ValidateMinimum (dateDiff.Days, 0.0d, dateErrorMessage, true); // Check for the special case of a zero length period. if (dateDiff.Days == 0) { return(0.0m); } // Compute the discount factor at the start and end of the period. var dfToStart = ComputeDiscountFactor (capletBootstrapSettings, offsets, discountFactors, startDate); var dfToEnd = ComputeDiscountFactor (capletBootstrapSettings, offsets, discountFactors, endDate); // Compute the year fraction. var dayCount = capletBootstrapSettings.GetValue("DayCount", "ACT/365.FIXED"); IDayCounter dayCountObj = DayCounterHelper.Parse(dayCount); var tau = (decimal)dayCountObj.YearFraction (startDate, endDate); // Compute and validate the forward rate. var forwardRate = (dfToStart - dfToEnd) / (tau * dfToEnd); const string rateErrorMessage = "Negative forward rate encountered: check inputs"; DataQualityValidator.ValidateMinimum (forwardRate, 0.0m, rateErrorMessage, true); return(forwardRate); }
/// <summary> /// /// </summary> /// <param name="fraInputRange"></param> /// <returns></returns> public static Fra GetFpMLFra(FraInputRange fraInputRange) { var fra = new Fra { adjustedEffectiveDate = DateTypesHelper.ToRequiredIdentifierDate(fraInputRange.AdjustedEffectiveDate), adjustedTerminationDate = fraInputRange.AdjustedTerminationDate, paymentDate = DateTypesHelper.ToAdjustableDate(fraInputRange.UnadjustedPaymentDate, fraInputRange.PaymentDateBusinessDayConvention, fraInputRange.PaymentDateBusinessCenters) }; if ("resetDate" != fraInputRange.FixingDayOffsetDateRelativeTo) { throw new ArgumentException("The fixing date must be specified as 'resetDate'-relative!", nameof(fraInputRange)); } var fixingDayType = EnumHelper.Parse <DayTypeEnum>(fraInputRange.FixingDayOffsetDayType); fra.fixingDateOffset = RelativeDateOffsetHelper.Create(fraInputRange.FixingDayOffsetPeriod, fixingDayType, fraInputRange.FixingDayOffsetBusinessDayConvention, fraInputRange.FixingDayOffsetBusinessCenters, fraInputRange.FixingDayOffsetDateRelativeTo); fra.dayCountFraction = DayCountFractionHelper.Parse(fraInputRange.DayCountFraction); IDayCounter dayCounter = DayCounterHelper.Parse(fra.dayCountFraction.Value); fra.calculationPeriodNumberOfDays = dayCounter.DayCount(fra.adjustedEffectiveDate.Value, fra.adjustedTerminationDate).ToString(); fra.notional = MoneyHelper.GetAmount(fraInputRange.NotionalAmount, fraInputRange.NotionalCurrency); fra.fixedRate = (decimal)fraInputRange.FixedRate; fra.floatingRateIndex = FloatingRateIndexHelper.Parse(fraInputRange.FloatingRateIndex); fra.indexTenor = new[] { PeriodHelper.Parse(fraInputRange.IndexTenor) }; fra.fraDiscounting = fraInputRange.FraDiscounting; PartyReference nabParty = PartyReferenceFactory.Create("NAB"); PartyReference counterParty = PartyReferenceFactory.Create("COUNTERPARTY"); if (bool.Parse(fraInputRange.Sell)) { fra.sellerPartyReference = nabParty; fra.buyerPartyReference = counterParty; } else { fra.sellerPartyReference = counterParty; fra.buyerPartyReference = nabParty; } return(fra); }
/// <summary> /// Caculates the number of weekdays between two dates /// </summary> public static int WeekdaysBetweenTwoDates(DateTime firstDate, DateTime secondDate) { //Compare supplied dates if (ValidateInputDates(firstDate, secondDate)) { return(0); } //Get the date range between the two dates excluding firstDate and secondDate var dateRange = DayCounterHelper.GetDateRangeBetweenTwoDates(firstDate, secondDate); //Count the number of dates that are a weekday "Monday, Tuesday, Wednesday, Thursday, Friday" var weekdayCount = DayCounterHelper.GetWeekdays(dateRange).Count(); //Return the count return(weekdayCount); }
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); }
public void TestYearFraction() { _dayCount = "ACT/ACT.ISDA"; // Instantiate a class object and check that it is not null. IDayCounter obj = DayCounterHelper.Parse(_dayCount); Assert.AreNotEqual(obj, null); // Test the default day count convention. DateTime targetDate1 = new DateTime(2005, 12, 15, 0, 0, 0); _expected = 0.1726027397; _actual = obj.YearFraction(_refDate, targetDate1); AssertExtension.Less(Math.Abs(_actual - _expected), _tolerance); // Test ACT/360 day count convention in lower case format. _dayCount = "ACT/360"; DateTime targetDate2 = new DateTime(2006, 1, 17, 0, 0, 0); _expected = 0.26301369863013694262537; _actual = obj.YearFraction(_refDate, targetDate2); double temp = _actual - _expected; AssertExtension.Less(Math.Abs(temp), _tolerance); // Test ACT/365 day count convention. _dayCount = "ACT/365.FIXED"; DateTime targetDate3 = new DateTime(2005, 12, 25, 0, 0, 0); _expected = 0.1999999999; _actual = obj.YearFraction(_refDate, targetDate3); temp = _actual - _expected; AssertExtension.Less(Math.Abs(temp), _tolerance); // Test negative year fraction. _dayCount = "ACT/360"; DateTime targetDate4 = new DateTime(2004, 8, 15, 0, 0, 0); _expected = -1.160603338; _actual = obj.YearFraction(_refDate, targetDate4); temp = _actual - _expected; AssertExtension.Less(Math.Abs(temp), _tolerance); }
///<summary> ///</summary> ///<param name="valuationDate"></param> ///<param name="floatMargin"></param> ///<param name="fixedRate"></param> ///<param name="payTerms"></param> ///<param name="payRolls"></param> ///<param name="receiveTerms"></param> ///<param name="receiveRolls"></param> ///<param name="originalCurve"></param> ///<param name="bulletPaymentDate"></param> ///<param name="bulletPaymentValue"></param> ///<param name="listInstrumentIdAndQuotes"></param> ///<param name="listPerturbations"></param> ///<returns></returns> public static List <DoubleRangeItem> CalculateFixedSideSensitivity2(DateTime valuationDate, double floatMargin, double fixedRate, BillsSwapPricer2TermsRange payTerms, List <AmortisingResultItem> payRolls, BillsSwapPricer2TermsRange receiveTerms, List <AmortisingResultItem> receiveRolls, RateCurve originalCurve, DateTime bulletPaymentDate, double bulletPaymentValue, List <InstrumentIdAndQuoteRangeItem> listInstrumentIdAndQuotes, List <DoubleRangeItem> listPerturbations) { var result = new List <DoubleRangeItem>(); if (null == listPerturbations) { listPerturbations = new List <DoubleRangeItem>(); foreach (InstrumentIdAndQuoteRangeItem item in listInstrumentIdAndQuotes) { item.InstrumentId = RemoveExtraInformationFromInstrumentId(item.InstrumentId); var defaultPerturbationAmount = new DoubleRangeItem { Value = GetDefaultPerturbationAmount(item.InstrumentId) }; listPerturbations.Add(defaultPerturbationAmount); } } for (int i = 0; i < listInstrumentIdAndQuotes.Count; i++) { InstrumentIdAndQuoteRangeItem item = listInstrumentIdAndQuotes[i]; item.InstrumentId = RemoveExtraInformationFromInstrumentId(item.InstrumentId); DoubleRangeItem perturbItem = listPerturbations[i]; // pay == fixed. // IDayCounter dayCounter = DayCounterHelper.Parse(payTerms.DayCountConvention); var perturbationArray = new List <Pair <string, decimal> > { new Pair <string, decimal>(item.InstrumentId, (decimal)perturbItem.Value) }; //var perturbedCurveId = ObjectCacheHelper.PerturbRateCurve(curveId, perturbationArray); // Perturb the curve // var perturbedReceiveCurve = (RateCurve)originalCurve.PerturbCurve(perturbationArray); double sensitivity = GetFixedSideSensitivity(valuationDate, payRolls, receiveRolls, dayCounter, originalCurve, perturbedReceiveCurve, floatMargin, fixedRate, bulletPaymentDate, bulletPaymentValue); var bucketSensitivityItem = new DoubleRangeItem { Value = sensitivity }; result.Add(bucketSensitivityItem); } return(result); }
/// <summary> /// Returns the calculated year fraction for the dates provided. /// </summary> /// <param name="startDateArray">The start date array.</param> /// <param name="endDateArray">The end date arrray.</param> /// <param name="dayCountType">The day count fraction type, eg Actual/365.</param> /// <returns>The year fractions as a range of decimals.</returns> public object[,] YearFractions(Excel.Range startDateArray, Excel.Range endDateArray, string dayCountType) { var unqStartDateVals = DataRangeHelper.StripDateTimeRange(startDateArray); var unqEndDateVals = DataRangeHelper.StripDateTimeRange(endDateArray); int count = unqStartDateVals.Count; if (count != unqEndDateVals.Count) { throw new ArgumentException("Size of startDates and endDates arrays must match"); } IDayCounter dayCounter = DayCounterHelper.Parse(dayCountType); var yearFractions = new List <double>(); for (int i = 0; i < count; i++) { yearFractions.Add(dayCounter.YearFraction(unqStartDateVals[i], unqEndDateVals[i])); } return(RangeHelper.ConvertArrayToRange(yearFractions)); }