代码之家  ›  专栏  ›  技术社区  ›  Mike Wills

生成摊销计划

  •  3
  • Mike Wills  · 技术社区  · 16 年前

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

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

    6 回复  |  直到 8 年前
        1
  •  6
  •   Benry    12 年前

    最近我第一次买房子的时候,我写了一个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.
    }
    

    之后很容易做一个摊销表。(正如其他人提到的,请注意舍入错误,我在实现中没有充分处理这个问题。)

        2
  •  4
  •   Brian    16 年前

    有很多网站提供这些公式。一个在下面: http://www.math4finance.com/financial-formulas.php

    不需要复杂的算法,因为公式通常很简单。

        3
  •  0
  •   Walter Mitty    16 年前

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

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

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

        4
  •  0
  •   Code Whisperer    9 年前
    var annuity =  P * (i + i / (Math.pow(1+i,n) -1));
    
    //P: principal, I: periodic interest rate, N: number of periods
    
        5
  •  0
  •   Rickferd    8 年前

    C中的摊销计划公式#

                numerator = i * principle * (Math.Pow(1 + i, n));
                denominator = (Math.Pow(1 + i, n) - 1);
    
                /* Calculation of Amortization Payment Amount  */
                payment = numerator / denominator;
    
        6
  •  -1
  •   community wiki Mike Wills    16 年前

    这就是我最终创造的。我已经发布了整个测试程序。它是用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
    

    此代码已通过我们的贷款计算器进行了测试。如果测试与Excel相比,20万美元的贷款减少了约32美分。我相信这对解决问题是有帮助的。