Algorithm 生成摊销计划

Algorithm 生成摊销计划,algorithm,language-agnostic,amortization,Algorithm,Language Agnostic,Amortization,我的任务是创建一个生成摊销计划的程序。到目前为止,我只做了一点研究,但我需要计算出付款、每笔付款的利息和每笔付款的本金。有人能给我指出正确的方向来解决这个问题吗?虽然我将在RPG中写这篇文章,但我相信其他人将来也会使用这个算法 (更新)好的,那么我如何根据一年365天计算呢?有很多网站提供这些公式。一个是: 不需要花哨的算法,因为公式通常非常简单。布赖恩是对的。公式很简单 如果您希望您的解决方案是一个好的解决方案,您将注意舍入错误。如果您只是让舍入误差累积和传播,您可以在计划结束时减去几美分。

我的任务是创建一个生成摊销计划的程序。到目前为止,我只做了一点研究,但我需要计算出付款、每笔付款的利息和每笔付款的本金。有人能给我指出正确的方向来解决这个问题吗?虽然我将在RPG中写这篇文章,但我相信其他人将来也会使用这个算法


(更新)好的,那么我如何根据一年365天计算呢?

有很多网站提供这些公式。一个是:


不需要花哨的算法,因为公式通常非常简单。

布赖恩是对的。公式很简单

如果您希望您的解决方案是一个好的解决方案,您将注意舍入错误。如果您只是让舍入误差累积和传播,您可以在计划结束时减去几美分。通过仔细编程,您可以将错误降至最低


此外,如果您的计算机上有MS Excel,您可以从MS office online下载摊销模板。

最近,当我购买第一套住房时,我编写了一个JavaScript应用程序供个人使用

下面是一段修改后的代码片段,用于确定每月付款:

var balance = 200000; // for example
var periods = 360; // 30 years
var monthlyRate = (0.065)/12;  // 0.065= APR of 6.5% as decimal
var monthyPayment = (monthlyRate /(1-(Math.pow((1+monthlyRate),-(periods)))))*balance;

