GnuCash  5.6-150-g038405b370+
fin.c
1 /***************************************************************************
2  fin.c - description
3  -------------------
4  begin : Thursday June 15 2000
5  email : tboldt@attglobal.net
6  Author : Terry D. Boldt
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
18 /*
19  * Functions to compute financial equations and amortization schedules
20  * 6-15-2000
21  *
22  */
23 
24 /*
25  * Financial Calculator
26  *
27  * This version for use WITH ANSI.SYS display driver
28  *
29  * This is a complete financial computation utility to solve for the
30  * five * standard financial values: n, %i, PV, PMT and FV
31  *
32  * n == number of payment periods
33  * %i == nominal interest rate, NAR, charged
34  * PV == Present Value
35  * PMT == Periodic Payment
36  * FV == Future Value
37  *
38  * In addition, two additional parameters may be specified:
39  *
40  * 1) Compounding Frequency per year, CF. The compounding frequency
41  * per year may be discrete or continuous and may be different from
42  * the Payment Frequency per year
43  *
44  * 2) Payment Frequency per year, PF. Payments may be made at the
45  * beginning or the end of the payment period.
46  *
47  * When an amortization schedule is desired, the financial
48  * transaction Effective Date, ED, and Initial Payment Date, IP, must
49  * also be entered.
50  *
51  * Canadian and European style mortgages can be handled in a simple,
52  * straight-forward manner. Standard financial sign conventions are
53  * used:
54  *
55  * "Money paid out is Negative, Money received is Positive"
56  *
57  * Time value of money:
58  *
59  * If you borrow money, you can expect to pay rent or interest for its use;
60  * conversely you expect to receive rent interest on money you loan or invest.
61  * When you rent property, equipment, etc., rental payments are normal; this
62  * is also true when renting or borrowing money. Therefore, money is
63  * considered to have a "time value". Money available now, has a greater value
64  * than money available at some future date because of its rental value or the
65  * interest that it can produce during the intervening period.
66  *
67  * Simple Interest:
68  *
69  * If you loaned $800 to a friend with an agreement that at the end of one
70  * year he would would repay you $896, the "time value" you placed on your
71  * $800 (principal) was $96 (interest) for the one year period (term) of the
72  * loan. This relationship of principal, interest, and time (term) is most
73  * frequently expressed as an Annual Percentage Rate (APR). In this case the
74  * APR was 12.0% [(96/800)*100]. This example illustrates the four basic
75  * factors involved in a simple interest case. The time period (one year),
76  * rate (12.0% APR), present value of the principal ($800) and the future
77  * value of the principal including interest ($896).
78  *
79  * Compound Interest:
80  *
81  * In many cases the interest charge is computed periodically during the term
82  * of the agreement. For example, money left in a savings account earns
83  * interest that is periodically added to the principal and in turn earns
84  * additional interest during succeeding periods. The accumulation of interest
85  * during the investment period represents compound interest. If the loan
86  * agreement you made with your friend had specified a "compound interest
87  * rate" of 12% (compounded monthly) the $800 principal would have earned
88  * $101.46 interest for the one year period. The value of the original $800
89  * would be increased by 1% the first month to $808 which in turn would be
90  * increased by 1% to 816.08 the second month, reaching a future value of
91  * $901.46 after the twelfth iteration. The monthly compounding of the nominal
92  * annual rate (NAR) of 12% produces an effective Annual Percentage Rate (APR)
93  * of 12.683% [(101.46/800)*100]. Interest may be compounded at any regular
94  * interval; annually, semiannually, monthly, weekly, daily, even continuously
95  * (a specification in some financial models).
96  *
97  * Periodic Payments:
98  *
99  * When money is loaned for longer periods of time, it is customary for the
100  * agreement to require the borrower to make periodic payments to the lender
101  * during the term of the loan. The payments may be only large enough to repay
102  * the interest, with the principal due at the end of the loan period (an
103  * interest only loan), or large enough to fully repay both the interest and
104  * principal during the term of the loan (a fully amoritized loan). Many loans
105  * fall somewhere between, with payments that do not fully cover repayment of
106  * both the principal and interest. These loans require a larger final payment
107  * (balloon) to complete their amortization. Payments may occur at the
108  * beginning or end of a payment period. If you and your friend had agreed on
109  * monthly repayment of the $800 loan at 12% NAR compounded monthly, twelve
110  * payments of $71.08 for a total of $852.96 would be required to amortize the
111  * loan. The $101.46 interest from the annual plan is more than the $52.96
112  * under the monthly plan because under the monthly plan your friend would not
113  * have had the use of $800 for a full year.
114  *
115  * Financial Transactions:
116  *
117  * The above paragraphs introduce the basic factors that govern most
118  * financial transactions; the time period, interest rate, present value,
119  * payments and the future value. In addition, certain conventions must be
120  * adhered to: the interest rate must be relative to the compounding frequency
121  * and payment periods, and the term must be expressed as the total number of
122  * payments (or compounding periods if there are no payments). Loans, leases,
123  * mortgages, annuities, savings plans, appreciation, and compound growth are
124  * among the many financial problems that can be defined in these terms. Some
125  * transactions do not involve payments, but all of the other factors play a
126  * part in "time value of money" transactions. When any one of the five (four
127  * - if no payments are involved) factors is unknown, it can be derived from
128  * formulas using the known factors.
129  *
130  * Standard Financial Conventions Are:
131  *
132  * Money RECEIVED is a POSITIVE value and is represented by an arrow
133  * above * the line
134  *
135  * Money PAID OUT is a NEGATIVE value and is represented by an arrow
136  * below * the line.
137  *
138  * If payments are a part of the transaction, the number of payments
139  * must * equal the number of periods (n).
140  *
141  * Payments may be represented as occurring at the end or beginning of
142  * the * periods.
143  *
144  * Diagram to visualize the positive and negative cash flows (cash
145  * flow * diagrams):
146  *
147  * Amounts shown above the line are positive, received, and amounts
148  * shown below the line are negative, paid out.
149  *
150  * 1)
151  * FV*
152  * 1 2 3 4 . . . . . . . . . n ³
153  * Period ÚÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÙ * ³ * * PV * * Appreciation * Depreciation * Compound Growth * Savings Account * * **************************************************************************** * * 2) FV * PV = 0 * ³ * Period ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÙ * ³ 1 ³ 2 ³ 3 ³ 4 ³ . ³ . ³ . ³ . ³ . ³ . ³ . ³ . ³ . ³ n * * PMT PMT PMT PMT PMT PMT PMT PMT PMT PMT PMT PMT PMT PMT * * Annuity (series of payments) * Pension Fund * Savings Plan * Sinking Fund * * **************************************************************************** * * 3) * PV * ³ FV=0 * Period ÀÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ * 1 ³ 2 ³ 3 ³ 4 ³ . ³ . ³ . ³ . ³ . ³ . ³ . ³ . ³ . ³ n ³ * * PMT PMT PMT PMT PMT PMT PMT PMT PMT PMT PMT PMT PMT PMT * * Amortization * Direct Reduction Loan * Mortgage (fully amortized) * * **************************************************************************** * * 4) * FV* * PMT PMT PMT PMT PMT PMT PMT PMT PMT PMT PMT PMT PMT ³ + * PMT * 1 ³ 2 ³ 3 ³ 4 ³ . ³ . ³ . ³ . ³ . ³ . ³ . ³ . ³ . ³ n ³ * Period ÚÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÙ * ³ * * PV * * Annuity * Lease (with buy back or residual)* * Loan or Mortgage (with balloon)* * * **************************************************************************** * * First lets discuss interest before discussing the financial * equation. Most financial transactions utilize a nominal interest * rate, NAR, i.e., the interest rate per year. The NAR must be * converted to the interest rate per payment interval and the * compounding accounted for before it can be used in computing an * interest payment. After this conversion process, the interest * used is the effective interest rate, EIR. In converting NAR to * EIR, there are two concepts to discuss first, the Compounding * Frequency and the Payment Frequency and * whether the interest is * coumpounded in discrete intervals or continuously. The * compounding Frequency, CF, is simply the number of times per * year, the monies in the financial transaction are compounded. In * the U.S., monies are usually compounded daily on bank deposits, * and monthly on loans. Sometimes Long term deposits are compounded * quarterly or weekly. * * The Payment Frequency, PF, is simply how often during a year * payments are made in the transaction. Payments are usually * scheduled on a regular basis and can be made at the beginning or * end of the payment period. If made at the beginning of the * payment period, interest must be applied to the payment as well * as any previous money paid or money still owed. * * Normal values for CF and PF are: * 1 == annual * 2 == semi-annual * 3 == tri-annual * 4 == quaterly * 6 == bi-monthly * 12 == monthly * 24 == semi-monthly * 26 == bi-weekly * 52 == weekly * 360 == daily * 365 == daily * * a) the Compounding Frequency per year, CF, need not be identical * to the Payment Frequency per year, PF, and/or, * * b) Interest may be compounded in either discrete intervals or continuously * compounded. * * c) Also, payments may be made at the beginning of the payment * period or at the end of the payment period. * * CF and PF are defaulted to 1. The default is for discrete interest * intervals and payments are defaulted to the end of the payment * period. * * When a solution for n, PV, PMT or FV is required, the nominal interest * rate, i, must first be converted to the effective interest rate per payment * period. This rate, ieff, is then used to compute the selected variable. To * convert i to ieff, the following expressions are used: * * Discrete interest periods: * * 19) ieff = (1 + i/CF)^(CF/PF) - 1 * * Continuous Interest * * 20) ieff = e^(i/PF) - 1 = exp(i/PF) - 1 * * When interest is computed, the computation produces the effective interest * rate, ieff. This value must then be converted to the nominal interest rate. * Function _I below returns the nominal interest rate NOT the effective * interest rate. ieff is converted to i using the following expressions: * * Discrete Case: * * i = CF*[(1+ieff)^(PF/CF) - 1] * * Continuous Case: * * i = ln[(1+ieff)^PF] * * **************************************************************************** * * NOTE: in the equations below for the financial transaction, all * interest rates are the effective interest rate, ieff. The symbol * will be shortned to just 'i'. * * **************************************************************************** * * The basic financial equation used is: * * 1) PV*(1 + i)^n + PMT*(1 + iX)*[(1+i)^n - 1]/i + FV = 0 * Where: X = 0 for end of period payments, and * X = 1 for beginning of period payments * * **************************************************************************** * * NOTE: this equation is derived in the following manner: * * Start with the basic equation to find the balance or Present * Value, PV[1], after one payment period. Note PV[1] is the Present * value after on payment and PV[0] is the initial Present * Value. PV[0] will be shortened to just PV. * * The interest due at the end of the first payment period is: * * ID[1] = (PV + X * PMT) * i * where: X = 0 for end of period payments, and * X = 1 for beginning of period payments. * * Thus: * PV[1] = PV + (PMT + ID[1]) * = PV + (PMT + (PV + X * PMT) * i) * = PV * (1 + i) + PMT * (1 + Xi) * * This equation works for all of the money diagrams shown * above. The Present Value, money received or paid, is modified by * a payment made at the beginning of a payment period and * multiplied by the effective interest rate to compute the interest * due during the payment period. The interest due is then added to * the payment to obtain the amount to be added to the Present Value * to compute the new Present Value. * * For diagram 1): PV < 0, PMT == 0, PV[1] < 0 * For diagram 2): PV == 0, PMT < 0, PV[1] < 0 * For Diagram 3): PV > 0, PMT < 0, PV[1] >= 0 or PV[1] <= 0 * For Diagram 4): PV < 0, PMT > 0, PV[1] <= 0 or PV[1] >= 0 * * X may be 0 or 1 for any diagram. * * For the standard loan, PV is the money borrowed, PMT is the * periodic payment to repay the loan and i is the effective * interest rate agreed upon. * * To calculate the Present Value after the second payment period, * the above calculation is applied iteratively to PV_1: * * PV[2] = PV[1] + (PMT + (PV[1] + X * PMT) * i) * = PV[1] * (1 + i) + PMT * (1 + iX) * = (PV * (1 + i) + PMT * (1 + iX)) * (1 + i) + PMT * (1 + iX) * = PV * (1 + i)^2 + PMT * (1 + iX) * (1 + i) * + PMT * (1 + iX) * * Similarly: * * PV[3] = PV[2] + (PMT + (PV[2] + X * PMT) * i) * = PV[2] * (1 + i) + PMT * (1 + iX) * = PV * (1 + i)^2 + PMT * (1 + iX) * (1 + i) * + PMT * (1+ iX)) * ( 1 + i) * + PMT * (1+ iX) * = PV * (1 + i)^3 + PMT * (1 + iX) * (1 + i)^2 * + PMT * (1 + iX) * (1 + i)^2 * + PMT * (1 + iX) * (1 + i) * + PMT * (1 + iX) * * And for the n'th payment: * * PV[n] = PV[n-1] + (PMT + (PV[n-1] + X * PMT) * i) * PV[n] = PV * (1 + i)^n + PMT * (1 + iX) * (1 + i)^(n-1) * + PMT * (1 + iX) * (1 + i)^(n-2) + * . * . * . * + PMT * (1 + iX) * (1 + i) * + PMT * (1 + iX) * PV[n] = PV * (1 + i)^n + PMT * (1 + iX) * [(1 + i)^(n-1) + ... * + (1 + i) + 1] * * **************************************************************************** * * The sum of the finite series: * * 1 + k + (k^2) + (k^3) + ... + (k^n) = (1-k^(n+1))/(1-k) * * as can be seen by the following. Let S(n) be the series sum. Then * * S(n) - k * S(n) = 1 - k^(n+1) * * and solving for S(n): * * S(n) = [1-k^(n+1)]/[1-k] = 1 + k + (k^2) + (k^3) + ... + (k^n) * * **************************************************************************** * * PV[n] = PV * (1 + i)^n + PMT * (1 + iX) * [(1 + i)^(n-1) + ... * + (1 + i) + 1] * = PV * (1 + i)^n + PMT * (1 + iX) * [1 - (1 + i)^n]/[1 - (1 + i)] * = PV * (1 + i)^n + PMT * (1 + iX) * [1 - (1 + i)^n]/[-i] * = PV * (1 + i)^n + PMT * (1 + iX) * [(1 + i)^n - 1]/i * * The formaula for PV[n] can be proven using mathematical induction. * * or: * * PV * (1 + i)^n + PMT * [(1 + i)^n - 1]/i - PV[n] = 0 * * If after n payments, the remaining balance is repaid as a lump * sum, the lump sum is known as the Future Value, FV[n]. Since * FV[n] is negative if paid and positive if received, FV[n] is the * negative of PV[n]. Since n is assumed to be the last payment, * FV[n] will be shortened to simply FV. * * Setting: FV = -PV[N] * * 1) PV*(1 + i)^n + PMT*(1 + iX)*[(1 + i)^n - 1]/i + FV = 0 * * Up to this point, we have said nothing about the value of * PMT. PMT can be any value mutually agreed upon by the lender and * the borrower. From the equation for PV[1]: * * PV[1] = PV + (PMT + (PV + X * PMT) * i), * * Several things can be said about PMT. * * 1. If PMT = PV * i, and X = 0 (end of period payments): * * The payment is exactly equal to the interest due and PV[1] = * PV. In this case, the borrower must make larger future * payments to reduce the balance due, or make a single payment, * after some agreed upon number of payments, with PMT = PV to * completely pay off the loan. This is an interest only payment * with a balloon payment at the end. * * 2. If PMT < PV * i, and X = 0 * * The payment is insufficient to cover even the interest charged * and the balance due grows * * 3. If PMT > PV * i, and X = 0 * * The payment is sufficient to cover the interest charged with a * residual amount to be applied to reduce the balance due. The * larger the residual amount, the faster the loan is repaid. For * most mortgages or other loans made today, the lender and * borrower agree upon a certain number of repayment periods and * the interest to be charged per payment period. The interest * may be multiplied by 12 and stated as an annual interest * rate. Then the lender and borrower want to compute a periodic * payment, PMT, which will reduce the balance due to zero after * the agreed upon number of payment have been made. If N is the * agreed upon number of periodic payments, then we want to use: * * PV * (1 + i)^N + PMT*(1 +iX)*[(1 + i)^N - 1]/i + FV = 0 * * with FV = 0 to compute PMT: * * PMT = -[PV * i * (1 + i)^(N - X)]/[(1 + i)^N - 1] * * The value of PMT computed will reduce the balance due to zero * after N periodic payments. * * **************************************************************************** * * * With a simple alegebraic re-arrangement, The financial Equation becomes: * * 2) [PV + PMT*(1 + iX)/i][(1 + i)^n - 1] + PV + FV = 0 * * or * * 3) (PV + C)*A + PV + FV = 0 * * where: * 4) A = (1 + i)^n - 1 * * 5) B = (1 + iX)/i * * 6) C = PMT*B * * The form of equation 3) simplifies the calculation procedure for all five * variables, which are readily solved as follows: * * 7) n = ln[(C - FV)/(C + PV)]/ln((1 + i) * * 8) PV = -[FV + A*C]/(A + 1) * * 9) PMT = -[FV + PV*(A + 1)]/[A*B] * * 10) FV = -[PV + A*(PV + C)] * * Equations 4), 5) and 6) are computed by functions: * * _A * _B * _C * * respectively. Equations 7), 8), 9) and 10) are computed by functions: * * _N * _PV * _PMT * _FV * * respectively. * * The solution for interest is broken into two cases: * * PMT == 0 * i = [FV/PV]^(1/n) - 1 * * PMT != 0 * * Since equation 3) cannot be solved explicitly for i in this * case, an iterative technique must be employed. Newton's * method, using exact expressions for the function of i and its * derivative, are employed. The expressions are: * * 12) i[k+1] = i[k] - f(i[k])/f'(i[k]) * where: i[k+1] == (k+1)st iteration of i * i[k] == kth iteration of i * and: * * 13) f(i) = A*(PV+C) + PV + FV * * 14) f'(i) = n*D*(PV+C) - (A*C)/i * * 15) D = (1 + i)^(n-1) = (A+1)/(1+i) * * To start the iterative solution for i, an initial guess must be made * for the value of i. The closer this guess is to the actual value, * the fewer iterations will have to be made, and the greater the * probability that the required solution will be obtained. The initial * guess for i is obtained as follows: * * if PMT*FV >= 0, then PV case * if PMT*FV < 0, then FV case * * PV case: * | n*PMT + PV + FV | * 16) i[0] = | ----------------| * | n*PV | * * = abs[(n*PMT + PV + FV)/(n*PV)] * * FV case: * a) PV != 0 * * | FV - n*PMT | * 17) i[0] = |---------------------------| * | 3*[PMT*(n-1)^2 + PV - FV] | * * = abs[(FV-n*PMT)/(3*(PMT*(n-1)^2+PV-FV))] * b) PV == 0 * * | FV + n*PMT | * 18) i[0] = |---------------------------| * | 3*[PMT*(n-1)^2 + PV - FV] | * * = abs[(FV+n*PMT)/(3*(PMT*(n-1)^2+PV-FV))] * * **************************************************************************** * Constant payment to principal loan * * In this loan, each total payment is different, with each * succeeding payment less than the preceding payment. Each payment * is the total of the constant amount to the principal plus the * interest for the period. The constant payment to the principal is * computed as: * * C = -PV / N * * Where PV is the loan amount to be repaid in N payments * (periods). Note that the constant payment to principal could be * any value agreed to by the two parties involved. * * Thus the principal after the first payment is: * PV[1] = PV[0] + C = PV + C * after the second payment, the principal is: * PV[2] = PV[1] + C = PV[0] + 2C * In general, the remaining principal after n payments is: * PV[n] = PV[0] + nC = PV + nC * * If the effective interest per payment period is i, then the * interest for the first payment is: * * I[1] = -i*PV[0] = -i*PV * and for the second: * I[2] = -i * PV[1] * and in general, for the n'th payment the interest is: * I[n] = -i * PV[n-1] * = -i * (PV + (n-1)C) * The total payment for any period, n, is: * P[n] = C + I[n] * = C + i * (PV + (n-1)C) * = C(1 + i) - i * (PV + nC) * The total interest paid to period n is: * T[n] = I[1] + I[2] + I[3] + ... + I[n] * T[n] = sum(j = 1 to n: I[j]) * T[n] = sum(j = 1 to n: -i * (PV + (j-1)C)) * T[n] = sum(j=1 to n: -i*PV) + sum(j=1 to n: iC) + sum(j=1 to n: -iCj) * T[n] = -i*n*PV + i*n*C - i*C*sum(j=1 to n:j) * sum(j=1 to n:j) = n(n+1)/2 * T[n] = -i*n*(PV + C) - i*C*n(n+1)/2 * T[n] = -i*n*(PV + (C*(n - 1)/2)) * * Note: substituting for C = -PV/N, in the equations for PV[n], I[n], * P[n], and T[n] would give the following equations: * * PV[n] = PV*(1 - n/N) * I[n] = -i*PV*(1 + N - n)/N * P[n] = -i*PV*(2 + N - n)/N * T[n] = -i*n*PV*(2*N - n + 1)/(2*N) * * Using these equations for the calculations would eliminate the * dependence on C, but only if C is always defined as above and * would eliminate the possibility of another value for C. If the * value of C was less than -PV/N then a balloon payment would be * due at the final payment and this is a possible alternative for * some people. * * **************************************************************************** * * Amortization Schedules. * * Financial Transactions have an effective Date, ED, and an Initial Payment * Date, IP. ED may or may not be the same as IP, but IP is always the same * or later than ED. Most financial transaction calculators assume that * IP is equal to ED for beginning of period payments or at the end of the * first payment period for end of period payments. * * This is not always true. IP may be delayed for financial reasons * such as cash flow or accounting calendar. The subsequent payments * then follow the agreed upon periodicity. Since money has a time * value, the "delayed" IP must be accounted for. Computing an * "Effective PV", pve, is one means of handling a delayed IP. * * EDj == the Julian Day Number of ED, and * IPj == the Julian Day Number of IP in the following. * * pve is be computed as: * * pve = pv*(1 + i)^(s*PF/d*CF) * * Where: d = length of the payment period in days, and * s = IPj - EDj - d*X * * Computing an amortization Schedule for a given financial transaction is * simply applying the basic equation iteratively for each payment period: * * PV[n] = PV[n-1] + (PMT + (PV[n-1] + X * PMT) * i) * * At the end of each iteration, PV[n] is rounded to the nearest cent. For * each payment period, the interest due may be computed separately as: * * ID[n] = (PMT + (PV[n-1] + X * PMT) * i) * * and rounded to the nearest cent. PV[n] then becomes: * * PV[n] = PV[n-1] + PMT + ID[n] * * For those cases where a yearly summary only is desired, it is not * necessary to compute each transaction for each payment period, * rather the PV may be computed for the beginning of each year, * PV[yr], and the FV computed for the end of the year, FV[yr]. The * interest paid during the year is the computed as: * * ID[yr] = (NP * PMT) + PV[yr] + FV[yr] * * Since the final payment may not be equal to the periodic payment, * the final payment must be computed separately as follows. Two * derivations are given below for the final payment equation. Both * derivations are given below since one or the other may be clearer * to some readers. Both derivations are essentially the same, they * just have different starting points. The first is the fastest. * * 1) final_pmt == final payment @ payment n == int(n) * from above the basic financial equation: * PV[n] = PV[n-1]*(1 + i) + final_pmt * (1 + iX), * i == effective interest rate * * solving for final_pmt, we have: * * final_pmt * (1 + iX) = PV[n] - PV[n-1]*(1 + i) * = FV[n-1]*(1 + i) - FV[n] * final_pmt = FV[n-1]*(1+i)/(1 + iX) - FV[n]/(1 + iX) * * final_pmt = FV[n-1]*(1 + i) - FV[n], * for X == 0, end of period payments * * = FV[n-1] - FV[n]/(1 + i), * for X == 1, beginning of period payments * * 2) final_pmt == final payment @ payment n == int(n) * i[n] == interest due @ payment n * i[n] = (PV[n-1] + X * final_pmt) * i, i == effective interest rate * = (X * final_pmt - FV[n]) * i * * Now the final payment is the sum of the interest due, plus * the present value at the next to last payment plus any * residual future value after the last payment: * * final_pmt = -i[n] - PV[n-1] - FV[n] * = FV[n-1] - i[n] - FV[n] * = FV[n-1] - (X *final_pmt - FV[n-1])*i - FV[n] * = FV[n-1]*(1 + i) - X*final_pmt*i - FV[n] * * solving for final_pmt: * final_pmt*(1 + iX) = FV[n-1]*(1 + i) - FV[n] * final_pmt = FV[n-1]*(1 + i)/(1 + iX) - FV[n]/(1 + iX) * * final_pmt = FV[n-1]*(1 + i) - FV[n], * for X == 0, end of period payments * * = FV[n-1] - FV[n]/(1 + i), * for X == 1, beginning of period payments * *============================================================================ * * The amortization schedule is computed for four different situations: * * 1) The original financial data is used. This ignores any possible * agjustment to the Present value due to any delay in the initial * payment. This is quite common in mortgages where end of period * payments are used and the first payment is scheduled for the end * of the first whole period, i.e., any partial payment period from * ED to the beginning of the next payment period is ignored. * * 2) The original periodic payment is used, the Present Value is * adjusted for the delayed Initial Payment. The total number of * payments remains the same. The final payment is adjusted to bring * the balance into agreement with the agreed upon final Future * Value. * * 3) A new periodic payment is computed based upon the adjusted * Present Value, the agreed originally upon number of total * payments and the agreed upon Future Value. The new periodic * payments are computed to minimize the final payment in accordance * with the Future Value after the last payment. * * 4) The original periodic payment is retained and a new number of * total payments is computed based upon the adjusted Present Value * and the agreed upon Future Value. * * The amortization schedule may be computed and displayed in three manners: * * 1. The payment *, interest paid, principal paid and remaining PV * for each payment period are computed and displayed. At the end of * each year a summary is computed and displayed and the total * interest paid is displayed at the end. * * 2. A summary is computed and displayed for each year. The * interest paid during the year is computed and displayed as well * as the remaining balance at years end. The total interest paid * is displayed at the end. * * 3. An amortization schedule is computed for a common method of * advanced payment of principal is computed and displayed. In this * amortization, the principal for the next payment is computed and * added into the current payment. This method will cut the number * of total payments in half and will cut the interest paid almost * in half. For mortgages, this method of prepayment has the * advantage of keeping the total payments small during the initial * payment periods The payments grow until the last payment period * when presumably the borrower can afford larger payments. * * =========================================================================== * NOTE: For Payment Frequencies, PF, semi-monthly or less, i.e., PF * == 12 or PF == 24, a 360 day calendar year and 30 day month are * used. For Payment Frequencies, PF, greater than semi-monthly, PF * > 24, the actual number of days per year and per payment period * are used. The actual values are computed using the built-in * 'julian_day_number' function * * **************************************************************************** * * Note: in the following examples, the user input is preceded by the * prompt "<>". The result of evaluating the input expression is then * displayed. I have taken the liberty of including comments in the * example input/output sessions by preceding with ' *'. Thus, for * the line: <>n=5 *set number of periods the comment that setting the * number of periods is not really input and the true input is only: * <>n=5 * * Example 1: Simple Interest * Find annual simple interest rate (%) for an $800 loan to be repayed at the * end of one year with a single payment of $896. * <>d * <>CF=PF=1 * 1.00 * <>n=1 * 1.00 * <>pv=-800 * -800.00 * <>fv=896 * 896.00 * <>I * 12.00 * * Example 2: Compound Interest * Find the future value of $800 after one year at a nominal rate of 12% * compounded monthly. No payments are specified, so the payment frequency is * set equal to the compounding frequency at the default values. * <>d * <>n=12 * 12.00 * <>i=12 * 12.00 * <>pv=-800 * -800.00 * <>FV * 901.46 * * Example 3: Periodic Payment: * Find the monthly end-of-period payment required to fully amortize the loan * in Example 2. A fully amortized loan has a future value of zero. * <>fv=0 * 0.00 * <>PMT * 71.08 * * Example 4: Conventional Mortgage * * Find the number of monthly payments necessary to fully amortize a * loan of $100,000 at a nominal rate of 13.25% compounded monthly, if * monthly end-of-period payments of $1125.75 are made. * * <>d * <>i=13.25 * 13.25 * <>pv=100000 * 100,000.00 * <>pmt=-1125.75 * -1,125.75 * <>_N(i,pv,pmt,fv,CF,PF,disc,bep) * 360.10 * <>N * 360 * * Example 5: Final Payment * Using the data in example 4, find the amount of the final payment if n is * changed to 360. The final payment will be equal to the regular payment plus * any balance, future value, remaining at the end of period number 360. * <>n=360 * 360.00 * <>FV * -108.87 * <>pmt+fv * -1,234.62 * * Using the data from this loan, compute the amortization schedule * when the Effective date of the loan is June 6, 1996 and the * initial payment is made on August 1, 1996. Ignore any change in * the PV due to the delayed initial payment caused by the partial * payment period from June 6 to July 1. * * <>ED = 06/06/1996 * Effective Date set: 06/06/1996 ( 2450241 ) * <>IP = 08/01/1996 * Initial Payment Date set: 08/01/1996 ( 2450297 ) * <>a * Effective Date: 06/06/96 * Initial Payment Date: 08/01/96 * The amortization options are: * The Old Present Value (pv) was: 100,000.00 * The Old Periodic Payment (pmt) was: -1,125.75 * The Old Future Value (fv) was: -108.87 * 1: Amortize with Original Transaction Values * and balloon final payment: -1,125.75 * * The New Present Value (pve) is: 100,919.30 * The New Periodic Payment (pmt) is: -1,136.10 * 2: Amortize with Original Periodic Payment * and balloon final payment: -49,023.68 * 3: Amortize with New Periodic Payment * and balloon final payment: -1,132.57 * 4: Amortize with Original Periodic Payment, * new number of total payments (n): 417 * and final payment: -2,090.27 * * Enter choice 1, 2, 3 or 4: <> * * Press '1' * Amortization Schedule: * Yearly, y, per Payment, p, or Advanced Payment, a, Amortization * Enter choice y, p or a: * <> * * Press 'y' * Enter Filename for Amortization Schedule. * (null string uses Standard Output): * Press enter to display output on screen * * Amortization Table * Effective Date: Thu Jun 06 00:00:00 1996 * Initial Payment Date: Thu Aug 01 00:00:00 1996 * Compounding Frequency per year: 12 * Payment Frequency per year: 12 * Compounding: Discrete * Payments: End of Period * Payments (359): -1,125.75 * Final payment: -1,125.75 * Nominal Annual Interest Rate: 13.25 * Effective Interest Rate Per Payment Period: 0.0110417 * Present Value: 100,000.00 * Year Interest Ending Balance * 1996 -5,518.42 -99,889.67 * 1997 -13,218.14 -99,598.81 * 1998 -13,177.17 -99,266.98 * 1999 -13,130.43 -98,888.41 * 2000 -13,077.11 -98,456.52 * 2001 -13,016.28 -97,963.80 * 2002 -12,946.88 -97,401.68 * 2003 -12,867.70 -96,760.38 * 2004 -12,777.38 -96,028.76 * 2005 -12,674.33 -95,194.09 * 2006 -12,556.76 -94,241.85 * 2007 -12,422.64 -93,155.49 * 2008 -12,269.63 -91,916.12 * 2009 -12,095.06 -90,502.18 * 2010 -11,895.91 -88,889.09 * 2011 -11,668.70 -87,048.79 * 2012 -11,409.50 -84,949.29 * 2013 -11,113.78 -82,554.07 * 2014 -10,776.41 -79,821.48 * 2015 -10,391.53 -76,704.01 * 2016 -9,952.43 -73,147.44 * 2017 -9,451.49 -69,089.93 * 2018 -8,879.99 -64,460.92 * 2019 -8,227.99 -59,179.91 * 2020 -7,484.16 -53,155.07 * 2021 -6,635.56 -46,281.63 * 2022 -5,667.43 -38,440.06 * 2023 -4,562.94 -29,494.00 * 2024 -3,302.89 -19,287.89 * 2025 -1,865.36 -7,644.25 * 2026 -236.00 -108.87 * * Total Interest: -305,270.00 * * NOTE: The amortization table leaves the FV as it was when the amortization * function was entered. Thus, a balance of 108.87 is due at the end of the * table. To completely pay the loan, set fv to 0.0: * <>fv=0 * 0.0 * <>a * Effective Date: 06/06/96 * Initial Payment Date: 08/01/96 * The amortization options are: * The Old Present Value (pv) was: 100,000.00 * The Old Periodic Payment (pmt) was: -1,125.75 * The Old Future Value (fv) was: 0.00 * 1: Amortize with Original Transaction Values * and balloon final payment: -1,234.62 * * The New Present Value (pve) is: 100,919.30 * The New Periodic Payment (pmt) is: -1,136.12 * 2: Amortize with Original Periodic Payment * and balloon final payment: -49,132.55 * 3: Amortize with New Periodic Payment * and balloon final payment: -1,148.90 * 4: Amortize with Original Periodic Payment, * new number of total payments (n): 417 * and final payment: -2,199.14 * * Enter choice 1, 2, 3 or 4: <> * Press '1' * Amortization Schedule: * Yearly, y, per Payment, p, or Advanced Payment, a, Amortization * Enter choice y, p or a: * <> * Press 'y' * Enter Filename for Amortization Schedule. * (null string uses Standard Output): * Press enter to display output on screen * * Amortization Table * Effective Date: Thu Jun 06 00:00:00 1996 * Initial Payment Date: Thu Aug 01 00:00:00 1996 * Compounding Frequency per year: 12 * Payment Frequency per year: 12 * Compounding: Discrete * Payments: End of Period * Payments (359): -1,125.75 * Final payment: -1,234.62 * Nominal Annual Interest Rate: 13.25 * Effective Interest Rate Per Payment Period: 0.0110417 * Present Value: 100,000.00 * Year Interest Ending Balance * 1996 -5,518.42 -99,889.67 * 1997 -13,218.14 -99,598.81 * 1998 -13,177.17 -99,266.98 * 1999 -13,130.43 -98,888.41 * 2000 -13,077.11 -98,456.52 * 2001 -13,016.28 -97,963.80 * 2002 -12,946.88 -97,401.68 * 2003 -12,867.70 -96,760.38 * 2004 -12,777.38 -96,028.76 * 2005 -12,674.33 -95,194.09 * 2006 -12,556.76 -94,241.85 * 2007 -12,422.64 -93,155.49 * 2008 -12,269.63 -91,916.12 * 2009 -12,095.06 -90,502.18 * 2010 -11,895.91 -88,889.09 * 2011 -11,668.70 -87,048.79 * 2012 -11,409.50 -84,949.29 * 2013 -11,113.78 -82,554.07 * 2014 -10,776.41 -79,821.48 * 2015 -10,391.53 -76,704.01 * 2016 -9,952.43 -73,147.44 * 2017 -9,451.49 -69,089.93 * 2018 -8,879.99 -64,460.92 * 2019 -8,227.99 -59,179.91 * 2020 -7,484.16 -53,155.07 * 2021 -6,635.56 -46,281.63 * 2022 -5,667.43 -38,440.06 * 2023 -4,562.94 -29,494.00 * 2024 -3,302.89 -19,287.89 * 2025 -1,865.36 -7,644.25 * 2026 -344.87 0.00 * * Total Interest: -305,378.87 * * Example 6: Balloon Payment * On long term loans, small changes in the periodic payments can generate * large changes in the future value. If the monthly payment in example 5 is * rounded down to $1125, how much additional (balloon) payment will be due * with the final regular payment. * <>pmt=-1125 * -1,125 * <>FV * -3,579.99 * * Example 7: Canadian Mortgage * Find the monthly end-of-period payment necessary to fully amortize a 25 year * $85,000 loan at 11% compounded semi-annually. * <>d * <>CF=2 * 2.00 * <>n=300 * 300.00 * <>i=11 * 11.00 * <>pv=85000 * 85,000.00 * <>PMT * -818.15 * * Example 8: European Mortgage * The "effective annual rate (EAR)" is used in some countries (especially * in Europe) in lieu of the nominal rate commonly used in the United States * and Canada. For a 30 year $90,000 mortgage at 14% (EAR), compute the monthly * end-of-period payments. When using an EAR, the compounding frequency is * set to 1. * <>d * <>CF=1 * 1.00 * <>n=30*12 * 360.00 * <>i=14 * 14.00 * <>pv=90000 * 90,000.00 * <>PMT * -1,007.88 * * Example 9: Bi-weekly Savings * Compute the future value, fv, of bi-weekly savings of $100 for 3 years at a * nominal annual rate of 5.5% compounded daily. (Set payment to * beginning-of-period, bep = TRUE) * <>d * <>bep=TRUE * 1.00 * <>CF=365 * 365.00 * <>PF=26 * 26.00 * <>n=3*26 * 78.00 * <>i=5.5 * 5.50 * <>pmt=-100 * -100.00 * <>FV * 8,489.32 * * Example 10: Present Value - Annuity Due * What is the present value of $500 to be received at the beginning of each * quarter over a 10 year period if money is being discounted at 10% nominal * annual rate compounded monthly? * <>d * <>bep=TRUE * 1.00 * <>PF=4 * 4.00 * <>n=4*10 * 40.00 * <>i=10 * 10.00 * <>pmt=500 * 500.00 * <>PV * -12,822.64 * * Example 11: Effective Rate - 365/360 Basis * Compute the effective annual rate (%APR) for a nominal annual rate of 12% * compounded on a 365/360 basis used by some Savings & Loan Associations. * <>d * <>n=365 * 365.00 * <>CF=365 * 365.00 * <>PF=360 * 360.00 * <>i=12 * 12.00 * <>pv=-100 * -100.00 * <>FV * 112.94 * <>fv+pv * 12.94 * * Example 12: Mortgage with "Points" * * What is the true APR of a 30 year, $75,000 loan at a nominal rate * of 13.25% compounded monthly, with monthly end-of-period payments, * if 3 "points" are charged? The pv must be reduced by the dollar * value of the points and/or any lenders fees to establish an * effective pv. Because payments remain the same, the true APR will * be higher than the nominal rate. Note, first compute the payments * on the pv of the loan amount. * * <>d * <>CF=PF=1 * 1.00 * <>n=30*12 * 360.00 * <>i=13.25/12 * 1.10 * <>pv=75000 * 75,000.00 * <>PMT * -844.33 * <>pv -= pv*.03 * 72,750.00 * <>CF=PF=12 * 12.00 * <>I * 13.69 * * Example 13: Equivalent Payments * Find the equivalent monthly payment required to amortize a 20 year $40,000 * loan at 10.5% nominal annual rate compounded monthly, with 10 annual * payments of $5029.71 remaining. Compute the pv of the remaining annual * payments, then change n, the number of periods, and the payment frequency, * PF, to a monthly basis and compute the equivalent monthly pmt. * <>d * <>PF=1 * 1.00 * <>n=10 * 10.00 * <>i=10.5 * 10.50 * <>pmt=-5029.71 * -5,029.71 * <>PV * 29,595.88 * <>PF=12 * 12.00 * <>n=120 * 120.00 * <>PMT * -399.35 * * Example 14: Perpetuity - Continuous Compounding * If you can purchase a single payment annuity with an initial investment of * $60,000 that will be invested at 15% nominal annual rate compounded * continuously, what is the maximum monthly return you can receive without * reducing the $60,000 principal? If the principal is not disturbed, the * payments can go on indefinitely (a perpetuity). Note that the term,n, of * a perpetuity is immaterial. It can be any non-zero value. * <>d * <>disc=FALSE * 0.00 * <>n=12 * 12.00 * <>CF=1 * 1.00 * <>i=15 * 15.00 * <>fv=60000 * 60,000.00 * <>pv=-60000 * -60,000.00 * <>PMT * 754.71 * * references: * 1. PPC ROM User's Manual * pages 148 - 164 * */ #include <time.h> #include <stdio.h> #include <glib.h> #include <math.h> #if defined(G_OS_WIN32) && !defined(_MSC_VER) #include <pow.h> #endif #include <string.h> #include <stdlib.h> #define FIN_STATICS #include "finvar.h" #include "finproto.h" #include "fin_static_proto.h" /* return 'x' rounded to 'places' past decimal if 'places' < 0, return * 'x' */ static double rnd (double x, unsigned places) { static const size_t buflen = 50; /* make buffer large enough */ double r; char buf[buflen]; snprintf (buf, buflen, "%.*f", (int) places, x); r = strtod(buf, NULL); return r; } /* rnd */ /* return absolute value of 'x' this function is provided by a macro * in C */ static double dabs (double x) { return (x >= 0.0) ? x : -x; } /* dabs */ /* Compute constant used in calculations */ static double _A (double eint, unsigned per) { return pow ((1.0 + eint), (double) per) - 1.0; } /* _A */ /* Compute constant used in calculations */ static double _B (double eint, unsigned beg) { /* if eint == 0.0, all processing _must_ stop or a recursive loop will start. */ g_return_val_if_fail(eint != 0.0, 0.0); return (1.0 + eint * (double) beg) / eint; } /* _B */ /* Compute constant used in calculations */ static double _C (double eint, double pmt, unsigned beg) { g_return_val_if_fail(eint != 0.0, 0.0); return pmt * _B(eint, beg); } /* _C */ /* compute Number of Periods from preset data */ unsigned fi_calc_num_payments (fi_ptr fi) { return fi->npp = (unsigned) rnd (_fi_calc_num_payments (fi->ir, fi->pv, fi->pmt, fi->fv, fi->CF, fi->PF, fi->disc, fi->bep), 0); } /* fi_calc_num_payments */ /* Compute number of periods from: * 1. Nominal Interest * 2. Present Value * 3. Periodic Payment * 4. Future Value */ double _fi_calc_num_payments (double nint, /* nominal interest rate */ double pv, /* present value */ double pmt, /* periodic payment */ double fv, /* future value */ unsigned CF, /* compounding frequency */ unsigned PF, /* payment frequency */ unsigned disc, /* discrete/continuous compounding */ unsigned bep) /* beginning/end of period payment */ { double eint = eff_int (nint / 100.0, CF, PF, disc); double CC = _C (eint, pmt, bep); CC = (CC - fv) / (CC + pv); return (CC > 0.0) ? log (CC) / log (1.0 + eint) : 0.0; } /* _fi_calc_num_payments */ /* compute Interest from preset data */ double fi_calc_interest (fi_ptr fi) { if (fi->npp) fi->ir = _fi_calc_interest (fi->npp, fi->pv, fi->pmt, fi->fv, fi->CF, fi->PF, fi->disc, fi->bep); return fi->ir; } /* fi_calc_interest */ double ratio = 1e4; /* ratio used in iterative solution for interest */ /* Compute Nominal Interest from: * 1. Number of periods * 2. Present Value * 3. Periodic Payment * 4. Future Value */ double _fi_calc_interest (unsigned per,/* number of periods */ double pv, /* present value */ double pmt, /* periodic payment */ double fv, /* future value */ unsigned CF, /* compounding frequency */ unsigned PF, /* payment frequency */ unsigned disc, /* discrete/continuous compounding */ unsigned bep) /* beginning/end of period payment */ { double eint; double a, dik; int ri; if (pmt == 0.0) eint = pow ((dabs (fv) / dabs (pv)), (1.0 / (double) per)) - 1.0; else { if ((pmt * fv) < 0.0) { if (pv) a = -1.0; else a = 1.0; eint = dabs ((fv + a * (double) per * pmt) / (3.0 * (((double) per - 1.0) * ((double) per - 1.0) * pmt + pv - fv))); } else { if ((pv * pmt) < 0.0) { eint = dabs (((double) per * pmt + pv + fv) / ((double) per * pv)); } else { a = dabs (pmt / (dabs (pv) + dabs (fv))); eint = a + 1.0 / (a * (double) per * (double) per * (double) per); } } do { dik = fi (per, eint, pv, pmt, fv, bep) / fip (per, eint, pv, pmt, fv, bep); eint -= dik; (void) modf (ratio * (dik / eint), &a); ri = (unsigned) a; } while (ri); } /* endif */ return 100.0 * nom_int (eint, CF, PF, disc); } /* _fi_calc_interest */ /* compute Present value from preset data */ double fi_calc_present_value (fi_ptr fi) { return fi->pv = rnd (_fi_calc_present_value (fi->npp, fi->ir, fi->pmt, fi->fv, fi->CF, fi->PF, fi->disc, fi->bep), fi->prec); } /* fi_calc_present_value */ /* Compute Present Value from: * 1. Number of periods * 2. Nominal Interest * 3. Periodic Payment * 4. Future Value */ double _fi_calc_present_value (unsigned per, /* number of periods */ double nint, /* nominal interest rate */ double pmt, /* periodic payment */ double fv, /* future value */ unsigned CF, /* compounding frequency */ unsigned PF, /* payment frequency */ unsigned disc, /* discrete/continuous compounding */ unsigned bep) /* beginning/end of period payment */ { double eint = eff_int (nint / 100.0, CF, PF, disc); double AA = _A (eint, per); double CC = _C (eint, pmt, bep); return -(fv + (AA * CC)) / (AA + 1.0); } /* _fi_calc_present_value */ /* compute Periodic Payment from preset data */ double fi_calc_payment (fi_ptr fi) { return fi->pmt = rnd (_fi_calc_payment (fi->npp, fi->ir, fi->pv, fi->fv, fi->CF, fi->PF, fi->disc, fi->bep), fi->prec); } /* fi_calc_payment */ /* Compute Periodic Payment from: * 1. Number of periods * 2. Nominal Interest * 3. Present Value * 4. Future Value */ double _fi_calc_payment (unsigned per, /* number of periods */ double nint, /* nominal interest rate */ double pv, /* present value */ double fv, /* future value */ unsigned CF, /* compounding frequency */ unsigned PF, /* payment frequency */ unsigned disc,/* discrete/continuous compounding */ unsigned bep) /* beginning/end of period payment */ { double eint = eff_int (nint / 100.0, CF, PF, disc); double AA = _A (eint, per); double BB = _B (eint, bep); g_return_val_if_fail(BB != 0.0, 0.0); return -(fv + pv * (AA + 1.0)) / (AA * BB); } /* _fi_calc_payment */ /* compute Future Value from preset data */ double fi_calc_future_value (fi_ptr fi) { return fi->fv = rnd (_fi_calc_future_value (fi->npp, fi->ir, fi->pv, fi->pmt, fi->CF, fi->PF, fi->disc, fi->bep), fi->prec); } /* fi_calc_future_value */ /* Compute Future Value from: * 1. Number of periods * 2. Nominal Interest * 3. Present Value * 4. Periodic Payments */ double _fi_calc_future_value (unsigned per, /* number of periods */ double nint, /* nominal interest rate */ double pv, /* present value */ double pmt, /* periodic payment */ unsigned CF, /* compounding frequency */ unsigned PF, /* payment frequency */ unsigned disc, /* discrete/continuous compounding */ unsigned bep) /* beginning/end of period payment */ { double eint = eff_int (nint / 100.0, CF, PF, disc); double AA = _A (eint, per); double CC = _C (eint, pmt, bep); return -(pv + AA * (pv + CC)); } /* _fi_calc_future_value */ /* compute Nominal Interest Rate from Effective Interest Rate */ static double nom_int (double eint, unsigned CF, unsigned PF, unsigned disc) { double nint; if (disc) { if (CF == PF) { nint = CF * eint; } else { nint = CF * (pow ((1.0 + eint), ((double) PF / (double) CF)) - 1.0); } /* * endif */ } else nint = log (pow (1.0 + eint, PF)); return nint; } /* nom_int */ /* Compute Effective Interest Rate from Nominal Interest Rate */ static double eff_int (double nint, unsigned CF, unsigned PF, unsigned disc) { double eint; if (disc) { if (CF == PF) { eint = nint / (double) CF; } else { eint = pow ((1.0 + nint / (double) CF), ((double) CF / (double) PF)) - 1.0; } /* endif */ } else eint = exp (nint / (double) PF) - 1.0; return eint; } /* eff_int */ /* calculation used in interest computation */ static double fi (unsigned per, double eint, double pv, double pmt, double fv, unsigned bep) { return _A (eint, per) * (pv + _C (eint, pmt, bep)) + pv + fv; } /* fi */ /* calculation used in interest computation */ static double fip (unsigned per, double eint, double pv, double pmt, double fv, unsigned bep) { double AA = _A (eint, per); double CC = _C (eint, pmt, bep); double D = (AA + 1.0) / (1.0 + eint); g_return_val_if_fail(CC != 0.0, 0.0); return (double) per * (pv + CC) * D - (AA * CC) / eint; } /* fip */ void set_default (fi_ptr fi) { /* flag whether accrueing interest at beginning or end of period * FALSE --> end * TRUE --> beginning * default to end of period payment s */ fi->bep = FALSE; /* flag for discrete or continuous interest * TRUE --> discrete * FALSE --> continuous * default to discrete interest */ fi->disc = TRUE; /* set compounding, CF, and payment, PF, frequency per year * default to monthly payments and compounding */ fi->CF = fi->PF = 12; /* standard loan quantities: * number of periods: n */ fi->npp = 0; /* annual interest: i */ fi->ir = 0.0; /* Present Value: pv */ fi->pv = 0.0; /* Payment: pmt */ fi->pmt = 0.0; /* Future Value: fv */ fi->fv = 0.0; } /* set_default */ /* compute Julian Day Number from calendar date */ unsigned long julian_day_number (unsigned year, unsigned month, unsigned day) { /* Gregorian/Julian Calendar Flag. * TRUE == Julian * FALSE == Gregorian */ unsigned gregorian = TRUE; /* assume we are dealing with current dates */ double yr; double pfac = 0.6; unsigned long ljdn; yr = year + (month - 3.0) / 12.0; ljdn = (long) (367.0 * yr + pfac) - (2 * (long) (yr)) + (long) (yr / 4.0) + (long) day + 1721117L; if (gregorian) ljdn += -(long) (yr / 100.0) + (long) (yr / 400.0) + 2; return ljdn; } /* julian_day_number */ amort_sched_ptr Amortization_init (amort_sched_ptr amortsched) { unsigned n = amortsched->n; double nint = amortsched->nint; double pv = amortsched->pv; double pmt = amortsched->pmt; double fv = amortsched->fv; double eint; double new_pmt; double pve; unsigned CF = amortsched->CF; unsigned PF = amortsched->PF; unsigned disc = amortsched->disc; unsigned bep = amortsched->bep; unsigned new_n; unsigned prec = amortsched->prec; unsigned long s, d, days_to_yr_end, Eff_Date_jdn = julian_day_number (amortsched->year_E, amortsched->month_E, amortsched->day_E), Init_Date_jdn = julian_day_number (amortsched->year_I, amortsched->month_I, amortsched->day_I); amortsched->Eff_Date_jdn = Eff_Date_jdn; amortsched->Init_Date_jdn = Init_Date_jdn; amortsched->yday_E = Eff_Date_jdn - julian_day_number (amortsched->year_E, 1, 1); amortsched->yday_I = Init_Date_jdn - julian_day_number (amortsched->year_I, 1, 1); amortsched->eint = eint = eff_int (nint / 100.0, CF, PF, disc); amortsched->fv_case = dabs (fv) > dabs (pv); amortsched->bp = bep ? 1.0 : 0.0; if (PF > 24) { /* Payment frequency per year greater than bi-monthly * use actual number of days */ s = Init_Date_jdn - Eff_Date_jdn; days_to_yr_end = julian_day_number (amortsched->year_I + 1, 1, 0) - Init_Date_jdn; d = 366 / PF; } else { /* Payment frequency per year bi-monthly or less * use 30 days/month, 360 days/year */ if (Eff_Date_jdn == Init_Date_jdn) { s = 0; } else { s = ((amortsched->year_I - amortsched->year_E) * 360) + ((amortsched->month_I - amortsched->month_E) * 30) + amortsched->day_I - amortsched->day_E; } /* endif */ days_to_yr_end = 390 - (amortsched->month_I * 30) - amortsched->day_I; d = 360 / PF; } /* endif */ if (!bep) { /* ordinary annuity */ s -= d; } /* endif */ amortsched->yr_pmt = (days_to_yr_end + d) / d; if (pmt == 0.0) { amortsched->pve = pv; } else { amortsched->pve = rnd (pv * pow ((1.0 + eint), ((double) (s * PF) / (double) (d * CF))), prec); } /* endif */ pve = amortsched->pve; /* compute new data to fully amortize loan: * new periodic payment, new_pmt * * option 1: Amortize with original transaction - ignore interest * due to delayed initial payment * * option 2: Amortize with new pv, pve == original pv adjusted for * delayed initial payment, original payment, original fv and * original total number of payments, adjust final payment * * option 3: amortize with new pv, pve, and new payments adjusted to * minimize final payment, keep original number of payments and * original fv * * option 4: amortize with new pv, pve, original payments and new * number of payments to keep original final fv */ /* option 3, compute new periodic payment */ amortsched->new_pmt = new_pmt = rnd (_fi_calc_payment (n, nint, pve, fv, CF, PF, disc, bep), prec); /* option 4: compute new number of total payments, new_n */ amortsched->new_n = new_n = (unsigned) rnd (_fi_calc_num_payments (nint, pve, pmt, fv, CF, PF, disc, bep), 0); /* following used in QTAwk to insure integer value, not needed in C */ /* n = int(n); */ /* compute payment for constant payment to principal loan and final * payment for original loan amount include interest due */ amortsched->cpmt1 = rnd (-pv / n, prec); amortsched->final_pmt_opt_1 = -pv - amortsched->cpmt1 * (n - 1); amortsched->final_pmt_opt_1 *= eint + 1; /* compute payment for constant payment to principal loan and final * payment for delayed loan amount include interest due */ amortsched->cpmt2 = rnd (-pve / n, prec); amortsched->final_pmt_opt_2 = -pve - amortsched->cpmt2 * (n - 1); amortsched->final_pmt_opt_2 *= eint + 1; if (bep) { amortsched->final_pmt_opt_3 = rnd (_fi_calc_future_value (n - 1, nint, pv, pmt, CF, PF, disc, bep) - (fv / (1.0 + eint)), prec); amortsched->final_pmt_opt_4 = rnd (_fi_calc_future_value (n - 1, nint, pve, pmt, CF, PF, disc, bep) - (fv / (1.0 + eint)), prec); amortsched->final_pmt_opt_5 = rnd (_fi_calc_future_value (n - 1, nint, pve, new_pmt, CF, PF, disc, bep) - (fv / (1.0 + eint)), prec); if (new_n) amortsched->final_pmt_opt_6 = rnd (_fi_calc_future_value (new_n - 1, nint, pve, pmt, CF, PF, disc, bep) - (fv / (1.0 + eint)), prec); else amortsched->final_pmt_opt_6 = 0.0; } else { amortsched->final_pmt_opt_3 = rnd (_fi_calc_future_value (n - 1, nint, pv, pmt, CF, PF, disc, bep) * (1.0 + eint) - fv, prec); amortsched->final_pmt_opt_4 = rnd (_fi_calc_future_value (n - 1, nint, pve, pmt, CF, PF, disc, bep) * (1.0 + eint) - fv, prec); amortsched->final_pmt_opt_5 = rnd (_fi_calc_future_value (n - 1, nint, pve, new_pmt, CF, PF, disc, bep) * (1.0 + eint) - fv, prec); if (new_n) amortsched->final_pmt_opt_6 = rnd (_fi_calc_future_value (new_n - 1, nint, pve, pmt, CF, PF, disc, bep) * (1.0 + eint) - fv, prec); else amortsched->final_pmt_opt_6 = 0.0; } /* endif */ /* compute delayed interest */ amortsched->delayed_int = pv - amortsched->pve; return amortsched; } /* Amortization_init */ amort_sched_ptr Amortization_Schedule (amort_sched_ptr amortsched) { unsigned n = amortsched->n; double nint = amortsched->nint; double pv = amortsched->pv; double pmt = amortsched->pmt; double fv = amortsched->fv; double eint = amortsched->eint; unsigned CF = amortsched->CF; unsigned PF = amortsched->PF; unsigned disc = amortsched->disc; unsigned bep = amortsched->bep; double cpmt = 0; double final_pmt = 0; char summary = amortsched->summary; unsigned option = amortsched->option; unsigned yr_pmt = amortsched->yr_pmt; unsigned fv_case = amortsched->fv_case; unsigned prec = amortsched->prec; unsigned j, s, yr, per_cnt, pmt_cnt = 0, k = 0, sum_prt; int jj; unsigned long d; double yr_fv, sum_int, yr_int, prin, adv_pmt, pmt_int, hpv = 0.0; yearly_summary_ptr yrly_sum; amort_sched_yr_ptr amortyr; sched_pmt_ptr pmtsched = NULL; sum_int = yr_int = 0.0; switch (option) { case 1: amortsched->cpmt = cpmt = amortsched->cpmt1; /* re-compute final payment without interest */ amortsched->final_pmt = final_pmt = -pv - cpmt * (n - 1); summary = (summary == 'y') ? 'x' : 'o'; break; case 2: amortsched->cpmt = cpmt = amortsched->cpmt2; pv = amortsched->pve; /* re-compute final payment without interest */ amortsched->final_pmt = final_pmt = -pv - cpmt * (n - 1); summary = (summary == 'y') ? 'x' : 'o'; break; case 3: amortsched->final_pmt = final_pmt = amortsched->final_pmt_opt_3; break; case 4: pv = amortsched->pve; amortsched->final_pmt = final_pmt = amortsched->final_pmt_opt_4; break; case 5: pv = amortsched->pve; pmt = amortsched->new_pmt; amortsched->final_pmt = final_pmt = amortsched->final_pmt_opt_5; break; case 6: n = amortsched->new_n; pv = amortsched->pve; amortsched->final_pmt = final_pmt = amortsched->final_pmt_opt_6; break; } /* endswitch */ yr = amortsched->year_I; sum_prt = TRUE; switch (summary) { case 'a': /* variable advanced prepayment schedule. prepayment equals next * period principal. */ amortsched->schedule.first_yr = amortyr = (amort_sched_yr_ptr) calloc (1, sizeof (amort_sched_yr)); for (per_cnt = 0, s = 1, j = n; pv != fv; j -= 2, per_cnt++) { /* basic equation to compute interest this payment period */ pmt_int = -rnd ((pv + (amortsched->bp * pmt)) * eint, prec); /* sum yearly interest paid */ yr_int += pmt_int; /* sum total interest paid */ sum_int += pmt_int; /* compute principal paid this payment period and round to nearest cent */ if (dabs (pmt) > dabs (pv)) { prin = -pv; pmt = prin + pmt_int; adv_pmt = 0.0; pv = fv; } else { prin = rnd (pmt - pmt_int, prec); /* compute remaining pv and round to nearest cent */ pv = rnd (pv + prin, prec); /* compute principal for next payment cycle and round to nearest cent */ adv_pmt = rnd (pmt + (pv + (amortsched->bp * pmt)) * eint, prec); if (dabs (pv) >= dabs (adv_pmt)) { /* remaining pv greater than advanced principal payment * compute remaining pv and round to nearest cent */ pv = rnd (pv + adv_pmt, prec); } else { /* remaining pv less than advanced principal payment reduce * advanced pricipla payment to remaining pv */ adv_pmt = -pv; /* and set remaining pv to fv */ pv = fv; } /* ## endif */ } /* # endif */ if (sum_prt) { jj = (j < yr_pmt) ? j + 1 : yr_pmt; amortyr->payments = pmtsched = (sched_pmt_ptr) calloc (jj, sizeof (sched_pmt)); pmt_cnt = 0; sum_prt = FALSE; } /* endif */ pmtsched->period_num = s++; pmtsched->interest = pmt_int; pmtsched->principal = prin; pmtsched->advanced_pmt = adv_pmt; pmtsched->total_pmt = pmt + adv_pmt; pmtsched->balance = pv; pmtsched++; pmt_cnt++; if (!--yr_pmt) { yr_pmt = PF; amortyr->year = yr++; amortyr->interest_pd = yr_int; amortyr->principal_pd = pv - hpv; amortyr->yr_end_balance = pv; amortyr->total_interest_pd = sum_int; amortyr->num_periods = pmt_cnt; amortyr->next_yr = (amort_sched_yr_ptr) calloc (1, sizeof (amort_sched_yr)); amortyr = amortyr->next_yr; hpv = pv; yr_int = 0.0; sum_prt = TRUE; } /* endif */ } /* endfor */ if (dabs (pv) > 0.0) { /* basic equation to compute interest this payment period */ pmt_int = -rnd ((pv + (amortsched->bp * pmt)) * eint, prec); /* sum yearly interest paid */ yr_int += pmt_int; /* sum total interest paid */ sum_int += pmt_int; /* compute principal paid this payment period and round to nearest cent */ prin = rnd (pmt - pmt_int, prec); final_pmt = pmt; /* compute remaining pv and round to nearest cent */ pv = rnd (pv + prin, prec); /* Set advanced principal payment to remaining pv */ adv_pmt = -pv; amortyr->final_pmt = final_pmt += adv_pmt; /* and set remaining pv to fv */ pv = fv; if (pmtsched) { pmtsched->period_num = s++; pmtsched->interest = pmt_int; pmtsched->principal = prin; pmtsched->advanced_pmt = adv_pmt; pmtsched->total_pmt = final_pmt; pmtsched->balance = pv; } per_cnt++; pmt_cnt++; } /* endif */ if (dabs (yr_int) > 0.0) { amortyr->year = yr++; amortyr->interest_pd = yr_int; amortyr->principal_pd = pv - hpv; amortyr->total_interest_pd = sum_int; amortyr->num_periods = pmt_cnt; } /* endif */ amortsched->total_periods = per_cnt; break; case 'f': /* fixed prepaymet schedule prepayment specified by user */ amortsched->schedule.first_yr = amortyr = (amort_sched_yr_ptr) calloc (1, sizeof (amort_sched_yr)); /* set advnaced payment */ adv_pmt = amortsched->fixed_pmt; for (per_cnt = 0, s = 1, j = n; j && (pv != fv); j--, per_cnt++) { /* basic equation to compute interest this payment period */ pmt_int = -rnd ((pv + (amortsched->bp * pmt)) * eint, prec); /* sum yearly interest paid */ yr_int += pmt_int; /* sum total interest paid */ sum_int += pmt_int; /* compute principal paid this payment period and round to nearest cent */ if (dabs (pmt) > dabs (pv)) { prin = -pv; pmt = prin + pmt_int; adv_pmt = 0.0; pv = 0.0; } else { prin = rnd (pmt - pmt_int, prec); /* compute remaining pv and round to nearest cent */ pv = rnd (pv + prin, prec); if (dabs (pv) >= dabs (adv_pmt)) { /* remaining pv greater than advanced principal payment * compute remaining pv and round to nearest cent */ pv = rnd (pv + adv_pmt, prec); } else { /* remaining pv less than advanced principal payment reduce * advanced principal payment to remaining pv and set * remaining pv to fv */ adv_pmt = -pv; pv = fv; } /*## endif */ } /* # endif */ if (sum_prt) { jj = (j < yr_pmt) ? j + 1 : yr_pmt; amortyr->payments = pmtsched = (sched_pmt_ptr) calloc (jj, sizeof (sched_pmt)); pmt_cnt = 0; sum_prt = FALSE; } else { (amortyr->num_periods)++; } /* ## endif */ pmtsched->period_num = s++; pmtsched->interest = pmt_int; pmtsched->principal = prin; pmtsched->advanced_pmt = adv_pmt; pmtsched->total_pmt = pmt + adv_pmt; pmtsched->balance = pv; pmt_cnt++; pmtsched++; if (!--yr_pmt) { yr_pmt = PF; amortyr->year = yr++; amortyr->interest_pd = yr_int; amortyr->principal_pd = pv - hpv; amortyr->yr_end_balance = pv; amortyr->total_interest_pd = sum_int; amortyr->num_periods = pmt_cnt; amortyr->next_yr = (amort_sched_yr_ptr) calloc (1, sizeof (amort_sched_yr)); amortyr = amortyr->next_yr; hpv = pv; yr_int = 0.0; sum_prt = TRUE; } /* ## endif */ } /* ## endfor */ if (pv != fv) { /* # basic equation to compute interest this payment period */ pmt_int = -rnd ((pv + (amortsched->bp * pmt)) * eint, prec); /* # sum yearly interest paid */ yr_int += pmt_int; /* # sum total interest paid */ sum_int += pmt_int; /* # compute principal paid this payment period and round to nearest cent */ prin = rnd (pmt - pmt_int, prec); final_pmt = pmt; /* # compute remaining pv and round to nearest cent */ pv = rnd (pv + prin, prec); /* # Set advanced principal payment to remaining pv */ adv_pmt = -pv; amortyr->final_pmt = final_pmt += adv_pmt; /* # and set remaining pv to fv */ pv = fv; if (pmtsched) { pmtsched->period_num = s++; pmtsched->interest = pmt_int; pmtsched->principal = prin; pmtsched->advanced_pmt = adv_pmt; pmtsched->total_pmt = final_pmt; pmtsched->balance = pv; } per_cnt++; pmt_cnt++; } /* # endif */ if (dabs (yr_int) > 0.0) { amortyr->year = yr++; amortyr->interest_pd = yr_int; amortyr->principal_pd = pv - hpv; amortyr->total_interest_pd = sum_int; amortyr->num_periods = pmt_cnt; } /* endif */ amortsched->total_periods = per_cnt; break; case 'o': /* Constant payment to principal use constant payment equal to * original pv divided by number of periods. constant payment to * principal could be amount specified by user. */ amortsched->schedule.first_yr = amortyr = (amort_sched_yr_ptr) calloc (1, sizeof (amort_sched_yr)); amortsched->total_periods = n; d = yr_pmt; for (s = 1, j = n - 1; j; j--, k++) { pmt_int = -rnd (pv * eint, prec); /* sum yearly interest paid */ yr_int += pmt_int; /* sum total interest paid */ sum_int += pmt_int; pv = rnd (pv + cpmt, prec); if (sum_prt) { jj = (j < yr_pmt) ? j + 1 : yr_pmt; amortyr->payments = pmtsched = (sched_pmt_ptr) calloc (jj, sizeof (sched_pmt)); amortyr->num_periods = jj; k = 0; sum_prt = FALSE; } /* endif */ pmtsched->period_num = s++; pmtsched->interest = pmt_int; pmtsched->total_pmt = cpmt + pmt_int; pmtsched->balance = pv; pmtsched++; if (!--yr_pmt) { yr_pmt = PF; amortyr->year = yr++; amortyr->interest_pd = yr_int; amortyr->principal_pd = d * cpmt; amortyr->yr_end_balance = pv; amortyr->total_interest_pd = sum_int; amortyr->next_yr = (amort_sched_yr_ptr) calloc (1, sizeof (amort_sched_yr)); amortyr = amortyr->next_yr; d = PF; yr_int = 0.0; sum_prt = TRUE; } /* endif */ } /* endfor */ if (pv) { pmt_int = -rnd (pv * eint, prec); /* sum yearly interest paid */ yr_int += pmt_int; /* sum total interest paid */ sum_int += pmt_int; if (pmtsched) { pmtsched->period_num = s++; pmtsched->interest = -pmt_int; pmtsched->total_pmt = -pv + pmt_int; pmtsched->balance = 0.0; } amortyr->final_pmt = -pv - pmt_int; } /* endif */ if (dabs (yr_int) > 0.0) { amortyr->year = yr++; amortyr->interest_pd = yr_int; amortyr->principal_pd = -pv + k * cpmt; amortyr->total_interest_pd = sum_int; } /* endif */ break; case 'p': /* normal amortization schedule interest, principal and balance * per payment period */ amortsched->schedule.first_yr = amortyr = (amort_sched_yr_ptr) calloc (1, sizeof (amort_sched_yr)); amortsched->total_periods = n; hpv = pv; for (s = 1, j = n - 1; j; j--) { /* basic equation for computing interest paid in payment period */ pmt_int = -rnd ((pv + (amortsched->bp * pmt)) * eint, prec); /* sum yearly interest paid */ yr_int += pmt_int; /* sum total interest paid */ sum_int += pmt_int; /* compute principal paid this payment period */ prin = rnd (pmt - pmt_int, prec); /* compute remaining pv and round to nearest cent */ pv = rnd (pv + prin, prec); if (sum_prt) { jj = (j < yr_pmt) ? j + 1 : yr_pmt; amortyr->payments = pmtsched = (sched_pmt_ptr) calloc (jj, sizeof (sched_pmt)); amortyr->num_periods = jj; sum_prt = FALSE; } /* endif */ if (fv_case) { pmtsched->period_num = s++; pmtsched->interest = pmt_int; pmtsched->balance = pv; pmtsched++; } else { pmtsched->period_num = s++; pmtsched->interest = pmt_int; pmtsched->principal = prin; pmtsched->balance = pv; pmtsched++; } /* endif */ if (!--yr_pmt) { yr_pmt = PF; amortyr->year = yr++; amortyr->interest_pd = yr_int; if (!fv_case) { amortyr->principal_pd = pv - hpv; } /* endif */ amortyr->yr_end_balance = pv; amortyr->total_interest_pd = sum_int; amortyr->next_yr = (amort_sched_yr_ptr) calloc (1, sizeof (amort_sched_yr)); amortyr = amortyr->next_yr; hpv = pv; yr_int = 0.0; sum_prt = TRUE; } /* * endif */ } /* * endfor */ /* determine if payment due at beginning or end of period in order * to correctly compute final payment, interest and principal */ if (bep) { /* paying remainder at beginning of period compute final payment */ final_pmt = -pv - fv / (1 + eint); /* then compute interest paid with final final payment */ pmt_int = -rnd ((pv + final_pmt) * eint, prec); /* then compute the principal paid */ prin = final_pmt + pmt_int; } else { /* basic equation for computing interest paid in payment period * for payment at end of period */ pmt_int = -rnd (pv * eint, prec); /* compute principal paid this payment period */ prin = -pv; /* compute the final payment note the final payment may be * computed either of two ways both are equivalent */ final_pmt = prin + pmt_int; } /* * endif */ pv = -fv; /* sum yearly interest paid */ yr_int += pmt_int; /* sum total interest paid */ sum_int += pmt_int; if (sum_prt) { amortyr->payments = pmtsched = (sched_pmt_ptr) calloc (1, sizeof (sched_pmt)); amortyr->num_periods = 1; } /* endif */ amortyr->final_pmt = final_pmt; if (fv_case) { pmtsched->period_num = s++; pmtsched->interest = pmt_int; pmtsched->balance = pv; } else { pmtsched->period_num = s++; pmtsched->interest = pmt_int; pmtsched->principal = prin; pmtsched->balance = pv; } /* endif */ if (dabs (yr_int) > 0.0) { amortyr->year = yr++; amortyr->interest_pd = yr_int; amortyr->total_interest_pd = sum_int; if (!bep) { amortyr->principal_pd = -hpv; } /* endif */ } /* endif */ break; case 'x': /* constant payment to principal - annual summary */ /* compute number of years to summarize */ j = n / PF; if (yr_pmt < PF) j++; amortsched->total_periods = j; amortsched->schedule.summary = yrly_sum = (yearly_summary_ptr) calloc (j, sizeof (yearly_summary)); jj = 0; for (j = n, sum_prt = 0; j > 0; j -= yr_pmt, yr_pmt = PF, sum_prt++) { if (j <= PF) { s = jj + j; yr_pmt = j; yr_fv = rnd (pv + cpmt * (s - 1), prec) + final_pmt; } else { s = jj + yr_pmt; yr_fv = rnd (pv + cpmt * s, prec); } /* endif */ prin = -eint * jj * (pv + (cpmt * (jj - 1) / 2.0)); yr_int = -eint * s * (pv + (cpmt * (s - 1) / 2.0)); yr_int = rnd (yr_int - prin, prec); jj += yr_pmt; sum_int += yr_int; yrly_sum[sum_prt].year = yr++; yrly_sum[sum_prt].interest = yr_int; yrly_sum[sum_prt].end_balance = yr_fv; } /* endfor */ break; case 'y': /* normal amortization - annual summary */ /* compute number of years to summarize */ j = n / PF; if (yr_pmt < PF) j++; if (n > (j * PF)) j++; amortsched->total_periods = j; amortsched->schedule.summary = yrly_sum = (yearly_summary_ptr) calloc (j, sizeof (yearly_summary)); hpv = pv; for (jj = n, j = 0; jj > 0; jj -= yr_pmt, yr_pmt = PF, j++) { if (jj <= (int)PF) { yr_fv = fv; yr_int = rnd (((jj - 1) * pmt) + hpv + final_pmt, prec); } else { yr_fv = -rnd (_fi_calc_future_value (yr_pmt, nint, hpv, pmt, CF, PF, disc, bep), prec); yr_int = rnd ((yr_pmt * pmt) + hpv - yr_fv, prec); } /* * endif */ sum_int += yr_int; yrly_sum[j].year = yr++; yrly_sum[j].interest = yr_int; yrly_sum[j].end_balance = yr_fv; hpv = yr_fv; } /* * endfor */ break; } /* * endswitch */ amortsched->total_interest = sum_int; return amortsched; } /* Amortization_Schedule */ /* function to free dynamically allocated memory used for amortization schedule */ void Amortization_free (amort_sched_ptr amortsched) { amort_sched_yr_ptr amortyr, prst_yr; switch (amortsched->summary) { case 'a': case 'f': case 'o': case 'p': for (amortyr = amortsched->schedule.first_yr; amortyr; amortyr = prst_yr) { if (amortyr->payments) free (amortyr->payments); prst_yr = amortyr->next_yr; free (amortyr); } /* endfor */ break; case 'y': free (amortsched->schedule.summary); break; } /* endswitch */ amortsched->schedule.first_yr = NULL; } /* amort_free */
154  * ³
155  *
156  * PV
157  *
158  * Appreciation
159  * Depreciation
160  * Compound Growth
161  * Savings Account
162  *
163  * ****************************************************************************
164  *
165  * 2) FV
166  * PV = 0
167  * ³
168  * Period ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÙ * ³ 1 ³ 2 ³ 3 ³ 4 ³ . ³ . ³ . ³ . ³ . ³ . ³ . ³ . ³ . ³ n * * PMT PMT PMT PMT PMT PMT PMT PMT PMT PMT PMT PMT PMT PMT * * Annuity (series of payments) * Pension Fund * Savings Plan * Sinking Fund * * **************************************************************************** * * 3) * PV * ³ FV=0 * Period ÀÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ * 1 ³ 2 ³ 3 ³ 4 ³ . ³ . ³ . ³ . ³ . ³ . ³ . ³ . ³ . ³ n ³ * * PMT PMT PMT PMT PMT PMT PMT PMT PMT PMT PMT PMT PMT PMT * * Amortization * Direct Reduction Loan * Mortgage (fully amortized) * * **************************************************************************** * * 4) * FV* * PMT PMT PMT PMT PMT PMT PMT PMT PMT PMT PMT PMT PMT ³ + * PMT * 1 ³ 2 ³ 3 ³ 4 ³ . ³ . ³ . ³ . ³ . ³ . ³ . ³ . ³ . ³ n ³ * Period ÚÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÙ * ³ * * PV * * Annuity * Lease (with buy back or residual)* * Loan or Mortgage (with balloon)* * * **************************************************************************** * * First lets discuss interest before discussing the financial * equation. Most financial transactions utilize a nominal interest * rate, NAR, i.e., the interest rate per year. The NAR must be * converted to the interest rate per payment interval and the * compounding accounted for before it can be used in computing an * interest payment. After this conversion process, the interest * used is the effective interest rate, EIR. In converting NAR to * EIR, there are two concepts to discuss first, the Compounding * Frequency and the Payment Frequency and * whether the interest is * coumpounded in discrete intervals or continuously. The * compounding Frequency, CF, is simply the number of times per * year, the monies in the financial transaction are compounded. In * the U.S., monies are usually compounded daily on bank deposits, * and monthly on loans. Sometimes Long term deposits are compounded * quarterly or weekly. * * The Payment Frequency, PF, is simply how often during a year * payments are made in the transaction. Payments are usually * scheduled on a regular basis and can be made at the beginning or * end of the payment period. If made at the beginning of the * payment period, interest must be applied to the payment as well * as any previous money paid or money still owed. * * Normal values for CF and PF are: * 1 == annual * 2 == semi-annual * 3 == tri-annual * 4 == quaterly * 6 == bi-monthly * 12 == monthly * 24 == semi-monthly * 26 == bi-weekly * 52 == weekly * 360 == daily * 365 == daily * * a) the Compounding Frequency per year, CF, need not be identical * to the Payment Frequency per year, PF, and/or, * * b) Interest may be compounded in either discrete intervals or continuously * compounded. * * c) Also, payments may be made at the beginning of the payment * period or at the end of the payment period. * * CF and PF are defaulted to 1. The default is for discrete interest * intervals and payments are defaulted to the end of the payment * period. * * When a solution for n, PV, PMT or FV is required, the nominal interest * rate, i, must first be converted to the effective interest rate per payment * period. This rate, ieff, is then used to compute the selected variable. To * convert i to ieff, the following expressions are used: * * Discrete interest periods: * * 19) ieff = (1 + i/CF)^(CF/PF) - 1 * * Continuous Interest * * 20) ieff = e^(i/PF) - 1 = exp(i/PF) - 1 * * When interest is computed, the computation produces the effective interest * rate, ieff. This value must then be converted to the nominal interest rate. * Function _I below returns the nominal interest rate NOT the effective * interest rate. ieff is converted to i using the following expressions: * * Discrete Case: * * i = CF*[(1+ieff)^(PF/CF) - 1] * * Continuous Case: * * i = ln[(1+ieff)^PF] * * **************************************************************************** * * NOTE: in the equations below for the financial transaction, all * interest rates are the effective interest rate, ieff. The symbol * will be shortned to just 'i'. * * **************************************************************************** * * The basic financial equation used is: * * 1) PV*(1 + i)^n + PMT*(1 + iX)*[(1+i)^n - 1]/i + FV = 0 * Where: X = 0 for end of period payments, and * X = 1 for beginning of period payments * * **************************************************************************** * * NOTE: this equation is derived in the following manner: * * Start with the basic equation to find the balance or Present * Value, PV[1], after one payment period. Note PV[1] is the Present * value after on payment and PV[0] is the initial Present * Value. PV[0] will be shortened to just PV. * * The interest due at the end of the first payment period is: * * ID[1] = (PV + X * PMT) * i * where: X = 0 for end of period payments, and * X = 1 for beginning of period payments. * * Thus: * PV[1] = PV + (PMT + ID[1]) * = PV + (PMT + (PV + X * PMT) * i) * = PV * (1 + i) + PMT * (1 + Xi) * * This equation works for all of the money diagrams shown * above. The Present Value, money received or paid, is modified by * a payment made at the beginning of a payment period and * multiplied by the effective interest rate to compute the interest * due during the payment period. The interest due is then added to * the payment to obtain the amount to be added to the Present Value * to compute the new Present Value. * * For diagram 1): PV < 0, PMT == 0, PV[1] < 0 * For diagram 2): PV == 0, PMT < 0, PV[1] < 0 * For Diagram 3): PV > 0, PMT < 0, PV[1] >= 0 or PV[1] <= 0 * For Diagram 4): PV < 0, PMT > 0, PV[1] <= 0 or PV[1] >= 0 * * X may be 0 or 1 for any diagram. * * For the standard loan, PV is the money borrowed, PMT is the * periodic payment to repay the loan and i is the effective * interest rate agreed upon. * * To calculate the Present Value after the second payment period, * the above calculation is applied iteratively to PV_1: * * PV[2] = PV[1] + (PMT + (PV[1] + X * PMT) * i) * = PV[1] * (1 + i) + PMT * (1 + iX) * = (PV * (1 + i) + PMT * (1 + iX)) * (1 + i) + PMT * (1 + iX) * = PV * (1 + i)^2 + PMT * (1 + iX) * (1 + i) * + PMT * (1 + iX) * * Similarly: * * PV[3] = PV[2] + (PMT + (PV[2] + X * PMT) * i) * = PV[2] * (1 + i) + PMT * (1 + iX) * = PV * (1 + i)^2 + PMT * (1 + iX) * (1 + i) * + PMT * (1+ iX)) * ( 1 + i) * + PMT * (1+ iX) * = PV * (1 + i)^3 + PMT * (1 + iX) * (1 + i)^2 * + PMT * (1 + iX) * (1 + i)^2 * + PMT * (1 + iX) * (1 + i) * + PMT * (1 + iX) * * And for the n'th payment: * * PV[n] = PV[n-1] + (PMT + (PV[n-1] + X * PMT) * i) * PV[n] = PV * (1 + i)^n + PMT * (1 + iX) * (1 + i)^(n-1) * + PMT * (1 + iX) * (1 + i)^(n-2) + * . * . * . * + PMT * (1 + iX) * (1 + i) * + PMT * (1 + iX) * PV[n] = PV * (1 + i)^n + PMT * (1 + iX) * [(1 + i)^(n-1) + ... * + (1 + i) + 1] * * **************************************************************************** * * The sum of the finite series: * * 1 + k + (k^2) + (k^3) + ... + (k^n) = (1-k^(n+1))/(1-k) * * as can be seen by the following. Let S(n) be the series sum. Then * * S(n) - k * S(n) = 1 - k^(n+1) * * and solving for S(n): * * S(n) = [1-k^(n+1)]/[1-k] = 1 + k + (k^2) + (k^3) + ... + (k^n) * * **************************************************************************** * * PV[n] = PV * (1 + i)^n + PMT * (1 + iX) * [(1 + i)^(n-1) + ... * + (1 + i) + 1] * = PV * (1 + i)^n + PMT * (1 + iX) * [1 - (1 + i)^n]/[1 - (1 + i)] * = PV * (1 + i)^n + PMT * (1 + iX) * [1 - (1 + i)^n]/[-i] * = PV * (1 + i)^n + PMT * (1 + iX) * [(1 + i)^n - 1]/i * * The formaula for PV[n] can be proven using mathematical induction. * * or: * * PV * (1 + i)^n + PMT * [(1 + i)^n - 1]/i - PV[n] = 0 * * If after n payments, the remaining balance is repaid as a lump * sum, the lump sum is known as the Future Value, FV[n]. Since * FV[n] is negative if paid and positive if received, FV[n] is the * negative of PV[n]. Since n is assumed to be the last payment, * FV[n] will be shortened to simply FV. * * Setting: FV = -PV[N] * * 1) PV*(1 + i)^n + PMT*(1 + iX)*[(1 + i)^n - 1]/i + FV = 0 * * Up to this point, we have said nothing about the value of * PMT. PMT can be any value mutually agreed upon by the lender and * the borrower. From the equation for PV[1]: * * PV[1] = PV + (PMT + (PV + X * PMT) * i), * * Several things can be said about PMT. * * 1. If PMT = PV * i, and X = 0 (end of period payments): * * The payment is exactly equal to the interest due and PV[1] = * PV. In this case, the borrower must make larger future * payments to reduce the balance due, or make a single payment, * after some agreed upon number of payments, with PMT = PV to * completely pay off the loan. This is an interest only payment * with a balloon payment at the end. * * 2. If PMT < PV * i, and X = 0 * * The payment is insufficient to cover even the interest charged * and the balance due grows * * 3. If PMT > PV * i, and X = 0 * * The payment is sufficient to cover the interest charged with a * residual amount to be applied to reduce the balance due. The * larger the residual amount, the faster the loan is repaid. For * most mortgages or other loans made today, the lender and * borrower agree upon a certain number of repayment periods and * the interest to be charged per payment period. The interest * may be multiplied by 12 and stated as an annual interest * rate. Then the lender and borrower want to compute a periodic * payment, PMT, which will reduce the balance due to zero after * the agreed upon number of payment have been made. If N is the * agreed upon number of periodic payments, then we want to use: * * PV * (1 + i)^N + PMT*(1 +iX)*[(1 + i)^N - 1]/i + FV = 0 * * with FV = 0 to compute PMT: * * PMT = -[PV * i * (1 + i)^(N - X)]/[(1 + i)^N - 1] * * The value of PMT computed will reduce the balance due to zero * after N periodic payments. * * **************************************************************************** * * * With a simple alegebraic re-arrangement, The financial Equation becomes: * * 2) [PV + PMT*(1 + iX)/i][(1 + i)^n - 1] + PV + FV = 0 * * or * * 3) (PV + C)*A + PV + FV = 0 * * where: * 4) A = (1 + i)^n - 1 * * 5) B = (1 + iX)/i * * 6) C = PMT*B * * The form of equation 3) simplifies the calculation procedure for all five * variables, which are readily solved as follows: * * 7) n = ln[(C - FV)/(C + PV)]/ln((1 + i) * * 8) PV = -[FV + A*C]/(A + 1) * * 9) PMT = -[FV + PV*(A + 1)]/[A*B] * * 10) FV = -[PV + A*(PV + C)] * * Equations 4), 5) and 6) are computed by functions: * * _A * _B * _C * * respectively. Equations 7), 8), 9) and 10) are computed by functions: * * _N * _PV * _PMT * _FV * * respectively. * * The solution for interest is broken into two cases: * * PMT == 0 * i = [FV/PV]^(1/n) - 1 * * PMT != 0 * * Since equation 3) cannot be solved explicitly for i in this * case, an iterative technique must be employed. Newton's * method, using exact expressions for the function of i and its * derivative, are employed. The expressions are: * * 12) i[k+1] = i[k] - f(i[k])/f'(i[k]) * where: i[k+1] == (k+1)st iteration of i * i[k] == kth iteration of i * and: * * 13) f(i) = A*(PV+C) + PV + FV * * 14) f'(i) = n*D*(PV+C) - (A*C)/i * * 15) D = (1 + i)^(n-1) = (A+1)/(1+i) * * To start the iterative solution for i, an initial guess must be made * for the value of i. The closer this guess is to the actual value, * the fewer iterations will have to be made, and the greater the * probability that the required solution will be obtained. The initial * guess for i is obtained as follows: * * if PMT*FV >= 0, then PV case * if PMT*FV < 0, then FV case * * PV case: * | n*PMT + PV + FV | * 16) i[0] = | ----------------| * | n*PV | * * = abs[(n*PMT + PV + FV)/(n*PV)] * * FV case: * a) PV != 0 * * | FV - n*PMT | * 17) i[0] = |---------------------------| * | 3*[PMT*(n-1)^2 + PV - FV] | * * = abs[(FV-n*PMT)/(3*(PMT*(n-1)^2+PV-FV))] * b) PV == 0 * * | FV + n*PMT | * 18) i[0] = |---------------------------| * | 3*[PMT*(n-1)^2 + PV - FV] | * * = abs[(FV+n*PMT)/(3*(PMT*(n-1)^2+PV-FV))] * * **************************************************************************** * Constant payment to principal loan * * In this loan, each total payment is different, with each * succeeding payment less than the preceding payment. Each payment * is the total of the constant amount to the principal plus the * interest for the period. The constant payment to the principal is * computed as: * * C = -PV / N * * Where PV is the loan amount to be repaid in N payments * (periods). Note that the constant payment to principal could be * any value agreed to by the two parties involved. * * Thus the principal after the first payment is: * PV[1] = PV[0] + C = PV + C * after the second payment, the principal is: * PV[2] = PV[1] + C = PV[0] + 2C * In general, the remaining principal after n payments is: * PV[n] = PV[0] + nC = PV + nC * * If the effective interest per payment period is i, then the * interest for the first payment is: * * I[1] = -i*PV[0] = -i*PV * and for the second: * I[2] = -i * PV[1] * and in general, for the n'th payment the interest is: * I[n] = -i * PV[n-1] * = -i * (PV + (n-1)C) * The total payment for any period, n, is: * P[n] = C + I[n] * = C + i * (PV + (n-1)C) * = C(1 + i) - i * (PV + nC) * The total interest paid to period n is: * T[n] = I[1] + I[2] + I[3] + ... + I[n] * T[n] = sum(j = 1 to n: I[j]) * T[n] = sum(j = 1 to n: -i * (PV + (j-1)C)) * T[n] = sum(j=1 to n: -i*PV) + sum(j=1 to n: iC) + sum(j=1 to n: -iCj) * T[n] = -i*n*PV + i*n*C - i*C*sum(j=1 to n:j) * sum(j=1 to n:j) = n(n+1)/2 * T[n] = -i*n*(PV + C) - i*C*n(n+1)/2 * T[n] = -i*n*(PV + (C*(n - 1)/2)) * * Note: substituting for C = -PV/N, in the equations for PV[n], I[n], * P[n], and T[n] would give the following equations: * * PV[n] = PV*(1 - n/N) * I[n] = -i*PV*(1 + N - n)/N * P[n] = -i*PV*(2 + N - n)/N * T[n] = -i*n*PV*(2*N - n + 1)/(2*N) * * Using these equations for the calculations would eliminate the * dependence on C, but only if C is always defined as above and * would eliminate the possibility of another value for C. If the * value of C was less than -PV/N then a balloon payment would be * due at the final payment and this is a possible alternative for * some people. * * **************************************************************************** * * Amortization Schedules. * * Financial Transactions have an effective Date, ED, and an Initial Payment * Date, IP. ED may or may not be the same as IP, but IP is always the same * or later than ED. Most financial transaction calculators assume that * IP is equal to ED for beginning of period payments or at the end of the * first payment period for end of period payments. * * This is not always true. IP may be delayed for financial reasons * such as cash flow or accounting calendar. The subsequent payments * then follow the agreed upon periodicity. Since money has a time * value, the "delayed" IP must be accounted for. Computing an * "Effective PV", pve, is one means of handling a delayed IP. * * EDj == the Julian Day Number of ED, and * IPj == the Julian Day Number of IP in the following. * * pve is be computed as: * * pve = pv*(1 + i)^(s*PF/d*CF) * * Where: d = length of the payment period in days, and * s = IPj - EDj - d*X * * Computing an amortization Schedule for a given financial transaction is * simply applying the basic equation iteratively for each payment period: * * PV[n] = PV[n-1] + (PMT + (PV[n-1] + X * PMT) * i) * * At the end of each iteration, PV[n] is rounded to the nearest cent. For * each payment period, the interest due may be computed separately as: * * ID[n] = (PMT + (PV[n-1] + X * PMT) * i) * * and rounded to the nearest cent. PV[n] then becomes: * * PV[n] = PV[n-1] + PMT + ID[n] * * For those cases where a yearly summary only is desired, it is not * necessary to compute each transaction for each payment period, * rather the PV may be computed for the beginning of each year, * PV[yr], and the FV computed for the end of the year, FV[yr]. The * interest paid during the year is the computed as: * * ID[yr] = (NP * PMT) + PV[yr] + FV[yr] * * Since the final payment may not be equal to the periodic payment, * the final payment must be computed separately as follows. Two * derivations are given below for the final payment equation. Both * derivations are given below since one or the other may be clearer * to some readers. Both derivations are essentially the same, they * just have different starting points. The first is the fastest. * * 1) final_pmt == final payment @ payment n == int(n) * from above the basic financial equation: * PV[n] = PV[n-1]*(1 + i) + final_pmt * (1 + iX), * i == effective interest rate * * solving for final_pmt, we have: * * final_pmt * (1 + iX) = PV[n] - PV[n-1]*(1 + i) * = FV[n-1]*(1 + i) - FV[n] * final_pmt = FV[n-1]*(1+i)/(1 + iX) - FV[n]/(1 + iX) * * final_pmt = FV[n-1]*(1 + i) - FV[n], * for X == 0, end of period payments * * = FV[n-1] - FV[n]/(1 + i), * for X == 1, beginning of period payments * * 2) final_pmt == final payment @ payment n == int(n) * i[n] == interest due @ payment n * i[n] = (PV[n-1] + X * final_pmt) * i, i == effective interest rate * = (X * final_pmt - FV[n]) * i * * Now the final payment is the sum of the interest due, plus * the present value at the next to last payment plus any * residual future value after the last payment: * * final_pmt = -i[n] - PV[n-1] - FV[n] * = FV[n-1] - i[n] - FV[n] * = FV[n-1] - (X *final_pmt - FV[n-1])*i - FV[n] * = FV[n-1]*(1 + i) - X*final_pmt*i - FV[n] * * solving for final_pmt: * final_pmt*(1 + iX) = FV[n-1]*(1 + i) - FV[n] * final_pmt = FV[n-1]*(1 + i)/(1 + iX) - FV[n]/(1 + iX) * * final_pmt = FV[n-1]*(1 + i) - FV[n], * for X == 0, end of period payments * * = FV[n-1] - FV[n]/(1 + i), * for X == 1, beginning of period payments * *============================================================================ * * The amortization schedule is computed for four different situations: * * 1) The original financial data is used. This ignores any possible * agjustment to the Present value due to any delay in the initial * payment. This is quite common in mortgages where end of period * payments are used and the first payment is scheduled for the end * of the first whole period, i.e., any partial payment period from * ED to the beginning of the next payment period is ignored. * * 2) The original periodic payment is used, the Present Value is * adjusted for the delayed Initial Payment. The total number of * payments remains the same. The final payment is adjusted to bring * the balance into agreement with the agreed upon final Future * Value. * * 3) A new periodic payment is computed based upon the adjusted * Present Value, the agreed originally upon number of total * payments and the agreed upon Future Value. The new periodic * payments are computed to minimize the final payment in accordance * with the Future Value after the last payment. * * 4) The original periodic payment is retained and a new number of * total payments is computed based upon the adjusted Present Value * and the agreed upon Future Value. * * The amortization schedule may be computed and displayed in three manners: * * 1. The payment *, interest paid, principal paid and remaining PV * for each payment period are computed and displayed. At the end of * each year a summary is computed and displayed and the total * interest paid is displayed at the end. * * 2. A summary is computed and displayed for each year. The * interest paid during the year is computed and displayed as well * as the remaining balance at years end. The total interest paid * is displayed at the end. * * 3. An amortization schedule is computed for a common method of * advanced payment of principal is computed and displayed. In this * amortization, the principal for the next payment is computed and * added into the current payment. This method will cut the number * of total payments in half and will cut the interest paid almost * in half. For mortgages, this method of prepayment has the * advantage of keeping the total payments small during the initial * payment periods The payments grow until the last payment period * when presumably the borrower can afford larger payments. * * =========================================================================== * NOTE: For Payment Frequencies, PF, semi-monthly or less, i.e., PF * == 12 or PF == 24, a 360 day calendar year and 30 day month are * used. For Payment Frequencies, PF, greater than semi-monthly, PF * > 24, the actual number of days per year and per payment period * are used. The actual values are computed using the built-in * 'julian_day_number' function * * **************************************************************************** * * Note: in the following examples, the user input is preceded by the * prompt "<>". The result of evaluating the input expression is then * displayed. I have taken the liberty of including comments in the * example input/output sessions by preceding with ' *'. Thus, for * the line: <>n=5 *set number of periods the comment that setting the * number of periods is not really input and the true input is only: * <>n=5 * * Example 1: Simple Interest * Find annual simple interest rate (%) for an $800 loan to be repayed at the * end of one year with a single payment of $896. * <>d * <>CF=PF=1 * 1.00 * <>n=1 * 1.00 * <>pv=-800 * -800.00 * <>fv=896 * 896.00 * <>I * 12.00 * * Example 2: Compound Interest * Find the future value of $800 after one year at a nominal rate of 12% * compounded monthly. No payments are specified, so the payment frequency is * set equal to the compounding frequency at the default values. * <>d * <>n=12 * 12.00 * <>i=12 * 12.00 * <>pv=-800 * -800.00 * <>FV * 901.46 * * Example 3: Periodic Payment: * Find the monthly end-of-period payment required to fully amortize the loan * in Example 2. A fully amortized loan has a future value of zero. * <>fv=0 * 0.00 * <>PMT * 71.08 * * Example 4: Conventional Mortgage * * Find the number of monthly payments necessary to fully amortize a * loan of $100,000 at a nominal rate of 13.25% compounded monthly, if * monthly end-of-period payments of $1125.75 are made. * * <>d * <>i=13.25 * 13.25 * <>pv=100000 * 100,000.00 * <>pmt=-1125.75 * -1,125.75 * <>_N(i,pv,pmt,fv,CF,PF,disc,bep) * 360.10 * <>N * 360 * * Example 5: Final Payment * Using the data in example 4, find the amount of the final payment if n is * changed to 360. The final payment will be equal to the regular payment plus * any balance, future value, remaining at the end of period number 360. * <>n=360 * 360.00 * <>FV * -108.87 * <>pmt+fv * -1,234.62 * * Using the data from this loan, compute the amortization schedule * when the Effective date of the loan is June 6, 1996 and the * initial payment is made on August 1, 1996. Ignore any change in * the PV due to the delayed initial payment caused by the partial * payment period from June 6 to July 1. * * <>ED = 06/06/1996 * Effective Date set: 06/06/1996 ( 2450241 ) * <>IP = 08/01/1996 * Initial Payment Date set: 08/01/1996 ( 2450297 ) * <>a * Effective Date: 06/06/96 * Initial Payment Date: 08/01/96 * The amortization options are: * The Old Present Value (pv) was: 100,000.00 * The Old Periodic Payment (pmt) was: -1,125.75 * The Old Future Value (fv) was: -108.87 * 1: Amortize with Original Transaction Values * and balloon final payment: -1,125.75 * * The New Present Value (pve) is: 100,919.30 * The New Periodic Payment (pmt) is: -1,136.10 * 2: Amortize with Original Periodic Payment * and balloon final payment: -49,023.68 * 3: Amortize with New Periodic Payment * and balloon final payment: -1,132.57 * 4: Amortize with Original Periodic Payment, * new number of total payments (n): 417 * and final payment: -2,090.27 * * Enter choice 1, 2, 3 or 4: <> * * Press '1' * Amortization Schedule: * Yearly, y, per Payment, p, or Advanced Payment, a, Amortization * Enter choice y, p or a: * <> * * Press 'y' * Enter Filename for Amortization Schedule. * (null string uses Standard Output): * Press enter to display output on screen * * Amortization Table * Effective Date: Thu Jun 06 00:00:00 1996 * Initial Payment Date: Thu Aug 01 00:00:00 1996 * Compounding Frequency per year: 12 * Payment Frequency per year: 12 * Compounding: Discrete * Payments: End of Period * Payments (359): -1,125.75 * Final payment: -1,125.75 * Nominal Annual Interest Rate: 13.25 * Effective Interest Rate Per Payment Period: 0.0110417 * Present Value: 100,000.00 * Year Interest Ending Balance * 1996 -5,518.42 -99,889.67 * 1997 -13,218.14 -99,598.81 * 1998 -13,177.17 -99,266.98 * 1999 -13,130.43 -98,888.41 * 2000 -13,077.11 -98,456.52 * 2001 -13,016.28 -97,963.80 * 2002 -12,946.88 -97,401.68 * 2003 -12,867.70 -96,760.38 * 2004 -12,777.38 -96,028.76 * 2005 -12,674.33 -95,194.09 * 2006 -12,556.76 -94,241.85 * 2007 -12,422.64 -93,155.49 * 2008 -12,269.63 -91,916.12 * 2009 -12,095.06 -90,502.18 * 2010 -11,895.91 -88,889.09 * 2011 -11,668.70 -87,048.79 * 2012 -11,409.50 -84,949.29 * 2013 -11,113.78 -82,554.07 * 2014 -10,776.41 -79,821.48 * 2015 -10,391.53 -76,704.01 * 2016 -9,952.43 -73,147.44 * 2017 -9,451.49 -69,089.93 * 2018 -8,879.99 -64,460.92 * 2019 -8,227.99 -59,179.91 * 2020 -7,484.16 -53,155.07 * 2021 -6,635.56 -46,281.63 * 2022 -5,667.43 -38,440.06 * 2023 -4,562.94 -29,494.00 * 2024 -3,302.89 -19,287.89 * 2025 -1,865.36 -7,644.25 * 2026 -236.00 -108.87 * * Total Interest: -305,270.00 * * NOTE: The amortization table leaves the FV as it was when the amortization * function was entered. Thus, a balance of 108.87 is due at the end of the * table. To completely pay the loan, set fv to 0.0: * <>fv=0 * 0.0 * <>a * Effective Date: 06/06/96 * Initial Payment Date: 08/01/96 * The amortization options are: * The Old Present Value (pv) was: 100,000.00 * The Old Periodic Payment (pmt) was: -1,125.75 * The Old Future Value (fv) was: 0.00 * 1: Amortize with Original Transaction Values * and balloon final payment: -1,234.62 * * The New Present Value (pve) is: 100,919.30 * The New Periodic Payment (pmt) is: -1,136.12 * 2: Amortize with Original Periodic Payment * and balloon final payment: -49,132.55 * 3: Amortize with New Periodic Payment * and balloon final payment: -1,148.90 * 4: Amortize with Original Periodic Payment, * new number of total payments (n): 417 * and final payment: -2,199.14 * * Enter choice 1, 2, 3 or 4: <> * Press '1' * Amortization Schedule: * Yearly, y, per Payment, p, or Advanced Payment, a, Amortization * Enter choice y, p or a: * <> * Press 'y' * Enter Filename for Amortization Schedule. * (null string uses Standard Output): * Press enter to display output on screen * * Amortization Table * Effective Date: Thu Jun 06 00:00:00 1996 * Initial Payment Date: Thu Aug 01 00:00:00 1996 * Compounding Frequency per year: 12 * Payment Frequency per year: 12 * Compounding: Discrete * Payments: End of Period * Payments (359): -1,125.75 * Final payment: -1,234.62 * Nominal Annual Interest Rate: 13.25 * Effective Interest Rate Per Payment Period: 0.0110417 * Present Value: 100,000.00 * Year Interest Ending Balance * 1996 -5,518.42 -99,889.67 * 1997 -13,218.14 -99,598.81 * 1998 -13,177.17 -99,266.98 * 1999 -13,130.43 -98,888.41 * 2000 -13,077.11 -98,456.52 * 2001 -13,016.28 -97,963.80 * 2002 -12,946.88 -97,401.68 * 2003 -12,867.70 -96,760.38 * 2004 -12,777.38 -96,028.76 * 2005 -12,674.33 -95,194.09 * 2006 -12,556.76 -94,241.85 * 2007 -12,422.64 -93,155.49 * 2008 -12,269.63 -91,916.12 * 2009 -12,095.06 -90,502.18 * 2010 -11,895.91 -88,889.09 * 2011 -11,668.70 -87,048.79 * 2012 -11,409.50 -84,949.29 * 2013 -11,113.78 -82,554.07 * 2014 -10,776.41 -79,821.48 * 2015 -10,391.53 -76,704.01 * 2016 -9,952.43 -73,147.44 * 2017 -9,451.49 -69,089.93 * 2018 -8,879.99 -64,460.92 * 2019 -8,227.99 -59,179.91 * 2020 -7,484.16 -53,155.07 * 2021 -6,635.56 -46,281.63 * 2022 -5,667.43 -38,440.06 * 2023 -4,562.94 -29,494.00 * 2024 -3,302.89 -19,287.89 * 2025 -1,865.36 -7,644.25 * 2026 -344.87 0.00 * * Total Interest: -305,378.87 * * Example 6: Balloon Payment * On long term loans, small changes in the periodic payments can generate * large changes in the future value. If the monthly payment in example 5 is * rounded down to $1125, how much additional (balloon) payment will be due * with the final regular payment. * <>pmt=-1125 * -1,125 * <>FV * -3,579.99 * * Example 7: Canadian Mortgage * Find the monthly end-of-period payment necessary to fully amortize a 25 year * $85,000 loan at 11% compounded semi-annually. * <>d * <>CF=2 * 2.00 * <>n=300 * 300.00 * <>i=11 * 11.00 * <>pv=85000 * 85,000.00 * <>PMT * -818.15 * * Example 8: European Mortgage * The "effective annual rate (EAR)" is used in some countries (especially * in Europe) in lieu of the nominal rate commonly used in the United States * and Canada. For a 30 year $90,000 mortgage at 14% (EAR), compute the monthly * end-of-period payments. When using an EAR, the compounding frequency is * set to 1. * <>d * <>CF=1 * 1.00 * <>n=30*12 * 360.00 * <>i=14 * 14.00 * <>pv=90000 * 90,000.00 * <>PMT * -1,007.88 * * Example 9: Bi-weekly Savings * Compute the future value, fv, of bi-weekly savings of $100 for 3 years at a * nominal annual rate of 5.5% compounded daily. (Set payment to * beginning-of-period, bep = TRUE) * <>d * <>bep=TRUE * 1.00 * <>CF=365 * 365.00 * <>PF=26 * 26.00 * <>n=3*26 * 78.00 * <>i=5.5 * 5.50 * <>pmt=-100 * -100.00 * <>FV * 8,489.32 * * Example 10: Present Value - Annuity Due * What is the present value of $500 to be received at the beginning of each * quarter over a 10 year period if money is being discounted at 10% nominal * annual rate compounded monthly? * <>d * <>bep=TRUE * 1.00 * <>PF=4 * 4.00 * <>n=4*10 * 40.00 * <>i=10 * 10.00 * <>pmt=500 * 500.00 * <>PV * -12,822.64 * * Example 11: Effective Rate - 365/360 Basis * Compute the effective annual rate (%APR) for a nominal annual rate of 12% * compounded on a 365/360 basis used by some Savings & Loan Associations. * <>d * <>n=365 * 365.00 * <>CF=365 * 365.00 * <>PF=360 * 360.00 * <>i=12 * 12.00 * <>pv=-100 * -100.00 * <>FV * 112.94 * <>fv+pv * 12.94 * * Example 12: Mortgage with "Points" * * What is the true APR of a 30 year, $75,000 loan at a nominal rate * of 13.25% compounded monthly, with monthly end-of-period payments, * if 3 "points" are charged? The pv must be reduced by the dollar * value of the points and/or any lenders fees to establish an * effective pv. Because payments remain the same, the true APR will * be higher than the nominal rate. Note, first compute the payments * on the pv of the loan amount. * * <>d * <>CF=PF=1 * 1.00 * <>n=30*12 * 360.00 * <>i=13.25/12 * 1.10 * <>pv=75000 * 75,000.00 * <>PMT * -844.33 * <>pv -= pv*.03 * 72,750.00 * <>CF=PF=12 * 12.00 * <>I * 13.69 * * Example 13: Equivalent Payments * Find the equivalent monthly payment required to amortize a 20 year $40,000 * loan at 10.5% nominal annual rate compounded monthly, with 10 annual * payments of $5029.71 remaining. Compute the pv of the remaining annual * payments, then change n, the number of periods, and the payment frequency, * PF, to a monthly basis and compute the equivalent monthly pmt. * <>d * <>PF=1 * 1.00 * <>n=10 * 10.00 * <>i=10.5 * 10.50 * <>pmt=-5029.71 * -5,029.71 * <>PV * 29,595.88 * <>PF=12 * 12.00 * <>n=120 * 120.00 * <>PMT * -399.35 * * Example 14: Perpetuity - Continuous Compounding * If you can purchase a single payment annuity with an initial investment of * $60,000 that will be invested at 15% nominal annual rate compounded * continuously, what is the maximum monthly return you can receive without * reducing the $60,000 principal? If the principal is not disturbed, the * payments can go on indefinitely (a perpetuity). Note that the term,n, of * a perpetuity is immaterial. It can be any non-zero value. * <>d * <>disc=FALSE * 0.00 * <>n=12 * 12.00 * <>CF=1 * 1.00 * <>i=15 * 15.00 * <>fv=60000 * 60,000.00 * <>pv=-60000 * -60,000.00 * <>PMT * 754.71 * * references: * 1. PPC ROM User's Manual * pages 148 - 164 * */ #include <time.h> #include <stdio.h> #include <glib.h> #include <math.h> #if defined(G_OS_WIN32) && !defined(_MSC_VER) #include <pow.h> #endif #include <string.h> #include <stdlib.h> #define FIN_STATICS #include "finvar.h" #include "finproto.h" #include "fin_static_proto.h" /* return 'x' rounded to 'places' past decimal if 'places' < 0, return * 'x' */ static double rnd (double x, unsigned places) { static const size_t buflen = 50; /* make buffer large enough */ double r; char buf[buflen]; snprintf (buf, buflen, "%.*f", (int) places, x); r = strtod(buf, NULL); return r; } /* rnd */ /* return absolute value of 'x' this function is provided by a macro * in C */ static double dabs (double x) { return (x >= 0.0) ? x : -x; } /* dabs */ /* Compute constant used in calculations */ static double _A (double eint, unsigned per) { return pow ((1.0 + eint), (double) per) - 1.0; } /* _A */ /* Compute constant used in calculations */ static double _B (double eint, unsigned beg) { /* if eint == 0.0, all processing _must_ stop or a recursive loop will start. */ g_return_val_if_fail(eint != 0.0, 0.0); return (1.0 + eint * (double) beg) / eint; } /* _B */ /* Compute constant used in calculations */ static double _C (double eint, double pmt, unsigned beg) { g_return_val_if_fail(eint != 0.0, 0.0); return pmt * _B(eint, beg); } /* _C */ /* compute Number of Periods from preset data */ unsigned fi_calc_num_payments (fi_ptr fi) { return fi->npp = (unsigned) rnd (_fi_calc_num_payments (fi->ir, fi->pv, fi->pmt, fi->fv, fi->CF, fi->PF, fi->disc, fi->bep), 0); } /* fi_calc_num_payments */ /* Compute number of periods from: * 1. Nominal Interest * 2. Present Value * 3. Periodic Payment * 4. Future Value */ double _fi_calc_num_payments (double nint, /* nominal interest rate */ double pv, /* present value */ double pmt, /* periodic payment */ double fv, /* future value */ unsigned CF, /* compounding frequency */ unsigned PF, /* payment frequency */ unsigned disc, /* discrete/continuous compounding */ unsigned bep) /* beginning/end of period payment */ { double eint = eff_int (nint / 100.0, CF, PF, disc); double CC = _C (eint, pmt, bep); CC = (CC - fv) / (CC + pv); return (CC > 0.0) ? log (CC) / log (1.0 + eint) : 0.0; } /* _fi_calc_num_payments */ /* compute Interest from preset data */ double fi_calc_interest (fi_ptr fi) { if (fi->npp) fi->ir = _fi_calc_interest (fi->npp, fi->pv, fi->pmt, fi->fv, fi->CF, fi->PF, fi->disc, fi->bep); return fi->ir; } /* fi_calc_interest */ double ratio = 1e4; /* ratio used in iterative solution for interest */ /* Compute Nominal Interest from: * 1. Number of periods * 2. Present Value * 3. Periodic Payment * 4. Future Value */ double _fi_calc_interest (unsigned per,/* number of periods */ double pv, /* present value */ double pmt, /* periodic payment */ double fv, /* future value */ unsigned CF, /* compounding frequency */ unsigned PF, /* payment frequency */ unsigned disc, /* discrete/continuous compounding */ unsigned bep) /* beginning/end of period payment */ { double eint; double a, dik; int ri; if (pmt == 0.0) eint = pow ((dabs (fv) / dabs (pv)), (1.0 / (double) per)) - 1.0; else { if ((pmt * fv) < 0.0) { if (pv) a = -1.0; else a = 1.0; eint = dabs ((fv + a * (double) per * pmt) / (3.0 * (((double) per - 1.0) * ((double) per - 1.0) * pmt + pv - fv))); } else { if ((pv * pmt) < 0.0) { eint = dabs (((double) per * pmt + pv + fv) / ((double) per * pv)); } else { a = dabs (pmt / (dabs (pv) + dabs (fv))); eint = a + 1.0 / (a * (double) per * (double) per * (double) per); } } do { dik = fi (per, eint, pv, pmt, fv, bep) / fip (per, eint, pv, pmt, fv, bep); eint -= dik; (void) modf (ratio * (dik / eint), &a); ri = (unsigned) a; } while (ri); } /* endif */ return 100.0 * nom_int (eint, CF, PF, disc); } /* _fi_calc_interest */ /* compute Present value from preset data */ double fi_calc_present_value (fi_ptr fi) { return fi->pv = rnd (_fi_calc_present_value (fi->npp, fi->ir, fi->pmt, fi->fv, fi->CF, fi->PF, fi->disc, fi->bep), fi->prec); } /* fi_calc_present_value */ /* Compute Present Value from: * 1. Number of periods * 2. Nominal Interest * 3. Periodic Payment * 4. Future Value */ double _fi_calc_present_value (unsigned per, /* number of periods */ double nint, /* nominal interest rate */ double pmt, /* periodic payment */ double fv, /* future value */ unsigned CF, /* compounding frequency */ unsigned PF, /* payment frequency */ unsigned disc, /* discrete/continuous compounding */ unsigned bep) /* beginning/end of period payment */ { double eint = eff_int (nint / 100.0, CF, PF, disc); double AA = _A (eint, per); double CC = _C (eint, pmt, bep); return -(fv + (AA * CC)) / (AA + 1.0); } /* _fi_calc_present_value */ /* compute Periodic Payment from preset data */ double fi_calc_payment (fi_ptr fi) { return fi->pmt = rnd (_fi_calc_payment (fi->npp, fi->ir, fi->pv, fi->fv, fi->CF, fi->PF, fi->disc, fi->bep), fi->prec); } /* fi_calc_payment */ /* Compute Periodic Payment from: * 1. Number of periods * 2. Nominal Interest * 3. Present Value * 4. Future Value */ double _fi_calc_payment (unsigned per, /* number of periods */ double nint, /* nominal interest rate */ double pv, /* present value */ double fv, /* future value */ unsigned CF, /* compounding frequency */ unsigned PF, /* payment frequency */ unsigned disc,/* discrete/continuous compounding */ unsigned bep) /* beginning/end of period payment */ { double eint = eff_int (nint / 100.0, CF, PF, disc); double AA = _A (eint, per); double BB = _B (eint, bep); g_return_val_if_fail(BB != 0.0, 0.0); return -(fv + pv * (AA + 1.0)) / (AA * BB); } /* _fi_calc_payment */ /* compute Future Value from preset data */ double fi_calc_future_value (fi_ptr fi) { return fi->fv = rnd (_fi_calc_future_value (fi->npp, fi->ir, fi->pv, fi->pmt, fi->CF, fi->PF, fi->disc, fi->bep), fi->prec); } /* fi_calc_future_value */ /* Compute Future Value from: * 1. Number of periods * 2. Nominal Interest * 3. Present Value * 4. Periodic Payments */ double _fi_calc_future_value (unsigned per, /* number of periods */ double nint, /* nominal interest rate */ double pv, /* present value */ double pmt, /* periodic payment */ unsigned CF, /* compounding frequency */ unsigned PF, /* payment frequency */ unsigned disc, /* discrete/continuous compounding */ unsigned bep) /* beginning/end of period payment */ { double eint = eff_int (nint / 100.0, CF, PF, disc); double AA = _A (eint, per); double CC = _C (eint, pmt, bep); return -(pv + AA * (pv + CC)); } /* _fi_calc_future_value */ /* compute Nominal Interest Rate from Effective Interest Rate */ static double nom_int (double eint, unsigned CF, unsigned PF, unsigned disc) { double nint; if (disc) { if (CF == PF) { nint = CF * eint; } else { nint = CF * (pow ((1.0 + eint), ((double) PF / (double) CF)) - 1.0); } /* * endif */ } else nint = log (pow (1.0 + eint, PF)); return nint; } /* nom_int */ /* Compute Effective Interest Rate from Nominal Interest Rate */ static double eff_int (double nint, unsigned CF, unsigned PF, unsigned disc) { double eint; if (disc) { if (CF == PF) { eint = nint / (double) CF; } else { eint = pow ((1.0 + nint / (double) CF), ((double) CF / (double) PF)) - 1.0; } /* endif */ } else eint = exp (nint / (double) PF) - 1.0; return eint; } /* eff_int */ /* calculation used in interest computation */ static double fi (unsigned per, double eint, double pv, double pmt, double fv, unsigned bep) { return _A (eint, per) * (pv + _C (eint, pmt, bep)) + pv + fv; } /* fi */ /* calculation used in interest computation */ static double fip (unsigned per, double eint, double pv, double pmt, double fv, unsigned bep) { double AA = _A (eint, per); double CC = _C (eint, pmt, bep); double D = (AA + 1.0) / (1.0 + eint); g_return_val_if_fail(CC != 0.0, 0.0); return (double) per * (pv + CC) * D - (AA * CC) / eint; } /* fip */ void set_default (fi_ptr fi) { /* flag whether accrueing interest at beginning or end of period * FALSE --> end * TRUE --> beginning * default to end of period payment s */ fi->bep = FALSE; /* flag for discrete or continuous interest * TRUE --> discrete * FALSE --> continuous * default to discrete interest */ fi->disc = TRUE; /* set compounding, CF, and payment, PF, frequency per year * default to monthly payments and compounding */ fi->CF = fi->PF = 12; /* standard loan quantities: * number of periods: n */ fi->npp = 0; /* annual interest: i */ fi->ir = 0.0; /* Present Value: pv */ fi->pv = 0.0; /* Payment: pmt */ fi->pmt = 0.0; /* Future Value: fv */ fi->fv = 0.0; } /* set_default */ /* compute Julian Day Number from calendar date */ unsigned long julian_day_number (unsigned year, unsigned month, unsigned day) { /* Gregorian/Julian Calendar Flag. * TRUE == Julian * FALSE == Gregorian */ unsigned gregorian = TRUE; /* assume we are dealing with current dates */ double yr; double pfac = 0.6; unsigned long ljdn; yr = year + (month - 3.0) / 12.0; ljdn = (long) (367.0 * yr + pfac) - (2 * (long) (yr)) + (long) (yr / 4.0) + (long) day + 1721117L; if (gregorian) ljdn += -(long) (yr / 100.0) + (long) (yr / 400.0) + 2; return ljdn; } /* julian_day_number */ amort_sched_ptr Amortization_init (amort_sched_ptr amortsched) { unsigned n = amortsched->n; double nint = amortsched->nint; double pv = amortsched->pv; double pmt = amortsched->pmt; double fv = amortsched->fv; double eint; double new_pmt; double pve; unsigned CF = amortsched->CF; unsigned PF = amortsched->PF; unsigned disc = amortsched->disc; unsigned bep = amortsched->bep; unsigned new_n; unsigned prec = amortsched->prec; unsigned long s, d, days_to_yr_end, Eff_Date_jdn = julian_day_number (amortsched->year_E, amortsched->month_E, amortsched->day_E), Init_Date_jdn = julian_day_number (amortsched->year_I, amortsched->month_I, amortsched->day_I); amortsched->Eff_Date_jdn = Eff_Date_jdn; amortsched->Init_Date_jdn = Init_Date_jdn; amortsched->yday_E = Eff_Date_jdn - julian_day_number (amortsched->year_E, 1, 1); amortsched->yday_I = Init_Date_jdn - julian_day_number (amortsched->year_I, 1, 1); amortsched->eint = eint = eff_int (nint / 100.0, CF, PF, disc); amortsched->fv_case = dabs (fv) > dabs (pv); amortsched->bp = bep ? 1.0 : 0.0; if (PF > 24) { /* Payment frequency per year greater than bi-monthly * use actual number of days */ s = Init_Date_jdn - Eff_Date_jdn; days_to_yr_end = julian_day_number (amortsched->year_I + 1, 1, 0) - Init_Date_jdn; d = 366 / PF; } else { /* Payment frequency per year bi-monthly or less * use 30 days/month, 360 days/year */ if (Eff_Date_jdn == Init_Date_jdn) { s = 0; } else { s = ((amortsched->year_I - amortsched->year_E) * 360) + ((amortsched->month_I - amortsched->month_E) * 30) + amortsched->day_I - amortsched->day_E; } /* endif */ days_to_yr_end = 390 - (amortsched->month_I * 30) - amortsched->day_I; d = 360 / PF; } /* endif */ if (!bep) { /* ordinary annuity */ s -= d; } /* endif */ amortsched->yr_pmt = (days_to_yr_end + d) / d; if (pmt == 0.0) { amortsched->pve = pv; } else { amortsched->pve = rnd (pv * pow ((1.0 + eint), ((double) (s * PF) / (double) (d * CF))), prec); } /* endif */ pve = amortsched->pve; /* compute new data to fully amortize loan: * new periodic payment, new_pmt * * option 1: Amortize with original transaction - ignore interest * due to delayed initial payment * * option 2: Amortize with new pv, pve == original pv adjusted for * delayed initial payment, original payment, original fv and * original total number of payments, adjust final payment * * option 3: amortize with new pv, pve, and new payments adjusted to * minimize final payment, keep original number of payments and * original fv * * option 4: amortize with new pv, pve, original payments and new * number of payments to keep original final fv */ /* option 3, compute new periodic payment */ amortsched->new_pmt = new_pmt = rnd (_fi_calc_payment (n, nint, pve, fv, CF, PF, disc, bep), prec); /* option 4: compute new number of total payments, new_n */ amortsched->new_n = new_n = (unsigned) rnd (_fi_calc_num_payments (nint, pve, pmt, fv, CF, PF, disc, bep), 0); /* following used in QTAwk to insure integer value, not needed in C */ /* n = int(n); */ /* compute payment for constant payment to principal loan and final * payment for original loan amount include interest due */ amortsched->cpmt1 = rnd (-pv / n, prec); amortsched->final_pmt_opt_1 = -pv - amortsched->cpmt1 * (n - 1); amortsched->final_pmt_opt_1 *= eint + 1; /* compute payment for constant payment to principal loan and final * payment for delayed loan amount include interest due */ amortsched->cpmt2 = rnd (-pve / n, prec); amortsched->final_pmt_opt_2 = -pve - amortsched->cpmt2 * (n - 1); amortsched->final_pmt_opt_2 *= eint + 1; if (bep) { amortsched->final_pmt_opt_3 = rnd (_fi_calc_future_value (n - 1, nint, pv, pmt, CF, PF, disc, bep) - (fv / (1.0 + eint)), prec); amortsched->final_pmt_opt_4 = rnd (_fi_calc_future_value (n - 1, nint, pve, pmt, CF, PF, disc, bep) - (fv / (1.0 + eint)), prec); amortsched->final_pmt_opt_5 = rnd (_fi_calc_future_value (n - 1, nint, pve, new_pmt, CF, PF, disc, bep) - (fv / (1.0 + eint)), prec); if (new_n) amortsched->final_pmt_opt_6 = rnd (_fi_calc_future_value (new_n - 1, nint, pve, pmt, CF, PF, disc, bep) - (fv / (1.0 + eint)), prec); else amortsched->final_pmt_opt_6 = 0.0; } else { amortsched->final_pmt_opt_3 = rnd (_fi_calc_future_value (n - 1, nint, pv, pmt, CF, PF, disc, bep) * (1.0 + eint) - fv, prec); amortsched->final_pmt_opt_4 = rnd (_fi_calc_future_value (n - 1, nint, pve, pmt, CF, PF, disc, bep) * (1.0 + eint) - fv, prec); amortsched->final_pmt_opt_5 = rnd (_fi_calc_future_value (n - 1, nint, pve, new_pmt, CF, PF, disc, bep) * (1.0 + eint) - fv, prec); if (new_n) amortsched->final_pmt_opt_6 = rnd (_fi_calc_future_value (new_n - 1, nint, pve, pmt, CF, PF, disc, bep) * (1.0 + eint) - fv, prec); else amortsched->final_pmt_opt_6 = 0.0; } /* endif */ /* compute delayed interest */ amortsched->delayed_int = pv - amortsched->pve; return amortsched; } /* Amortization_init */ amort_sched_ptr Amortization_Schedule (amort_sched_ptr amortsched) { unsigned n = amortsched->n; double nint = amortsched->nint; double pv = amortsched->pv; double pmt = amortsched->pmt; double fv = amortsched->fv; double eint = amortsched->eint; unsigned CF = amortsched->CF; unsigned PF = amortsched->PF; unsigned disc = amortsched->disc; unsigned bep = amortsched->bep; double cpmt = 0; double final_pmt = 0; char summary = amortsched->summary; unsigned option = amortsched->option; unsigned yr_pmt = amortsched->yr_pmt; unsigned fv_case = amortsched->fv_case; unsigned prec = amortsched->prec; unsigned j, s, yr, per_cnt, pmt_cnt = 0, k = 0, sum_prt; int jj; unsigned long d; double yr_fv, sum_int, yr_int, prin, adv_pmt, pmt_int, hpv = 0.0; yearly_summary_ptr yrly_sum; amort_sched_yr_ptr amortyr; sched_pmt_ptr pmtsched = NULL; sum_int = yr_int = 0.0; switch (option) { case 1: amortsched->cpmt = cpmt = amortsched->cpmt1; /* re-compute final payment without interest */ amortsched->final_pmt = final_pmt = -pv - cpmt * (n - 1); summary = (summary == 'y') ? 'x' : 'o'; break; case 2: amortsched->cpmt = cpmt = amortsched->cpmt2; pv = amortsched->pve; /* re-compute final payment without interest */ amortsched->final_pmt = final_pmt = -pv - cpmt * (n - 1); summary = (summary == 'y') ? 'x' : 'o'; break; case 3: amortsched->final_pmt = final_pmt = amortsched->final_pmt_opt_3; break; case 4: pv = amortsched->pve; amortsched->final_pmt = final_pmt = amortsched->final_pmt_opt_4; break; case 5: pv = amortsched->pve; pmt = amortsched->new_pmt; amortsched->final_pmt = final_pmt = amortsched->final_pmt_opt_5; break; case 6: n = amortsched->new_n; pv = amortsched->pve; amortsched->final_pmt = final_pmt = amortsched->final_pmt_opt_6; break; } /* endswitch */ yr = amortsched->year_I; sum_prt = TRUE; switch (summary) { case 'a': /* variable advanced prepayment schedule. prepayment equals next * period principal. */ amortsched->schedule.first_yr = amortyr = (amort_sched_yr_ptr) calloc (1, sizeof (amort_sched_yr)); for (per_cnt = 0, s = 1, j = n; pv != fv; j -= 2, per_cnt++) { /* basic equation to compute interest this payment period */ pmt_int = -rnd ((pv + (amortsched->bp * pmt)) * eint, prec); /* sum yearly interest paid */ yr_int += pmt_int; /* sum total interest paid */ sum_int += pmt_int; /* compute principal paid this payment period and round to nearest cent */ if (dabs (pmt) > dabs (pv)) { prin = -pv; pmt = prin + pmt_int; adv_pmt = 0.0; pv = fv; } else { prin = rnd (pmt - pmt_int, prec); /* compute remaining pv and round to nearest cent */ pv = rnd (pv + prin, prec); /* compute principal for next payment cycle and round to nearest cent */ adv_pmt = rnd (pmt + (pv + (amortsched->bp * pmt)) * eint, prec); if (dabs (pv) >= dabs (adv_pmt)) { /* remaining pv greater than advanced principal payment * compute remaining pv and round to nearest cent */ pv = rnd (pv + adv_pmt, prec); } else { /* remaining pv less than advanced principal payment reduce * advanced pricipla payment to remaining pv */ adv_pmt = -pv; /* and set remaining pv to fv */ pv = fv; } /* ## endif */ } /* # endif */ if (sum_prt) { jj = (j < yr_pmt) ? j + 1 : yr_pmt; amortyr->payments = pmtsched = (sched_pmt_ptr) calloc (jj, sizeof (sched_pmt)); pmt_cnt = 0; sum_prt = FALSE; } /* endif */ pmtsched->period_num = s++; pmtsched->interest = pmt_int; pmtsched->principal = prin; pmtsched->advanced_pmt = adv_pmt; pmtsched->total_pmt = pmt + adv_pmt; pmtsched->balance = pv; pmtsched++; pmt_cnt++; if (!--yr_pmt) { yr_pmt = PF; amortyr->year = yr++; amortyr->interest_pd = yr_int; amortyr->principal_pd = pv - hpv; amortyr->yr_end_balance = pv; amortyr->total_interest_pd = sum_int; amortyr->num_periods = pmt_cnt; amortyr->next_yr = (amort_sched_yr_ptr) calloc (1, sizeof (amort_sched_yr)); amortyr = amortyr->next_yr; hpv = pv; yr_int = 0.0; sum_prt = TRUE; } /* endif */ } /* endfor */ if (dabs (pv) > 0.0) { /* basic equation to compute interest this payment period */ pmt_int = -rnd ((pv + (amortsched->bp * pmt)) * eint, prec); /* sum yearly interest paid */ yr_int += pmt_int; /* sum total interest paid */ sum_int += pmt_int; /* compute principal paid this payment period and round to nearest cent */ prin = rnd (pmt - pmt_int, prec); final_pmt = pmt; /* compute remaining pv and round to nearest cent */ pv = rnd (pv + prin, prec); /* Set advanced principal payment to remaining pv */ adv_pmt = -pv; amortyr->final_pmt = final_pmt += adv_pmt; /* and set remaining pv to fv */ pv = fv; if (pmtsched) { pmtsched->period_num = s++; pmtsched->interest = pmt_int; pmtsched->principal = prin; pmtsched->advanced_pmt = adv_pmt; pmtsched->total_pmt = final_pmt; pmtsched->balance = pv; } per_cnt++; pmt_cnt++; } /* endif */ if (dabs (yr_int) > 0.0) { amortyr->year = yr++; amortyr->interest_pd = yr_int; amortyr->principal_pd = pv - hpv; amortyr->total_interest_pd = sum_int; amortyr->num_periods = pmt_cnt; } /* endif */ amortsched->total_periods = per_cnt; break; case 'f': /* fixed prepaymet schedule prepayment specified by user */ amortsched->schedule.first_yr = amortyr = (amort_sched_yr_ptr) calloc (1, sizeof (amort_sched_yr)); /* set advnaced payment */ adv_pmt = amortsched->fixed_pmt; for (per_cnt = 0, s = 1, j = n; j && (pv != fv); j--, per_cnt++) { /* basic equation to compute interest this payment period */ pmt_int = -rnd ((pv + (amortsched->bp * pmt)) * eint, prec); /* sum yearly interest paid */ yr_int += pmt_int; /* sum total interest paid */ sum_int += pmt_int; /* compute principal paid this payment period and round to nearest cent */ if (dabs (pmt) > dabs (pv)) { prin = -pv; pmt = prin + pmt_int; adv_pmt = 0.0; pv = 0.0; } else { prin = rnd (pmt - pmt_int, prec); /* compute remaining pv and round to nearest cent */ pv = rnd (pv + prin, prec); if (dabs (pv) >= dabs (adv_pmt)) { /* remaining pv greater than advanced principal payment * compute remaining pv and round to nearest cent */ pv = rnd (pv + adv_pmt, prec); } else { /* remaining pv less than advanced principal payment reduce * advanced principal payment to remaining pv and set * remaining pv to fv */ adv_pmt = -pv; pv = fv; } /*## endif */ } /* # endif */ if (sum_prt) { jj = (j < yr_pmt) ? j + 1 : yr_pmt; amortyr->payments = pmtsched = (sched_pmt_ptr) calloc (jj, sizeof (sched_pmt)); pmt_cnt = 0; sum_prt = FALSE; } else { (amortyr->num_periods)++; } /* ## endif */ pmtsched->period_num = s++; pmtsched->interest = pmt_int; pmtsched->principal = prin; pmtsched->advanced_pmt = adv_pmt; pmtsched->total_pmt = pmt + adv_pmt; pmtsched->balance = pv; pmt_cnt++; pmtsched++; if (!--yr_pmt) { yr_pmt = PF; amortyr->year = yr++; amortyr->interest_pd = yr_int; amortyr->principal_pd = pv - hpv; amortyr->yr_end_balance = pv; amortyr->total_interest_pd = sum_int; amortyr->num_periods = pmt_cnt; amortyr->next_yr = (amort_sched_yr_ptr) calloc (1, sizeof (amort_sched_yr)); amortyr = amortyr->next_yr; hpv = pv; yr_int = 0.0; sum_prt = TRUE; } /* ## endif */ } /* ## endfor */ if (pv != fv) { /* # basic equation to compute interest this payment period */ pmt_int = -rnd ((pv + (amortsched->bp * pmt)) * eint, prec); /* # sum yearly interest paid */ yr_int += pmt_int; /* # sum total interest paid */ sum_int += pmt_int; /* # compute principal paid this payment period and round to nearest cent */ prin = rnd (pmt - pmt_int, prec); final_pmt = pmt; /* # compute remaining pv and round to nearest cent */ pv = rnd (pv + prin, prec); /* # Set advanced principal payment to remaining pv */ adv_pmt = -pv; amortyr->final_pmt = final_pmt += adv_pmt; /* # and set remaining pv to fv */ pv = fv; if (pmtsched) { pmtsched->period_num = s++; pmtsched->interest = pmt_int; pmtsched->principal = prin; pmtsched->advanced_pmt = adv_pmt; pmtsched->total_pmt = final_pmt; pmtsched->balance = pv; } per_cnt++; pmt_cnt++; } /* # endif */ if (dabs (yr_int) > 0.0) { amortyr->year = yr++; amortyr->interest_pd = yr_int; amortyr->principal_pd = pv - hpv; amortyr->total_interest_pd = sum_int; amortyr->num_periods = pmt_cnt; } /* endif */ amortsched->total_periods = per_cnt; break; case 'o': /* Constant payment to principal use constant payment equal to * original pv divided by number of periods. constant payment to * principal could be amount specified by user. */ amortsched->schedule.first_yr = amortyr = (amort_sched_yr_ptr) calloc (1, sizeof (amort_sched_yr)); amortsched->total_periods = n; d = yr_pmt; for (s = 1, j = n - 1; j; j--, k++) { pmt_int = -rnd (pv * eint, prec); /* sum yearly interest paid */ yr_int += pmt_int; /* sum total interest paid */ sum_int += pmt_int; pv = rnd (pv + cpmt, prec); if (sum_prt) { jj = (j < yr_pmt) ? j + 1 : yr_pmt; amortyr->payments = pmtsched = (sched_pmt_ptr) calloc (jj, sizeof (sched_pmt)); amortyr->num_periods = jj; k = 0; sum_prt = FALSE; } /* endif */ pmtsched->period_num = s++; pmtsched->interest = pmt_int; pmtsched->total_pmt = cpmt + pmt_int; pmtsched->balance = pv; pmtsched++; if (!--yr_pmt) { yr_pmt = PF; amortyr->year = yr++; amortyr->interest_pd = yr_int; amortyr->principal_pd = d * cpmt; amortyr->yr_end_balance = pv; amortyr->total_interest_pd = sum_int; amortyr->next_yr = (amort_sched_yr_ptr) calloc (1, sizeof (amort_sched_yr)); amortyr = amortyr->next_yr; d = PF; yr_int = 0.0; sum_prt = TRUE; } /* endif */ } /* endfor */ if (pv) { pmt_int = -rnd (pv * eint, prec); /* sum yearly interest paid */ yr_int += pmt_int; /* sum total interest paid */ sum_int += pmt_int; if (pmtsched) { pmtsched->period_num = s++; pmtsched->interest = -pmt_int; pmtsched->total_pmt = -pv + pmt_int; pmtsched->balance = 0.0; } amortyr->final_pmt = -pv - pmt_int; } /* endif */ if (dabs (yr_int) > 0.0) { amortyr->year = yr++; amortyr->interest_pd = yr_int; amortyr->principal_pd = -pv + k * cpmt; amortyr->total_interest_pd = sum_int; } /* endif */ break; case 'p': /* normal amortization schedule interest, principal and balance * per payment period */ amortsched->schedule.first_yr = amortyr = (amort_sched_yr_ptr) calloc (1, sizeof (amort_sched_yr)); amortsched->total_periods = n; hpv = pv; for (s = 1, j = n - 1; j; j--) { /* basic equation for computing interest paid in payment period */ pmt_int = -rnd ((pv + (amortsched->bp * pmt)) * eint, prec); /* sum yearly interest paid */ yr_int += pmt_int; /* sum total interest paid */ sum_int += pmt_int; /* compute principal paid this payment period */ prin = rnd (pmt - pmt_int, prec); /* compute remaining pv and round to nearest cent */ pv = rnd (pv + prin, prec); if (sum_prt) { jj = (j < yr_pmt) ? j + 1 : yr_pmt; amortyr->payments = pmtsched = (sched_pmt_ptr) calloc (jj, sizeof (sched_pmt)); amortyr->num_periods = jj; sum_prt = FALSE; } /* endif */ if (fv_case) { pmtsched->period_num = s++; pmtsched->interest = pmt_int; pmtsched->balance = pv; pmtsched++; } else { pmtsched->period_num = s++; pmtsched->interest = pmt_int; pmtsched->principal = prin; pmtsched->balance = pv; pmtsched++; } /* endif */ if (!--yr_pmt) { yr_pmt = PF; amortyr->year = yr++; amortyr->interest_pd = yr_int; if (!fv_case) { amortyr->principal_pd = pv - hpv; } /* endif */ amortyr->yr_end_balance = pv; amortyr->total_interest_pd = sum_int; amortyr->next_yr = (amort_sched_yr_ptr) calloc (1, sizeof (amort_sched_yr)); amortyr = amortyr->next_yr; hpv = pv; yr_int = 0.0; sum_prt = TRUE; } /* * endif */ } /* * endfor */ /* determine if payment due at beginning or end of period in order * to correctly compute final payment, interest and principal */ if (bep) { /* paying remainder at beginning of period compute final payment */ final_pmt = -pv - fv / (1 + eint); /* then compute interest paid with final final payment */ pmt_int = -rnd ((pv + final_pmt) * eint, prec); /* then compute the principal paid */ prin = final_pmt + pmt_int; } else { /* basic equation for computing interest paid in payment period * for payment at end of period */ pmt_int = -rnd (pv * eint, prec); /* compute principal paid this payment period */ prin = -pv; /* compute the final payment note the final payment may be * computed either of two ways both are equivalent */ final_pmt = prin + pmt_int; } /* * endif */ pv = -fv; /* sum yearly interest paid */ yr_int += pmt_int; /* sum total interest paid */ sum_int += pmt_int; if (sum_prt) { amortyr->payments = pmtsched = (sched_pmt_ptr) calloc (1, sizeof (sched_pmt)); amortyr->num_periods = 1; } /* endif */ amortyr->final_pmt = final_pmt; if (fv_case) { pmtsched->period_num = s++; pmtsched->interest = pmt_int; pmtsched->balance = pv; } else { pmtsched->period_num = s++; pmtsched->interest = pmt_int; pmtsched->principal = prin; pmtsched->balance = pv; } /* endif */ if (dabs (yr_int) > 0.0) { amortyr->year = yr++; amortyr->interest_pd = yr_int; amortyr->total_interest_pd = sum_int; if (!bep) { amortyr->principal_pd = -hpv; } /* endif */ } /* endif */ break; case 'x': /* constant payment to principal - annual summary */ /* compute number of years to summarize */ j = n / PF; if (yr_pmt < PF) j++; amortsched->total_periods = j; amortsched->schedule.summary = yrly_sum = (yearly_summary_ptr) calloc (j, sizeof (yearly_summary)); jj = 0; for (j = n, sum_prt = 0; j > 0; j -= yr_pmt, yr_pmt = PF, sum_prt++) { if (j <= PF) { s = jj + j; yr_pmt = j; yr_fv = rnd (pv + cpmt * (s - 1), prec) + final_pmt; } else { s = jj + yr_pmt; yr_fv = rnd (pv + cpmt * s, prec); } /* endif */ prin = -eint * jj * (pv + (cpmt * (jj - 1) / 2.0)); yr_int = -eint * s * (pv + (cpmt * (s - 1) / 2.0)); yr_int = rnd (yr_int - prin, prec); jj += yr_pmt; sum_int += yr_int; yrly_sum[sum_prt].year = yr++; yrly_sum[sum_prt].interest = yr_int; yrly_sum[sum_prt].end_balance = yr_fv; } /* endfor */ break; case 'y': /* normal amortization - annual summary */ /* compute number of years to summarize */ j = n / PF; if (yr_pmt < PF) j++; if (n > (j * PF)) j++; amortsched->total_periods = j; amortsched->schedule.summary = yrly_sum = (yearly_summary_ptr) calloc (j, sizeof (yearly_summary)); hpv = pv; for (jj = n, j = 0; jj > 0; jj -= yr_pmt, yr_pmt = PF, j++) { if (jj <= (int)PF) { yr_fv = fv; yr_int = rnd (((jj - 1) * pmt) + hpv + final_pmt, prec); } else { yr_fv = -rnd (_fi_calc_future_value (yr_pmt, nint, hpv, pmt, CF, PF, disc, bep), prec); yr_int = rnd ((yr_pmt * pmt) + hpv - yr_fv, prec); } /* * endif */ sum_int += yr_int; yrly_sum[j].year = yr++; yrly_sum[j].interest = yr_int; yrly_sum[j].end_balance = yr_fv; hpv = yr_fv; } /* * endfor */ break; } /* * endswitch */ amortsched->total_interest = sum_int; return amortsched; } /* Amortization_Schedule */ /* function to free dynamically allocated memory used for amortization schedule */ void Amortization_free (amort_sched_ptr amortsched) { amort_sched_yr_ptr amortyr, prst_yr; switch (amortsched->summary) { case 'a': case 'f': case 'o': case 'p': for (amortyr = amortsched->schedule.first_yr; amortyr; amortyr = prst_yr) { if (amortyr->payments) free (amortyr->payments); prst_yr = amortyr->next_yr; free (amortyr); } /* endfor */ break; case 'y': free (amortsched->schedule.summary); break; } /* endswitch */ amortsched->schedule.first_yr = NULL; } /* amort_free */
169  * ³ 1 ³ 2 ³ 3 ³ 4 ³ . ³ . ³ . ³ . ³ . ³ . ³ . ³ . ³ . ³ n
170  *
171  * PMT PMT PMT PMT PMT PMT PMT PMT PMT PMT PMT PMT PMT PMT
172  *
173  * Annuity (series of payments)
174  * Pension Fund
175  * Savings Plan
176  * Sinking Fund
177  *
178  * ****************************************************************************
179  *
180  * 3)
181  * PV
182  * ³ FV=0
183  * Period ÀÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿
184  * 1 ³ 2 ³ 3 ³ 4 ³ . ³ . ³ . ³ . ³ . ³ . ³ . ³ . ³ . ³ n ³
185  *
186  * PMT PMT PMT PMT PMT PMT PMT PMT PMT PMT PMT PMT PMT PMT
187  *
188  * Amortization
189  * Direct Reduction Loan
190  * Mortgage (fully amortized)
191  *
192  * ****************************************************************************
193  *
194  * 4)
195  * FV*
196  * PMT PMT PMT PMT PMT PMT PMT PMT PMT PMT PMT PMT PMT ³ +
197  * PMT
198  * 1 ³ 2 ³ 3 ³ 4 ³ . ³ . ³ . ³ . ³ . ³ . ³ . ³ . ³ . ³ n ³
199  * Period ÚÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÙ * ³ * * PV * * Annuity * Lease (with buy back or residual)* * Loan or Mortgage (with balloon)* * * **************************************************************************** * * First lets discuss interest before discussing the financial * equation. Most financial transactions utilize a nominal interest * rate, NAR, i.e., the interest rate per year. The NAR must be * converted to the interest rate per payment interval and the * compounding accounted for before it can be used in computing an * interest payment. After this conversion process, the interest * used is the effective interest rate, EIR. In converting NAR to * EIR, there are two concepts to discuss first, the Compounding * Frequency and the Payment Frequency and * whether the interest is * coumpounded in discrete intervals or continuously. The * compounding Frequency, CF, is simply the number of times per * year, the monies in the financial transaction are compounded. In * the U.S., monies are usually compounded daily on bank deposits, * and monthly on loans. Sometimes Long term deposits are compounded * quarterly or weekly. * * The Payment Frequency, PF, is simply how often during a year * payments are made in the transaction. Payments are usually * scheduled on a regular basis and can be made at the beginning or * end of the payment period. If made at the beginning of the * payment period, interest must be applied to the payment as well * as any previous money paid or money still owed. * * Normal values for CF and PF are: * 1 == annual * 2 == semi-annual * 3 == tri-annual * 4 == quaterly * 6 == bi-monthly * 12 == monthly * 24 == semi-monthly * 26 == bi-weekly * 52 == weekly * 360 == daily * 365 == daily * * a) the Compounding Frequency per year, CF, need not be identical * to the Payment Frequency per year, PF, and/or, * * b) Interest may be compounded in either discrete intervals or continuously * compounded. * * c) Also, payments may be made at the beginning of the payment * period or at the end of the payment period. * * CF and PF are defaulted to 1. The default is for discrete interest * intervals and payments are defaulted to the end of the payment * period. * * When a solution for n, PV, PMT or FV is required, the nominal interest * rate, i, must first be converted to the effective interest rate per payment * period. This rate, ieff, is then used to compute the selected variable. To * convert i to ieff, the following expressions are used: * * Discrete interest periods: * * 19) ieff = (1 + i/CF)^(CF/PF) - 1 * * Continuous Interest * * 20) ieff = e^(i/PF) - 1 = exp(i/PF) - 1 * * When interest is computed, the computation produces the effective interest * rate, ieff. This value must then be converted to the nominal interest rate. * Function _I below returns the nominal interest rate NOT the effective * interest rate. ieff is converted to i using the following expressions: * * Discrete Case: * * i = CF*[(1+ieff)^(PF/CF) - 1] * * Continuous Case: * * i = ln[(1+ieff)^PF] * * **************************************************************************** * * NOTE: in the equations below for the financial transaction, all * interest rates are the effective interest rate, ieff. The symbol * will be shortned to just 'i'. * * **************************************************************************** * * The basic financial equation used is: * * 1) PV*(1 + i)^n + PMT*(1 + iX)*[(1+i)^n - 1]/i + FV = 0 * Where: X = 0 for end of period payments, and * X = 1 for beginning of period payments * * **************************************************************************** * * NOTE: this equation is derived in the following manner: * * Start with the basic equation to find the balance or Present * Value, PV[1], after one payment period. Note PV[1] is the Present * value after on payment and PV[0] is the initial Present * Value. PV[0] will be shortened to just PV. * * The interest due at the end of the first payment period is: * * ID[1] = (PV + X * PMT) * i * where: X = 0 for end of period payments, and * X = 1 for beginning of period payments. * * Thus: * PV[1] = PV + (PMT + ID[1]) * = PV + (PMT + (PV + X * PMT) * i) * = PV * (1 + i) + PMT * (1 + Xi) * * This equation works for all of the money diagrams shown * above. The Present Value, money received or paid, is modified by * a payment made at the beginning of a payment period and * multiplied by the effective interest rate to compute the interest * due during the payment period. The interest due is then added to * the payment to obtain the amount to be added to the Present Value * to compute the new Present Value. * * For diagram 1): PV < 0, PMT == 0, PV[1] < 0 * For diagram 2): PV == 0, PMT < 0, PV[1] < 0 * For Diagram 3): PV > 0, PMT < 0, PV[1] >= 0 or PV[1] <= 0 * For Diagram 4): PV < 0, PMT > 0, PV[1] <= 0 or PV[1] >= 0 * * X may be 0 or 1 for any diagram. * * For the standard loan, PV is the money borrowed, PMT is the * periodic payment to repay the loan and i is the effective * interest rate agreed upon. * * To calculate the Present Value after the second payment period, * the above calculation is applied iteratively to PV_1: * * PV[2] = PV[1] + (PMT + (PV[1] + X * PMT) * i) * = PV[1] * (1 + i) + PMT * (1 + iX) * = (PV * (1 + i) + PMT * (1 + iX)) * (1 + i) + PMT * (1 + iX) * = PV * (1 + i)^2 + PMT * (1 + iX) * (1 + i) * + PMT * (1 + iX) * * Similarly: * * PV[3] = PV[2] + (PMT + (PV[2] + X * PMT) * i) * = PV[2] * (1 + i) + PMT * (1 + iX) * = PV * (1 + i)^2 + PMT * (1 + iX) * (1 + i) * + PMT * (1+ iX)) * ( 1 + i) * + PMT * (1+ iX) * = PV * (1 + i)^3 + PMT * (1 + iX) * (1 + i)^2 * + PMT * (1 + iX) * (1 + i)^2 * + PMT * (1 + iX) * (1 + i) * + PMT * (1 + iX) * * And for the n'th payment: * * PV[n] = PV[n-1] + (PMT + (PV[n-1] + X * PMT) * i) * PV[n] = PV * (1 + i)^n + PMT * (1 + iX) * (1 + i)^(n-1) * + PMT * (1 + iX) * (1 + i)^(n-2) + * . * . * . * + PMT * (1 + iX) * (1 + i) * + PMT * (1 + iX) * PV[n] = PV * (1 + i)^n + PMT * (1 + iX) * [(1 + i)^(n-1) + ... * + (1 + i) + 1] * * **************************************************************************** * * The sum of the finite series: * * 1 + k + (k^2) + (k^3) + ... + (k^n) = (1-k^(n+1))/(1-k) * * as can be seen by the following. Let S(n) be the series sum. Then * * S(n) - k * S(n) = 1 - k^(n+1) * * and solving for S(n): * * S(n) = [1-k^(n+1)]/[1-k] = 1 + k + (k^2) + (k^3) + ... + (k^n) * * **************************************************************************** * * PV[n] = PV * (1 + i)^n + PMT * (1 + iX) * [(1 + i)^(n-1) + ... * + (1 + i) + 1] * = PV * (1 + i)^n + PMT * (1 + iX) * [1 - (1 + i)^n]/[1 - (1 + i)] * = PV * (1 + i)^n + PMT * (1 + iX) * [1 - (1 + i)^n]/[-i] * = PV * (1 + i)^n + PMT * (1 + iX) * [(1 + i)^n - 1]/i * * The formaula for PV[n] can be proven using mathematical induction. * * or: * * PV * (1 + i)^n + PMT * [(1 + i)^n - 1]/i - PV[n] = 0 * * If after n payments, the remaining balance is repaid as a lump * sum, the lump sum is known as the Future Value, FV[n]. Since * FV[n] is negative if paid and positive if received, FV[n] is the * negative of PV[n]. Since n is assumed to be the last payment, * FV[n] will be shortened to simply FV. * * Setting: FV = -PV[N] * * 1) PV*(1 + i)^n + PMT*(1 + iX)*[(1 + i)^n - 1]/i + FV = 0 * * Up to this point, we have said nothing about the value of * PMT. PMT can be any value mutually agreed upon by the lender and * the borrower. From the equation for PV[1]: * * PV[1] = PV + (PMT + (PV + X * PMT) * i), * * Several things can be said about PMT. * * 1. If PMT = PV * i, and X = 0 (end of period payments): * * The payment is exactly equal to the interest due and PV[1] = * PV. In this case, the borrower must make larger future * payments to reduce the balance due, or make a single payment, * after some agreed upon number of payments, with PMT = PV to * completely pay off the loan. This is an interest only payment * with a balloon payment at the end. * * 2. If PMT < PV * i, and X = 0 * * The payment is insufficient to cover even the interest charged * and the balance due grows * * 3. If PMT > PV * i, and X = 0 * * The payment is sufficient to cover the interest charged with a * residual amount to be applied to reduce the balance due. The * larger the residual amount, the faster the loan is repaid. For * most mortgages or other loans made today, the lender and * borrower agree upon a certain number of repayment periods and * the interest to be charged per payment period. The interest * may be multiplied by 12 and stated as an annual interest * rate. Then the lender and borrower want to compute a periodic * payment, PMT, which will reduce the balance due to zero after * the agreed upon number of payment have been made. If N is the * agreed upon number of periodic payments, then we want to use: * * PV * (1 + i)^N + PMT*(1 +iX)*[(1 + i)^N - 1]/i + FV = 0 * * with FV = 0 to compute PMT: * * PMT = -[PV * i * (1 + i)^(N - X)]/[(1 + i)^N - 1] * * The value of PMT computed will reduce the balance due to zero * after N periodic payments. * * **************************************************************************** * * * With a simple alegebraic re-arrangement, The financial Equation becomes: * * 2) [PV + PMT*(1 + iX)/i][(1 + i)^n - 1] + PV + FV = 0 * * or * * 3) (PV + C)*A + PV + FV = 0 * * where: * 4) A = (1 + i)^n - 1 * * 5) B = (1 + iX)/i * * 6) C = PMT*B * * The form of equation 3) simplifies the calculation procedure for all five * variables, which are readily solved as follows: * * 7) n = ln[(C - FV)/(C + PV)]/ln((1 + i) * * 8) PV = -[FV + A*C]/(A + 1) * * 9) PMT = -[FV + PV*(A + 1)]/[A*B] * * 10) FV = -[PV + A*(PV + C)] * * Equations 4), 5) and 6) are computed by functions: * * _A * _B * _C * * respectively. Equations 7), 8), 9) and 10) are computed by functions: * * _N * _PV * _PMT * _FV * * respectively. * * The solution for interest is broken into two cases: * * PMT == 0 * i = [FV/PV]^(1/n) - 1 * * PMT != 0 * * Since equation 3) cannot be solved explicitly for i in this * case, an iterative technique must be employed. Newton's * method, using exact expressions for the function of i and its * derivative, are employed. The expressions are: * * 12) i[k+1] = i[k] - f(i[k])/f'(i[k]) * where: i[k+1] == (k+1)st iteration of i * i[k] == kth iteration of i * and: * * 13) f(i) = A*(PV+C) + PV + FV * * 14) f'(i) = n*D*(PV+C) - (A*C)/i * * 15) D = (1 + i)^(n-1) = (A+1)/(1+i) * * To start the iterative solution for i, an initial guess must be made * for the value of i. The closer this guess is to the actual value, * the fewer iterations will have to be made, and the greater the * probability that the required solution will be obtained. The initial * guess for i is obtained as follows: * * if PMT*FV >= 0, then PV case * if PMT*FV < 0, then FV case * * PV case: * | n*PMT + PV + FV | * 16) i[0] = | ----------------| * | n*PV | * * = abs[(n*PMT + PV + FV)/(n*PV)] * * FV case: * a) PV != 0 * * | FV - n*PMT | * 17) i[0] = |---------------------------| * | 3*[PMT*(n-1)^2 + PV - FV] | * * = abs[(FV-n*PMT)/(3*(PMT*(n-1)^2+PV-FV))] * b) PV == 0 * * | FV + n*PMT | * 18) i[0] = |---------------------------| * | 3*[PMT*(n-1)^2 + PV - FV] | * * = abs[(FV+n*PMT)/(3*(PMT*(n-1)^2+PV-FV))] * * **************************************************************************** * Constant payment to principal loan * * In this loan, each total payment is different, with each * succeeding payment less than the preceding payment. Each payment * is the total of the constant amount to the principal plus the * interest for the period. The constant payment to the principal is * computed as: * * C = -PV / N * * Where PV is the loan amount to be repaid in N payments * (periods). Note that the constant payment to principal could be * any value agreed to by the two parties involved. * * Thus the principal after the first payment is: * PV[1] = PV[0] + C = PV + C * after the second payment, the principal is: * PV[2] = PV[1] + C = PV[0] + 2C * In general, the remaining principal after n payments is: * PV[n] = PV[0] + nC = PV + nC * * If the effective interest per payment period is i, then the * interest for the first payment is: * * I[1] = -i*PV[0] = -i*PV * and for the second: * I[2] = -i * PV[1] * and in general, for the n'th payment the interest is: * I[n] = -i * PV[n-1] * = -i * (PV + (n-1)C) * The total payment for any period, n, is: * P[n] = C + I[n] * = C + i * (PV + (n-1)C) * = C(1 + i) - i * (PV + nC) * The total interest paid to period n is: * T[n] = I[1] + I[2] + I[3] + ... + I[n] * T[n] = sum(j = 1 to n: I[j]) * T[n] = sum(j = 1 to n: -i * (PV + (j-1)C)) * T[n] = sum(j=1 to n: -i*PV) + sum(j=1 to n: iC) + sum(j=1 to n: -iCj) * T[n] = -i*n*PV + i*n*C - i*C*sum(j=1 to n:j) * sum(j=1 to n:j) = n(n+1)/2 * T[n] = -i*n*(PV + C) - i*C*n(n+1)/2 * T[n] = -i*n*(PV + (C*(n - 1)/2)) * * Note: substituting for C = -PV/N, in the equations for PV[n], I[n], * P[n], and T[n] would give the following equations: * * PV[n] = PV*(1 - n/N) * I[n] = -i*PV*(1 + N - n)/N * P[n] = -i*PV*(2 + N - n)/N * T[n] = -i*n*PV*(2*N - n + 1)/(2*N) * * Using these equations for the calculations would eliminate the * dependence on C, but only if C is always defined as above and * would eliminate the possibility of another value for C. If the * value of C was less than -PV/N then a balloon payment would be * due at the final payment and this is a possible alternative for * some people. * * **************************************************************************** * * Amortization Schedules. * * Financial Transactions have an effective Date, ED, and an Initial Payment * Date, IP. ED may or may not be the same as IP, but IP is always the same * or later than ED. Most financial transaction calculators assume that * IP is equal to ED for beginning of period payments or at the end of the * first payment period for end of period payments. * * This is not always true. IP may be delayed for financial reasons * such as cash flow or accounting calendar. The subsequent payments * then follow the agreed upon periodicity. Since money has a time * value, the "delayed" IP must be accounted for. Computing an * "Effective PV", pve, is one means of handling a delayed IP. * * EDj == the Julian Day Number of ED, and * IPj == the Julian Day Number of IP in the following. * * pve is be computed as: * * pve = pv*(1 + i)^(s*PF/d*CF) * * Where: d = length of the payment period in days, and * s = IPj - EDj - d*X * * Computing an amortization Schedule for a given financial transaction is * simply applying the basic equation iteratively for each payment period: * * PV[n] = PV[n-1] + (PMT + (PV[n-1] + X * PMT) * i) * * At the end of each iteration, PV[n] is rounded to the nearest cent. For * each payment period, the interest due may be computed separately as: * * ID[n] = (PMT + (PV[n-1] + X * PMT) * i) * * and rounded to the nearest cent. PV[n] then becomes: * * PV[n] = PV[n-1] + PMT + ID[n] * * For those cases where a yearly summary only is desired, it is not * necessary to compute each transaction for each payment period, * rather the PV may be computed for the beginning of each year, * PV[yr], and the FV computed for the end of the year, FV[yr]. The * interest paid during the year is the computed as: * * ID[yr] = (NP * PMT) + PV[yr] + FV[yr] * * Since the final payment may not be equal to the periodic payment, * the final payment must be computed separately as follows. Two * derivations are given below for the final payment equation. Both * derivations are given below since one or the other may be clearer * to some readers. Both derivations are essentially the same, they * just have different starting points. The first is the fastest. * * 1) final_pmt == final payment @ payment n == int(n) * from above the basic financial equation: * PV[n] = PV[n-1]*(1 + i) + final_pmt * (1 + iX), * i == effective interest rate * * solving for final_pmt, we have: * * final_pmt * (1 + iX) = PV[n] - PV[n-1]*(1 + i) * = FV[n-1]*(1 + i) - FV[n] * final_pmt = FV[n-1]*(1+i)/(1 + iX) - FV[n]/(1 + iX) * * final_pmt = FV[n-1]*(1 + i) - FV[n], * for X == 0, end of period payments * * = FV[n-1] - FV[n]/(1 + i), * for X == 1, beginning of period payments * * 2) final_pmt == final payment @ payment n == int(n) * i[n] == interest due @ payment n * i[n] = (PV[n-1] + X * final_pmt) * i, i == effective interest rate * = (X * final_pmt - FV[n]) * i * * Now the final payment is the sum of the interest due, plus * the present value at the next to last payment plus any * residual future value after the last payment: * * final_pmt = -i[n] - PV[n-1] - FV[n] * = FV[n-1] - i[n] - FV[n] * = FV[n-1] - (X *final_pmt - FV[n-1])*i - FV[n] * = FV[n-1]*(1 + i) - X*final_pmt*i - FV[n] * * solving for final_pmt: * final_pmt*(1 + iX) = FV[n-1]*(1 + i) - FV[n] * final_pmt = FV[n-1]*(1 + i)/(1 + iX) - FV[n]/(1 + iX) * * final_pmt = FV[n-1]*(1 + i) - FV[n], * for X == 0, end of period payments * * = FV[n-1] - FV[n]/(1 + i), * for X == 1, beginning of period payments * *============================================================================ * * The amortization schedule is computed for four different situations: * * 1) The original financial data is used. This ignores any possible * agjustment to the Present value due to any delay in the initial * payment. This is quite common in mortgages where end of period * payments are used and the first payment is scheduled for the end * of the first whole period, i.e., any partial payment period from * ED to the beginning of the next payment period is ignored. * * 2) The original periodic payment is used, the Present Value is * adjusted for the delayed Initial Payment. The total number of * payments remains the same. The final payment is adjusted to bring * the balance into agreement with the agreed upon final Future * Value. * * 3) A new periodic payment is computed based upon the adjusted * Present Value, the agreed originally upon number of total * payments and the agreed upon Future Value. The new periodic * payments are computed to minimize the final payment in accordance * with the Future Value after the last payment. * * 4) The original periodic payment is retained and a new number of * total payments is computed based upon the adjusted Present Value * and the agreed upon Future Value. * * The amortization schedule may be computed and displayed in three manners: * * 1. The payment *, interest paid, principal paid and remaining PV * for each payment period are computed and displayed. At the end of * each year a summary is computed and displayed and the total * interest paid is displayed at the end. * * 2. A summary is computed and displayed for each year. The * interest paid during the year is computed and displayed as well * as the remaining balance at years end. The total interest paid * is displayed at the end. * * 3. An amortization schedule is computed for a common method of * advanced payment of principal is computed and displayed. In this * amortization, the principal for the next payment is computed and * added into the current payment. This method will cut the number * of total payments in half and will cut the interest paid almost * in half. For mortgages, this method of prepayment has the * advantage of keeping the total payments small during the initial * payment periods The payments grow until the last payment period * when presumably the borrower can afford larger payments. * * =========================================================================== * NOTE: For Payment Frequencies, PF, semi-monthly or less, i.e., PF * == 12 or PF == 24, a 360 day calendar year and 30 day month are * used. For Payment Frequencies, PF, greater than semi-monthly, PF * > 24, the actual number of days per year and per payment period * are used. The actual values are computed using the built-in * 'julian_day_number' function * * **************************************************************************** * * Note: in the following examples, the user input is preceded by the * prompt "<>". The result of evaluating the input expression is then * displayed. I have taken the liberty of including comments in the * example input/output sessions by preceding with ' *'. Thus, for * the line: <>n=5 *set number of periods the comment that setting the * number of periods is not really input and the true input is only: * <>n=5 * * Example 1: Simple Interest * Find annual simple interest rate (%) for an $800 loan to be repayed at the * end of one year with a single payment of $896. * <>d * <>CF=PF=1 * 1.00 * <>n=1 * 1.00 * <>pv=-800 * -800.00 * <>fv=896 * 896.00 * <>I * 12.00 * * Example 2: Compound Interest * Find the future value of $800 after one year at a nominal rate of 12% * compounded monthly. No payments are specified, so the payment frequency is * set equal to the compounding frequency at the default values. * <>d * <>n=12 * 12.00 * <>i=12 * 12.00 * <>pv=-800 * -800.00 * <>FV * 901.46 * * Example 3: Periodic Payment: * Find the monthly end-of-period payment required to fully amortize the loan * in Example 2. A fully amortized loan has a future value of zero. * <>fv=0 * 0.00 * <>PMT * 71.08 * * Example 4: Conventional Mortgage * * Find the number of monthly payments necessary to fully amortize a * loan of $100,000 at a nominal rate of 13.25% compounded monthly, if * monthly end-of-period payments of $1125.75 are made. * * <>d * <>i=13.25 * 13.25 * <>pv=100000 * 100,000.00 * <>pmt=-1125.75 * -1,125.75 * <>_N(i,pv,pmt,fv,CF,PF,disc,bep) * 360.10 * <>N * 360 * * Example 5: Final Payment * Using the data in example 4, find the amount of the final payment if n is * changed to 360. The final payment will be equal to the regular payment plus * any balance, future value, remaining at the end of period number 360. * <>n=360 * 360.00 * <>FV * -108.87 * <>pmt+fv * -1,234.62 * * Using the data from this loan, compute the amortization schedule * when the Effective date of the loan is June 6, 1996 and the * initial payment is made on August 1, 1996. Ignore any change in * the PV due to the delayed initial payment caused by the partial * payment period from June 6 to July 1. * * <>ED = 06/06/1996 * Effective Date set: 06/06/1996 ( 2450241 ) * <>IP = 08/01/1996 * Initial Payment Date set: 08/01/1996 ( 2450297 ) * <>a * Effective Date: 06/06/96 * Initial Payment Date: 08/01/96 * The amortization options are: * The Old Present Value (pv) was: 100,000.00 * The Old Periodic Payment (pmt) was: -1,125.75 * The Old Future Value (fv) was: -108.87 * 1: Amortize with Original Transaction Values * and balloon final payment: -1,125.75 * * The New Present Value (pve) is: 100,919.30 * The New Periodic Payment (pmt) is: -1,136.10 * 2: Amortize with Original Periodic Payment * and balloon final payment: -49,023.68 * 3: Amortize with New Periodic Payment * and balloon final payment: -1,132.57 * 4: Amortize with Original Periodic Payment, * new number of total payments (n): 417 * and final payment: -2,090.27 * * Enter choice 1, 2, 3 or 4: <> * * Press '1' * Amortization Schedule: * Yearly, y, per Payment, p, or Advanced Payment, a, Amortization * Enter choice y, p or a: * <> * * Press 'y' * Enter Filename for Amortization Schedule. * (null string uses Standard Output): * Press enter to display output on screen * * Amortization Table * Effective Date: Thu Jun 06 00:00:00 1996 * Initial Payment Date: Thu Aug 01 00:00:00 1996 * Compounding Frequency per year: 12 * Payment Frequency per year: 12 * Compounding: Discrete * Payments: End of Period * Payments (359): -1,125.75 * Final payment: -1,125.75 * Nominal Annual Interest Rate: 13.25 * Effective Interest Rate Per Payment Period: 0.0110417 * Present Value: 100,000.00 * Year Interest Ending Balance * 1996 -5,518.42 -99,889.67 * 1997 -13,218.14 -99,598.81 * 1998 -13,177.17 -99,266.98 * 1999 -13,130.43 -98,888.41 * 2000 -13,077.11 -98,456.52 * 2001 -13,016.28 -97,963.80 * 2002 -12,946.88 -97,401.68 * 2003 -12,867.70 -96,760.38 * 2004 -12,777.38 -96,028.76 * 2005 -12,674.33 -95,194.09 * 2006 -12,556.76 -94,241.85 * 2007 -12,422.64 -93,155.49 * 2008 -12,269.63 -91,916.12 * 2009 -12,095.06 -90,502.18 * 2010 -11,895.91 -88,889.09 * 2011 -11,668.70 -87,048.79 * 2012 -11,409.50 -84,949.29 * 2013 -11,113.78 -82,554.07 * 2014 -10,776.41 -79,821.48 * 2015 -10,391.53 -76,704.01 * 2016 -9,952.43 -73,147.44 * 2017 -9,451.49 -69,089.93 * 2018 -8,879.99 -64,460.92 * 2019 -8,227.99 -59,179.91 * 2020 -7,484.16 -53,155.07 * 2021 -6,635.56 -46,281.63 * 2022 -5,667.43 -38,440.06 * 2023 -4,562.94 -29,494.00 * 2024 -3,302.89 -19,287.89 * 2025 -1,865.36 -7,644.25 * 2026 -236.00 -108.87 * * Total Interest: -305,270.00 * * NOTE: The amortization table leaves the FV as it was when the amortization * function was entered. Thus, a balance of 108.87 is due at the end of the * table. To completely pay the loan, set fv to 0.0: * <>fv=0 * 0.0 * <>a * Effective Date: 06/06/96 * Initial Payment Date: 08/01/96 * The amortization options are: * The Old Present Value (pv) was: 100,000.00 * The Old Periodic Payment (pmt) was: -1,125.75 * The Old Future Value (fv) was: 0.00 * 1: Amortize with Original Transaction Values * and balloon final payment: -1,234.62 * * The New Present Value (pve) is: 100,919.30 * The New Periodic Payment (pmt) is: -1,136.12 * 2: Amortize with Original Periodic Payment * and balloon final payment: -49,132.55 * 3: Amortize with New Periodic Payment * and balloon final payment: -1,148.90 * 4: Amortize with Original Periodic Payment, * new number of total payments (n): 417 * and final payment: -2,199.14 * * Enter choice 1, 2, 3 or 4: <> * Press '1' * Amortization Schedule: * Yearly, y, per Payment, p, or Advanced Payment, a, Amortization * Enter choice y, p or a: * <> * Press 'y' * Enter Filename for Amortization Schedule. * (null string uses Standard Output): * Press enter to display output on screen * * Amortization Table * Effective Date: Thu Jun 06 00:00:00 1996 * Initial Payment Date: Thu Aug 01 00:00:00 1996 * Compounding Frequency per year: 12 * Payment Frequency per year: 12 * Compounding: Discrete * Payments: End of Period * Payments (359): -1,125.75 * Final payment: -1,234.62 * Nominal Annual Interest Rate: 13.25 * Effective Interest Rate Per Payment Period: 0.0110417 * Present Value: 100,000.00 * Year Interest Ending Balance * 1996 -5,518.42 -99,889.67 * 1997 -13,218.14 -99,598.81 * 1998 -13,177.17 -99,266.98 * 1999 -13,130.43 -98,888.41 * 2000 -13,077.11 -98,456.52 * 2001 -13,016.28 -97,963.80 * 2002 -12,946.88 -97,401.68 * 2003 -12,867.70 -96,760.38 * 2004 -12,777.38 -96,028.76 * 2005 -12,674.33 -95,194.09 * 2006 -12,556.76 -94,241.85 * 2007 -12,422.64 -93,155.49 * 2008 -12,269.63 -91,916.12 * 2009 -12,095.06 -90,502.18 * 2010 -11,895.91 -88,889.09 * 2011 -11,668.70 -87,048.79 * 2012 -11,409.50 -84,949.29 * 2013 -11,113.78 -82,554.07 * 2014 -10,776.41 -79,821.48 * 2015 -10,391.53 -76,704.01 * 2016 -9,952.43 -73,147.44 * 2017 -9,451.49 -69,089.93 * 2018 -8,879.99 -64,460.92 * 2019 -8,227.99 -59,179.91 * 2020 -7,484.16 -53,155.07 * 2021 -6,635.56 -46,281.63 * 2022 -5,667.43 -38,440.06 * 2023 -4,562.94 -29,494.00 * 2024 -3,302.89 -19,287.89 * 2025 -1,865.36 -7,644.25 * 2026 -344.87 0.00 * * Total Interest: -305,378.87 * * Example 6: Balloon Payment * On long term loans, small changes in the periodic payments can generate * large changes in the future value. If the monthly payment in example 5 is * rounded down to $1125, how much additional (balloon) payment will be due * with the final regular payment. * <>pmt=-1125 * -1,125 * <>FV * -3,579.99 * * Example 7: Canadian Mortgage * Find the monthly end-of-period payment necessary to fully amortize a 25 year * $85,000 loan at 11% compounded semi-annually. * <>d * <>CF=2 * 2.00 * <>n=300 * 300.00 * <>i=11 * 11.00 * <>pv=85000 * 85,000.00 * <>PMT * -818.15 * * Example 8: European Mortgage * The "effective annual rate (EAR)" is used in some countries (especially * in Europe) in lieu of the nominal rate commonly used in the United States * and Canada. For a 30 year $90,000 mortgage at 14% (EAR), compute the monthly * end-of-period payments. When using an EAR, the compounding frequency is * set to 1. * <>d * <>CF=1 * 1.00 * <>n=30*12 * 360.00 * <>i=14 * 14.00 * <>pv=90000 * 90,000.00 * <>PMT * -1,007.88 * * Example 9: Bi-weekly Savings * Compute the future value, fv, of bi-weekly savings of $100 for 3 years at a * nominal annual rate of 5.5% compounded daily. (Set payment to * beginning-of-period, bep = TRUE) * <>d * <>bep=TRUE * 1.00 * <>CF=365 * 365.00 * <>PF=26 * 26.00 * <>n=3*26 * 78.00 * <>i=5.5 * 5.50 * <>pmt=-100 * -100.00 * <>FV * 8,489.32 * * Example 10: Present Value - Annuity Due * What is the present value of $500 to be received at the beginning of each * quarter over a 10 year period if money is being discounted at 10% nominal * annual rate compounded monthly? * <>d * <>bep=TRUE * 1.00 * <>PF=4 * 4.00 * <>n=4*10 * 40.00 * <>i=10 * 10.00 * <>pmt=500 * 500.00 * <>PV * -12,822.64 * * Example 11: Effective Rate - 365/360 Basis * Compute the effective annual rate (%APR) for a nominal annual rate of 12% * compounded on a 365/360 basis used by some Savings & Loan Associations. * <>d * <>n=365 * 365.00 * <>CF=365 * 365.00 * <>PF=360 * 360.00 * <>i=12 * 12.00 * <>pv=-100 * -100.00 * <>FV * 112.94 * <>fv+pv * 12.94 * * Example 12: Mortgage with "Points" * * What is the true APR of a 30 year, $75,000 loan at a nominal rate * of 13.25% compounded monthly, with monthly end-of-period payments, * if 3 "points" are charged? The pv must be reduced by the dollar * value of the points and/or any lenders fees to establish an * effective pv. Because payments remain the same, the true APR will * be higher than the nominal rate. Note, first compute the payments * on the pv of the loan amount. * * <>d * <>CF=PF=1 * 1.00 * <>n=30*12 * 360.00 * <>i=13.25/12 * 1.10 * <>pv=75000 * 75,000.00 * <>PMT * -844.33 * <>pv -= pv*.03 * 72,750.00 * <>CF=PF=12 * 12.00 * <>I * 13.69 * * Example 13: Equivalent Payments * Find the equivalent monthly payment required to amortize a 20 year $40,000 * loan at 10.5% nominal annual rate compounded monthly, with 10 annual * payments of $5029.71 remaining. Compute the pv of the remaining annual * payments, then change n, the number of periods, and the payment frequency, * PF, to a monthly basis and compute the equivalent monthly pmt. * <>d * <>PF=1 * 1.00 * <>n=10 * 10.00 * <>i=10.5 * 10.50 * <>pmt=-5029.71 * -5,029.71 * <>PV * 29,595.88 * <>PF=12 * 12.00 * <>n=120 * 120.00 * <>PMT * -399.35 * * Example 14: Perpetuity - Continuous Compounding * If you can purchase a single payment annuity with an initial investment of * $60,000 that will be invested at 15% nominal annual rate compounded * continuously, what is the maximum monthly return you can receive without * reducing the $60,000 principal? If the principal is not disturbed, the * payments can go on indefinitely (a perpetuity). Note that the term,n, of * a perpetuity is immaterial. It can be any non-zero value. * <>d * <>disc=FALSE * 0.00 * <>n=12 * 12.00 * <>CF=1 * 1.00 * <>i=15 * 15.00 * <>fv=60000 * 60,000.00 * <>pv=-60000 * -60,000.00 * <>PMT * 754.71 * * references: * 1. PPC ROM User's Manual * pages 148 - 164 * */ #include <time.h> #include <stdio.h> #include <glib.h> #include <math.h> #if defined(G_OS_WIN32) && !defined(_MSC_VER) #include <pow.h> #endif #include <string.h> #include <stdlib.h> #define FIN_STATICS #include "finvar.h" #include "finproto.h" #include "fin_static_proto.h" /* return 'x' rounded to 'places' past decimal if 'places' < 0, return * 'x' */ static double rnd (double x, unsigned places) { static const size_t buflen = 50; /* make buffer large enough */ double r; char buf[buflen]; snprintf (buf, buflen, "%.*f", (int) places, x); r = strtod(buf, NULL); return r; } /* rnd */ /* return absolute value of 'x' this function is provided by a macro * in C */ static double dabs (double x) { return (x >= 0.0) ? x : -x; } /* dabs */ /* Compute constant used in calculations */ static double _A (double eint, unsigned per) { return pow ((1.0 + eint), (double) per) - 1.0; } /* _A */ /* Compute constant used in calculations */ static double _B (double eint, unsigned beg) { /* if eint == 0.0, all processing _must_ stop or a recursive loop will start. */ g_return_val_if_fail(eint != 0.0, 0.0); return (1.0 + eint * (double) beg) / eint; } /* _B */ /* Compute constant used in calculations */ static double _C (double eint, double pmt, unsigned beg) { g_return_val_if_fail(eint != 0.0, 0.0); return pmt * _B(eint, beg); } /* _C */ /* compute Number of Periods from preset data */ unsigned fi_calc_num_payments (fi_ptr fi) { return fi->npp = (unsigned) rnd (_fi_calc_num_payments (fi->ir, fi->pv, fi->pmt, fi->fv, fi->CF, fi->PF, fi->disc, fi->bep), 0); } /* fi_calc_num_payments */ /* Compute number of periods from: * 1. Nominal Interest * 2. Present Value * 3. Periodic Payment * 4. Future Value */ double _fi_calc_num_payments (double nint, /* nominal interest rate */ double pv, /* present value */ double pmt, /* periodic payment */ double fv, /* future value */ unsigned CF, /* compounding frequency */ unsigned PF, /* payment frequency */ unsigned disc, /* discrete/continuous compounding */ unsigned bep) /* beginning/end of period payment */ { double eint = eff_int (nint / 100.0, CF, PF, disc); double CC = _C (eint, pmt, bep); CC = (CC - fv) / (CC + pv); return (CC > 0.0) ? log (CC) / log (1.0 + eint) : 0.0; } /* _fi_calc_num_payments */ /* compute Interest from preset data */ double fi_calc_interest (fi_ptr fi) { if (fi->npp) fi->ir = _fi_calc_interest (fi->npp, fi->pv, fi->pmt, fi->fv, fi->CF, fi->PF, fi->disc, fi->bep); return fi->ir; } /* fi_calc_interest */ double ratio = 1e4; /* ratio used in iterative solution for interest */ /* Compute Nominal Interest from: * 1. Number of periods * 2. Present Value * 3. Periodic Payment * 4. Future Value */ double _fi_calc_interest (unsigned per,/* number of periods */ double pv, /* present value */ double pmt, /* periodic payment */ double fv, /* future value */ unsigned CF, /* compounding frequency */ unsigned PF, /* payment frequency */ unsigned disc, /* discrete/continuous compounding */ unsigned bep) /* beginning/end of period payment */ { double eint; double a, dik; int ri; if (pmt == 0.0) eint = pow ((dabs (fv) / dabs (pv)), (1.0 / (double) per)) - 1.0; else { if ((pmt * fv) < 0.0) { if (pv) a = -1.0; else a = 1.0; eint = dabs ((fv + a * (double) per * pmt) / (3.0 * (((double) per - 1.0) * ((double) per - 1.0) * pmt + pv - fv))); } else { if ((pv * pmt) < 0.0) { eint = dabs (((double) per * pmt + pv + fv) / ((double) per * pv)); } else { a = dabs (pmt / (dabs (pv) + dabs (fv))); eint = a + 1.0 / (a * (double) per * (double) per * (double) per); } } do { dik = fi (per, eint, pv, pmt, fv, bep) / fip (per, eint, pv, pmt, fv, bep); eint -= dik; (void) modf (ratio * (dik / eint), &a); ri = (unsigned) a; } while (ri); } /* endif */ return 100.0 * nom_int (eint, CF, PF, disc); } /* _fi_calc_interest */ /* compute Present value from preset data */ double fi_calc_present_value (fi_ptr fi) { return fi->pv = rnd (_fi_calc_present_value (fi->npp, fi->ir, fi->pmt, fi->fv, fi->CF, fi->PF, fi->disc, fi->bep), fi->prec); } /* fi_calc_present_value */ /* Compute Present Value from: * 1. Number of periods * 2. Nominal Interest * 3. Periodic Payment * 4. Future Value */ double _fi_calc_present_value (unsigned per, /* number of periods */ double nint, /* nominal interest rate */ double pmt, /* periodic payment */ double fv, /* future value */ unsigned CF, /* compounding frequency */ unsigned PF, /* payment frequency */ unsigned disc, /* discrete/continuous compounding */ unsigned bep) /* beginning/end of period payment */ { double eint = eff_int (nint / 100.0, CF, PF, disc); double AA = _A (eint, per); double CC = _C (eint, pmt, bep); return -(fv + (AA * CC)) / (AA + 1.0); } /* _fi_calc_present_value */ /* compute Periodic Payment from preset data */ double fi_calc_payment (fi_ptr fi) { return fi->pmt = rnd (_fi_calc_payment (fi->npp, fi->ir, fi->pv, fi->fv, fi->CF, fi->PF, fi->disc, fi->bep), fi->prec); } /* fi_calc_payment */ /* Compute Periodic Payment from: * 1. Number of periods * 2. Nominal Interest * 3. Present Value * 4. Future Value */ double _fi_calc_payment (unsigned per, /* number of periods */ double nint, /* nominal interest rate */ double pv, /* present value */ double fv, /* future value */ unsigned CF, /* compounding frequency */ unsigned PF, /* payment frequency */ unsigned disc,/* discrete/continuous compounding */ unsigned bep) /* beginning/end of period payment */ { double eint = eff_int (nint / 100.0, CF, PF, disc); double AA = _A (eint, per); double BB = _B (eint, bep); g_return_val_if_fail(BB != 0.0, 0.0); return -(fv + pv * (AA + 1.0)) / (AA * BB); } /* _fi_calc_payment */ /* compute Future Value from preset data */ double fi_calc_future_value (fi_ptr fi) { return fi->fv = rnd (_fi_calc_future_value (fi->npp, fi->ir, fi->pv, fi->pmt, fi->CF, fi->PF, fi->disc, fi->bep), fi->prec); } /* fi_calc_future_value */ /* Compute Future Value from: * 1. Number of periods * 2. Nominal Interest * 3. Present Value * 4. Periodic Payments */ double _fi_calc_future_value (unsigned per, /* number of periods */ double nint, /* nominal interest rate */ double pv, /* present value */ double pmt, /* periodic payment */ unsigned CF, /* compounding frequency */ unsigned PF, /* payment frequency */ unsigned disc, /* discrete/continuous compounding */ unsigned bep) /* beginning/end of period payment */ { double eint = eff_int (nint / 100.0, CF, PF, disc); double AA = _A (eint, per); double CC = _C (eint, pmt, bep); return -(pv + AA * (pv + CC)); } /* _fi_calc_future_value */ /* compute Nominal Interest Rate from Effective Interest Rate */ static double nom_int (double eint, unsigned CF, unsigned PF, unsigned disc) { double nint; if (disc) { if (CF == PF) { nint = CF * eint; } else { nint = CF * (pow ((1.0 + eint), ((double) PF / (double) CF)) - 1.0); } /* * endif */ } else nint = log (pow (1.0 + eint, PF)); return nint; } /* nom_int */ /* Compute Effective Interest Rate from Nominal Interest Rate */ static double eff_int (double nint, unsigned CF, unsigned PF, unsigned disc) { double eint; if (disc) { if (CF == PF) { eint = nint / (double) CF; } else { eint = pow ((1.0 + nint / (double) CF), ((double) CF / (double) PF)) - 1.0; } /* endif */ } else eint = exp (nint / (double) PF) - 1.0; return eint; } /* eff_int */ /* calculation used in interest computation */ static double fi (unsigned per, double eint, double pv, double pmt, double fv, unsigned bep) { return _A (eint, per) * (pv + _C (eint, pmt, bep)) + pv + fv; } /* fi */ /* calculation used in interest computation */ static double fip (unsigned per, double eint, double pv, double pmt, double fv, unsigned bep) { double AA = _A (eint, per); double CC = _C (eint, pmt, bep); double D = (AA + 1.0) / (1.0 + eint); g_return_val_if_fail(CC != 0.0, 0.0); return (double) per * (pv + CC) * D - (AA * CC) / eint; } /* fip */ void set_default (fi_ptr fi) { /* flag whether accrueing interest at beginning or end of period * FALSE --> end * TRUE --> beginning * default to end of period payment s */ fi->bep = FALSE; /* flag for discrete or continuous interest * TRUE --> discrete * FALSE --> continuous * default to discrete interest */ fi->disc = TRUE; /* set compounding, CF, and payment, PF, frequency per year * default to monthly payments and compounding */ fi->CF = fi->PF = 12; /* standard loan quantities: * number of periods: n */ fi->npp = 0; /* annual interest: i */ fi->ir = 0.0; /* Present Value: pv */ fi->pv = 0.0; /* Payment: pmt */ fi->pmt = 0.0; /* Future Value: fv */ fi->fv = 0.0; } /* set_default */ /* compute Julian Day Number from calendar date */ unsigned long julian_day_number (unsigned year, unsigned month, unsigned day) { /* Gregorian/Julian Calendar Flag. * TRUE == Julian * FALSE == Gregorian */ unsigned gregorian = TRUE; /* assume we are dealing with current dates */ double yr; double pfac = 0.6; unsigned long ljdn; yr = year + (month - 3.0) / 12.0; ljdn = (long) (367.0 * yr + pfac) - (2 * (long) (yr)) + (long) (yr / 4.0) + (long) day + 1721117L; if (gregorian) ljdn += -(long) (yr / 100.0) + (long) (yr / 400.0) + 2; return ljdn; } /* julian_day_number */ amort_sched_ptr Amortization_init (amort_sched_ptr amortsched) { unsigned n = amortsched->n; double nint = amortsched->nint; double pv = amortsched->pv; double pmt = amortsched->pmt; double fv = amortsched->fv; double eint; double new_pmt; double pve; unsigned CF = amortsched->CF; unsigned PF = amortsched->PF; unsigned disc = amortsched->disc; unsigned bep = amortsched->bep; unsigned new_n; unsigned prec = amortsched->prec; unsigned long s, d, days_to_yr_end, Eff_Date_jdn = julian_day_number (amortsched->year_E, amortsched->month_E, amortsched->day_E), Init_Date_jdn = julian_day_number (amortsched->year_I, amortsched->month_I, amortsched->day_I); amortsched->Eff_Date_jdn = Eff_Date_jdn; amortsched->Init_Date_jdn = Init_Date_jdn; amortsched->yday_E = Eff_Date_jdn - julian_day_number (amortsched->year_E, 1, 1); amortsched->yday_I = Init_Date_jdn - julian_day_number (amortsched->year_I, 1, 1); amortsched->eint = eint = eff_int (nint / 100.0, CF, PF, disc); amortsched->fv_case = dabs (fv) > dabs (pv); amortsched->bp = bep ? 1.0 : 0.0; if (PF > 24) { /* Payment frequency per year greater than bi-monthly * use actual number of days */ s = Init_Date_jdn - Eff_Date_jdn; days_to_yr_end = julian_day_number (amortsched->year_I + 1, 1, 0) - Init_Date_jdn; d = 366 / PF; } else { /* Payment frequency per year bi-monthly or less * use 30 days/month, 360 days/year */ if (Eff_Date_jdn == Init_Date_jdn) { s = 0; } else { s = ((amortsched->year_I - amortsched->year_E) * 360) + ((amortsched->month_I - amortsched->month_E) * 30) + amortsched->day_I - amortsched->day_E; } /* endif */ days_to_yr_end = 390 - (amortsched->month_I * 30) - amortsched->day_I; d = 360 / PF; } /* endif */ if (!bep) { /* ordinary annuity */ s -= d; } /* endif */ amortsched->yr_pmt = (days_to_yr_end + d) / d; if (pmt == 0.0) { amortsched->pve = pv; } else { amortsched->pve = rnd (pv * pow ((1.0 + eint), ((double) (s * PF) / (double) (d * CF))), prec); } /* endif */ pve = amortsched->pve; /* compute new data to fully amortize loan: * new periodic payment, new_pmt * * option 1: Amortize with original transaction - ignore interest * due to delayed initial payment * * option 2: Amortize with new pv, pve == original pv adjusted for * delayed initial payment, original payment, original fv and * original total number of payments, adjust final payment * * option 3: amortize with new pv, pve, and new payments adjusted to * minimize final payment, keep original number of payments and * original fv * * option 4: amortize with new pv, pve, original payments and new * number of payments to keep original final fv */ /* option 3, compute new periodic payment */ amortsched->new_pmt = new_pmt = rnd (_fi_calc_payment (n, nint, pve, fv, CF, PF, disc, bep), prec); /* option 4: compute new number of total payments, new_n */ amortsched->new_n = new_n = (unsigned) rnd (_fi_calc_num_payments (nint, pve, pmt, fv, CF, PF, disc, bep), 0); /* following used in QTAwk to insure integer value, not needed in C */ /* n = int(n); */ /* compute payment for constant payment to principal loan and final * payment for original loan amount include interest due */ amortsched->cpmt1 = rnd (-pv / n, prec); amortsched->final_pmt_opt_1 = -pv - amortsched->cpmt1 * (n - 1); amortsched->final_pmt_opt_1 *= eint + 1; /* compute payment for constant payment to principal loan and final * payment for delayed loan amount include interest due */ amortsched->cpmt2 = rnd (-pve / n, prec); amortsched->final_pmt_opt_2 = -pve - amortsched->cpmt2 * (n - 1); amortsched->final_pmt_opt_2 *= eint + 1; if (bep) { amortsched->final_pmt_opt_3 = rnd (_fi_calc_future_value (n - 1, nint, pv, pmt, CF, PF, disc, bep) - (fv / (1.0 + eint)), prec); amortsched->final_pmt_opt_4 = rnd (_fi_calc_future_value (n - 1, nint, pve, pmt, CF, PF, disc, bep) - (fv / (1.0 + eint)), prec); amortsched->final_pmt_opt_5 = rnd (_fi_calc_future_value (n - 1, nint, pve, new_pmt, CF, PF, disc, bep) - (fv / (1.0 + eint)), prec); if (new_n) amortsched->final_pmt_opt_6 = rnd (_fi_calc_future_value (new_n - 1, nint, pve, pmt, CF, PF, disc, bep) - (fv / (1.0 + eint)), prec); else amortsched->final_pmt_opt_6 = 0.0; } else { amortsched->final_pmt_opt_3 = rnd (_fi_calc_future_value (n - 1, nint, pv, pmt, CF, PF, disc, bep) * (1.0 + eint) - fv, prec); amortsched->final_pmt_opt_4 = rnd (_fi_calc_future_value (n - 1, nint, pve, pmt, CF, PF, disc, bep) * (1.0 + eint) - fv, prec); amortsched->final_pmt_opt_5 = rnd (_fi_calc_future_value (n - 1, nint, pve, new_pmt, CF, PF, disc, bep) * (1.0 + eint) - fv, prec); if (new_n) amortsched->final_pmt_opt_6 = rnd (_fi_calc_future_value (new_n - 1, nint, pve, pmt, CF, PF, disc, bep) * (1.0 + eint) - fv, prec); else amortsched->final_pmt_opt_6 = 0.0; } /* endif */ /* compute delayed interest */ amortsched->delayed_int = pv - amortsched->pve; return amortsched; } /* Amortization_init */ amort_sched_ptr Amortization_Schedule (amort_sched_ptr amortsched) { unsigned n = amortsched->n; double nint = amortsched->nint; double pv = amortsched->pv; double pmt = amortsched->pmt; double fv = amortsched->fv; double eint = amortsched->eint; unsigned CF = amortsched->CF; unsigned PF = amortsched->PF; unsigned disc = amortsched->disc; unsigned bep = amortsched->bep; double cpmt = 0; double final_pmt = 0; char summary = amortsched->summary; unsigned option = amortsched->option; unsigned yr_pmt = amortsched->yr_pmt; unsigned fv_case = amortsched->fv_case; unsigned prec = amortsched->prec; unsigned j, s, yr, per_cnt, pmt_cnt = 0, k = 0, sum_prt; int jj; unsigned long d; double yr_fv, sum_int, yr_int, prin, adv_pmt, pmt_int, hpv = 0.0; yearly_summary_ptr yrly_sum; amort_sched_yr_ptr amortyr; sched_pmt_ptr pmtsched = NULL; sum_int = yr_int = 0.0; switch (option) { case 1: amortsched->cpmt = cpmt = amortsched->cpmt1; /* re-compute final payment without interest */ amortsched->final_pmt = final_pmt = -pv - cpmt * (n - 1); summary = (summary == 'y') ? 'x' : 'o'; break; case 2: amortsched->cpmt = cpmt = amortsched->cpmt2; pv = amortsched->pve; /* re-compute final payment without interest */ amortsched->final_pmt = final_pmt = -pv - cpmt * (n - 1); summary = (summary == 'y') ? 'x' : 'o'; break; case 3: amortsched->final_pmt = final_pmt = amortsched->final_pmt_opt_3; break; case 4: pv = amortsched->pve; amortsched->final_pmt = final_pmt = amortsched->final_pmt_opt_4; break; case 5: pv = amortsched->pve; pmt = amortsched->new_pmt; amortsched->final_pmt = final_pmt = amortsched->final_pmt_opt_5; break; case 6: n = amortsched->new_n; pv = amortsched->pve; amortsched->final_pmt = final_pmt = amortsched->final_pmt_opt_6; break; } /* endswitch */ yr = amortsched->year_I; sum_prt = TRUE; switch (summary) { case 'a': /* variable advanced prepayment schedule. prepayment equals next * period principal. */ amortsched->schedule.first_yr = amortyr = (amort_sched_yr_ptr) calloc (1, sizeof (amort_sched_yr)); for (per_cnt = 0, s = 1, j = n; pv != fv; j -= 2, per_cnt++) { /* basic equation to compute interest this payment period */ pmt_int = -rnd ((pv + (amortsched->bp * pmt)) * eint, prec); /* sum yearly interest paid */ yr_int += pmt_int; /* sum total interest paid */ sum_int += pmt_int; /* compute principal paid this payment period and round to nearest cent */ if (dabs (pmt) > dabs (pv)) { prin = -pv; pmt = prin + pmt_int; adv_pmt = 0.0; pv = fv; } else { prin = rnd (pmt - pmt_int, prec); /* compute remaining pv and round to nearest cent */ pv = rnd (pv + prin, prec); /* compute principal for next payment cycle and round to nearest cent */ adv_pmt = rnd (pmt + (pv + (amortsched->bp * pmt)) * eint, prec); if (dabs (pv) >= dabs (adv_pmt)) { /* remaining pv greater than advanced principal payment * compute remaining pv and round to nearest cent */ pv = rnd (pv + adv_pmt, prec); } else { /* remaining pv less than advanced principal payment reduce * advanced pricipla payment to remaining pv */ adv_pmt = -pv; /* and set remaining pv to fv */ pv = fv; } /* ## endif */ } /* # endif */ if (sum_prt) { jj = (j < yr_pmt) ? j + 1 : yr_pmt; amortyr->payments = pmtsched = (sched_pmt_ptr) calloc (jj, sizeof (sched_pmt)); pmt_cnt = 0; sum_prt = FALSE; } /* endif */ pmtsched->period_num = s++; pmtsched->interest = pmt_int; pmtsched->principal = prin; pmtsched->advanced_pmt = adv_pmt; pmtsched->total_pmt = pmt + adv_pmt; pmtsched->balance = pv; pmtsched++; pmt_cnt++; if (!--yr_pmt) { yr_pmt = PF; amortyr->year = yr++; amortyr->interest_pd = yr_int; amortyr->principal_pd = pv - hpv; amortyr->yr_end_balance = pv; amortyr->total_interest_pd = sum_int; amortyr->num_periods = pmt_cnt; amortyr->next_yr = (amort_sched_yr_ptr) calloc (1, sizeof (amort_sched_yr)); amortyr = amortyr->next_yr; hpv = pv; yr_int = 0.0; sum_prt = TRUE; } /* endif */ } /* endfor */ if (dabs (pv) > 0.0) { /* basic equation to compute interest this payment period */ pmt_int = -rnd ((pv + (amortsched->bp * pmt)) * eint, prec); /* sum yearly interest paid */ yr_int += pmt_int; /* sum total interest paid */ sum_int += pmt_int; /* compute principal paid this payment period and round to nearest cent */ prin = rnd (pmt - pmt_int, prec); final_pmt = pmt; /* compute remaining pv and round to nearest cent */ pv = rnd (pv + prin, prec); /* Set advanced principal payment to remaining pv */ adv_pmt = -pv; amortyr->final_pmt = final_pmt += adv_pmt; /* and set remaining pv to fv */ pv = fv; if (pmtsched) { pmtsched->period_num = s++; pmtsched->interest = pmt_int; pmtsched->principal = prin; pmtsched->advanced_pmt = adv_pmt; pmtsched->total_pmt = final_pmt; pmtsched->balance = pv; } per_cnt++; pmt_cnt++; } /* endif */ if (dabs (yr_int) > 0.0) { amortyr->year = yr++; amortyr->interest_pd = yr_int; amortyr->principal_pd = pv - hpv; amortyr->total_interest_pd = sum_int; amortyr->num_periods = pmt_cnt; } /* endif */ amortsched->total_periods = per_cnt; break; case 'f': /* fixed prepaymet schedule prepayment specified by user */ amortsched->schedule.first_yr = amortyr = (amort_sched_yr_ptr) calloc (1, sizeof (amort_sched_yr)); /* set advnaced payment */ adv_pmt = amortsched->fixed_pmt; for (per_cnt = 0, s = 1, j = n; j && (pv != fv); j--, per_cnt++) { /* basic equation to compute interest this payment period */ pmt_int = -rnd ((pv + (amortsched->bp * pmt)) * eint, prec); /* sum yearly interest paid */ yr_int += pmt_int; /* sum total interest paid */ sum_int += pmt_int; /* compute principal paid this payment period and round to nearest cent */ if (dabs (pmt) > dabs (pv)) { prin = -pv; pmt = prin + pmt_int; adv_pmt = 0.0; pv = 0.0; } else { prin = rnd (pmt - pmt_int, prec); /* compute remaining pv and round to nearest cent */ pv = rnd (pv + prin, prec); if (dabs (pv) >= dabs (adv_pmt)) { /* remaining pv greater than advanced principal payment * compute remaining pv and round to nearest cent */ pv = rnd (pv + adv_pmt, prec); } else { /* remaining pv less than advanced principal payment reduce * advanced principal payment to remaining pv and set * remaining pv to fv */ adv_pmt = -pv; pv = fv; } /*## endif */ } /* # endif */ if (sum_prt) { jj = (j < yr_pmt) ? j + 1 : yr_pmt; amortyr->payments = pmtsched = (sched_pmt_ptr) calloc (jj, sizeof (sched_pmt)); pmt_cnt = 0; sum_prt = FALSE; } else { (amortyr->num_periods)++; } /* ## endif */ pmtsched->period_num = s++; pmtsched->interest = pmt_int; pmtsched->principal = prin; pmtsched->advanced_pmt = adv_pmt; pmtsched->total_pmt = pmt + adv_pmt; pmtsched->balance = pv; pmt_cnt++; pmtsched++; if (!--yr_pmt) { yr_pmt = PF; amortyr->year = yr++; amortyr->interest_pd = yr_int; amortyr->principal_pd = pv - hpv; amortyr->yr_end_balance = pv; amortyr->total_interest_pd = sum_int; amortyr->num_periods = pmt_cnt; amortyr->next_yr = (amort_sched_yr_ptr) calloc (1, sizeof (amort_sched_yr)); amortyr = amortyr->next_yr; hpv = pv; yr_int = 0.0; sum_prt = TRUE; } /* ## endif */ } /* ## endfor */ if (pv != fv) { /* # basic equation to compute interest this payment period */ pmt_int = -rnd ((pv + (amortsched->bp * pmt)) * eint, prec); /* # sum yearly interest paid */ yr_int += pmt_int; /* # sum total interest paid */ sum_int += pmt_int; /* # compute principal paid this payment period and round to nearest cent */ prin = rnd (pmt - pmt_int, prec); final_pmt = pmt; /* # compute remaining pv and round to nearest cent */ pv = rnd (pv + prin, prec); /* # Set advanced principal payment to remaining pv */ adv_pmt = -pv; amortyr->final_pmt = final_pmt += adv_pmt; /* # and set remaining pv to fv */ pv = fv; if (pmtsched) { pmtsched->period_num = s++; pmtsched->interest = pmt_int; pmtsched->principal = prin; pmtsched->advanced_pmt = adv_pmt; pmtsched->total_pmt = final_pmt; pmtsched->balance = pv; } per_cnt++; pmt_cnt++; } /* # endif */ if (dabs (yr_int) > 0.0) { amortyr->year = yr++; amortyr->interest_pd = yr_int; amortyr->principal_pd = pv - hpv; amortyr->total_interest_pd = sum_int; amortyr->num_periods = pmt_cnt; } /* endif */ amortsched->total_periods = per_cnt; break; case 'o': /* Constant payment to principal use constant payment equal to * original pv divided by number of periods. constant payment to * principal could be amount specified by user. */ amortsched->schedule.first_yr = amortyr = (amort_sched_yr_ptr) calloc (1, sizeof (amort_sched_yr)); amortsched->total_periods = n; d = yr_pmt; for (s = 1, j = n - 1; j; j--, k++) { pmt_int = -rnd (pv * eint, prec); /* sum yearly interest paid */ yr_int += pmt_int; /* sum total interest paid */ sum_int += pmt_int; pv = rnd (pv + cpmt, prec); if (sum_prt) { jj = (j < yr_pmt) ? j + 1 : yr_pmt; amortyr->payments = pmtsched = (sched_pmt_ptr) calloc (jj, sizeof (sched_pmt)); amortyr->num_periods = jj; k = 0; sum_prt = FALSE; } /* endif */ pmtsched->period_num = s++; pmtsched->interest = pmt_int; pmtsched->total_pmt = cpmt + pmt_int; pmtsched->balance = pv; pmtsched++; if (!--yr_pmt) { yr_pmt = PF; amortyr->year = yr++; amortyr->interest_pd = yr_int; amortyr->principal_pd = d * cpmt; amortyr->yr_end_balance = pv; amortyr->total_interest_pd = sum_int; amortyr->next_yr = (amort_sched_yr_ptr) calloc (1, sizeof (amort_sched_yr)); amortyr = amortyr->next_yr; d = PF; yr_int = 0.0; sum_prt = TRUE; } /* endif */ } /* endfor */ if (pv) { pmt_int = -rnd (pv * eint, prec); /* sum yearly interest paid */ yr_int += pmt_int; /* sum total interest paid */ sum_int += pmt_int; if (pmtsched) { pmtsched->period_num = s++; pmtsched->interest = -pmt_int; pmtsched->total_pmt = -pv + pmt_int; pmtsched->balance = 0.0; } amortyr->final_pmt = -pv - pmt_int; } /* endif */ if (dabs (yr_int) > 0.0) { amortyr->year = yr++; amortyr->interest_pd = yr_int; amortyr->principal_pd = -pv + k * cpmt; amortyr->total_interest_pd = sum_int; } /* endif */ break; case 'p': /* normal amortization schedule interest, principal and balance * per payment period */ amortsched->schedule.first_yr = amortyr = (amort_sched_yr_ptr) calloc (1, sizeof (amort_sched_yr)); amortsched->total_periods = n; hpv = pv; for (s = 1, j = n - 1; j; j--) { /* basic equation for computing interest paid in payment period */ pmt_int = -rnd ((pv + (amortsched->bp * pmt)) * eint, prec); /* sum yearly interest paid */ yr_int += pmt_int; /* sum total interest paid */ sum_int += pmt_int; /* compute principal paid this payment period */ prin = rnd (pmt - pmt_int, prec); /* compute remaining pv and round to nearest cent */ pv = rnd (pv + prin, prec); if (sum_prt) { jj = (j < yr_pmt) ? j + 1 : yr_pmt; amortyr->payments = pmtsched = (sched_pmt_ptr) calloc (jj, sizeof (sched_pmt)); amortyr->num_periods = jj; sum_prt = FALSE; } /* endif */ if (fv_case) { pmtsched->period_num = s++; pmtsched->interest = pmt_int; pmtsched->balance = pv; pmtsched++; } else { pmtsched->period_num = s++; pmtsched->interest = pmt_int; pmtsched->principal = prin; pmtsched->balance = pv; pmtsched++; } /* endif */ if (!--yr_pmt) { yr_pmt = PF; amortyr->year = yr++; amortyr->interest_pd = yr_int; if (!fv_case) { amortyr->principal_pd = pv - hpv; } /* endif */ amortyr->yr_end_balance = pv; amortyr->total_interest_pd = sum_int; amortyr->next_yr = (amort_sched_yr_ptr) calloc (1, sizeof (amort_sched_yr)); amortyr = amortyr->next_yr; hpv = pv; yr_int = 0.0; sum_prt = TRUE; } /* * endif */ } /* * endfor */ /* determine if payment due at beginning or end of period in order * to correctly compute final payment, interest and principal */ if (bep) { /* paying remainder at beginning of period compute final payment */ final_pmt = -pv - fv / (1 + eint); /* then compute interest paid with final final payment */ pmt_int = -rnd ((pv + final_pmt) * eint, prec); /* then compute the principal paid */ prin = final_pmt + pmt_int; } else { /* basic equation for computing interest paid in payment period * for payment at end of period */ pmt_int = -rnd (pv * eint, prec); /* compute principal paid this payment period */ prin = -pv; /* compute the final payment note the final payment may be * computed either of two ways both are equivalent */ final_pmt = prin + pmt_int; } /* * endif */ pv = -fv; /* sum yearly interest paid */ yr_int += pmt_int; /* sum total interest paid */ sum_int += pmt_int; if (sum_prt) { amortyr->payments = pmtsched = (sched_pmt_ptr) calloc (1, sizeof (sched_pmt)); amortyr->num_periods = 1; } /* endif */ amortyr->final_pmt = final_pmt; if (fv_case) { pmtsched->period_num = s++; pmtsched->interest = pmt_int; pmtsched->balance = pv; } else { pmtsched->period_num = s++; pmtsched->interest = pmt_int; pmtsched->principal = prin; pmtsched->balance = pv; } /* endif */ if (dabs (yr_int) > 0.0) { amortyr->year = yr++; amortyr->interest_pd = yr_int; amortyr->total_interest_pd = sum_int; if (!bep) { amortyr->principal_pd = -hpv; } /* endif */ } /* endif */ break; case 'x': /* constant payment to principal - annual summary */ /* compute number of years to summarize */ j = n / PF; if (yr_pmt < PF) j++; amortsched->total_periods = j; amortsched->schedule.summary = yrly_sum = (yearly_summary_ptr) calloc (j, sizeof (yearly_summary)); jj = 0; for (j = n, sum_prt = 0; j > 0; j -= yr_pmt, yr_pmt = PF, sum_prt++) { if (j <= PF) { s = jj + j; yr_pmt = j; yr_fv = rnd (pv + cpmt * (s - 1), prec) + final_pmt; } else { s = jj + yr_pmt; yr_fv = rnd (pv + cpmt * s, prec); } /* endif */ prin = -eint * jj * (pv + (cpmt * (jj - 1) / 2.0)); yr_int = -eint * s * (pv + (cpmt * (s - 1) / 2.0)); yr_int = rnd (yr_int - prin, prec); jj += yr_pmt; sum_int += yr_int; yrly_sum[sum_prt].year = yr++; yrly_sum[sum_prt].interest = yr_int; yrly_sum[sum_prt].end_balance = yr_fv; } /* endfor */ break; case 'y': /* normal amortization - annual summary */ /* compute number of years to summarize */ j = n / PF; if (yr_pmt < PF) j++; if (n > (j * PF)) j++; amortsched->total_periods = j; amortsched->schedule.summary = yrly_sum = (yearly_summary_ptr) calloc (j, sizeof (yearly_summary)); hpv = pv; for (jj = n, j = 0; jj > 0; jj -= yr_pmt, yr_pmt = PF, j++) { if (jj <= (int)PF) { yr_fv = fv; yr_int = rnd (((jj - 1) * pmt) + hpv + final_pmt, prec); } else { yr_fv = -rnd (_fi_calc_future_value (yr_pmt, nint, hpv, pmt, CF, PF, disc, bep), prec); yr_int = rnd ((yr_pmt * pmt) + hpv - yr_fv, prec); } /* * endif */ sum_int += yr_int; yrly_sum[j].year = yr++; yrly_sum[j].interest = yr_int; yrly_sum[j].end_balance = yr_fv; hpv = yr_fv; } /* * endfor */ break; } /* * endswitch */ amortsched->total_interest = sum_int; return amortsched; } /* Amortization_Schedule */ /* function to free dynamically allocated memory used for amortization schedule */ void Amortization_free (amort_sched_ptr amortsched) { amort_sched_yr_ptr amortyr, prst_yr; switch (amortsched->summary) { case 'a': case 'f': case 'o': case 'p': for (amortyr = amortsched->schedule.first_yr; amortyr; amortyr = prst_yr) { if (amortyr->payments) free (amortyr->payments); prst_yr = amortyr->next_yr; free (amortyr); } /* endfor */ break; case 'y': free (amortsched->schedule.summary); break; } /* endswitch */ amortsched->schedule.first_yr = NULL; } /* amort_free */
200  * ³
201  *
202  * PV
203  *
204  * Annuity
205  * Lease (with buy back or residual)*
206  * Loan or Mortgage (with balloon)*
207  *
208  * ****************************************************************************
209  *
210  * First lets discuss interest before discussing the financial
211  * equation. Most financial transactions utilize a nominal interest
212  * rate, NAR, i.e., the interest rate per year. The NAR must be
213  * converted to the interest rate per payment interval and the
214  * compounding accounted for before it can be used in computing an
215  * interest payment. After this conversion process, the interest
216  * used is the effective interest rate, EIR. In converting NAR to
217  * EIR, there are two concepts to discuss first, the Compounding
218  * Frequency and the Payment Frequency and * whether the interest is
219  * coumpounded in discrete intervals or continuously. The
220  * compounding Frequency, CF, is simply the number of times per
221  * year, the monies in the financial transaction are compounded. In
222  * the U.S., monies are usually compounded daily on bank deposits,
223  * and monthly on loans. Sometimes Long term deposits are compounded
224  * quarterly or weekly.
225  *
226  * The Payment Frequency, PF, is simply how often during a year
227  * payments are made in the transaction. Payments are usually
228  * scheduled on a regular basis and can be made at the beginning or
229  * end of the payment period. If made at the beginning of the
230  * payment period, interest must be applied to the payment as well
231  * as any previous money paid or money still owed.
232  *
233  * Normal values for CF and PF are:
234  * 1 == annual
235  * 2 == semi-annual
236  * 3 == tri-annual
237  * 4 == quaterly
238  * 6 == bi-monthly
239  * 12 == monthly
240  * 24 == semi-monthly
241  * 26 == bi-weekly
242  * 52 == weekly
243  * 360 == daily
244  * 365 == daily
245  *
246  * a) the Compounding Frequency per year, CF, need not be identical
247  * to the Payment Frequency per year, PF, and/or,
248  *
249  * b) Interest may be compounded in either discrete intervals or continuously
250  * compounded.
251  *
252  * c) Also, payments may be made at the beginning of the payment
253  * period or at the end of the payment period.
254  *
255  * CF and PF are defaulted to 1. The default is for discrete interest
256  * intervals and payments are defaulted to the end of the payment
257  * period.
258  *
259  * When a solution for n, PV, PMT or FV is required, the nominal interest
260  * rate, i, must first be converted to the effective interest rate per payment
261  * period. This rate, ieff, is then used to compute the selected variable. To
262  * convert i to ieff, the following expressions are used:
263  *
264  * Discrete interest periods:
265  *
266  * 19) ieff = (1 + i/CF)^(CF/PF) - 1
267  *
268  * Continuous Interest
269  *
270  * 20) ieff = e^(i/PF) - 1 = exp(i/PF) - 1
271  *
272  * When interest is computed, the computation produces the effective interest
273  * rate, ieff. This value must then be converted to the nominal interest rate.
274  * Function _I below returns the nominal interest rate NOT the effective
275  * interest rate. ieff is converted to i using the following expressions:
276  *
277  * Discrete Case:
278  *
279  * i = CF*[(1+ieff)^(PF/CF) - 1]
280  *
281  * Continuous Case:
282  *
283  * i = ln[(1+ieff)^PF]
284  *
285  * ****************************************************************************
286  *
287  * NOTE: in the equations below for the financial transaction, all
288  * interest rates are the effective interest rate, ieff. The symbol
289  * will be shortned to just 'i'.
290  *
291  * ****************************************************************************
292  *
293  * The basic financial equation used is:
294  *
295  * 1) PV*(1 + i)^n + PMT*(1 + iX)*[(1+i)^n - 1]/i + FV = 0
296  * Where: X = 0 for end of period payments, and
297  * X = 1 for beginning of period payments
298  *
299  * ****************************************************************************
300  *
301  * NOTE: this equation is derived in the following manner:
302  *
303  * Start with the basic equation to find the balance or Present
304  * Value, PV[1], after one payment period. Note PV[1] is the Present
305  * value after on payment and PV[0] is the initial Present
306  * Value. PV[0] will be shortened to just PV.
307  *
308  * The interest due at the end of the first payment period is:
309  *
310  * ID[1] = (PV + X * PMT) * i
311  * where: X = 0 for end of period payments, and
312  * X = 1 for beginning of period payments.
313  *
314  * Thus:
315  * PV[1] = PV + (PMT + ID[1])
316  * = PV + (PMT + (PV + X * PMT) * i)
317  * = PV * (1 + i) + PMT * (1 + Xi)
318  *
319  * This equation works for all of the money diagrams shown
320  * above. The Present Value, money received or paid, is modified by
321  * a payment made at the beginning of a payment period and
322  * multiplied by the effective interest rate to compute the interest
323  * due during the payment period. The interest due is then added to
324  * the payment to obtain the amount to be added to the Present Value
325  * to compute the new Present Value.
326  *
327  * For diagram 1): PV < 0, PMT == 0, PV[1] < 0
328  * For diagram 2): PV == 0, PMT < 0, PV[1] < 0
329  * For Diagram 3): PV > 0, PMT < 0, PV[1] >= 0 or PV[1] <= 0
330  * For Diagram 4): PV < 0, PMT > 0, PV[1] <= 0 or PV[1] >= 0
331  *
332  * X may be 0 or 1 for any diagram.
333  *
334  * For the standard loan, PV is the money borrowed, PMT is the
335  * periodic payment to repay the loan and i is the effective
336  * interest rate agreed upon.
337  *
338  * To calculate the Present Value after the second payment period,
339  * the above calculation is applied iteratively to PV_1:
340  *
341  * PV[2] = PV[1] + (PMT + (PV[1] + X * PMT) * i)
342  * = PV[1] * (1 + i) + PMT * (1 + iX)
343  * = (PV * (1 + i) + PMT * (1 + iX)) * (1 + i) + PMT * (1 + iX)
344  * = PV * (1 + i)^2 + PMT * (1 + iX) * (1 + i)
345  * + PMT * (1 + iX)
346  *
347  * Similarly:
348  *
349  * PV[3] = PV[2] + (PMT + (PV[2] + X * PMT) * i)
350  * = PV[2] * (1 + i) + PMT * (1 + iX)
351  * = PV * (1 + i)^2 + PMT * (1 + iX) * (1 + i)
352  * + PMT * (1+ iX)) * ( 1 + i)
353  * + PMT * (1+ iX)
354  * = PV * (1 + i)^3 + PMT * (1 + iX) * (1 + i)^2
355  * + PMT * (1 + iX) * (1 + i)^2
356  * + PMT * (1 + iX) * (1 + i)
357  * + PMT * (1 + iX)
358  *
359  * And for the n'th payment:
360  *
361  * PV[n] = PV[n-1] + (PMT + (PV[n-1] + X * PMT) * i)
362  * PV[n] = PV * (1 + i)^n + PMT * (1 + iX) * (1 + i)^(n-1)
363  * + PMT * (1 + iX) * (1 + i)^(n-2) +
364  * .
365  * .
366  * .
367  * + PMT * (1 + iX) * (1 + i)
368  * + PMT * (1 + iX)
369  * PV[n] = PV * (1 + i)^n + PMT * (1 + iX) * [(1 + i)^(n-1) + ...
370  * + (1 + i) + 1]
371  *
372  * ****************************************************************************
373  *
374  * The sum of the finite series:
375  *
376  * 1 + k + (k^2) + (k^3) + ... + (k^n) = (1-k^(n+1))/(1-k)
377  *
378  * as can be seen by the following. Let S(n) be the series sum. Then
379  *
380  * S(n) - k * S(n) = 1 - k^(n+1)
381  *
382  * and solving for S(n):
383  *
384  * S(n) = [1-k^(n+1)]/[1-k] = 1 + k + (k^2) + (k^3) + ... + (k^n)
385  *
386  * ****************************************************************************
387  *
388  * PV[n] = PV * (1 + i)^n + PMT * (1 + iX) * [(1 + i)^(n-1) + ...
389  * + (1 + i) + 1]
390  * = PV * (1 + i)^n + PMT * (1 + iX) * [1 - (1 + i)^n]/[1 - (1 + i)]
391  * = PV * (1 + i)^n + PMT * (1 + iX) * [1 - (1 + i)^n]/[-i]
392  * = PV * (1 + i)^n + PMT * (1 + iX) * [(1 + i)^n - 1]/i
393  *
394  * The formaula for PV[n] can be proven using mathematical induction.
395  *
396  * or:
397  *
398  * PV * (1 + i)^n + PMT * [(1 + i)^n - 1]/i - PV[n] = 0
399  *
400  * If after n payments, the remaining balance is repaid as a lump
401  * sum, the lump sum is known as the Future Value, FV[n]. Since
402  * FV[n] is negative if paid and positive if received, FV[n] is the
403  * negative of PV[n]. Since n is assumed to be the last payment,
404  * FV[n] will be shortened to simply FV.
405  *
406  * Setting: FV = -PV[N]
407  *
408  * 1) PV*(1 + i)^n + PMT*(1 + iX)*[(1 + i)^n - 1]/i + FV = 0
409  *
410  * Up to this point, we have said nothing about the value of
411  * PMT. PMT can be any value mutually agreed upon by the lender and
412  * the borrower. From the equation for PV[1]:
413  *
414  * PV[1] = PV + (PMT + (PV + X * PMT) * i),
415  *
416  * Several things can be said about PMT.
417  *
418  * 1. If PMT = PV * i, and X = 0 (end of period payments):
419  *
420  * The payment is exactly equal to the interest due and PV[1] =
421  * PV. In this case, the borrower must make larger future
422  * payments to reduce the balance due, or make a single payment,
423  * after some agreed upon number of payments, with PMT = PV to
424  * completely pay off the loan. This is an interest only payment
425  * with a balloon payment at the end.
426  *
427  * 2. If PMT < PV * i, and X = 0
428  *
429  * The payment is insufficient to cover even the interest charged
430  * and the balance due grows
431  *
432  * 3. If PMT > PV * i, and X = 0
433  *
434  * The payment is sufficient to cover the interest charged with a
435  * residual amount to be applied to reduce the balance due. The
436  * larger the residual amount, the faster the loan is repaid. For
437  * most mortgages or other loans made today, the lender and
438  * borrower agree upon a certain number of repayment periods and
439  * the interest to be charged per payment period. The interest
440  * may be multiplied by 12 and stated as an annual interest
441  * rate. Then the lender and borrower want to compute a periodic
442  * payment, PMT, which will reduce the balance due to zero after
443  * the agreed upon number of payment have been made. If N is the
444  * agreed upon number of periodic payments, then we want to use:
445  *
446  * PV * (1 + i)^N + PMT*(1 +iX)*[(1 + i)^N - 1]/i + FV = 0
447  *
448  * with FV = 0 to compute PMT:
449  *
450  * PMT = -[PV * i * (1 + i)^(N - X)]/[(1 + i)^N - 1]
451  *
452  * The value of PMT computed will reduce the balance due to zero
453  * after N periodic payments.
454  *
455  * ****************************************************************************
456  *
457  *
458  * With a simple alegebraic re-arrangement, The financial Equation becomes:
459  *
460  * 2) [PV + PMT*(1 + iX)/i][(1 + i)^n - 1] + PV + FV = 0
461  *
462  * or
463  *
464  * 3) (PV + C)*A + PV + FV = 0
465  *
466  * where:
467  * 4) A = (1 + i)^n - 1
468  *
469  * 5) B = (1 + iX)/i
470  *
471  * 6) C = PMT*B
472  *
473  * The form of equation 3) simplifies the calculation procedure for all five
474  * variables, which are readily solved as follows:
475  *
476  * 7) n = ln[(C - FV)/(C + PV)]/ln((1 + i)
477  *
478  * 8) PV = -[FV + A*C]/(A + 1)
479  *
480  * 9) PMT = -[FV + PV*(A + 1)]/[A*B]
481  *
482  * 10) FV = -[PV + A*(PV + C)]
483  *
484  * Equations 4), 5) and 6) are computed by functions:
485  *
486  * _A
487  * _B
488  * _C
489  *
490  * respectively. Equations 7), 8), 9) and 10) are computed by functions:
491  *
492  * _N
493  * _PV
494  * _PMT
495  * _FV
496  *
497  * respectively.
498  *
499  * The solution for interest is broken into two cases:
500  *
501  * PMT == 0
502  * i = [FV/PV]^(1/n) - 1
503  *
504  * PMT != 0
505  *
506  * Since equation 3) cannot be solved explicitly for i in this
507  * case, an iterative technique must be employed. Newton's
508  * method, using exact expressions for the function of i and its
509  * derivative, are employed. The expressions are:
510  *
511  * 12) i[k+1] = i[k] - f(i[k])/f'(i[k])
512  * where: i[k+1] == (k+1)st iteration of i
513  * i[k] == kth iteration of i
514  * and:
515  *
516  * 13) f(i) = A*(PV+C) + PV + FV
517  *
518  * 14) f'(i) = n*D*(PV+C) - (A*C)/i
519  *
520  * 15) D = (1 + i)^(n-1) = (A+1)/(1+i)
521  *
522  * To start the iterative solution for i, an initial guess must be made
523  * for the value of i. The closer this guess is to the actual value,
524  * the fewer iterations will have to be made, and the greater the
525  * probability that the required solution will be obtained. The initial
526  * guess for i is obtained as follows:
527  *
528  * if PMT*FV >= 0, then PV case
529  * if PMT*FV < 0, then FV case
530  *
531  * PV case:
532  * | n*PMT + PV + FV |
533  * 16) i[0] = | ----------------|
534  * | n*PV |
535  *
536  * = abs[(n*PMT + PV + FV)/(n*PV)]
537  *
538  * FV case:
539  * a) PV != 0
540  *
541  * | FV - n*PMT |
542  * 17) i[0] = |---------------------------|
543  * | 3*[PMT*(n-1)^2 + PV - FV] |
544  *
545  * = abs[(FV-n*PMT)/(3*(PMT*(n-1)^2+PV-FV))]
546  * b) PV == 0
547  *
548  * | FV + n*PMT |
549  * 18) i[0] = |---------------------------|
550  * | 3*[PMT*(n-1)^2 + PV - FV] |
551  *
552  * = abs[(FV+n*PMT)/(3*(PMT*(n-1)^2+PV-FV))]
553  *
554  * ****************************************************************************
555  * Constant payment to principal loan
556  *
557  * In this loan, each total payment is different, with each
558  * succeeding payment less than the preceding payment. Each payment
559  * is the total of the constant amount to the principal plus the
560  * interest for the period. The constant payment to the principal is
561  * computed as:
562  *
563  * C = -PV / N
564  *
565  * Where PV is the loan amount to be repaid in N payments
566  * (periods). Note that the constant payment to principal could be
567  * any value agreed to by the two parties involved.
568  *
569  * Thus the principal after the first payment is:
570  * PV[1] = PV[0] + C = PV + C
571  * after the second payment, the principal is:
572  * PV[2] = PV[1] + C = PV[0] + 2C
573  * In general, the remaining principal after n payments is:
574  * PV[n] = PV[0] + nC = PV + nC
575  *
576  * If the effective interest per payment period is i, then the
577  * interest for the first payment is:
578  *
579  * I[1] = -i*PV[0] = -i*PV
580  * and for the second:
581  * I[2] = -i * PV[1]
582  * and in general, for the n'th payment the interest is:
583  * I[n] = -i * PV[n-1]
584  * = -i * (PV + (n-1)C)
585  * The total payment for any period, n, is:
586  * P[n] = C + I[n]
587  * = C + i * (PV + (n-1)C)
588  * = C(1 + i) - i * (PV + nC)
589  * The total interest paid to period n is:
590  * T[n] = I[1] + I[2] + I[3] + ... + I[n]
591  * T[n] = sum(j = 1 to n: I[j])
592  * T[n] = sum(j = 1 to n: -i * (PV + (j-1)C))
593  * T[n] = sum(j=1 to n: -i*PV) + sum(j=1 to n: iC) + sum(j=1 to n: -iCj)
594  * T[n] = -i*n*PV + i*n*C - i*C*sum(j=1 to n:j)
595  * sum(j=1 to n:j) = n(n+1)/2
596  * T[n] = -i*n*(PV + C) - i*C*n(n+1)/2
597  * T[n] = -i*n*(PV + (C*(n - 1)/2))
598  *
599  * Note: substituting for C = -PV/N, in the equations for PV[n], I[n],
600  * P[n], and T[n] would give the following equations:
601  *
602  * PV[n] = PV*(1 - n/N)
603  * I[n] = -i*PV*(1 + N - n)/N
604  * P[n] = -i*PV*(2 + N - n)/N
605  * T[n] = -i*n*PV*(2*N - n + 1)/(2*N)
606  *
607  * Using these equations for the calculations would eliminate the
608  * dependence on C, but only if C is always defined as above and
609  * would eliminate the possibility of another value for C. If the
610  * value of C was less than -PV/N then a balloon payment would be
611  * due at the final payment and this is a possible alternative for
612  * some people.
613  *
614  * ****************************************************************************
615  *
616  * Amortization Schedules.
617  *
618  * Financial Transactions have an effective Date, ED, and an Initial Payment
619  * Date, IP. ED may or may not be the same as IP, but IP is always the same
620  * or later than ED. Most financial transaction calculators assume that
621  * IP is equal to ED for beginning of period payments or at the end of the
622  * first payment period for end of period payments.
623  *
624  * This is not always true. IP may be delayed for financial reasons
625  * such as cash flow or accounting calendar. The subsequent payments
626  * then follow the agreed upon periodicity. Since money has a time
627  * value, the "delayed" IP must be accounted for. Computing an
628  * "Effective PV", pve, is one means of handling a delayed IP.
629  *
630  * EDj == the Julian Day Number of ED, and
631  * IPj == the Julian Day Number of IP in the following.
632  *
633  * pve is be computed as:
634  *
635  * pve = pv*(1 + i)^(s*PF/d*CF)
636  *
637  * Where: d = length of the payment period in days, and
638  * s = IPj - EDj - d*X
639  *
640  * Computing an amortization Schedule for a given financial transaction is
641  * simply applying the basic equation iteratively for each payment period:
642  *
643  * PV[n] = PV[n-1] + (PMT + (PV[n-1] + X * PMT) * i)
644  *
645  * At the end of each iteration, PV[n] is rounded to the nearest cent. For
646  * each payment period, the interest due may be computed separately as:
647  *
648  * ID[n] = (PMT + (PV[n-1] + X * PMT) * i)
649  *
650  * and rounded to the nearest cent. PV[n] then becomes:
651  *
652  * PV[n] = PV[n-1] + PMT + ID[n]
653  *
654  * For those cases where a yearly summary only is desired, it is not
655  * necessary to compute each transaction for each payment period,
656  * rather the PV may be computed for the beginning of each year,
657  * PV[yr], and the FV computed for the end of the year, FV[yr]. The
658  * interest paid during the year is the computed as:
659  *
660  * ID[yr] = (NP * PMT) + PV[yr] + FV[yr]
661  *
662  * Since the final payment may not be equal to the periodic payment,
663  * the final payment must be computed separately as follows. Two
664  * derivations are given below for the final payment equation. Both
665  * derivations are given below since one or the other may be clearer
666  * to some readers. Both derivations are essentially the same, they
667  * just have different starting points. The first is the fastest.
668  *
669  * 1) final_pmt == final payment @ payment n == int(n)
670  * from above the basic financial equation:
671  * PV[n] = PV[n-1]*(1 + i) + final_pmt * (1 + iX),
672  * i == effective interest rate
673  *
674  * solving for final_pmt, we have:
675  *
676  * final_pmt * (1 + iX) = PV[n] - PV[n-1]*(1 + i)
677  * = FV[n-1]*(1 + i) - FV[n]
678  * final_pmt = FV[n-1]*(1+i)/(1 + iX) - FV[n]/(1 + iX)
679  *
680  * final_pmt = FV[n-1]*(1 + i) - FV[n],
681  * for X == 0, end of period payments
682  *
683  * = FV[n-1] - FV[n]/(1 + i),
684  * for X == 1, beginning of period payments
685  *
686  * 2) final_pmt == final payment @ payment n == int(n)
687  * i[n] == interest due @ payment n
688  * i[n] = (PV[n-1] + X * final_pmt) * i, i == effective interest rate
689  * = (X * final_pmt - FV[n]) * i
690  *
691  * Now the final payment is the sum of the interest due, plus
692  * the present value at the next to last payment plus any
693  * residual future value after the last payment:
694  *
695  * final_pmt = -i[n] - PV[n-1] - FV[n]
696  * = FV[n-1] - i[n] - FV[n]
697  * = FV[n-1] - (X *final_pmt - FV[n-1])*i - FV[n]
698  * = FV[n-1]*(1 + i) - X*final_pmt*i - FV[n]
699  *
700  * solving for final_pmt:
701  * final_pmt*(1 + iX) = FV[n-1]*(1 + i) - FV[n]
702  * final_pmt = FV[n-1]*(1 + i)/(1 + iX) - FV[n]/(1 + iX)
703  *
704  * final_pmt = FV[n-1]*(1 + i) - FV[n],
705  * for X == 0, end of period payments
706  *
707  * = FV[n-1] - FV[n]/(1 + i),
708  * for X == 1, beginning of period payments
709  *
710  *============================================================================
711  *
712  * The amortization schedule is computed for four different situations:
713  *
714  * 1) The original financial data is used. This ignores any possible
715  * agjustment to the Present value due to any delay in the initial
716  * payment. This is quite common in mortgages where end of period
717  * payments are used and the first payment is scheduled for the end
718  * of the first whole period, i.e., any partial payment period from
719  * ED to the beginning of the next payment period is ignored.
720  *
721  * 2) The original periodic payment is used, the Present Value is
722  * adjusted for the delayed Initial Payment. The total number of
723  * payments remains the same. The final payment is adjusted to bring
724  * the balance into agreement with the agreed upon final Future
725  * Value.
726  *
727  * 3) A new periodic payment is computed based upon the adjusted
728  * Present Value, the agreed originally upon number of total
729  * payments and the agreed upon Future Value. The new periodic
730  * payments are computed to minimize the final payment in accordance
731  * with the Future Value after the last payment.
732  *
733  * 4) The original periodic payment is retained and a new number of
734  * total payments is computed based upon the adjusted Present Value
735  * and the agreed upon Future Value.
736  *
737  * The amortization schedule may be computed and displayed in three manners:
738  *
739  * 1. The payment *, interest paid, principal paid and remaining PV
740  * for each payment period are computed and displayed. At the end of
741  * each year a summary is computed and displayed and the total
742  * interest paid is displayed at the end.
743  *
744  * 2. A summary is computed and displayed for each year. The
745  * interest paid during the year is computed and displayed as well
746  * as the remaining balance at years end. The total interest paid
747  * is displayed at the end.
748  *
749  * 3. An amortization schedule is computed for a common method of
750  * advanced payment of principal is computed and displayed. In this
751  * amortization, the principal for the next payment is computed and
752  * added into the current payment. This method will cut the number
753  * of total payments in half and will cut the interest paid almost
754  * in half. For mortgages, this method of prepayment has the
755  * advantage of keeping the total payments small during the initial
756  * payment periods The payments grow until the last payment period
757  * when presumably the borrower can afford larger payments.
758  *
759  * ===========================================================================
760  * NOTE: For Payment Frequencies, PF, semi-monthly or less, i.e., PF
761  * == 12 or PF == 24, a 360 day calendar year and 30 day month are
762  * used. For Payment Frequencies, PF, greater than semi-monthly, PF
763  * > 24, the actual number of days per year and per payment period
764  * are used. The actual values are computed using the built-in
765  * 'julian_day_number' function
766  *
767  * ****************************************************************************
768  *
769  * Note: in the following examples, the user input is preceded by the
770  * prompt "<>". The result of evaluating the input expression is then
771  * displayed. I have taken the liberty of including comments in the
772  * example input/output sessions by preceding with ' *'. Thus, for
773  * the line: <>n=5 *set number of periods the comment that setting the
774  * number of periods is not really input and the true input is only:
775  * <>n=5
776  *
777  * Example 1: Simple Interest
778  * Find annual simple interest rate (%) for an $800 loan to be repayed at the
779  * end of one year with a single payment of $896.
780  * <>d
781  * <>CF=PF=1
782  * 1.00
783  * <>n=1
784  * 1.00
785  * <>pv=-800
786  * -800.00
787  * <>fv=896
788  * 896.00
789  * <>I
790  * 12.00
791  *
792  * Example 2: Compound Interest
793  * Find the future value of $800 after one year at a nominal rate of 12%
794  * compounded monthly. No payments are specified, so the payment frequency is
795  * set equal to the compounding frequency at the default values.
796  * <>d
797  * <>n=12
798  * 12.00
799  * <>i=12
800  * 12.00
801  * <>pv=-800
802  * -800.00
803  * <>FV
804  * 901.46
805  *
806  * Example 3: Periodic Payment:
807  * Find the monthly end-of-period payment required to fully amortize the loan
808  * in Example 2. A fully amortized loan has a future value of zero.
809  * <>fv=0
810  * 0.00
811  * <>PMT
812  * 71.08
813  *
814  * Example 4: Conventional Mortgage
815  *
816  * Find the number of monthly payments necessary to fully amortize a
817  * loan of $100,000 at a nominal rate of 13.25% compounded monthly, if
818  * monthly end-of-period payments of $1125.75 are made.
819  *
820  * <>d
821  * <>i=13.25
822  * 13.25
823  * <>pv=100000
824  * 100,000.00
825  * <>pmt=-1125.75
826  * -1,125.75
827  * <>_N(i,pv,pmt,fv,CF,PF,disc,bep)
828  * 360.10
829  * <>N
830  * 360
831  *
832  * Example 5: Final Payment
833  * Using the data in example 4, find the amount of the final payment if n is
834  * changed to 360. The final payment will be equal to the regular payment plus
835  * any balance, future value, remaining at the end of period number 360.
836  * <>n=360
837  * 360.00
838  * <>FV
839  * -108.87
840  * <>pmt+fv
841  * -1,234.62
842  *
843  * Using the data from this loan, compute the amortization schedule
844  * when the Effective date of the loan is June 6, 1996 and the
845  * initial payment is made on August 1, 1996. Ignore any change in
846  * the PV due to the delayed initial payment caused by the partial
847  * payment period from June 6 to July 1.
848  *
849  * <>ED = 06/06/1996
850  * Effective Date set: 06/06/1996 ( 2450241 )
851  * <>IP = 08/01/1996
852  * Initial Payment Date set: 08/01/1996 ( 2450297 )
853  * <>a
854  * Effective Date: 06/06/96
855  * Initial Payment Date: 08/01/96
856  * The amortization options are:
857  * The Old Present Value (pv) was: 100,000.00
858  * The Old Periodic Payment (pmt) was: -1,125.75
859  * The Old Future Value (fv) was: -108.87
860  * 1: Amortize with Original Transaction Values
861  * and balloon final payment: -1,125.75
862  *
863  * The New Present Value (pve) is: 100,919.30
864  * The New Periodic Payment (pmt) is: -1,136.10
865  * 2: Amortize with Original Periodic Payment
866  * and balloon final payment: -49,023.68
867  * 3: Amortize with New Periodic Payment
868  * and balloon final payment: -1,132.57
869  * 4: Amortize with Original Periodic Payment,
870  * new number of total payments (n): 417
871  * and final payment: -2,090.27
872  *
873  * Enter choice 1, 2, 3 or 4: <>
874  *
875  * Press '1'
876  * Amortization Schedule:
877  * Yearly, y, per Payment, p, or Advanced Payment, a, Amortization
878  * Enter choice y, p or a:
879  * <>
880  *
881  * Press 'y'
882  * Enter Filename for Amortization Schedule.
883  * (null string uses Standard Output):
884  * Press enter to display output on screen
885  *
886  * Amortization Table
887  * Effective Date: Thu Jun 06 00:00:00 1996
888  * Initial Payment Date: Thu Aug 01 00:00:00 1996
889  * Compounding Frequency per year: 12
890  * Payment Frequency per year: 12
891  * Compounding: Discrete
892  * Payments: End of Period
893  * Payments (359): -1,125.75
894  * Final payment: -1,125.75
895  * Nominal Annual Interest Rate: 13.25
896  * Effective Interest Rate Per Payment Period: 0.0110417
897  * Present Value: 100,000.00
898  * Year Interest Ending Balance
899  * 1996 -5,518.42 -99,889.67
900  * 1997 -13,218.14 -99,598.81
901  * 1998 -13,177.17 -99,266.98
902  * 1999 -13,130.43 -98,888.41
903  * 2000 -13,077.11 -98,456.52
904  * 2001 -13,016.28 -97,963.80
905  * 2002 -12,946.88 -97,401.68
906  * 2003 -12,867.70 -96,760.38
907  * 2004 -12,777.38 -96,028.76
908  * 2005 -12,674.33 -95,194.09
909  * 2006 -12,556.76 -94,241.85
910  * 2007 -12,422.64 -93,155.49
911  * 2008 -12,269.63 -91,916.12
912  * 2009 -12,095.06 -90,502.18
913  * 2010 -11,895.91 -88,889.09
914  * 2011 -11,668.70 -87,048.79
915  * 2012 -11,409.50 -84,949.29
916  * 2013 -11,113.78 -82,554.07
917  * 2014 -10,776.41 -79,821.48
918  * 2015 -10,391.53 -76,704.01
919  * 2016 -9,952.43 -73,147.44
920  * 2017 -9,451.49 -69,089.93
921  * 2018 -8,879.99 -64,460.92
922  * 2019 -8,227.99 -59,179.91
923  * 2020 -7,484.16 -53,155.07
924  * 2021 -6,635.56 -46,281.63
925  * 2022 -5,667.43 -38,440.06
926  * 2023 -4,562.94 -29,494.00
927  * 2024 -3,302.89 -19,287.89
928  * 2025 -1,865.36 -7,644.25
929  * 2026 -236.00 -108.87
930  *
931  * Total Interest: -305,270.00
932  *
933  * NOTE: The amortization table leaves the FV as it was when the amortization
934  * function was entered. Thus, a balance of 108.87 is due at the end of the
935  * table. To completely pay the loan, set fv to 0.0:
936  * <>fv=0
937  * 0.0
938  * <>a
939  * Effective Date: 06/06/96
940  * Initial Payment Date: 08/01/96
941  * The amortization options are:
942  * The Old Present Value (pv) was: 100,000.00
943  * The Old Periodic Payment (pmt) was: -1,125.75
944  * The Old Future Value (fv) was: 0.00
945  * 1: Amortize with Original Transaction Values
946  * and balloon final payment: -1,234.62
947  *
948  * The New Present Value (pve) is: 100,919.30
949  * The New Periodic Payment (pmt) is: -1,136.12
950  * 2: Amortize with Original Periodic Payment
951  * and balloon final payment: -49,132.55
952  * 3: Amortize with New Periodic Payment
953  * and balloon final payment: -1,148.90
954  * 4: Amortize with Original Periodic Payment,
955  * new number of total payments (n): 417
956  * and final payment: -2,199.14
957  *
958  * Enter choice 1, 2, 3 or 4: <>
959  * Press '1'
960  * Amortization Schedule:
961  * Yearly, y, per Payment, p, or Advanced Payment, a, Amortization
962  * Enter choice y, p or a:
963  * <>
964  * Press 'y'
965  * Enter Filename for Amortization Schedule.
966  * (null string uses Standard Output):
967  * Press enter to display output on screen
968  *
969  * Amortization Table
970  * Effective Date: Thu Jun 06 00:00:00 1996
971  * Initial Payment Date: Thu Aug 01 00:00:00 1996
972  * Compounding Frequency per year: 12
973  * Payment Frequency per year: 12
974  * Compounding: Discrete
975  * Payments: End of Period
976  * Payments (359): -1,125.75
977  * Final payment: -1,234.62
978  * Nominal Annual Interest Rate: 13.25
979  * Effective Interest Rate Per Payment Period: 0.0110417
980  * Present Value: 100,000.00
981  * Year Interest Ending Balance
982  * 1996 -5,518.42 -99,889.67
983  * 1997 -13,218.14 -99,598.81
984  * 1998 -13,177.17 -99,266.98
985  * 1999 -13,130.43 -98,888.41
986  * 2000 -13,077.11 -98,456.52
987  * 2001 -13,016.28 -97,963.80
988  * 2002 -12,946.88 -97,401.68
989  * 2003 -12,867.70 -96,760.38
990  * 2004 -12,777.38 -96,028.76
991  * 2005 -12,674.33 -95,194.09
992  * 2006 -12,556.76 -94,241.85
993  * 2007 -12,422.64 -93,155.49
994  * 2008 -12,269.63 -91,916.12
995  * 2009 -12,095.06 -90,502.18
996  * 2010 -11,895.91 -88,889.09
997  * 2011 -11,668.70 -87,048.79
998  * 2012 -11,409.50 -84,949.29
999  * 2013 -11,113.78 -82,554.07
1000  * 2014 -10,776.41 -79,821.48
1001  * 2015 -10,391.53 -76,704.01
1002  * 2016 -9,952.43 -73,147.44
1003  * 2017 -9,451.49 -69,089.93
1004  * 2018 -8,879.99 -64,460.92
1005  * 2019 -8,227.99 -59,179.91
1006  * 2020 -7,484.16 -53,155.07
1007  * 2021 -6,635.56 -46,281.63
1008  * 2022 -5,667.43 -38,440.06
1009  * 2023 -4,562.94 -29,494.00
1010  * 2024 -3,302.89 -19,287.89
1011  * 2025 -1,865.36 -7,644.25
1012  * 2026 -344.87 0.00
1013  *
1014  * Total Interest: -305,378.87
1015  *
1016  * Example 6: Balloon Payment
1017  * On long term loans, small changes in the periodic payments can generate
1018  * large changes in the future value. If the monthly payment in example 5 is
1019  * rounded down to $1125, how much additional (balloon) payment will be due
1020  * with the final regular payment.
1021  * <>pmt=-1125
1022  * -1,125
1023  * <>FV
1024  * -3,579.99
1025  *
1026  * Example 7: Canadian Mortgage
1027  * Find the monthly end-of-period payment necessary to fully amortize a 25 year
1028  * $85,000 loan at 11% compounded semi-annually.
1029  * <>d
1030  * <>CF=2
1031  * 2.00
1032  * <>n=300
1033  * 300.00
1034  * <>i=11
1035  * 11.00
1036  * <>pv=85000
1037  * 85,000.00
1038  * <>PMT
1039  * -818.15
1040  *
1041  * Example 8: European Mortgage
1042  * The "effective annual rate (EAR)" is used in some countries (especially
1043  * in Europe) in lieu of the nominal rate commonly used in the United States
1044  * and Canada. For a 30 year $90,000 mortgage at 14% (EAR), compute the monthly
1045  * end-of-period payments. When using an EAR, the compounding frequency is
1046  * set to 1.
1047  * <>d
1048  * <>CF=1
1049  * 1.00
1050  * <>n=30*12
1051  * 360.00
1052  * <>i=14
1053  * 14.00
1054  * <>pv=90000
1055  * 90,000.00
1056  * <>PMT
1057  * -1,007.88
1058  *
1059  * Example 9: Bi-weekly Savings
1060  * Compute the future value, fv, of bi-weekly savings of $100 for 3 years at a
1061  * nominal annual rate of 5.5% compounded daily. (Set payment to
1062  * beginning-of-period, bep = TRUE)
1063  * <>d
1064  * <>bep=TRUE
1065  * 1.00
1066  * <>CF=365
1067  * 365.00
1068  * <>PF=26
1069  * 26.00
1070  * <>n=3*26
1071  * 78.00
1072  * <>i=5.5
1073  * 5.50
1074  * <>pmt=-100
1075  * -100.00
1076  * <>FV
1077  * 8,489.32
1078  *
1079  * Example 10: Present Value - Annuity Due
1080  * What is the present value of $500 to be received at the beginning of each
1081  * quarter over a 10 year period if money is being discounted at 10% nominal
1082  * annual rate compounded monthly?
1083  * <>d
1084  * <>bep=TRUE
1085  * 1.00
1086  * <>PF=4
1087  * 4.00
1088  * <>n=4*10
1089  * 40.00
1090  * <>i=10
1091  * 10.00
1092  * <>pmt=500
1093  * 500.00
1094  * <>PV
1095  * -12,822.64
1096  *
1097  * Example 11: Effective Rate - 365/360 Basis
1098  * Compute the effective annual rate (%APR) for a nominal annual rate of 12%
1099  * compounded on a 365/360 basis used by some Savings & Loan Associations.
1100  * <>d
1101  * <>n=365
1102  * 365.00
1103  * <>CF=365
1104  * 365.00
1105  * <>PF=360
1106  * 360.00
1107  * <>i=12
1108  * 12.00
1109  * <>pv=-100
1110  * -100.00
1111  * <>FV
1112  * 112.94
1113  * <>fv+pv
1114  * 12.94
1115  *
1116  * Example 12: Mortgage with "Points"
1117  *
1118  * What is the true APR of a 30 year, $75,000 loan at a nominal rate
1119  * of 13.25% compounded monthly, with monthly end-of-period payments,
1120  * if 3 "points" are charged? The pv must be reduced by the dollar
1121  * value of the points and/or any lenders fees to establish an
1122  * effective pv. Because payments remain the same, the true APR will
1123  * be higher than the nominal rate. Note, first compute the payments
1124  * on the pv of the loan amount.
1125  *
1126  * <>d
1127  * <>CF=PF=1
1128  * 1.00
1129  * <>n=30*12
1130  * 360.00
1131  * <>i=13.25/12
1132  * 1.10
1133  * <>pv=75000
1134  * 75,000.00
1135  * <>PMT
1136  * -844.33
1137  * <>pv -= pv*.03
1138  * 72,750.00
1139  * <>CF=PF=12
1140  * 12.00
1141  * <>I
1142  * 13.69
1143  *
1144  * Example 13: Equivalent Payments
1145  * Find the equivalent monthly payment required to amortize a 20 year $40,000
1146  * loan at 10.5% nominal annual rate compounded monthly, with 10 annual
1147  * payments of $5029.71 remaining. Compute the pv of the remaining annual
1148  * payments, then change n, the number of periods, and the payment frequency,
1149  * PF, to a monthly basis and compute the equivalent monthly pmt.
1150  * <>d
1151  * <>PF=1
1152  * 1.00
1153  * <>n=10
1154  * 10.00
1155  * <>i=10.5
1156  * 10.50
1157  * <>pmt=-5029.71
1158  * -5,029.71
1159  * <>PV
1160  * 29,595.88
1161  * <>PF=12
1162  * 12.00
1163  * <>n=120
1164  * 120.00
1165  * <>PMT
1166  * -399.35
1167  *
1168  * Example 14: Perpetuity - Continuous Compounding
1169  * If you can purchase a single payment annuity with an initial investment of
1170  * $60,000 that will be invested at 15% nominal annual rate compounded
1171  * continuously, what is the maximum monthly return you can receive without
1172  * reducing the $60,000 principal? If the principal is not disturbed, the
1173  * payments can go on indefinitely (a perpetuity). Note that the term,n, of
1174  * a perpetuity is immaterial. It can be any non-zero value.
1175  * <>d
1176  * <>disc=FALSE
1177  * 0.00
1178  * <>n=12
1179  * 12.00
1180  * <>CF=1
1181  * 1.00
1182  * <>i=15
1183  * 15.00
1184  * <>fv=60000
1185  * 60,000.00
1186  * <>pv=-60000
1187  * -60,000.00
1188  * <>PMT
1189  * 754.71
1190  *
1191  * references:
1192  * 1. PPC ROM User's Manual
1193  * pages 148 - 164
1194  *
1195  */
1196 
1197 #include <time.h>
1198 #include <stdio.h>
1199 #include <glib.h>
1200 #include <math.h>
1201 #if defined(G_OS_WIN32) && !defined(_MSC_VER)
1202 #include <pow.h>
1203 #endif
1204 #include <string.h>
1205 #include <stdlib.h>
1206 
1207 #define FIN_STATICS
1208 #include "finvar.h"
1209 #include "finproto.h"
1210 #include "fin_static_proto.h"
1211 
1212 /* return 'x' rounded to 'places' past decimal if 'places' < 0, return
1213  * 'x' */
1214 static double
1215 rnd (double x, unsigned places)
1216 {
1217  static const size_t buflen = 50; /* make buffer large enough */
1218  double r;
1219  char buf[buflen];
1220 
1221  snprintf (buf, buflen, "%.*f", (int) places, x);
1222  r = strtod(buf, NULL);
1223 
1224  return r;
1225 } /* rnd */
1226 
1227 /* return absolute value of 'x' this function is provided by a macro
1228  * in C */
1229 static double
1230 dabs (double x)
1231 {
1232  return (x >= 0.0) ? x : -x;
1233 } /* dabs */
1234 
1235 /* Compute constant used in calculations */
1236 static double
1237 _A (double eint, unsigned per)
1238 {
1239  return pow ((1.0 + eint), (double) per) - 1.0;
1240 } /* _A */
1241 
1242 /* Compute constant used in calculations */
1243 static double
1244 _B (double eint, unsigned beg)
1245 {
1246  /* if eint == 0.0, all processing _must_ stop or
1247  a recursive loop will start. */
1248  g_return_val_if_fail(eint != 0.0, 0.0);
1249  return (1.0 + eint * (double) beg) / eint;
1250 } /* _B */
1251 
1252 /* Compute constant used in calculations */
1253 static double
1254 _C (double eint, double pmt, unsigned beg)
1255 {
1256  g_return_val_if_fail(eint != 0.0, 0.0);
1257  return pmt * _B(eint, beg);
1258 } /* _C */
1259 
1260 /* compute Number of Periods from preset data */
1261 unsigned
1262 fi_calc_num_payments (fi_ptr fi)
1263 {
1264  return fi->npp =
1265  (unsigned)
1266  rnd (_fi_calc_num_payments
1267  (fi->ir, fi->pv, fi->pmt, fi->fv, fi->CF, fi->PF, fi->disc, fi->bep),
1268  0);
1269 } /* fi_calc_num_payments */
1270 
1271 /* Compute number of periods from:
1272  * 1. Nominal Interest
1273  * 2. Present Value
1274  * 3. Periodic Payment
1275  * 4. Future Value
1276  */
1277 double
1278 _fi_calc_num_payments (double nint, /* nominal interest rate */
1279  double pv, /* present value */
1280  double pmt, /* periodic payment */
1281  double fv, /* future value */
1282  unsigned CF, /* compounding frequency */
1283  unsigned PF, /* payment frequency */
1284  unsigned disc, /* discrete/continuous compounding */
1285  unsigned bep) /* beginning/end of period payment */
1286 {
1287  double eint = eff_int (nint / 100.0, CF, PF, disc);
1288  double CC = _C (eint, pmt, bep);
1289  CC = (CC - fv) / (CC + pv);
1290  return (CC > 0.0) ? log (CC) / log (1.0 + eint) : 0.0;
1291 } /* _fi_calc_num_payments */
1292 
1293 /* compute Interest from preset data */
1294 double
1295 fi_calc_interest (fi_ptr fi)
1296 {
1297  if (fi->npp)
1298  fi->ir = _fi_calc_interest (fi->npp, fi->pv, fi->pmt, fi->fv,
1299  fi->CF, fi->PF, fi->disc, fi->bep);
1300 
1301  return fi->ir;
1302 } /* fi_calc_interest */
1303 
1304 double ratio = 1e4; /* ratio used in iterative solution for interest */
1305 
1306 /* Compute Nominal Interest from:
1307  * 1. Number of periods
1308  * 2. Present Value
1309  * 3. Periodic Payment
1310  * 4. Future Value
1311  */
1312 double
1313 _fi_calc_interest (unsigned per,/* number of periods */
1314  double pv, /* present value */
1315  double pmt, /* periodic payment */
1316  double fv, /* future value */
1317  unsigned CF, /* compounding frequency */
1318  unsigned PF, /* payment frequency */
1319  unsigned disc, /* discrete/continuous compounding */
1320  unsigned bep) /* beginning/end of period payment */
1321 {
1322  double eint;
1323  double a, dik;
1324  int ri;
1325 
1326  if (pmt == 0.0)
1327  eint = pow ((dabs (fv) / dabs (pv)), (1.0 / (double) per)) - 1.0;
1328  else
1329  {
1330  if ((pmt * fv) < 0.0)
1331  {
1332  if (pv)
1333  a = -1.0;
1334  else
1335  a = 1.0;
1336  eint =
1337  dabs ((fv + a * (double) per * pmt) /
1338  (3.0 *
1339  (((double) per - 1.0) * ((double) per - 1.0) * pmt + pv -
1340  fv)));
1341  }
1342  else
1343  {
1344  if ((pv * pmt) < 0.0)
1345  {
1346  eint = dabs (((double) per * pmt + pv + fv) / ((double) per * pv));
1347  }
1348  else
1349  {
1350  a = dabs (pmt / (dabs (pv) + dabs (fv)));
1351  eint = a + 1.0 / (a * (double) per * (double) per * (double) per);
1352  }
1353  }
1354  do
1355  {
1356  dik =
1357  fi (per, eint, pv, pmt, fv, bep) / fip (per, eint, pv, pmt, fv, bep);
1358  eint -= dik;
1359  (void) modf (ratio * (dik / eint), &a);
1360  ri = (unsigned) a;
1361  }
1362  while (ri);
1363  } /* endif */
1364 
1365  return 100.0 * nom_int (eint, CF, PF, disc);
1366 } /* _fi_calc_interest */
1367 
1368 /* compute Present value from preset data */
1369 double
1370 fi_calc_present_value (fi_ptr fi)
1371 {
1372  return fi->pv =
1373  rnd (_fi_calc_present_value
1374  (fi->npp, fi->ir, fi->pmt, fi->fv, fi->CF, fi->PF, fi->disc,
1375  fi->bep), fi->prec);
1376 } /* fi_calc_present_value */
1377 
1378 /* Compute Present Value from:
1379  * 1. Number of periods
1380  * 2. Nominal Interest
1381  * 3. Periodic Payment
1382  * 4. Future Value
1383  */
1384 double
1385 _fi_calc_present_value (unsigned per, /* number of periods */
1386  double nint, /* nominal interest rate */
1387  double pmt, /* periodic payment */
1388  double fv, /* future value */
1389  unsigned CF, /* compounding frequency */
1390  unsigned PF, /* payment frequency */
1391  unsigned disc, /* discrete/continuous compounding */
1392  unsigned bep) /* beginning/end of period payment */
1393 {
1394  double eint = eff_int (nint / 100.0, CF, PF, disc);
1395  double AA = _A (eint, per);
1396  double CC = _C (eint, pmt, bep);
1397 
1398  return -(fv + (AA * CC)) / (AA + 1.0);
1399 } /* _fi_calc_present_value */
1400 
1401 /* compute Periodic Payment from preset data */
1402 double
1403 fi_calc_payment (fi_ptr fi)
1404 {
1405  return fi->pmt =
1406  rnd (_fi_calc_payment
1407  (fi->npp, fi->ir, fi->pv, fi->fv, fi->CF, fi->PF, fi->disc, fi->bep),
1408  fi->prec);
1409 } /* fi_calc_payment */
1410 
1411 /* Compute Periodic Payment from:
1412  * 1. Number of periods
1413  * 2. Nominal Interest
1414  * 3. Present Value
1415  * 4. Future Value
1416  */
1417 double
1418 _fi_calc_payment (unsigned per, /* number of periods */
1419  double nint, /* nominal interest rate */
1420  double pv, /* present value */
1421  double fv, /* future value */
1422  unsigned CF, /* compounding frequency */
1423  unsigned PF, /* payment frequency */
1424  unsigned disc,/* discrete/continuous compounding */
1425  unsigned bep) /* beginning/end of period payment */
1426 {
1427  double eint = eff_int (nint / 100.0, CF, PF, disc);
1428  double AA = _A (eint, per);
1429  double BB = _B (eint, bep);
1430  g_return_val_if_fail(BB != 0.0, 0.0);
1431 
1432  return -(fv + pv * (AA + 1.0)) / (AA * BB);
1433 } /* _fi_calc_payment */
1434 
1435 /* compute Future Value from preset data */
1436 double
1437 fi_calc_future_value (fi_ptr fi)
1438 {
1439  return fi->fv =
1440  rnd (_fi_calc_future_value
1441  (fi->npp, fi->ir, fi->pv, fi->pmt, fi->CF, fi->PF, fi->disc,
1442  fi->bep), fi->prec);
1443 } /* fi_calc_future_value */
1444 
1445 /* Compute Future Value from:
1446  * 1. Number of periods
1447  * 2. Nominal Interest
1448  * 3. Present Value
1449  * 4. Periodic Payments
1450  */
1451 double
1452 _fi_calc_future_value (unsigned per, /* number of periods */
1453  double nint, /* nominal interest rate */
1454  double pv, /* present value */
1455  double pmt, /* periodic payment */
1456  unsigned CF, /* compounding frequency */
1457  unsigned PF, /* payment frequency */
1458  unsigned disc, /* discrete/continuous compounding */
1459  unsigned bep) /* beginning/end of period payment */
1460 {
1461  double eint = eff_int (nint / 100.0, CF, PF, disc);
1462  double AA = _A (eint, per);
1463  double CC = _C (eint, pmt, bep);
1464 
1465  return -(pv + AA * (pv + CC));
1466 } /* _fi_calc_future_value */
1467 
1468 /* compute Nominal Interest Rate from Effective Interest Rate */
1469 static double
1470 nom_int (double eint, unsigned CF, unsigned PF, unsigned disc)
1471 {
1472  double nint;
1473 
1474  if (disc)
1475  {
1476  if (CF == PF)
1477  {
1478  nint = CF * eint;
1479  }
1480  else
1481  {
1482  nint = CF * (pow ((1.0 + eint), ((double) PF / (double) CF)) - 1.0);
1483  } /* * endif */
1484  }
1485  else
1486  nint = log (pow (1.0 + eint, PF));
1487 
1488  return nint;
1489 } /* nom_int */
1490 
1491 /* Compute Effective Interest Rate from Nominal Interest Rate */
1492 static double
1493 eff_int (double nint, unsigned CF, unsigned PF, unsigned disc)
1494 {
1495  double eint;
1496 
1497  if (disc)
1498  {
1499  if (CF == PF)
1500  {
1501  eint = nint / (double) CF;
1502  }
1503  else
1504  {
1505  eint =
1506  pow ((1.0 + nint / (double) CF), ((double) CF / (double) PF)) - 1.0;
1507  } /* endif */
1508  }
1509  else
1510  eint = exp (nint / (double) PF) - 1.0;
1511 
1512  return eint;
1513 } /* eff_int */
1514 
1515 /* calculation used in interest computation */
1516 static double
1517 fi (unsigned per, double eint, double pv, double pmt, double fv, unsigned bep)
1518 {
1519  return _A (eint, per) * (pv + _C (eint, pmt, bep)) + pv + fv;
1520 } /* fi */
1521 
1522 /* calculation used in interest computation
1523  */
1524 static double
1525 fip (unsigned per, double eint, double pv, double pmt, double fv, unsigned bep)
1526 {
1527  double AA = _A (eint, per);
1528  double CC = _C (eint, pmt, bep);
1529  double D = (AA + 1.0) / (1.0 + eint);
1530  g_return_val_if_fail(CC != 0.0, 0.0);
1531  return (double) per * (pv + CC) * D - (AA * CC) / eint;
1532 } /* fip */
1533 
1534 void
1535 set_default (fi_ptr fi)
1536 {
1537  /* flag whether accrueing interest at beginning or end of period
1538  * FALSE --> end
1539  * TRUE --> beginning
1540  * default to end of period payment s
1541  */
1542  fi->bep = FALSE;
1543 
1544  /* flag for discrete or continuous interest
1545  * TRUE --> discrete
1546  * FALSE --> continuous
1547  * default to discrete interest
1548  */
1549  fi->disc = TRUE;
1550 
1551  /* set compounding, CF, and payment, PF, frequency per year
1552  * default to monthly payments and compounding
1553  */
1554  fi->CF = fi->PF = 12;
1555 
1556  /* standard loan quantities:
1557  * number of periods: n
1558  */
1559  fi->npp = 0;
1560 
1561  /* annual interest: i
1562  */
1563  fi->ir = 0.0;
1564 
1565  /* Present Value: pv
1566  */
1567  fi->pv = 0.0;
1568 
1569  /* Payment: pmt
1570  */
1571  fi->pmt = 0.0;
1572 
1573  /* Future Value: fv
1574  */
1575  fi->fv = 0.0;
1576 
1577 } /* set_default */
1578 
1579 /* compute Julian Day Number from calendar date
1580  */
1581 unsigned long
1582 julian_day_number (unsigned year, unsigned month, unsigned day)
1583 {
1584  /* Gregorian/Julian Calendar Flag.
1585  * TRUE == Julian
1586  * FALSE == Gregorian
1587  */
1588  unsigned gregorian = TRUE; /* assume we are dealing with current dates */
1589  double yr;
1590  double pfac = 0.6;
1591  unsigned long ljdn;
1592 
1593  yr = year + (month - 3.0) / 12.0;
1594  ljdn = (long) (367.0 * yr + pfac) - (2 * (long) (yr)) + (long) (yr / 4.0)
1595  + (long) day + 1721117L;
1596  if (gregorian)
1597  ljdn += -(long) (yr / 100.0) + (long) (yr / 400.0) + 2;
1598 
1599  return ljdn;
1600 } /* julian_day_number */
1601 
1602 amort_sched_ptr
1603 Amortization_init (amort_sched_ptr amortsched)
1604 {
1605  unsigned n = amortsched->n;
1606  double nint = amortsched->nint;
1607  double pv = amortsched->pv;
1608  double pmt = amortsched->pmt;
1609  double fv = amortsched->fv;
1610  double eint;
1611  double new_pmt;
1612  double pve;
1613  unsigned CF = amortsched->CF;
1614  unsigned PF = amortsched->PF;
1615  unsigned disc = amortsched->disc;
1616  unsigned bep = amortsched->bep;
1617  unsigned new_n;
1618  unsigned prec = amortsched->prec;
1619  unsigned long s,
1620  d,
1621  days_to_yr_end,
1622  Eff_Date_jdn =
1623  julian_day_number (amortsched->year_E, amortsched->month_E,
1624  amortsched->day_E), Init_Date_jdn =
1625  julian_day_number (amortsched->year_I, amortsched->month_I,
1626  amortsched->day_I);
1627 
1628  amortsched->Eff_Date_jdn = Eff_Date_jdn;
1629  amortsched->Init_Date_jdn = Init_Date_jdn;
1630  amortsched->yday_E =
1631  Eff_Date_jdn - julian_day_number (amortsched->year_E, 1, 1);
1632  amortsched->yday_I =
1633  Init_Date_jdn - julian_day_number (amortsched->year_I, 1, 1);
1634  amortsched->eint = eint = eff_int (nint / 100.0, CF, PF, disc);
1635  amortsched->fv_case = dabs (fv) > dabs (pv);
1636  amortsched->bp = bep ? 1.0 : 0.0;
1637 
1638  if (PF > 24)
1639  {
1640  /* Payment frequency per year greater than bi-monthly
1641  * use actual number of days
1642  */
1643  s = Init_Date_jdn - Eff_Date_jdn;
1644  days_to_yr_end =
1645  julian_day_number (amortsched->year_I + 1, 1, 0) - Init_Date_jdn;
1646  d = 366 / PF;
1647  }
1648  else
1649  {
1650  /* Payment frequency per year bi-monthly or less
1651  * use 30 days/month, 360 days/year
1652  */
1653  if (Eff_Date_jdn == Init_Date_jdn)
1654  {
1655  s = 0;
1656  }
1657  else
1658  {
1659  s =
1660  ((amortsched->year_I - amortsched->year_E) * 360) +
1661  ((amortsched->month_I - amortsched->month_E) * 30) +
1662  amortsched->day_I - amortsched->day_E;
1663  } /* endif */
1664  days_to_yr_end = 390 - (amortsched->month_I * 30) - amortsched->day_I;
1665  d = 360 / PF;
1666  } /* endif */
1667 
1668  if (!bep)
1669  {
1670  /* ordinary annuity
1671  */
1672  s -= d;
1673  } /* endif */
1674 
1675  amortsched->yr_pmt = (days_to_yr_end + d) / d;
1676 
1677  if (pmt == 0.0)
1678  {
1679  amortsched->pve = pv;
1680  }
1681  else
1682  {
1683  amortsched->pve =
1684  rnd (pv * pow ((1.0 + eint), ((double) (s * PF) / (double) (d * CF))),
1685  prec);
1686  } /* endif */
1687 
1688  pve = amortsched->pve;
1689 
1690  /* compute new data to fully amortize loan:
1691  * new periodic payment, new_pmt
1692  *
1693  * option 1: Amortize with original transaction - ignore interest
1694  * due to delayed initial payment
1695  *
1696  * option 2: Amortize with new pv, pve == original pv adjusted for
1697  * delayed initial payment, original payment, original fv and
1698  * original total number of payments, adjust final payment
1699  *
1700  * option 3: amortize with new pv, pve, and new payments adjusted to
1701  * minimize final payment, keep original number of payments and
1702  * original fv
1703  *
1704  * option 4: amortize with new pv, pve, original payments and new
1705  * number of payments to keep original final fv */
1706 
1707  /* option 3, compute new periodic payment */
1708  amortsched->new_pmt = new_pmt =
1709  rnd (_fi_calc_payment (n, nint, pve, fv, CF, PF, disc, bep), prec);
1710 
1711  /* option 4: compute new number of total payments, new_n */
1712  amortsched->new_n = new_n =
1713  (unsigned)
1714  rnd (_fi_calc_num_payments (nint, pve, pmt, fv, CF, PF, disc, bep), 0);
1715 
1716  /* following used in QTAwk to insure integer value, not needed in C */
1717  /* n = int(n); */
1718 
1719  /* compute payment for constant payment to principal loan and final
1720  * payment for original loan amount include interest due */
1721  amortsched->cpmt1 = rnd (-pv / n, prec);
1722  amortsched->final_pmt_opt_1 = -pv - amortsched->cpmt1 * (n - 1);
1723  amortsched->final_pmt_opt_1 *= eint + 1;
1724 
1725  /* compute payment for constant payment to principal loan and final
1726  * payment for delayed loan amount include interest due */
1727  amortsched->cpmt2 = rnd (-pve / n, prec);
1728  amortsched->final_pmt_opt_2 = -pve - amortsched->cpmt2 * (n - 1);
1729  amortsched->final_pmt_opt_2 *= eint + 1;
1730 
1731  if (bep)
1732  {
1733  amortsched->final_pmt_opt_3 =
1734  rnd (_fi_calc_future_value (n - 1, nint, pv, pmt, CF, PF, disc, bep) -
1735  (fv / (1.0 + eint)), prec);
1736  amortsched->final_pmt_opt_4 =
1737  rnd (_fi_calc_future_value (n - 1, nint, pve, pmt, CF, PF, disc, bep) -
1738  (fv / (1.0 + eint)), prec);
1739  amortsched->final_pmt_opt_5 =
1740  rnd (_fi_calc_future_value
1741  (n - 1, nint, pve, new_pmt, CF, PF, disc,
1742  bep) - (fv / (1.0 + eint)), prec);
1743  if (new_n)
1744  amortsched->final_pmt_opt_6 =
1745  rnd (_fi_calc_future_value
1746  (new_n - 1, nint, pve, pmt, CF, PF, disc,
1747  bep) - (fv / (1.0 + eint)), prec);
1748  else
1749  amortsched->final_pmt_opt_6 = 0.0;
1750  }
1751  else
1752  {
1753  amortsched->final_pmt_opt_3 =
1754  rnd (_fi_calc_future_value (n - 1, nint, pv, pmt, CF, PF, disc, bep) *
1755  (1.0 + eint) - fv, prec);
1756  amortsched->final_pmt_opt_4 =
1757  rnd (_fi_calc_future_value (n - 1, nint, pve, pmt, CF, PF, disc, bep) *
1758  (1.0 + eint) - fv, prec);
1759  amortsched->final_pmt_opt_5 =
1760  rnd (_fi_calc_future_value
1761  (n - 1, nint, pve, new_pmt, CF, PF, disc, bep) * (1.0 + eint) - fv,
1762  prec);
1763  if (new_n)
1764  amortsched->final_pmt_opt_6 =
1765  rnd (_fi_calc_future_value
1766  (new_n - 1, nint, pve, pmt, CF, PF, disc,
1767  bep) * (1.0 + eint) - fv, prec);
1768  else
1769  amortsched->final_pmt_opt_6 = 0.0;
1770  } /* endif */
1771 
1772  /* compute delayed interest */
1773  amortsched->delayed_int = pv - amortsched->pve;
1774 
1775  return amortsched;
1776 } /* Amortization_init */
1777 
1778 amort_sched_ptr
1779 Amortization_Schedule (amort_sched_ptr amortsched)
1780 {
1781  unsigned n = amortsched->n;
1782  double nint = amortsched->nint;
1783  double pv = amortsched->pv;
1784  double pmt = amortsched->pmt;
1785  double fv = amortsched->fv;
1786  double eint = amortsched->eint;
1787  unsigned CF = amortsched->CF;
1788  unsigned PF = amortsched->PF;
1789  unsigned disc = amortsched->disc;
1790  unsigned bep = amortsched->bep;
1791  double cpmt = 0;
1792  double final_pmt = 0;
1793  char summary = amortsched->summary;
1794  unsigned option = amortsched->option;
1795  unsigned yr_pmt = amortsched->yr_pmt;
1796  unsigned fv_case = amortsched->fv_case;
1797  unsigned prec = amortsched->prec;
1798  unsigned j, s, yr, per_cnt, pmt_cnt = 0, k = 0, sum_prt;
1799 
1800  int jj;
1801 
1802  unsigned long d;
1803 
1804  double yr_fv, sum_int, yr_int, prin, adv_pmt, pmt_int, hpv = 0.0;
1805  yearly_summary_ptr yrly_sum;
1806  amort_sched_yr_ptr amortyr;
1807  sched_pmt_ptr pmtsched = NULL;
1808 
1809  sum_int = yr_int = 0.0;
1810 
1811  switch (option)
1812  {
1813  case 1:
1814  amortsched->cpmt = cpmt = amortsched->cpmt1;
1815  /* re-compute final payment without interest
1816  */
1817  amortsched->final_pmt = final_pmt = -pv - cpmt * (n - 1);
1818  summary = (summary == 'y') ? 'x' : 'o';
1819  break;
1820  case 2:
1821  amortsched->cpmt = cpmt = amortsched->cpmt2;
1822  pv = amortsched->pve;
1823  /* re-compute final payment without interest
1824  */
1825  amortsched->final_pmt = final_pmt = -pv - cpmt * (n - 1);
1826  summary = (summary == 'y') ? 'x' : 'o';
1827  break;
1828  case 3:
1829  amortsched->final_pmt = final_pmt = amortsched->final_pmt_opt_3;
1830  break;
1831  case 4:
1832  pv = amortsched->pve;
1833  amortsched->final_pmt = final_pmt = amortsched->final_pmt_opt_4;
1834  break;
1835  case 5:
1836  pv = amortsched->pve;
1837  pmt = amortsched->new_pmt;
1838  amortsched->final_pmt = final_pmt = amortsched->final_pmt_opt_5;
1839  break;
1840  case 6:
1841  n = amortsched->new_n;
1842  pv = amortsched->pve;
1843  amortsched->final_pmt = final_pmt = amortsched->final_pmt_opt_6;
1844  break;
1845  } /* endswitch */
1846 
1847  yr = amortsched->year_I;
1848  sum_prt = TRUE;
1849  switch (summary)
1850  {
1851  case 'a':
1852  /* variable advanced prepayment schedule. prepayment equals next
1853  * period principal. */
1854  amortsched->schedule.first_yr =
1855  amortyr = (amort_sched_yr_ptr) calloc (1, sizeof (amort_sched_yr));
1856 
1857  for (per_cnt = 0, s = 1, j = n; pv != fv; j -= 2, per_cnt++)
1858  {
1859  /* basic equation to compute interest this payment period */
1860  pmt_int = -rnd ((pv + (amortsched->bp * pmt)) * eint, prec);
1861 
1862  /* sum yearly interest paid */
1863  yr_int += pmt_int;
1864 
1865  /* sum total interest paid */
1866  sum_int += pmt_int;
1867 
1868  /* compute principal paid this payment period and round to
1869  nearest cent */
1870  if (dabs (pmt) > dabs (pv))
1871  {
1872  prin = -pv;
1873  pmt = prin + pmt_int;
1874  adv_pmt = 0.0;
1875  pv = fv;
1876  }
1877  else
1878  {
1879  prin = rnd (pmt - pmt_int, prec);
1880 
1881  /* compute remaining pv and round to nearest cent */
1882  pv = rnd (pv + prin, prec);
1883 
1884  /* compute principal for next payment cycle and round to
1885  nearest cent */
1886  adv_pmt = rnd (pmt + (pv + (amortsched->bp * pmt)) * eint, prec);
1887 
1888  if (dabs (pv) >= dabs (adv_pmt))
1889  {
1890  /* remaining pv greater than advanced principal payment
1891  * compute remaining pv and round to nearest cent */
1892  pv = rnd (pv + adv_pmt, prec);
1893  }
1894  else
1895  {
1896  /* remaining pv less than advanced principal payment reduce
1897  * advanced pricipla payment to remaining pv */
1898  adv_pmt = -pv;
1899 
1900  /* and set remaining pv to fv */
1901  pv = fv;
1902  } /* ## endif */
1903  } /* # endif */
1904 
1905  if (sum_prt)
1906  {
1907  jj = (j < yr_pmt) ? j + 1 : yr_pmt;
1908  amortyr->payments =
1909  pmtsched = (sched_pmt_ptr) calloc (jj, sizeof (sched_pmt));
1910  pmt_cnt = 0;
1911 
1912  sum_prt = FALSE;
1913  } /* endif */
1914 
1915  pmtsched->period_num = s++;
1916  pmtsched->interest = pmt_int;
1917  pmtsched->principal = prin;
1918  pmtsched->advanced_pmt = adv_pmt;
1919  pmtsched->total_pmt = pmt + adv_pmt;
1920  pmtsched->balance = pv;
1921  pmtsched++;
1922  pmt_cnt++;
1923 
1924  if (!--yr_pmt)
1925  {
1926  yr_pmt = PF;
1927 
1928  amortyr->year = yr++;
1929  amortyr->interest_pd = yr_int;
1930  amortyr->principal_pd = pv - hpv;
1931  amortyr->yr_end_balance = pv;
1932  amortyr->total_interest_pd = sum_int;
1933  amortyr->num_periods = pmt_cnt;
1934  amortyr->next_yr =
1935  (amort_sched_yr_ptr) calloc (1, sizeof (amort_sched_yr));
1936  amortyr = amortyr->next_yr;
1937 
1938  hpv = pv;
1939  yr_int = 0.0;
1940  sum_prt = TRUE;
1941  } /* endif */
1942  } /* endfor */
1943 
1944  if (dabs (pv) > 0.0)
1945  {
1946  /* basic equation to compute interest this payment period */
1947  pmt_int = -rnd ((pv + (amortsched->bp * pmt)) * eint, prec);
1948 
1949  /* sum yearly interest paid */
1950  yr_int += pmt_int;
1951 
1952  /* sum total interest paid */
1953  sum_int += pmt_int;
1954 
1955  /* compute principal paid this payment period and round to
1956  nearest cent */
1957  prin = rnd (pmt - pmt_int, prec);
1958  final_pmt = pmt;
1959 
1960  /* compute remaining pv and round to nearest cent */
1961  pv = rnd (pv + prin, prec);
1962 
1963  /* Set advanced principal payment to remaining pv */
1964  adv_pmt = -pv;
1965  amortyr->final_pmt = final_pmt += adv_pmt;
1966 
1967  /* and set remaining pv to fv */
1968  pv = fv;
1969 
1970  if (pmtsched)
1971  {
1972  pmtsched->period_num = s++;
1973  pmtsched->interest = pmt_int;
1974  pmtsched->principal = prin;
1975  pmtsched->advanced_pmt = adv_pmt;
1976  pmtsched->total_pmt = final_pmt;
1977  pmtsched->balance = pv;
1978  }
1979 
1980  per_cnt++;
1981  pmt_cnt++;
1982  } /* endif */
1983 
1984  if (dabs (yr_int) > 0.0)
1985  {
1986  amortyr->year = yr++;
1987  amortyr->interest_pd = yr_int;
1988  amortyr->principal_pd = pv - hpv;
1989  amortyr->total_interest_pd = sum_int;
1990  amortyr->num_periods = pmt_cnt;
1991  } /* endif */
1992 
1993  amortsched->total_periods = per_cnt;
1994  break;
1995  case 'f':
1996  /* fixed prepaymet schedule prepayment specified by user */
1997  amortsched->schedule.first_yr =
1998  amortyr = (amort_sched_yr_ptr) calloc (1, sizeof (amort_sched_yr));
1999 
2000  /* set advnaced payment */
2001  adv_pmt = amortsched->fixed_pmt;
2002 
2003  for (per_cnt = 0, s = 1, j = n; j && (pv != fv); j--, per_cnt++)
2004  {
2005  /* basic equation to compute interest this payment period */
2006  pmt_int = -rnd ((pv + (amortsched->bp * pmt)) * eint, prec);
2007  /* sum yearly interest paid
2008  */
2009  yr_int += pmt_int;
2010  /* sum total interest paid */
2011  sum_int += pmt_int;
2012 
2013  /* compute principal paid this payment period and round to
2014  nearest cent */
2015  if (dabs (pmt) > dabs (pv))
2016  {
2017  prin = -pv;
2018  pmt = prin + pmt_int;
2019  adv_pmt = 0.0;
2020  pv = 0.0;
2021  }
2022  else
2023  {
2024  prin = rnd (pmt - pmt_int, prec);
2025 
2026  /* compute remaining pv and round to nearest cent */
2027  pv = rnd (pv + prin, prec);
2028 
2029  if (dabs (pv) >= dabs (adv_pmt))
2030  {
2031  /* remaining pv greater than advanced principal payment
2032  * compute remaining pv and round to nearest cent */
2033  pv = rnd (pv + adv_pmt, prec);
2034  }
2035  else
2036  {
2037  /* remaining pv less than advanced principal payment reduce
2038  * advanced principal payment to remaining pv and set
2039  * remaining pv to fv */
2040  adv_pmt = -pv;
2041  pv = fv;
2042  } /*## endif */
2043  } /* # endif */
2044 
2045  if (sum_prt)
2046  {
2047  jj = (j < yr_pmt) ? j + 1 : yr_pmt;
2048  amortyr->payments =
2049  pmtsched = (sched_pmt_ptr) calloc (jj, sizeof (sched_pmt));
2050  pmt_cnt = 0;
2051 
2052  sum_prt = FALSE;
2053  }
2054  else
2055  {
2056  (amortyr->num_periods)++;
2057  } /* ## endif */
2058 
2059  pmtsched->period_num = s++;
2060  pmtsched->interest = pmt_int;
2061  pmtsched->principal = prin;
2062  pmtsched->advanced_pmt = adv_pmt;
2063  pmtsched->total_pmt = pmt + adv_pmt;
2064  pmtsched->balance = pv;
2065  pmt_cnt++;
2066  pmtsched++;
2067 
2068  if (!--yr_pmt)
2069  {
2070  yr_pmt = PF;
2071 
2072  amortyr->year = yr++;
2073  amortyr->interest_pd = yr_int;
2074  amortyr->principal_pd = pv - hpv;
2075  amortyr->yr_end_balance = pv;
2076  amortyr->total_interest_pd = sum_int;
2077  amortyr->num_periods = pmt_cnt;
2078  amortyr->next_yr =
2079  (amort_sched_yr_ptr) calloc (1, sizeof (amort_sched_yr));
2080  amortyr = amortyr->next_yr;
2081 
2082  hpv = pv;
2083  yr_int = 0.0;
2084  sum_prt = TRUE;
2085  } /* ## endif */
2086  } /* ## endfor */
2087 
2088  if (pv != fv)
2089  {
2090  /* # basic equation to compute interest this payment period */
2091  pmt_int = -rnd ((pv + (amortsched->bp * pmt)) * eint, prec);
2092 
2093  /* # sum yearly interest paid */
2094  yr_int += pmt_int;
2095  /* # sum total interest paid */
2096  sum_int += pmt_int;
2097 
2098  /* # compute principal paid this payment period and round to
2099  nearest cent */
2100  prin = rnd (pmt - pmt_int, prec);
2101  final_pmt = pmt;
2102 
2103  /* # compute remaining pv and round to nearest cent */
2104  pv = rnd (pv + prin, prec);
2105 
2106  /* # Set advanced principal payment to remaining pv */
2107  adv_pmt = -pv;
2108  amortyr->final_pmt = final_pmt += adv_pmt;
2109 
2110  /* # and set remaining pv to fv */
2111  pv = fv;
2112 
2113  if (pmtsched)
2114  {
2115  pmtsched->period_num = s++;
2116  pmtsched->interest = pmt_int;
2117  pmtsched->principal = prin;
2118  pmtsched->advanced_pmt = adv_pmt;
2119  pmtsched->total_pmt = final_pmt;
2120  pmtsched->balance = pv;
2121  }
2122 
2123  per_cnt++;
2124  pmt_cnt++;
2125  } /* # endif */
2126 
2127  if (dabs (yr_int) > 0.0)
2128  {
2129  amortyr->year = yr++;
2130  amortyr->interest_pd = yr_int;
2131  amortyr->principal_pd = pv - hpv;
2132  amortyr->total_interest_pd = sum_int;
2133  amortyr->num_periods = pmt_cnt;
2134  } /* endif */
2135 
2136  amortsched->total_periods = per_cnt;
2137  break;
2138  case 'o':
2139  /* Constant payment to principal use constant payment equal to
2140  * original pv divided by number of periods. constant payment to
2141  * principal could be amount specified by user. */
2142  amortsched->schedule.first_yr =
2143  amortyr = (amort_sched_yr_ptr) calloc (1, sizeof (amort_sched_yr));
2144  amortsched->total_periods = n;
2145 
2146  d = yr_pmt;
2147  for (s = 1, j = n - 1; j; j--, k++)
2148  {
2149  pmt_int = -rnd (pv * eint, prec);
2150 
2151  /* sum yearly interest paid */
2152  yr_int += pmt_int;
2153 
2154  /* sum total interest paid */
2155  sum_int += pmt_int;
2156 
2157  pv = rnd (pv + cpmt, prec);
2158 
2159  if (sum_prt)
2160  {
2161  jj = (j < yr_pmt) ? j + 1 : yr_pmt;
2162  amortyr->payments =
2163  pmtsched = (sched_pmt_ptr) calloc (jj, sizeof (sched_pmt));
2164  amortyr->num_periods = jj;
2165  k = 0;
2166 
2167  sum_prt = FALSE;
2168  } /* endif */
2169 
2170  pmtsched->period_num = s++;
2171  pmtsched->interest = pmt_int;
2172  pmtsched->total_pmt = cpmt + pmt_int;
2173  pmtsched->balance = pv;
2174  pmtsched++;
2175 
2176  if (!--yr_pmt)
2177  {
2178  yr_pmt = PF;
2179 
2180  amortyr->year = yr++;
2181  amortyr->interest_pd = yr_int;
2182  amortyr->principal_pd = d * cpmt;
2183  amortyr->yr_end_balance = pv;
2184  amortyr->total_interest_pd = sum_int;
2185  amortyr->next_yr =
2186  (amort_sched_yr_ptr) calloc (1, sizeof (amort_sched_yr));
2187  amortyr = amortyr->next_yr;
2188 
2189  d = PF;
2190  yr_int = 0.0;
2191  sum_prt = TRUE;
2192  } /* endif */
2193  } /* endfor */
2194 
2195  if (pv)
2196  {
2197  pmt_int = -rnd (pv * eint, prec);
2198 
2199  /* sum yearly interest paid */
2200  yr_int += pmt_int;
2201 
2202  /* sum total interest paid */
2203  sum_int += pmt_int;
2204  if (pmtsched)
2205  {
2206  pmtsched->period_num = s++;
2207  pmtsched->interest = -pmt_int;
2208  pmtsched->total_pmt = -pv + pmt_int;
2209  pmtsched->balance = 0.0;
2210  }
2211 
2212  amortyr->final_pmt = -pv - pmt_int;
2213  } /* endif */
2214 
2215  if (dabs (yr_int) > 0.0)
2216  {
2217  amortyr->year = yr++;
2218  amortyr->interest_pd = yr_int;
2219  amortyr->principal_pd = -pv + k * cpmt;
2220  amortyr->total_interest_pd = sum_int;
2221  } /* endif */
2222  break;
2223  case 'p':
2224  /* normal amortization schedule interest, principal and balance
2225  * per payment period */
2226  amortsched->schedule.first_yr =
2227  amortyr = (amort_sched_yr_ptr) calloc (1, sizeof (amort_sched_yr));
2228  amortsched->total_periods = n;
2229 
2230  hpv = pv;
2231  for (s = 1, j = n - 1; j; j--)
2232  {
2233  /* basic equation for computing interest paid in payment period */
2234  pmt_int = -rnd ((pv + (amortsched->bp * pmt)) * eint, prec);
2235 
2236  /* sum yearly interest paid */
2237  yr_int += pmt_int;
2238 
2239  /* sum total interest paid */
2240  sum_int += pmt_int;
2241 
2242  /* compute principal paid this payment period */
2243  prin = rnd (pmt - pmt_int, prec);
2244 
2245  /* compute remaining pv and round to nearest cent */
2246  pv = rnd (pv + prin, prec);
2247 
2248  if (sum_prt)
2249  {
2250  jj = (j < yr_pmt) ? j + 1 : yr_pmt;
2251  amortyr->payments =
2252  pmtsched = (sched_pmt_ptr) calloc (jj, sizeof (sched_pmt));
2253  amortyr->num_periods = jj;
2254 
2255  sum_prt = FALSE;
2256  } /* endif */
2257 
2258  if (fv_case)
2259  {
2260  pmtsched->period_num = s++;
2261  pmtsched->interest = pmt_int;
2262  pmtsched->balance = pv;
2263  pmtsched++;
2264  }
2265  else
2266  {
2267  pmtsched->period_num = s++;
2268  pmtsched->interest = pmt_int;
2269  pmtsched->principal = prin;
2270  pmtsched->balance = pv;
2271  pmtsched++;
2272  } /* endif */
2273 
2274  if (!--yr_pmt)
2275  {
2276  yr_pmt = PF;
2277 
2278  amortyr->year = yr++;
2279  amortyr->interest_pd = yr_int;
2280  if (!fv_case)
2281  {
2282  amortyr->principal_pd = pv - hpv;
2283  } /* endif */
2284  amortyr->yr_end_balance = pv;
2285  amortyr->total_interest_pd = sum_int;
2286  amortyr->next_yr =
2287  (amort_sched_yr_ptr) calloc (1, sizeof (amort_sched_yr));
2288  amortyr = amortyr->next_yr;
2289 
2290  hpv = pv;
2291  yr_int = 0.0;
2292  sum_prt = TRUE;
2293  } /* * endif */
2294  } /* * endfor */
2295 
2296  /* determine if payment due at beginning or end of period in order
2297  * to correctly compute final payment, interest and principal */
2298  if (bep)
2299  {
2300  /* paying remainder at beginning of period compute final payment */
2301  final_pmt = -pv - fv / (1 + eint);
2302 
2303  /* then compute interest paid with final final payment */
2304  pmt_int = -rnd ((pv + final_pmt) * eint, prec);
2305 
2306  /* then compute the principal paid */
2307  prin = final_pmt + pmt_int;
2308  }
2309  else
2310  {
2311  /* basic equation for computing interest paid in payment period
2312  * for payment at end of period */
2313  pmt_int = -rnd (pv * eint, prec);
2314 
2315  /* compute principal paid this payment period */
2316  prin = -pv;
2317 
2318  /* compute the final payment note the final payment may be
2319  * computed either of two ways both are equivalent */
2320  final_pmt = prin + pmt_int;
2321  } /* * endif */
2322 
2323  pv = -fv;
2324 
2325  /* sum yearly interest paid */
2326  yr_int += pmt_int;
2327 
2328  /* sum total interest paid */
2329  sum_int += pmt_int;
2330 
2331  if (sum_prt)
2332  {
2333  amortyr->payments =
2334  pmtsched = (sched_pmt_ptr) calloc (1, sizeof (sched_pmt));
2335  amortyr->num_periods = 1;
2336  } /* endif */
2337 
2338  amortyr->final_pmt = final_pmt;
2339 
2340  if (fv_case)
2341  {
2342  pmtsched->period_num = s++;
2343  pmtsched->interest = pmt_int;
2344  pmtsched->balance = pv;
2345  }
2346  else
2347  {
2348  pmtsched->period_num = s++;
2349  pmtsched->interest = pmt_int;
2350  pmtsched->principal = prin;
2351  pmtsched->balance = pv;
2352  } /* endif */
2353 
2354  if (dabs (yr_int) > 0.0)
2355  {
2356  amortyr->year = yr++;
2357  amortyr->interest_pd = yr_int;
2358  amortyr->total_interest_pd = sum_int;
2359  if (!bep)
2360  {
2361  amortyr->principal_pd = -hpv;
2362  } /* endif */
2363  } /* endif */
2364 
2365  break;
2366  case 'x':
2367  /* constant payment to principal - annual summary */
2368  /* compute number of years to summarize */
2369  j = n / PF;
2370  if (yr_pmt < PF)
2371  j++;
2372  amortsched->total_periods = j;
2373  amortsched->schedule.summary =
2374  yrly_sum = (yearly_summary_ptr) calloc (j, sizeof (yearly_summary));
2375 
2376  jj = 0;
2377  for (j = n, sum_prt = 0; j > 0; j -= yr_pmt, yr_pmt = PF, sum_prt++)
2378  {
2379  if (j <= PF)
2380  {
2381  s = jj + j;
2382  yr_pmt = j;
2383  yr_fv = rnd (pv + cpmt * (s - 1), prec) + final_pmt;
2384  }
2385  else
2386  {
2387  s = jj + yr_pmt;
2388  yr_fv = rnd (pv + cpmt * s, prec);
2389  } /* endif */
2390  prin = -eint * jj * (pv + (cpmt * (jj - 1) / 2.0));
2391  yr_int = -eint * s * (pv + (cpmt * (s - 1) / 2.0));
2392  yr_int = rnd (yr_int - prin, prec);
2393  jj += yr_pmt;
2394 
2395  sum_int += yr_int;
2396 
2397  yrly_sum[sum_prt].year = yr++;
2398  yrly_sum[sum_prt].interest = yr_int;
2399  yrly_sum[sum_prt].end_balance = yr_fv;
2400  } /* endfor */
2401 
2402  break;
2403  case 'y':
2404  /* normal amortization - annual summary */
2405  /* compute number of years to summarize */
2406  j = n / PF;
2407  if (yr_pmt < PF)
2408  j++;
2409  if (n > (j * PF))
2410  j++;
2411  amortsched->total_periods = j;
2412  amortsched->schedule.summary =
2413  yrly_sum = (yearly_summary_ptr) calloc (j, sizeof (yearly_summary));
2414 
2415  hpv = pv;
2416 
2417  for (jj = n, j = 0; jj > 0; jj -= yr_pmt, yr_pmt = PF, j++)
2418  {
2419  if (jj <= (int)PF)
2420  {
2421  yr_fv = fv;
2422  yr_int = rnd (((jj - 1) * pmt) + hpv + final_pmt, prec);
2423  }
2424  else
2425  {
2426  yr_fv =
2427  -rnd (_fi_calc_future_value
2428  (yr_pmt, nint, hpv, pmt, CF, PF, disc, bep), prec);
2429  yr_int = rnd ((yr_pmt * pmt) + hpv - yr_fv, prec);
2430  } /* * endif */
2431 
2432  sum_int += yr_int;
2433 
2434  yrly_sum[j].year = yr++;
2435  yrly_sum[j].interest = yr_int;
2436  yrly_sum[j].end_balance = yr_fv;
2437  hpv = yr_fv;
2438  } /* * endfor */
2439 
2440  break;
2441  } /* * endswitch */
2442 
2443  amortsched->total_interest = sum_int;
2444 
2445  return amortsched;
2446 } /* Amortization_Schedule */
2447 
2448 /* function to free dynamically allocated memory used for amortization
2449  schedule */
2450 void
2451 Amortization_free (amort_sched_ptr amortsched)
2452 {
2453  amort_sched_yr_ptr amortyr, prst_yr;
2454 
2455  switch (amortsched->summary)
2456  {
2457  case 'a':
2458  case 'f':
2459  case 'o':
2460  case 'p':
2461  for (amortyr = amortsched->schedule.first_yr; amortyr; amortyr = prst_yr)
2462  {
2463  if (amortyr->payments)
2464  free (amortyr->payments);
2465  prst_yr = amortyr->next_yr;
2466  free (amortyr);
2467  } /* endfor */
2468  break;
2469  case 'y':
2470  free (amortsched->schedule.summary);
2471  break;
2472  } /* endswitch */
2473 
2474  amortsched->schedule.first_yr = NULL;
2475 } /* amort_free */