Ejemplo n.º 1
0
        /// <summary>
        /// 总利息
        /// </summary>
        /// <param name="principal">本金</param>
        /// <param name="rateType">利率计算方式</param>
        /// <param name="rate">利率</param>
        /// <param name="deadline">期限</param>
        /// <param name="periods">期数</param>
        /// <returns></returns>
        public decimal GetTotalInterest(decimal principal, RepaymentRateType rateType, decimal rate, decimal deadline, int periods = 1)
        {
            var list = this.GetRepayments(principal, rateType, rate, deadline, periods);

            if (list == null)
            {
                return(0);
            }
            return(list.Sum(r => r.Interest));
        }
Ejemplo n.º 2
0
        /// <summary>
        /// 单元金额
        /// </summary>
        /// <param name="rateType">利率计算方式</param>
        /// <returns></returns>
        public decimal GetUnitAmount(RepaymentRateType rateType = RepaymentRateType.年利率)
        {
            switch (rateType)
            {
            case RepaymentRateType.天利率:
                return(1m);

            case RepaymentRateType.月利率:
                return(1m / 30);

            case RepaymentRateType.季利率:
                return(1m / 90);

            default:
            case RepaymentRateType.年利率:
                return(1m / 360);
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// 获取N倍的单元金额
        /// </summary>
        /// <param name="amount">总金额</param>
        /// <param name="rateType">利率计算方式</param>
        /// <returns></returns>
        public decimal GetNUnitAmount(decimal amount, RepaymentRateType rateType = RepaymentRateType.年利率)
        {
            switch (rateType)
            {
            case RepaymentRateType.天利率:
                return(amount * 1m * 30);

            case RepaymentRateType.月利率:
                return(amount * 1m);

            case RepaymentRateType.季利率:
                return(amount * 1m / 3);

            default:
            case RepaymentRateType.年利率:
                return(amount * 1m / 12);
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// 还款列表
        /// </summary>
        /// <param name="principal">本金</param>
        /// <param name="rateType">利率计算方式</param>
        /// <param name="rate">利率</param>
        /// <param name="deadline">期限</param>
        /// <param name="periods">期数</param>
        /// <param name="autoFixPrincipalToInteger">是否为自动修正本金整数</param>
        /// <returns></returns>
        public override IEnumerable <RepaymentModel> GetRepayments(decimal principal, RepaymentRateType rateType, decimal rate, decimal deadline, int periods = 1, bool autoFixPrincipalToInteger = true)
        {
            if (periods <= 0)
            {
                throw new DomainException("还款期数不能小于0");
            }

            /*总利息*/
            var totalInterest = this.Strategy.GetNUnitAmount(principal * rate * deadline, rateType);
            var list          = new List <RepaymentModel>(periods);

            /*不用修正本金或进要修正本金但能整除*/
            if (!autoFixPrincipalToInteger || (autoFixPrincipalToInteger && principal % periods == 0))
            {
                for (var i = 1; i <= periods; i++)
                {
                    var model = new RepaymentModel()
                    {
                        Principal = principal / periods, Interest = totalInterest / periods, Period = i, PayDate = this.Strategy.GetPayTime(this.StartDate, deadline * i / periods)
                    };
                    list.Add(model);
                }
            }
            else
            {
                var fixPrincipal   = principal - principal % periods;
                var firstPrinciapl = principal - (periods - 1) * fixPrincipal / periods;
                var firstModel     = new RepaymentModel()
                {
                    Principal = firstPrinciapl, Interest = totalInterest / periods, Period = 1, PayDate = this.Strategy.GetPayTime(this.StartDate, deadline * 1 / periods)
                };
                list.Add(firstModel);

                /*只有大于1期后才可能重新计算本金与利息*/
                if (periods > 1)
                {
                    var changeAvg = (principal - firstPrinciapl) / (periods - 1);
                    for (var i = 2; i <= periods; i++)
                    {
                        var model = new RepaymentModel()
                        {
                            Principal = changeAvg, Interest = totalInterest / periods, Period = i, PayDate = this.Strategy.GetPayTime(this.StartDate, deadline * i / periods)
                        };
                        list.Add(model);
                    }
                }
            }

            return(list);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// 还款列表
        /// </summary>
        /// <param name="principal">本金</param>
        /// <param name="rateType">利率计算方式</param>
        /// <param name="rate">利率</param>
        /// <param name="deadline">期限</param>
        /// <param name="periods">期数</param>
        /// <param name="autoFixPrincipalToInteger">是否为自动修正本金整数</param>
        /// <returns></returns>
        public override IEnumerable <RepaymentModel> GetRepayments(decimal principal, RepaymentRateType rateType, decimal rate, decimal deadline, int periods = 1, bool autoFixPrincipalToInteger = true)
        {
            if (periods <= 0)
            {
                throw new ArgumentException("还款期数不能小于0");
            }

            return(new[] { new RepaymentModel()
                           {
                               Principal = principal, Interest = this.Strategy.GetNUnitAmount(principal * rate * deadline, rateType), Period = 1, PayDate = this.Strategy.GetPayTime(this.StartDate, deadline)
                           } });
        }
Ejemplo n.º 6
0
        /// <summary>
        /// 还款列表
        /// </summary>
        /// <param name="principal">本金</param>
        /// <param name="rateType">利率计算方式</param>
        /// <param name="rate">利率</param>
        /// <param name="deadline">期限</param>
        /// <param name="periods">期数</param>
        /// <param name="autoFixPrincipalToInteger">是否为自动修正本金整数</param>
        /// <returns></returns>
        public override IEnumerable <RepaymentModel> GetRepayments(decimal principal, RepaymentRateType rateType, decimal rate, decimal deadline, int periods = 1, bool autoFixPrincipalToInteger = true)
        {
            if (periods <= 0)
            {
                throw new ArgumentException("还款期数不能小于0");
            }

            var list = new List <RepaymentModel>(periods);

            for (var i = 1; i < periods; i++)
            {
                list.Add(new RepaymentModel()
                {
                    Principal = 0, Interest = this.Strategy.GetNUnitAmount(principal * rate * deadline, rateType) / periods, Period = i, PayDate = this.Strategy.GetPayTime(this.StartDate, i * deadline / periods)
                });
            }

            list.Add(new RepaymentModel()
            {
                Principal = principal, Interest = this.Strategy.GetNUnitAmount(principal * rate * deadline, rateType) / periods, Period = periods, PayDate = this.Strategy.GetPayTime(this.StartDate, deadline)
            });

            return(list);
        }
Ejemplo n.º 7
0
 /// <summary>
 /// 还款列表
 /// </summary>
 /// <param name="principal">本金</param>
 /// <param name="rateType">利率计算方式</param>
 /// <param name="rate">利率</param>
 /// <param name="deadline">期限</param>
 /// <param name="periods">期数</param>
 /// <param name="autoFixPrincipalToInteger">是否为自动修正本金整数</param>
 /// <returns></returns>
 public abstract IEnumerable <RepaymentModel> GetRepayments(decimal principal, RepaymentRateType rateType, decimal rate, decimal deadline, int periods = 1, bool autoFixPrincipalToInteger = true);
Ejemplo n.º 8
0
        /// <summary>
        /// 还款列表
        /// </summary>
        /// <param name="principal">本金</param>
        /// <param name="rateType">利率计算方式</param>
        /// <param name="rate">利率</param>
        /// <param name="deadline">期限</param>
        /// <param name="periods">期数</param>
        /// <param name="autoFixPrincipalToInteger">是否为自动修正本金整数</param>
        /// <returns></returns>
        public override IEnumerable <RepaymentModel> GetRepayments(decimal principal, RepaymentRateType rateType, decimal rate, decimal deadline, int periods = 1, bool autoFixPrincipalToInteger = true)
        {
            if (periods <= 0)
            {
                throw new DomainException("还款期数不能小于0");
            }

            switch (this.DateType)
            {
            case RepaymentTimeUnitType.天:
            {
                if (deadline / 30 != periods)
                {
                    throw new ArgumentException(string.Format("当前以天计算,共{0}天,期数应为{1},但参数的期数却为{2}", deadline, deadline / 30, periods));
                }
            }
            break;

            case RepaymentTimeUnitType.季:
            {
                if (deadline * 4 != periods)
                {
                    throw new ArgumentException(string.Format("当前以季计算,共{0}季,期数应为{1},但参数的期数却为{2}", deadline, deadline * 4, periods));
                }
            }
            break;

            case RepaymentTimeUnitType.年:
            {
                if (deadline * 12 != periods)
                {
                    throw new ArgumentException(string.Format("当前以年计算,共{0}年,期数应为{1},但参数的期数却为{2}", deadline, deadline * 12, periods));
                }
            }
            break;

            case RepaymentTimeUnitType.月:
            {
                if (deadline != periods)
                {
                    throw new ArgumentException(string.Format("当前以月计算,共{0}月,期数应为{1},但参数的期数却为{2}", deadline, deadline, periods));
                }
            }
            break;
            }
            switch (rateType)
            {
            case RepaymentRateType.天利率:
            {
                rate = rate * 30;
            }
            break;

            case RepaymentRateType.季利率:
            {
                rate = rate / 4;
            }
            break;

            case RepaymentRateType.年利率:
            {
                rate = rate / 12;
            }
            break;

            case RepaymentRateType.月利率:
                break;
            }

            var list = new List <RepaymentModel>(periods);
            /*算法中row第二个参数是指期数*/
            var factor = (decimal)Math.Pow((double)(1m + rate), periods);
            var avg    = principal * rate * factor / (factor - 1);

            //if (periods == 1)
            //    return new RepaymentModel[] { new RepaymentModel((avg - principal * rate * this.Strategy.GetUnitAmount()) * deadline, principal * rate * this.Strategy.GetUnitAmount() * deadline, 1, this.Strategy.GetPayTime(this.StartDate, deadline)) };

            var avgd = deadline / periods;

            if (!autoFixPrincipalToInteger || (autoFixPrincipalToInteger && principal % periods == 0))
            {
                for (var i = 1; i <= periods; i++)
                {
                    var interest = this.Strategy.GetNUnitAmount((principal - list.Sum(o => o.Principal)) * rate * deadline, RepaymentRateType.月利率) / periods;
                    var model    = new RepaymentModel()
                    {
                        Principal = (avg - interest), Interest = interest, Period = i, PayDate = this.Strategy.GetPayTime(this.StartDate, deadline * i / periods)
                    };
                    list.Add(model);
                }
            }
            else
            {
                for (var i = 1; i <= periods; i++)
                {
                    var interest     = this.Strategy.GetNUnitAmount((principal - list.Sum(o => o.Principal)) * rate * deadline, RepaymentRateType.月利率) / periods;
                    var fixPrincipal = (avg - interest).FormatC(0);
                    var model        = new RepaymentModel()
                    {
                        Principal = fixPrincipal, Interest = interest + (avg - interest - fixPrincipal), Period = i, PayDate = this.Strategy.GetPayTime(this.StartDate, deadline * i / periods)
                    };
                    list.Add(model);
                }
            }

            //list.Add(new RepaymentModel((avg - principal * rate) * avgd, principal * rate * avgd, 1, this.Strategy.GetPayTime(this.StartDate, avgd * 1)));

            //for (var i = 2; i <= periods; i++)
            //{
            //    var interest = (principal - list.Sum(o => o.Principal)) * rate * avgd;
            //    var model = new RepaymentModel((avg - interest) * avgd, interest * avgd, i, this.Strategy.GetPayTime(this.StartDate, avgd * i));
            //    list.Add(model);
            //}

            return(list);
        }
Ejemplo n.º 9
0
        /// <summary>
        /// 还款列表
        /// </summary>
        /// <param name="principal">本金</param>
        /// <param name="rateType">利率计算方式</param>
        /// <param name="rate">利率</param>
        /// <param name="deadline">期限</param>
        /// <param name="periods">期数</param>
        /// <param name="autoFixPrincipalToInteger">是否为自动修正本金整数</param>
        /// <returns></returns>
        public override IEnumerable <RepaymentModel> GetRepayments(decimal principal, RepaymentRateType rateType, decimal rate, decimal deadline, int periods = 1, bool autoFixPrincipalToInteger = true)
        {
            if (periods <= 0)
            {
                throw new ArgumentException("还款期数不能小于0");
            }

            var avgPrincipalPeriod = this.principalPeriods.Count(o => o.PayPrincipal);

            if (periods != this.principalPeriods.Count())
            {
                throw new ArgumentException("还款总期数不等于剩余还款本金期数");
            }

            /*先平均分出本金,在还了本金后要重新减去已经还的本金*/
            var prinList = new List <decimal>(avgPrincipalPeriod);
            var list     = new List <RepaymentModel>(periods);

            var hadPayPrincipal = 0m;

            /*不用修正本金*/
            if (!autoFixPrincipalToInteger)
            {
                for (var i = 0; i < avgPrincipalPeriod; i++)
                {
                    prinList.Add(principal / avgPrincipalPeriod);
                }

                int j = 0;
                for (var i = 1; i <= periods; i++)
                {
                    if (this.principalPeriods.ElementAt(i - 1).PayPrincipal)
                    {
                        list.Add(new RepaymentModel()
                        {
                            Principal = prinList[j], Interest = this.Strategy.GetNUnitAmount((principal - hadPayPrincipal) * rate * deadline, rateType) / periods, Period = i, PayDate = this.Strategy.GetPayTime(this.StartDate, i * deadline / periods)
                        });
                        hadPayPrincipal += prinList[j];
                        j++;
                    }
                    else
                    {
                        list.Add(new RepaymentModel()
                        {
                            Principal = 0, Interest = this.Strategy.GetNUnitAmount((principal - hadPayPrincipal) * rate * deadline, rateType) / periods, Period = i, PayDate = this.Strategy.GetPayTime(this.StartDate, i * deadline / periods)
                        });
                    }
                }

                return(list);
            }

            if (principal % avgPrincipalPeriod == 0)
            {
                for (var i = 0; i < avgPrincipalPeriod; i++)
                {
                    prinList.Add(principal / avgPrincipalPeriod);
                }
            }
            else
            {
                var fixPrincipal   = principal - principal % avgPrincipalPeriod;
                var firstPrinciapl = principal - (avgPrincipalPeriod - 1) * fixPrincipal / avgPrincipalPeriod;
                prinList.Add(firstPrinciapl);
                if (avgPrincipalPeriod > 1)
                {
                    for (var i = 1; i < avgPrincipalPeriod; i++)
                    {
                        prinList.Add((principal - firstPrinciapl) / (avgPrincipalPeriod - 1));
                    }
                }
            }

            int k = 0;

            for (var i = 1; i <= periods; i++)
            {
                if (this.principalPeriods.ElementAt(i - 1).PayPrincipal)
                {
                    list.Add(new RepaymentModel()
                    {
                        Principal = prinList[k], Interest = this.Strategy.GetNUnitAmount((principal - hadPayPrincipal) * rate * deadline, rateType) / periods, Period = i, PayDate = this.Strategy.GetPayTime(this.StartDate, i * deadline / periods)
                    });
                    hadPayPrincipal += prinList[k];
                    k++;
                }
                else
                {
                    list.Add(new RepaymentModel()
                    {
                        Principal = 0, Interest = this.Strategy.GetNUnitAmount((principal - hadPayPrincipal) * rate * deadline, rateType) / periods, Period = i, PayDate = this.Strategy.GetPayTime(this.StartDate, i * deadline / periods)
                    });
                }
            }

            return(list);
        }
Ejemplo n.º 10
0
        /// <summary>
        /// 还款列表
        /// </summary>
        /// <param name="principal">本金</param>
        /// <param name="rateType">利率计算方式</param>
        /// <param name="rate">利率</param>
        /// <param name="deadline">期限</param>
        /// <param name="periods">期数</param>
        /// <param name="autoFixPrincipalToInteger">是否为自动修正本金整数</param>
        /// <returns></returns>
        public override IEnumerable <RepaymentModel> GetRepayments(decimal principal, RepaymentRateType rateType, decimal rate, decimal deadline, int periods = 1, bool autoFixPrincipalToInteger = true)
        {
            if (periods <= 0)
            {
                throw new ArgumentException("还款期数不能小于0");
            }

            if (periods != this.principalPeriods.Count() || periods != this.principalPeriods.Max(p => p.Period))
            {
                throw new ArgumentException("还款总期数不等于剩余还款本金期数");
            }

            var list            = new List <RepaymentModel>(periods);
            var hadPayPrincipal = 0m;

            /*不用修正本金*/
            if (!autoFixPrincipalToInteger)
            {
                for (var i = 1; i <= periods; i++)
                {
                    var percent = this.principalPeriods.ElementAt(i - 1);
                    list.Add(new RepaymentModel()
                    {
                        Principal = principal * percent.Percent / 100, Interest = this.Strategy.GetNUnitAmount((principal - hadPayPrincipal) * rate * deadline, rateType) / periods, Period = i, PayDate = this.Strategy.GetPayTime(this.StartDate, i * deadline / periods)
                    });
                    hadPayPrincipal += principal * percent.Percent / 100;
                }

                return(list);
            }

            for (var i = 1; i <= periods; i++)
            {
                var percent = this.principalPeriods.ElementAt(i - 1);

                if (i != periods)
                {
                    list.Add(new RepaymentModel()
                    {
                        Principal = principal * percent.Percent / 100, Interest = this.Strategy.GetNUnitAmount((principal - hadPayPrincipal) * rate * deadline, rateType) / periods, Period = i, PayDate = this.Strategy.GetPayTime(this.StartDate, i * deadline / periods)
                    });
                }
                else
                {
                    list.Add(new RepaymentModel()
                    {
                        Principal = principal - hadPayPrincipal, Interest = this.Strategy.GetNUnitAmount((principal - hadPayPrincipal) * rate * deadline, rateType) / periods, Period = i, PayDate = this.Strategy.GetPayTime(this.StartDate, i * deadline / periods)
                    });
                }

                hadPayPrincipal += principal * percent.Percent / 100;
            }

            return(list);
        }