public static double CalculateAnnuity( DateTime repaymentPeriodStartDate, DateTime firstInstallmentDate, int numberOfInstallments, int installmentFrequencyPeriod, SimpleUnitOfTime installmentFrequencyUnitOfTime, double ratePercentage, SimpleUnitOfTime rateUnitOfTime, bool isCompound, CalendarBasisKind calendarBasis, double principalAmount, bool adjustFirstInstallment = false) { DateTime d2 = firstInstallmentDate.AddPeriod(installmentFrequencyPeriod * (numberOfInstallments - 1), installmentFrequencyUnitOfTime); double dummyAnnuity = 100; double outstanding = 0; double basis = 0; double interest = 0; DateTime d1; while (d2 > firstInstallmentDate) { d1 = d2.AddPeriod(-installmentFrequencyPeriod, installmentFrequencyUnitOfTime); basis = outstanding + dummyAnnuity; interest = InterestCalculation.CalculateInterest(d2, d1, d1, ratePercentage, rateUnitOfTime.CharLiteral(), isCompound, calendarBasis, basis).Sum(it => it.Interest); outstanding = basis + interest; d2 = d1; } d1 = repaymentPeriodStartDate; if (adjustFirstInstallment) { var prevDate = firstInstallmentDate.AddPeriod(-installmentFrequencyPeriod, installmentFrequencyUnitOfTime); if (prevDate < repaymentPeriodStartDate) { d1 = prevDate; } } basis = outstanding + dummyAnnuity; interest = InterestCalculation.CalculateInterest(d2, d1, d1, ratePercentage, rateUnitOfTime.CharLiteral(), isCompound, calendarBasis, basis).Sum(it => it.Interest); outstanding = basis + interest; return(principalAmount / outstanding * dummyAnnuity); }
public static char CharLiteral(this SimpleUnitOfTime unitOfTime) { switch (unitOfTime) { case SimpleUnitOfTime.D: return('D'); case SimpleUnitOfTime.M: return('M'); case SimpleUnitOfTime.Y: return('Y'); default: return('M'); } }
public static DateTime AddPeriod(this DateTime date, int period, SimpleUnitOfTime unitOfTime) { switch (unitOfTime) { case SimpleUnitOfTime.D: return(date.AddDays(period)); case SimpleUnitOfTime.M: return(date.AddMonths(period)); case SimpleUnitOfTime.Y: return(date.AddYears(period)); default: return(date.AddMonths(period)); } }
public InstallmentPlan CalculateInstallmentPlan(CalculateInstallmentPlanRequest request) { #region Request Validation int termUnits = 0; SimpleUnitOfTime termUnitOfTime = SimpleUnitOfTime.M; if (!string.IsNullOrEmpty(request.Term)) { termUnits = Utility.GetMonthsFromPeriod(request.Term); if (termUnits <= 0) { termUnits = Utility.GetDaysFromPeriod(request.Term); termUnitOfTime = SimpleUnitOfTime.D; } // string tmp = request.Term.Trim(); /*string uot = request.Term.Substring(request.Term.Length - 1); * string trm = request.Term.Substring(0, request.Term.Length - 1); * if (!int.TryParse(trm, out termUnits) || !SimpleUnitOfTime.TryParse(uot, out termUnitOfTime) || termUnits == 0) * { * // vp.Add(new ValidationproblemInner() { Field = "term", Errors = new List<ValidationproblemInnerErrors>() { new ValidationproblemInnerErrors() { Error = "002", Message = "Invalid term!" } } }); * }*/ } else if (request.FixedAnnuity == 0) { // vp.Add(new ValidationproblemInner() { Field = "fixedAnnuity", Errors = new List<ValidationproblemInnerErrors>() { new ValidationproblemInnerErrors() { Error = "003", Message = "If term is not specified, then fixedAnnuity must be!" } } }); } #endregion var calcReq = PrepareInstallmentPlanRequest(request, termUnits, termUnitOfTime); var res = CalculateInstalmentPlanCS(calcReq); var plan = GetPlanFromCalculationResponse(res.CalculationResponse); return(plan); }
private SimpleInterestRateInfo[] GetAdditionalRegularInterestInfo(List <PricedScheduledPeriod> periods, DateTime startDate, DateTime maturityDate, double percentage, SimpleUnitOfTime unitOfTime) { if (periods == null || periods.Count() == 0) { return(null); } periods = periods.OrderBy(p => p.StartDate).ToList(); DateTime runningDate = startDate.Date; var info = new List <SimpleInterestRateInfo>(); foreach (var period in periods) { if (startDate.Date > period.StartDate.Date || startDate.Date > period.EndDate.Date) { throw new ArgumentOutOfRangeException("All periods must start after start date."); } else if (runningDate.Date < period.StartDate.Date) { info.Add(new SimpleInterestRateInfo { Date = runningDate.Date, UnitOfTime = unitOfTime, Percentage = percentage, DateSpecified = true, UnitOfTimeSpecified = true, PercentageSpecified = true }); runningDate = period.EndDate.Date; info.Add(new SimpleInterestRateInfo { Date = period.StartDate.Date, UnitOfTime = period.UnitOfTime, Percentage = period.Percentage, DateSpecified = true, UnitOfTimeSpecified = true, PercentageSpecified = true }); } else if (runningDate.Date.Equals(period.StartDate.Date)) { runningDate = period.EndDate.Date; info.Add(new SimpleInterestRateInfo { Date = period.StartDate.Date, UnitOfTime = period.UnitOfTime, Percentage = period.Percentage, DateSpecified = true, UnitOfTimeSpecified = true, PercentageSpecified = true }); } } if (runningDate.Date < maturityDate.Date) { info.Add(new SimpleInterestRateInfo { Date = runningDate.Date, UnitOfTime = unitOfTime, Percentage = percentage, DateSpecified = true, UnitOfTimeSpecified = true, PercentageSpecified = true }); } return(info.ToArray()); }
private KdpInstallmentPlanCalculationRequest PrepareInstallmentPlanRequest(CalculateInstallmentPlanRequest request, int termUnits = 0, SimpleUnitOfTime termUnitOfTime = SimpleUnitOfTime.M) { KdpInstallmentPlanCalculationRequest calcReq = Mapper.Map <CalculateInstallmentPlanRequest, KdpInstallmentPlanCalculationRequest>(request); if (termUnits != 0) { switch (termUnitOfTime) { case SimpleUnitOfTime.Y: calcReq.NumberOfInstallments = termUnits * 12; break; case SimpleUnitOfTime.D: calcReq.NumberOfInstallments = termUnits / 30; // aproksimiramo break; default: calcReq.NumberOfInstallments = termUnits; break; } } else { calcReq.NumberOfInstallments = 9999; } calcReq.NumberOfInstallmentsSpecified = true; if (termUnits != 0) { switch (termUnitOfTime) { case SimpleUnitOfTime.Y: calcReq.MaturityDate = calcReq.StartDate.AddYears(termUnits); break; case SimpleUnitOfTime.D: calcReq.MaturityDate = calcReq.StartDate.AddDays(termUnits); break; default: calcReq.MaturityDate = calcReq.StartDate.AddMonths(termUnits); break; } } else { calcReq.MaturityDate = calcReq.StartDate.AddYears(100); } calcReq.MaturityDateSpecified = true; // da postavim sve datume koje sam zaboravio :) foreach (var prop in typeof(KdpInstallmentPlanCalculationRequest).GetProperties().Where(p => p.PropertyType == typeof(DateTime))) { prop.SetValue(calcReq, ((DateTime)prop.GetValue(calcReq)).Date); if (((DateTime)prop.GetValue(calcReq)).Date < calcReq.StartDate.Date) { prop.SetValue(calcReq, calcReq.StartDate.Date); } typeof(KdpInstallmentPlanCalculationRequest).GetProperty(prop.Name + "Specified").SetValue(calcReq, true); } calcReq.AdditionalRegularInterestInfo = GetAdditionalRegularInterestInfo(request.Periods, calcReq.StartDate, calcReq.MaturityDate, calcReq.RegularInterestPercentage, calcReq.RegularInterestUnitOfTime); calcReq.AdditionalConditions = calcReq.AdditionalRegularInterestInfo != null && calcReq.AdditionalRegularInterestInfo.Count() > 0; calcReq.AdditionalConditionsSpecified = calcReq.AdditionalRegularInterestInfo != null && calcReq.AdditionalRegularInterestInfo.Count() > 0; calcReq.RouteIdentifier = _options.Value.RouteIdentifier; calcReq.ArrangementType = _options.Value.ArrangementType; calcReq.ClientIdentifier = _options.Value.ClientIdentifier; calcReq.InstallmentPlanCalculationScenario = 2; calcReq.InstallmentPlanCalculationScenarioSpecified = true; return(calcReq); }