for (var i=0; i<360; i++) {
  var interestForMonth = balance * monthlyRate;
  var principalForMonth = monthlyPayment - interestForMonth;
  balance -= monthlyPayment; // probably should be -= principalForMonth see comments below
  // output as necessary.
}
var余额=200000;//例如
var期间=360;//30年
月利率风险值=(0.065)/12;//0.065=小数点后6.5%的APR
var月付款=(月利率/(1-(数学功率((1+月利率),-(期间ЮЮ))*余额;

对于(var i=0;i,这里是我最终创建的。我已经发布了整个测试程序。它是用RPG编写的,但是对于任何其他语言都应该很容易理解

 H ActGrp(*caller) BndDir('MODULES') DftActGrp(*no)
   //*********************************************************************
   // Program . . . . . AMORT
   //*********************************************************************
   // Printer/Display Files
 FAMORTDF   CF   E             WORKSTN sfile(SFL01:rrn01)
   //*********************************************************************
   // Named Constants
  /copy modules/qcopysrc,statuscopy

   // Named Indicators
 D indicatorPtr    S               *   Inz(%Addr(*IN))
 D                 DS                  Based(IndicatorPtr)
  /copy modules/qcopysrc,scrncopy

   // Subfile  Fields
 D rrn01           S              4P 0 inz(0)

   //*********************************************************************
   // Misc Fields
 D* Monthly Payment
 D m               S             12P 2        
 D* Principal
 D p               S             12P 2                                      
 D* Interest
 D i               S              5P 3                                      
 D* Length (in Years)
 D l               S              3P 0                                      
 D* Monthly Interest
 D j               S             10P10                                      
 D* # of Months
 D n               S              5P 0                                      
 D* Current Monthly Int.
 D h               S             12P 2                                      
 D* Current Principal
 D c               S             12P 2                                      
 D* New Balance
 D q               S             12P 2                                      

   //*********************************************************************
   // External Program Procedures

   // Internal Subprocedures
 D Init            PR
 D Main            PR
 D SubfileFilled   PR              N
 D ClearScreen     PR
 D IsValidData     PR              N
 D LoanPayment     PR            12P 2
 D  principal                    12P 2
 D  interest                      5P 3
 D  loanPeriod                    3P 0
 D  paymentsYear                  3P 0

   // External Subprocedures
   ///copy modules/qsrvsrc,p.string

   //*********************************************************************
   // Entry Parms
 D AMORT           PR                  extpgm('AMORT')
 D AMORT           PI
   //*********************************************************************
  /free
   Init();
   Main();

   *inlr = *on;
  /end-free

 P*--------------------------------------------------
 P* Procedure name: Init
 P* Purpose:
 P* Returns:
 P*--------------------------------------------------
 P Init            B
 D Init            PI

  /free

   pgm = 'AMORT';
   sflDsp = *off;

   return;

  /end-free
 P Init            E


 P*--------------------------------------------------
 P* Procedure name: Main
 P* Purpose:
 P* Returns:
 P*--------------------------------------------------
 P Main            B
 D Main            PI

  /free

   dow (not F3) and (not F12);

     write OVR01;
     exfmt CTL01;
     ClearScreen();

     if (IsValidData()) and (not F3) and (not F12);

       // Fill the header information
       dPayment = LoanPayment(dLoanAmt:dIntRate:dLoanPrd:dPayYear);
       dNumPaymnt = dLoanPrd * dPayYear;
       m = dPayment + dExtraPay;
       p = dLoanAmt;
       q = p;

       // Fill the table
       if (SubfileFilled());
         sflDsp = *on;
       endif;
     endif;

   enddo;

   return;

  /end-free
 P Main            E


 P*--------------------------------------------------
 P* Procedure name: SubfileFilled
 P* Purpose: Fill the subfile
 P* Returns:
 P*--------------------------------------------------
 P SubfileFilled   B
 D SubfileFilled   PI              N

 D isFilled        S               N
 D x               S              4P 0
 D intCume         S             12P 2
 D extraPayCume    S             12P 2
 D payDate         S               D
 D payment         S             12P 2
 D extraPayment    S             12P 2

  /free

   isFilled = *on;

   sflClear = *on;
   write CTL01;
   sflClear = *off;
   rrn01 = 0;
   x = 0;

   // Setup the work fields
   payment = dPayment;
   extraPayment = dExtraPay;
   payDate = dStartDate;

   // Create records until there is a zero balance
   dow (q > 0);

     x += 1;
     eval(h) h = p * j; // Monthly Interest

     // Adjust for final payment
     if (p < m);
       m = p + h;
       payment = p;
       extraPayment = h;
     endif;

     // Calulate Principal
     c = m - h;
     // Calulate the new balance
     q = p - c;

     // Accumulate the interest and extra payments
     intCume += h;
     extraPayCume += extraPayment;

     // Determine the next pay date
     select;
       when dTerms = '1'; //Yearly
         payDate += %years(1);
       when dTerms = '2'; //Semi-Annual
         payDate += %months(6);
       when dTerms = '3'; //Quarterly
         payDate += %months(3);
       when dTerms = '4'; //Monthly
         payDate += %months(1);
       when dTerms = '5'; //Bi-Weekly
         payDate += %days(14);
     endsl;

     // Fill the subfile
     sPayNum = x;
     sPayDate = payDate;
     sBegBal = p;
     sSchedPay = payment;
     sExtraPay = extraPayment;
     sTotPay = m;
     sInterest = h;
     sPrincipal = c;
     sEndBal = q;
     sCumeInt = intCume;

     // Move the End balance to the beginning balance
     p = q;

     rrn01 += 1;
     write SFL01;

   enddo;

   // Return the calculated information to the header
   dActPaymnt = x;
   dTotInt = intCume;
   dTotEPay = extraPayCume;

   if (rrn01 < 1);
     isFilled = *off;
   endif;

   return isFilled;

  /end-free
 P SubfileFilled   E


 P*--------------------------------------------------
 P* Procedure name: ClearScreen
 P* Purpose:
 P* Returns:
 P*--------------------------------------------------
 P ClearScreen     B
 D ClearScreen     PI

  /free

   c = 0;
   h = 0;
   i = 0;
   j = 0;
   l = 0;
   m = 0;
   n = 0;
   p = 0;
   q = 0;
   dPayment = 0;
   dNumPaymnt = 0;
   dActPaymnt = 0;
   dTotEPay = 0;
   dTotInt = 0;

   return;

  /end-free
 P ClearScreen     E


 P*--------------------------------------------------
 P* Procedure name: IsValidData
 P* Purpose: Validate the data on the screen
 P* Returns: True or False
 P*--------------------------------------------------
 P IsValidData     B
 D IsValidData     PI              N

 D isValid         S               N

  /free

   if (dLoanAmt <> 0) and (dIntRate <> 0) and (dLoanPrd <> 0) and
      (dPayYear <> 0) and (dStartDate <> %date('0001-01-01'));
     isValid = *on;
   else;
     isValid = *off;
   endif;

   return isValid;

  /end-free
 P IsValidData     E


 P*--------------------------------------------------
 P* Procedure name: LoanPayment
 P* Purpose: Calculates the payment
 P* Returns:
 P*--------------------------------------------------
 P LoanPayment     B
 D LoanPayment     PI            12P 2
 D  principal                    12P 2
 D  interest                      5P 3
 D  loanPeriod                    3P 0
 D  paymentsYear                  3P 0

 D retMonthlyPayment...
 D                 S             12P 2

  /free

   eval(h) n = loanPeriod * paymentsYear;
   eval(h) j = interest / (paymentsYear * 100);

   eval(h) m = principal * (j / (1 - (1 + j) ** -n));

   return m;

  /end-free
 P LoanPayment     E
H ActGrp(*调用者)BndDir('MODULES')DftActGrp(*否)
//*********************************************************************
//节目…阿莫特
//*********************************************************************
//打印机/显示文件
著名的CFE工作文件(SFL01:rrn01)
//*********************************************************************
//命名常数
/复制模块/qcopysrc,状态复制
//命名指标
D指示器S*Inz(%Addr(*IN))
D基于DS(指示灯)
/复制模块/qcopysrc,scrncopy
//子文件字段
D rrn01 S 4P 0英寸(0)
//*********************************************************************
//杂项字段
D*每月付款
D m S 12P 2
D*负责人
D p S 12P 2
D*利息
D i S 5P 3
D*长度(以年为单位)
D l S 3P 0
D*月利息
D j S 10P10
D*个月
D n S 5P 0
D*当前每月整数。
D h S 12P 2
D*现任校长
D c S 12P 2
D*新余额
D q S 12P 2
//*********************************************************************
//外部程序程序
//内部子流程
D初始PR
D主要公共关系
D子文件
D清屏公关
伊斯瓦利达酒店
D贷款支付PR 12P 2
D校长12P 2
D利息5P 3
D贷款期限3P 0
D付款期3P 0
//外部子过程
///复制模块/qsrvsrc,p.string
//*********************************************************************
//入口Parms
D阿莫特公司(“阿莫特”)
阿莫特皮酒店
//*********************************************************************
/免费的
Init();
Main();
*inlr=*on;
/结束自由
P*--------------------------------------------------
P*过程名称:Init
P*目的:
P*返回:
P*--------------------------------------------------
P初始B
D初始π
/免费的
pgm=‘阿莫特’;
sflDsp=*关闭;
返回;
/结束自由
P Init E
P*--------------------------------------------------
P*程序名称:Main
P*目的:
P*返回:
P*--------------------------------------------------
主干道
D主PI
/免费的
道指(非F3)和(非F12);
写入OVR01;
exfmt CTL01;
清除屏幕();
if(IsValidData())和(非F3)和(非F12);
//填写标题信息
D支付=贷款支付(dLoanAmt:dIntRate:dLoanPrd:dPayYear);
dNumPaymnt=dLoanPrd*dPayYear;
m=付款+右旋付款;
p=dLoanAmt;
q=p;
//填表
if(SubfileFilled());
sflDsp=*开启;
endif;
endif;
enddo;
返回;
/结束自由
主菜
P*--------------------------------------------------
P*过程名称:子文件已填充
P*用途:填写子文件
P*返回:
P*--------------------------------------------------
P子文件B
D子文件
D是S
D x S 4P 0
D国际课程S 12P 2
D额外费用S 12P 2
D付款日期S D
D付款S 12P 2
D额外付款S 12P 2
/免费的
isFilled=*打开;
sflClear=*打开;
写CTL01;
sflClear=*关闭;
rrn01=0;
x=0;
//设置工作字段
付款=付款;
额外支付=快速支付;
付款日期=数据开始日期;
//创建记录,直到余额为零
道琼斯指数(q>0);
x+=1;
eval(h)h=p*j;//月利息
//调整fi
var annuity =  P * (i + i / (Math.pow(1+i,n) -1));

//P: principal, I: periodic interest rate, N: number of periods
            numerator = i * principle * (Math.Pow(1 + i, n));
            denominator = (Math.Pow(1 + i, n) - 1);

            /* Calculation of Amortization Payment Amount  */
            payment = numerator / denominator;