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));
            }
        }
Ejemplo n.º 4
0
        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);
        }
Ejemplo n.º 5
0
        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());
        }
Ejemplo n.º 6
0
        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);
        }