/// <summary> /// Create a surface from an FpML /// </summary> /// <param name="fpmlData"></param> public VolatilitySurface(Pair <PricingStructure, PricingStructureValuation> fpmlData) { IDayCounter dc = Actual365.Instance; var termPoints = new List <TermPoint> { TermPointFactory.Create(1.0m, new DateTime()), TermPointFactory.Create(0.99m, new DateTime().AddDays(10)), TermPointFactory.Create(0.97m, new DateTime().AddDays(100)) }; var termCurve = TermCurve.Create(new DateTime(), new InterpolationMethod { Value = "LinearInterpolation" }, true, termPoints); Interpolator = new TermCurveInterpolator(termCurve, new DateTime(), dc);//TODO need to create a surfaceinterpolator. _algorithm = "Linear"; SetFpMLData(fpmlData); // var holder = new PricingStructureAlgorithmsHolder(); bool doBuild = GetVolatilityMatrix().dataPoints.point == null; if (doBuild) { // var bootstrapperName = holder.GetValue(PricingStructureType.RateVolatilityMatrix, _algorithm, "Bootstrapper"); // Bootstrapper = Bootstrap(bootstrapperName, PricingStructure, PricingStructureValuation); } // SetInterpolator(PricingStructureValuation.baseDate.Value, _algorithm, holder); _matrixIndexHelper = new SortedList <ExpiryTenorStrikeKey, int>(new ExpiryTenorStrikeKey()); ProcessVolatilityRepresentation(); }
/// <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="baseDate"></param> ///<param name="frequency"></param> ///<param name="dayCountFraction"></param> ///<returns></returns> ///<exception cref="NotImplementedException"></exception> public static decimal PeriodFractionFromCompoundingFrequency(DateTime baseDate, CompoundingFrequencyEnum frequency, DayCountFraction dayCountFraction) { switch (frequency) { case CompoundingFrequencyEnum.Continuous: return(0.0m); case CompoundingFrequencyEnum.Daily: IDayCounter dc = DayCounterHelper.Parse(dayCountFraction.Value); return((decimal)dc.YearFraction(baseDate, baseDate.AddDays(1.0d))); case CompoundingFrequencyEnum.Weekly: return((decimal)1 / 52); case CompoundingFrequencyEnum.Monthly: return((decimal)1 / 12); case CompoundingFrequencyEnum.Quarterly: return((decimal)1 / 4); case CompoundingFrequencyEnum.SemiAnnual: return((decimal)1 / 2); case CompoundingFrequencyEnum.Annual: return(1.0m); default: throw new NotImplementedException(); } }
public InterestRate EquivalentRate(IDayCounter dc, Compounding c, Frequency f, DateTimeOffset d1, DateTimeOffset d2) { var t1 = _dc.YearFraction(d1, d2); var t2 = dc.YearFraction(d1, d2); var compoundFactor = CompoundFactor(t1); return ImpliedRate(dc, compoundFactor, c, f, t2); }
/// <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 InterestRate(IDayCounter dc, double r, Compounding c, Frequency f) { _dc = dc; _r = r; _c = c; _f = f; }
public static InterestRate ImpliedRate(IDayCounter dc, double compoundFactor, Compounding c, Frequency f, double time) { double r; if (Helper.Equals(compoundFactor, 1.0)) { r = 0.0; } else { switch (c) { case Compounding.Simple: r = (compoundFactor - 1.0)/time; break; case Compounding.Compounded: r = (Math.Pow(compoundFactor, 1.0 / ((double)f * time)) - 1.0) * (double)f; break; case Compounding.Continuous: r = Math.Log(compoundFactor)/time; break; default: throw new NotImplementedException($"Unknown Compounding {c}"); } } return new InterestRate(dc, r, c, f); }
static void TestCreatingInvoices3(IDayCounter dayCalculator, string filename) { var loan = new FixedInterestLoan(dayCalculator) { InterestRate = 10, CurrentPrincipal = 10000, StartAmount = 10000, PayoutDate = new DateTime(2017, 10, 01), TenureYears = 10, }; var invoices = new List <Invoice>(); var baseDate = loan.PayoutDate; while (loan.CurrentPrincipal > 0.001) { baseDate = baseDate.AddMonths(1); var date = baseDate.AddDays(-1); var invoice = loan.AddInvoice(date, new DateTime(date.Year, date.Month, 1), baseDate, 0.0); loan.CurrentPrincipal -= invoice.Principal; invoices.Add(invoice); //Console.WriteLine(invoice.ToString()); //Console.WriteLine($"{invoice.InvoiceDate.ToString("MMM-yyyy")} | {Math.Round(invoice.FullInvoiceAmount, 0, MidpointRounding.AwayFromZero)} | {Math.Round(invoice.Interest, 0, MidpointRounding.AwayFromZero)} | {Math.Round(invoice.Principal, 0, MidpointRounding.AwayFromZero)} | {Math.Round(loan.CurrentPrincipal, 0, MidpointRounding.AwayFromZero)}"); } Console.WriteLine($"SUM: Principal {invoices.Sum(s => s.Principal)}, Interest: {invoices.Sum(s => s.Interest)}, InvoiceFee: {invoices.Sum(s => s.InvoiceFee)}, LateFee: {invoices.Sum(s => s.LateFee)}"); TestOutput.CreateCSV(invoices, filename); }
static void TestPayingOnLoan(IDayCounter dayCalculator) { var loan = new FixedEmiLoan(dayCalculator) { InterestRate = 10, CurrentPrincipal = 10000, StartAmount = 10000, PayoutDate = new DateTime(2017, 01, 01), TenureYears = 10, }; var invoices = new List <Invoice>(); var baseDate = loan.PayoutDate; for (int i = 0; i < 3; i++) { baseDate = baseDate.AddMonths(1); var date = baseDate.AddDays(-1); var invoice = loan.AddInvoice(date, new DateTime(date.Year, date.Month, 1), baseDate, 0.0); //loan.CurrentPrincipal -= invoice.Principal; invoices.Add(invoice); //Console.WriteLine(invoice.ToString()); //Console.WriteLine($"{invoice.InvoiceDate.ToString("MMM-yyyy")} | {Math.Round(invoice.FullInvoiceAmount, 0, MidpointRounding.AwayFromZero)} | {Math.Round(invoice.Interest, 0, MidpointRounding.AwayFromZero)} | {Math.Round(invoice.Principal, 0, MidpointRounding.AwayFromZero)} | {Math.Round(loan.CurrentPrincipal, 0, MidpointRounding.AwayFromZero)}"); } loan.Invoices = invoices; var payment = loan.Pay(new DateTime(2017, 03, 31), 5000.0); Console.WriteLine(payment.ToString()); Console.WriteLine($"SUM: Principal {invoices.Sum(s => s.Principal)}, Interest: {invoices.Sum(s => s.Interest)}, InvoiceFee: {invoices.Sum(s => s.InvoiceFee)}, LateFee: {invoices.Sum(s => s.LateFee)}"); Console.WriteLine("Current Principal: " + loan.CurrentPrincipal); }
/// <summary> /// Gets the times to expiry. /// </summary> /// <param name="expiryDates">The expiry Dates.</param> /// <param name="baseDate">The base Date.</param> /// <returns>A list of expity times.</returns> public List <double> GetTimesToExpiry(List <DateTime> expiryDates, DateTime baseDate) { IDayCounter cDefaultDayCounter = Actual365.Instance; return(expiryDates.Select(date => cDefaultDayCounter.YearFraction(baseDate, date)).ToList()); }
// need a based date? // ///<summary> ///</summary> ///<param name="discountCurve"></param> ///<param name="baseDate"></param> ///<param name="frequency"></param> ///<param name="dayCounter"></param> ///<returns></returns> ///<exception cref="System.Exception"></exception> public static TermCurve ToZeroCurve(TermCurve discountCurve, DateTime baseDate, CompoundingFrequencyEnum frequency, IDayCounter dayCounter) { TermCurve result = TermCurve.Create(new List <TermPoint>()); foreach (TermPoint point in discountCurve.point) { DateTime pointDate = XsdClassesFieldResolver.TimeDimensionGetDate(point.term); double zeroRateDouble; if (baseDate != pointDate) { double time = dayCounter.YearFraction(baseDate, pointDate); zeroRateDouble = RateAnalytics.DiscountFactorToZeroRate((double)point.mid, time, frequency); } else { // set after the loop zeroRateDouble = 0; } TermPoint zeroPoint = TermPointFactory.Create(Convert.ToDecimal(zeroRateDouble), pointDate); zeroPoint.id = point.id; result.Add(zeroPoint); } if (result.point[0].mid == 0) { result.point[0].mid = result.point[1].mid; } return(result); }
/// <summary> /// Computes the expiry interpolated Caplet volatility. /// </summary> /// <param name="expiry">The expiry date. /// Postcondition: expiry cannot be before the Calculation date.</param> /// <returns>Expiry interpolated Caplet volatility.</returns> public decimal ComputeVolatility(DateTime expiry) { // Convert the expiry into a corresponding time in ACT/365 // day count. IDayCounter dayCountObj = Actual365.Instance; var target = dayCountObj.YearFraction (_calculationDate, expiry); // Validate the time equivalent to the expiry date. var targetErrorMessage = "Expiry cannot be before: " + _calculationDate; DataQualityValidator.ValidateMinimum (target, 0.0d, targetErrorMessage, true); // Compute and return the Caplet volatility: flat line extrapolate // at each end. decimal volatility; if (target < 0.0d) { const string errorMessage = "Date cannot be before the Calculation Date"; throw new ArgumentException(errorMessage); } if (target >= 0.0d && target < decimal.ToDouble(_firstExpiry)) { volatility = _firstVolatility; } else { volatility = target > decimal.ToDouble(_lastExpiry) ? _lastVolatility : (decimal)_expiryInterpolationObj.ValueAt(target, true); } return(volatility); }
public static double GetEffectiveFrequency(List <AmortisingResultItem> cashflowsSchedule, BillsSwapPricer2TermsRange terms) { IDayCounter dayCounter = DayCounterHelper.Parse(terms.DayCountConvention); double effectiveFrequency = GetEffectiveFrequency(cashflowsSchedule, dayCounter); return(effectiveFrequency); }
public double GetAnnualYield(List <BillSwapPricerCashflowRow> input, IDayCounter dayCounter, RateCurve rateCurve) { double simpleYield = GetSimpleYield(input, dayCounter, rateCurve); double yearFraction = dayCounter.YearFraction(input[0].DateTime, input[input.Count - 1].DateTime); double annuallyCompoundingRate = Math.Pow(1.0 + simpleYield, 1 / yearFraction) - 1.0; return(annuallyCompoundingRate); }
/// <summary> /// The main ctor. /// </summary> /// <param name="termCurve"></param> /// <param name="baseDate"></param> /// <param name="centralBankMonthRules"></param> /// <param name="centralBankDays"></param> /// <param name="centralBank"></param> /// <param name="dayCounter"></param> public GapStepInterpolator(TermCurve termCurve, DateTime baseDate, int centralBankMonthRules, DateTime[] centralBankDays, CentralBanks centralBank, IDayCounter dayCounter) : base(ConvertTermCurve(centralBank.ToString(), termCurve, baseDate, centralBankDays, dayCounter), baseDate, dayCounter) { CentralBankDateRuleMonths = centralBankMonthRules; CentralBank = centralBank; CentralBankDays = centralBankDays; }
private static TermCurve ConvertTermCurve(string centralBankName, TermCurve termCurve, DateTime baseDate, DateTime[] centralBankDays, IDayCounter dayCounter) { var interpolationMethod = new InterpolationMethod { Value = "PiecewiseConstantRateInterpolation" }; termCurve.interpolationMethod = interpolationMethod; return(InterpolateGapStepTermPoints(centralBankName, termCurve, centralBankDays, baseDate, dayCounter)); }
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); }
/// <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 BillSwapPricer2SwapParRateObjectiveFunction(DateTime valuationDate, List <AmortisingResultItem> fixedCFs, List <AmortisingResultItem> floatCFs, RateCurve curve, IDayCounter dayCounter, double floatRateMargin, DateTime bulletPaymentDate, double bulletPaymentValue) { _fixedCFs = fixedCFs; _floatCFs = floatCFs; _curve = curve; _dayCounter = dayCounter; _floatRateMargin = floatRateMargin; _valuationDate = valuationDate; _bulletPaymentDate = bulletPaymentDate; _bulletPaymentValue = bulletPaymentValue; }
/// <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); }
//TODO add EOM, EOQ and EOY perturbation: this transfers the step to the specific day. //Also needs to add EOM swaps to the asset config file. /// <summary> /// The main ctor. /// </summary> /// <param name="termCurve"></param> /// <param name="baseDate"></param> /// <param name="centralBankDateRuleMonths"></param> /// <param name="centralBank"></param> /// <param name="dayCounter"></param> public GapStepInterpolator(TermCurve termCurve, DateTime baseDate, int centralBankDateRuleMonths, CentralBanks centralBank, IDayCounter dayCounter) : base(ConvertTermCurve(termCurve, baseDate, centralBankDateRuleMonths, dayCounter), baseDate, dayCounter) { CentralBankDateRuleMonths = centralBankDateRuleMonths; _centralBank = centralBank;//var names = Enum.GetNames(typeof(AssetFactory.Types)); //TODO remove this once working. var lastDate = (DateTime)termCurve.point[termCurve.point.Length - 1].term.Items[0]; CentralBankDays = CentralBanksHelper.GetCentralBankDays(baseDate, centralBank, centralBankDateRuleMonths, lastDate); TermCurve = InterpolateGapStepTermPoints(termCurve, CentralBankDays, baseDate, dayCounter); }
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> ///// Returns a list of non-interpolated values found in a immediate vicinity of requested point. ///// <remarks> ///// If a GetValue method returns a exact match - this method should be returning null. ///// </remarks> ///// </summary> ///// <param name="termCurve"></param> ///// <param name="dates"></param> ///// <returns></returns> //public static int[] GetPreviousIndices(TermCurve termCurve, DateTime[] dates) //{ // var termDates = termCurve.GetListTermDates(); // var results = new List<int>(); // var temp = new int[dates.Length]; // var counter = 0; // foreach (var date in dates) //This handles or is supposed to handle the case of multiple central bank dates between node points. // { // var index = Array.BinarySearch(termDates.ToArray(), date); // if (index >= 0) // { // temp[counter] = index; // } // else // { // var nextIndex = ~index; // var prevIndex = nextIndex - 1; // temp[counter] = prevIndex; // } // counter++; // } // for(var i =1; i <= temp.Length-1;i++) // { // var j = 1; // while(temp[i-1]==temp[i]) // { // j++; // } // results.Add(j); // } // return results.ToArray(); //} ///// <summary> ///// Returns a list of non-interpolated values found in a immediate vicinity of requested point. ///// <remarks> ///// If a GetValue method returns a exact match - this method should be returning null. ///// </remarks> ///// </summary> ///// <param name="termCurve"></param> ///// <param name="date"></param> ///// <returns></returns> //public static int GetPreviousIndex(TermCurve termCurve, DateTime date) //{ // var dates = termCurve.GetListTermDates(); // var index = Array.BinarySearch(dates.ToArray(), date); // if (index >= 0) // { // return index; // } // var nextIndex = ~index; // var prevIndex = nextIndex - 1; // return prevIndex; //} ///// <summary> ///// Returns a list of non-interpolated values found in a immediate vicinity of requested point. ///// <remarks> ///// If a GetValue method returns a exact match - this method should be returning null. ///// </remarks> ///// </summary> ///// <param name="termCurve"></param> ///// <param name="date"></param> ///// <returns></returns> //public static TermPoint GetPreviousPoint(TermCurve termCurve, DateTime date) //{ // var dates = termCurve.GetListTermDates(); // var values = termCurve.GetListMidValues(); // var index = Array.BinarySearch(dates.ToArray(), date); // if (index >= 0) // { // return termCurve.point[index]; // } // var nextIndex = ~index; // var prevIndex = nextIndex - 1; // //TODO check for DateTime1D point and return the date. // var prevPoint = TermPointFactory.Create(values[prevIndex], dates[prevIndex]); // return prevPoint; //} /// <summary> /// Returns a list of non-interpolated values found in a immediate vicinity of requested point. /// <remarks> /// If a GetValue method returns a exact match - this method should be returning null. /// This uses the Array.BinarySearch function which returns the index of the specified /// value in the specified array, if value is found; otherwise, a negative number. /// If value is not found and value is less than one or more elements in array, the /// negative number returned is the bitwise complement of the index of the first element /// that is larger than value. If value is not found and value is greater than all /// elements in array, the negative number returned is the bitwise complement of /// (the index of the last element plus 1). If this method is called with a non-sorted array, /// the return value can be incorrect and a negative number could be returned, even if value is present in array. /// </remarks> /// </summary> /// <param name="baseDate">The curve base date.</param> /// <param name="startDate">The interval start date.</param> /// <param name="endDate">The interval end date.</param> /// <param name="endRate">The start date continuous zero.</param> /// <param name="dayCounter">The day counter.</param> /// <param name="intermediateDate">The date must lie in the interval between start and end dates.</param> /// <param name="startRate">The start date continuous zero.</param> /// <returns></returns> public static decimal InterpolateRate(DateTime baseDate, DateTime startDate, decimal startRate, DateTime endDate, decimal endRate, IDayCounter dayCounter, DateTime intermediateDate) { var time1 = dayCounter.YearFraction(baseDate, startDate); var time2 = dayCounter.YearFraction(baseDate, endDate); var timei = dayCounter.YearFraction(baseDate, intermediateDate); var i1 = (time2 - timei) / (time2 - time1); var i2 = (timei - time1) / (time2 - time1); var r1 = (double)startRate; var r2 = (double)endRate; return((decimal)((i1 * r1 * time1 + i2 * r2 * time2) / timei)); }
public static double GetFixedSideSensitivity(DateTime valuationDate, List <AmortisingResultItem> fixedCFs, List <AmortisingResultItem> floatCFs, IDayCounter dayCounter, RateCurve originalCurve, RateCurve perturbedCurve, double floatRateMargin, double fixedRate, DateTime bulletPaymentDate, double bulletPaymentValue) { // solve for the fixed rate // var objectiveFunction = new BillSwapPricer2SwapParRateObjectiveFunction(valuationDate, fixedCFs, floatCFs, originalCurve, dayCounter, floatRateMargin, bulletPaymentDate, bulletPaymentValue); double originalPV = objectiveFunction.Value(fixedRate); var objectiveFunctionWithPerturbedCurve = new BillSwapPricer2SwapParRateObjectiveFunction(valuationDate, fixedCFs, floatCFs, perturbedCurve, dayCounter, floatRateMargin, bulletPaymentDate, bulletPaymentValue); double perturbedPV = objectiveFunctionWithPerturbedCurve.Value(fixedRate); return(perturbedPV - originalPV); }
///<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> /// Helper function used to initialise the private fields. /// </summary> /// <param name="volatilityCurve">The Bootstrap engine /// that contains the results of the bootstrap.</param> /// <param name="expiryInterpolationType">Type of the expiry /// interpolation. /// Example: Linear interpolation.</param> private void InitialisePrivateFields (VolatilityCurve volatilityCurve, ExpiryInterpolationType expiryInterpolationType) { // Initialise the Calculation Date. _calculationDate = volatilityCurve.GetBaseDate(); // Set the x and y arrays for the one dimensional interpolation. var results = volatilityCurve.BootstrapResults.Results; IDayCounter dayCountObj = Actual365.Instance; var tempXArray = new List <double>(); var tempYArray = new List <double>(); var count = 1; foreach (var expiry in results.Keys) { var timeToExpiry = dayCountObj.YearFraction (_calculationDate, expiry); tempXArray.Add(timeToExpiry); tempYArray.Add(decimal.ToDouble(results[expiry])); // Record the first and last time to expiry and available // bootstrap Caplet volatility. if (count == 1) { _firstExpiry = (decimal)timeToExpiry; _firstVolatility = results[expiry]; } _lastVolatility = results[expiry]; _lastExpiry = (decimal)timeToExpiry; ++count; } double[] xArray = tempXArray.ToArray(); double[] yArray = tempYArray.ToArray(); // Initialise the one dimensional interpolation object. switch (expiryInterpolationType) { case ExpiryInterpolationType.CubicHermiteSpline: _expiryInterpolationObj = new CubicHermiteSplineInterpolation(); _expiryInterpolationObj.Initialize(xArray, yArray); break; default: // Linear interpolation _expiryInterpolationObj = new LinearInterpolation(); _expiryInterpolationObj.Initialize(xArray, yArray); break; } }
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); }
/// <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]; }
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; } } }
private void SetInterpolator() { IDayCounter dc = Actual365.Instance; var termPoints = new List <TermPoint> { TermPointFactory.Create(1.0m, new DateTime()), TermPointFactory.Create(0.99m, new DateTime().AddDays(10)), TermPointFactory.Create(0.97m, new DateTime().AddDays(100)) }; var termCurve = TermCurve.Create(new DateTime(), new InterpolationMethod { Value = "LinearInterpolation" }, true, termPoints); Interpolator = new TermCurveInterpolator(termCurve, new DateTime(), dc); }
/// <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); }