home *** CD-ROM | disk | FTP | other *** search
- # Financial Calculator
- # Copyright (C) 1990 Terry D. Boldt, All Rights Reserved
- #
- # This version for use WITH ANSI.SYS display driver
- #
- # This is a complete financial computation utility to solve for the five
- # standard financial values: n, %i, PV, PMT and FV
- #
- # n == number of payment periods
- # %i == nominal interest charged
- # PV == Present Value
- # PMT == Periodic Payment
- # FV == Future Value
- #
- # In addition, two additional parameters may be specified:
- #
- # 1) Compounding frequency, CF. The compounding frequency may be discrete
- # or continuous and may be different from the Payment Frequency
- #
- # 2) Payment Frequency, PF.
- #
- # Canadian and European style mortgages can be handled in a simple,
- # straight-forward manner. Standard financial sign conventions are used:
- #
- # "Money paid out is Negative, Money received is Positive"
- #
- # Time value of money:
- #
- # If you borrow money, you can expect to pay rent or interest for its use;
- # conversely you expect to receive rent interest on money you loan or invest.
- # When you rent property, equipment, etc., rental payments are normal; this
- # is also true when renting or borrowing money. Therefore, money is
- # considered to have a "time value". Money available now, has a greater value
- # than money available at some future date bacause of its rental value or the
- # interest that it can produce during the intervening period.
- #
- # Simple Interest:
- #
- # If you loaned $800 to a friend with an agreement that at the end of one
- # year he would would repay you $896, the "time value" you placed on your
- # $800 (principal) was $96 (interest) for the one year period (term) of the
- # loan. This relationship of principal, interest, and time (trm) is most
- # frequently expressed as an Annual Percentage Rate (APR). In this case the
- # APR was 12.0% [(96/800)*100]. This example illustrates the four basic
- # factors involved in a simple ineterst case. The time period (one year),
- # rate (12.0% APR), present value of the principal ($800) and the future
- # value of the principal including interest ($896).
- #
- # Compound Interest:
- #
- # In many case the ineterst charge is computed periodically during the term
- # of the agreement. For example, money left is a savings account earns
- # interest that is periodically added to the principal and in turn earns
- # additional interest during succeeding periods. The accumulation of interest
- # during the investment period represents compound interest. If the loan
- # agreement you made with your friend had specified a "compound interest
- # rate" of 12% (compounded monthly) the $800 principal would have earned
- # $101.46 interest for the one year period. The value of the original $800
- # would be increased by 1% the first month to $808 which in turn would be
- # increased by 1% to 816.08 the second month,reaching a future value of
- # $901.46 after the twlefth iteration. The monthly compounding of the nominal
- # annual rate (NAR) of 12% produces an effective Annual Percentage Rate (APR)
- # of 12.683% [(101.46/800)*100]. Interest may be compounded at any regular
- # interval; annually, semiannually, monthly, weekly, daily, even continuously
- # (a specification in some financial models).
- #
- # Periodic Payments:
- #
- # When money is loaned for longer periods of time, it is customary for the
- # agreement to require the borrower to make periodic payments to the lender
- # during the term of the loan. The payments may be only large enough to repay
- # the interest, with the principal due at the end of the loan period (an
- # interest only loan), or large enough to fully repay both the interest and
- # principal during the term of the loan (a fully amoritized loan). Many loans
- # fall somewhere between, with payments that do not fully cover repayment of
- # both the principal and interst. These loans require a larger final payment
- # (balloon) to complete their amortization. Payments may occur at the
- # beginning or end of a payment period. If you and your friend had agreed on
- # monthly repayment of the $800 loan at 12% NAR compounded monthly, twelve
- # payments of $71.08 for a total of $852.96 would be required to amortize the
- # loan. The $101.46 interest from the annual plan is more than the $52.96
- # under the monthly plan because under the monthly plan your friend would not
- # have had the use of $800 for a full year.
- #
- # Finacial Transactions:
- #
- # The above paragraphs introduce the basic factors that govern most
- # financial transactions; the time period, interest rate, present value,
- # payments and the future value. In addition, certain conventions must be
- # adhered to: the interest rate must be relative to the compounding frequency
- # and payment periods, and the term must be expressed as the total number of
- # payments (or compounding periods if there are no payments). Loans, leases,
- # mortgages, annuities, savings plans, appreciation, and compound growth are
- # amoung the many financial problems that can be defined in these terms. Some
- # transactions do not involve payments, but all of the other factors play a
- # part in "time value of money" transactions. When any one of the five *four
- # - if no payments are involved) factors is unknown, it can be derived from
- # formulas using the known factors.
- #
- # Standard Financial Conventions Are:
- #
- # Money RECEIVED is a POSITIVE value and is represented by an arrow above
- # the line
- #
- # Money PAID OUT is a NEGATIVE value and is represented by an arrow below
- # the line.
- #
- # If payments are a part of the transaction, the number of payments must
- # equal the number of periods (n).
- #
- # Payments may be represented as occuring at the end or beginning of the
- # periods.
- #
- # Diagram or visualize the positive and negative cash flows (cash flow
- # diagrams):
- #
- #
- # FV*
- # 1 2 3 4 . . . . . . . . . n │
- # Period ┌───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘
- # │
- #
- # PV
- #
- # Appreciation
- # Depreciation
- # Compound Growth
- # Savings Account
- #
- ##############################################################################
- #
- # 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
- #
- ##############################################################################
- #
- # 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)
- #
- ##############################################################################
- #
- # 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)*
- #
- ##############################################################################
- #
- # The basic financial equation used is:
- #
- # 1) PV*(1 + i)^n + PMT*[(1+i)^n - 1]/i + FV = 0
- #
- # In the above form, equation 1) is suitable for the ordinary annuity
- # condition, when payments are made at the end of each period. To enable 1)
- # to solve the annuity due condition when payments are made at the beginning
- # of each period, a small modification is required. When this modification is
- # added, equation 1) becomes:
- #
- # 2) PV*(1 + i)^n + PMT*(1+iX)*[(1+i)^n - 1]/i + FV = 0
- #
- # where: X = 0 for ordinary annuity condition
- # X = 1 for annuity due condition
- #
- # With a simple alegebraic re-arrangement, 2) becomes:
- #
- # 3) [PV + PMT*(1 + iX)/i][(1 + i)^n - 1] + PV + FV = 0
- #
- # or
- #
- # 4) (PV + C)*A + PV + FV = 0
- #
- # where:
- # 5) A = (1 + i)^n - -1
- #
- # 6) B = (1 + iX)/i
- #
- # 7) C = PMT*B
- #
- # The form of equation 4) simplifies the calculation procedure for all five
- # variables, which are readily solved as follows:
- #
- # 8) n = ln[(C - FV)/(C + PV)]/ln((1 + i)
- #
- # 9) PV = -[FV + A*C]/(A + 1)
- #
- # 10) PMT = -[FV + PV*(A + 1)]/[A*B]
- #
- # 11) FV = -[PV + A*(PV + C)]
- #
- # Equations 5), 6) and 7) are computed by functions:
- #
- # _A
- # _B
- # _C
- #
- # respectively. Equations 8), 9), 10) and 11) 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))]
- #
- # As well as being able to select either an ordinary annuity or annuity due
- # situation, this utility also enables solutions to be obtained when:
- #
- # a) the compounding frequency, CF, is not identical to the payment
- # frequency, PF, and/or,
- #
- # b) Interest is compounded in either discrete intervals or is continuously
- # compounded.
- #
- #
- # The Compounding Frequency and Payment Frequency are defaulted to 1. The
- # default is for discrete interest intervals.
- #
- # 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 following examples, the user input is preceeded 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 preceeding with '#'. Thus, for the line:
- # <>n=5 #set number of periods
- # the comment that setting the number of periods is not really input.
- #
- # 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.
- # <>n=1
- # 1
- # <>pv=-800
- # -800
- # <>fv=896
- # 896
- # <>i=_I(n,pv,pmt,fv)
- # 12
- #
- # 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.
- # <>d
- # <>n=12
- # 12
- # <>CF=PF=12
- # 12
- # <>i=12
- # 12
- # <>pv=-800
- # -800
- # <>fv=_FV(n,i,pv,pmt)
- # 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
- # <>pmt=_PMT(n,i,pv,fv)
- # 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 end-of-period
- # payments of $1125.75 are made.
- # <>d
- # <>CF=PF=12
- # 12
- # <>i=13.25
- # 13.25
- # <>pv=100000
- # 100,000
- # <>pmt=-1125.75
- # -1,125.75
- # <>n=_N(i,pv,pmt,fv)
- # 360.1
- #
- # 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
- # <>fv=_FV(n,i,pv,pmt)
- # -108.87
- # <>pmt+fv
- # -1,234.62
- #
- # 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 addtional (balloon) payment will be due
- # with the final regular payment.
- # <>pmt=-1125
- # -1,125
- # <>fv=_FV(n,i,pv,pmt)
- # -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
- # <>PF=12
- # 12
- # <>n=300
- # 300
- # <>i=11
- # 11
- # <>pv=85000
- # 85,000
- # <>pmt=_PMT(n,i,pv,fv)
- # -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
- # <>PF=12
- # 12
- # <>n=30*12
- # 360
- # <>i=14
- # 14
- # <>pv=90000
- # 90,000
- # <>pmt=_PMT(n,i,pv,fv)
- # -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
- # <>CF=365
- # 365
- # <>PF=26
- # 26
- # <>n=3*26
- # 78
- # <>i=5.5
- # 5.5
- # <>pmt=-100
- # -100
- # <>fv=_FV(n,i,pv,pmt)
- # 8,489.32
- #
- # Example 10: Present Value - Annuit 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
- # <>CF=12
- # 12
- # <>PF=4
- # 4
- # <>n=4*10
- # 40
- # <>i=10
- # 10
- # <>pmt=500
- # 500
- # <>pv=_PV(n,i,pmt,fv)
- # -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
- # <>CF=365
- # 365
- # <>PF=360
- # 360
- # <>i=12
- # 12
- # <>pv=-100
- # -100
- # <>fv=_FV(n,i,pv,pmt)
- # 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
- # <>n=30*12
- # 360
- # <>i=13.25/12
- # 1.1041666666667
- # <>pv=75000
- # 75,000
- # <>pmt=_PMT(n,i,pv,fv)
- # -844.33
- # <>pv -= pv * .03
- # 72,750
- # <>CF=PF=12
- # 12
- # <>i=_I(n,pv,pmt,fv)
- # 13.692689279058
- #
- #
- # 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
- # <>CF=12
- # 12
- # <>n=10
- # 10
- # <>i=10.5
- # 10.5
- # <>pmt=-5029.71
- # -5,029.71
- # <>pv=_PV(n,i,pmt,fv)
- # 29,595.88
- # <>PF=12
- # 12
- # <>n=120
- # 120
- # <>pmt=_PMT(n,i,pv,fv)
- # -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
- # <>n=12
- # 12
- # <>PF=12
- # 12
- # <>i=15
- # 15
- # <>fv=60000
- # 60,000
- # <>pv=-60000
- # -60,000
- # <>pmt=_PMT(n,i,pv,fv)
- # 754.71
- #
- #
- # reference: PPC ROM User's Manual
- # pages 148 - 164
- #
- BEGIN {
- # ratio used in iterative solution for interest
- ratio = 1e4;
-
- # precesion of roundoff for n, pv, pmt and fv
- prec = 2;
-
- stderr = "stderr";
-
- # set display colors
- # highlight
- hl_color = "\x01b[0;32;40m";
- # normal display
- nl_color = "\x01b[1;31;44m";
-
- Yes = /^{_w}*[Yy](es)?{_w}*$/; # Yes answer
- No = /^{_w}*[Nn]o?{_w}*$/; # No answer
- Quit = /^{_w}*[Qq](uit)?({_w}+[Nn]o?)?{_w}*$/; # define regular expression To Quit
- Status = /^{_w}*[Ss](tat(us)?)?{_w}*$/;
- Default = /^{_w}*[Dd](efault)?{_w}*$/;
- Help = /^{_w}*[Hh](elp)?{_w}*$/;
- Cls = /^{_w}*[Cc](ls)?{_w}*$/;
-
- quit_status = TRUE;
-
- # find number of variables defined in calculator progam
- # any new variables defined by user will be in addition to this number
- # the number, vcnt, is then used in displaying status
- vcnt = var_number(FALSE);
-
- # display_cpyr;
- set_default;
- prt_instructions;
- prompt;
- }
-
- Quit {
- if ( NF > 1 ) {
- switch ( $2 ) {
- case Yes:
- quit_status = TRUE;
- break;
- case No:
- quit_status = FALSE;
- break;
- }
- }
- exit 2;
- }
-
- Status {
- prt_status;
- prompt;
- next;
- }
-
- Default {
- set_default;
- prompt;
- next;
- }
-
- Help {
- prt_instructions;
- prompt;
- next;
- }
-
- Cls {
- display_cpyr;
- prompt;
- next;
- }
-
- {
- line = $0;
- if ( $0 !~ /;$/ ) line ∩= ';'; #check for trailing ';'
- print '\t' ∩ addcomma(execute(line,TRUE,TRUE));
- prompt;
- }
-
- END {
- if ( quit_status ) display_cpyr;
- }
-
- # function to clear screen and home cursor
- function cls() {
- # clear screen and home cursor string
- local _cls_ = "\x01b[2J";
-
- printf(_cls_);
- }
-
- function display_cpyr() {
- cls;
- print "\nFinancial Calculator\n\x01b[0;32;40mCopyright (C) 1990 Terry D. Boldt, All Rights Reserved.\x01b[1;31;44m";
- }
-
- function prt_status() {
- local cd = disc ? "Discrete (disc = TRUE)" : "Continuous (disc = FALSE)";
- local eb = bep ? "Beginning of Period (bep = TRUE)" : "End of Period (bep = FALSE)";
- local j, jj, ostr;
-
- display_cpyr;
- print "Current Financial Calculator Status:";
- print "Compounding Frequency: (CF) " ∩ hl_color ∩ CF ∩ nl_color;
- print "Payment Frequency: (PF) " ∩ hl_color ∩ PF ∩ nl_color;
- print "Compounding: " ∩ hl_color ∩ cd ∩ nl_color;
- print "Payments: " ∩ hl_color ∩ eb ∩ nl_color;
- print "Number of Payment Periods (n): " ∩ hl_color ∩ addcomma(n) ∩ nl_color;
- print "Interest per Payment Period (i): " ∩ hl_color ∩ i ∩ nl_color;
- print "Present Value (pv): " ∩ hl_color ∩ addcomma(pv) ∩ nl_color;
- print "Periodic Payment (pmt): " ∩ hl_color ∩ addcomma(pmt) ∩ nl_color;
- print "Future Value (fv): " ∩ hl_color ∩ addcomma(fv) ∩ nl_color;
- print "User Defined Variables:";
- j = vcnt;
- for ( ostr = ud_sym(j++,jj) ; jj ; ostr = ud_sym(j++,jj) )
- print hl_color ∩ jj ∩ nl_color ∩ " == " ∩ addcomma(ostr);
- }
-
- function prt_instructions() {
- display_cpyr;
- print "To compute Loan Quantities:";
- print hl_color ∩ "N " ∩ nl_color ∩ "==> to compute # payment periods from i, pv, pmt, fv";
- print hl_color ∩ "_N(i,pv,pmt,fv) " ∩ nl_color ∩ "==> to compute # payment periods";
- print hl_color ∩ "I" ∩ nl_color ∩ " ==> to compute interest from n, pv, pmt, fv";
- print hl_color ∩ "_I(n,pv,pmt,fv)" ∩ nl_color ∩ " ==> to compute interest";
- print hl_color ∩ "PV" ∩ nl_color ∩ " ==> to compute Present Value from n, i, pmt, fv";
- print hl_color ∩ "_PV(n,i,pmt,fv)" ∩ nl_color ∩ " ==> to compute Present Value";
- print hl_color ∩ "PMT" ∩ nl_color ∩ " ==> to compute Payment from n, i, pv, fv";
- print hl_color ∩ "_PMT(n,i,pv,fv)" ∩ nl_color ∩ " ==> to compute Payment";
- print hl_color ∩ "FV" ∩ nl_color ∩ " ==> to compute Future Value from n, i, pv, pmt";
- print hl_color ∩ "_FV(n,i,pv,pmt)" ∩ nl_color ∩ " ==> to compute Future Value\n";
- print hl_color ∩ "[Qq](uit)?" ∩ nl_color ∩ " to Quit";
- print hl_color ∩ "[Ss](tatus)?" ∩ nl_color ∩ " to Display Status of Computations";
- print hl_color ∩ "[Dd](efault)?" ∩ nl_color ∩ " to Re-Initialize";
- print hl_color ∩ "[Cc](ls)?" ∩ nl_color ∩ " to Clear Screen";
- print hl_color ∩ "[Hh](elp)" ∩ nl_color ∩ " to Display This Help";
- }
-
- # Compute constant used in calculations
- function _A(nint,per) {
- return (1.0 + nint) ^ per - 1;
- }
-
- # Compute constant used in calculations
- function _B(nint,beg) {
- if ( nint == 0 ) {
- fprintf(stderr,"Zero Interest.\n");
- next;
- }
- return (1.0 + nint * beg)/nint;
- }
-
- # Compute constant used in calculations
- function _C(nint,pmt,beg) {
- return pmt * _B(nint,beg);
- }
-
- # compute Number of Periods from preset data
- function N() {
- return n = _N(i,pv,pmt,fv);
- }
-
- # Compute number of periods from:
- # 1. Nominal Interest
- # 2. Present Value
- # 3. Periodic Payment
- # 4. Future Value
- function _N(nint,pv,pmt,fv) {
- local intn = eff_int(nint/100.0);
- local CC = _C(intn,pmt,bep);
-
- return rnd(log((CC - fv)/(CC + pv))/log(1 + intn),prec);
- }
-
- # compute Interest from preset data
- function I() {
- return i = _I(n,pv,pmt,fv);
- }
-
- # Compute Nominal Interest from:
- # 1. Number of periods
- # 2. Present Value
- # 3. Periodic Payment
- # 4. Future Value
- function _I(per,pv,pmt,fv) {
- local inte;
- local a, ik, dik;
-
- if ( pmt == 0 ) {
- inte = ((abs(fv) + 0.0)/abs(pv))^(1/per) - 1;
- } else {
- if ( (pmt * fv) < 0 ) {
- if ( pv ) a = -1.0; else a = 1.0;
- inte = abs((fv + a * n * pmt)/(3 * ( (n-1)^2 * pmt + pv - fv) ));
- } else {
- if ( pv*pmt < 0 ) {
- inte = abs((n * pmt + pv + fv + 0.0)/(n * pv));
- } else {
- a = abs((pmt + 0.0)/(abs(pv) + abs(fv)));
- inte = a + 1/(a * per^3);
- }
- }
- do {
- dik = fi(per,inte,pv,pmt,fv)/fip(per,inte,pv,pmt,fv);
- inte -= dik;
- } while ( int(ratio * (dik/inte)) );
- }
- return 100.0 * nom_int(inte);
- }
-
- # compute Present value from preset data
- function PV(n,i,pmt,fv) {
- return pv = _PV(n,i,pmt,fv);
- }
-
- # Compute Present Value from:
- # 1. Number of periods
- # 2. Nominal Interest
- # 3. Periodic Payment
- # 4. Future Value
- function _PV(per,nint,pmt,fv) {
- local intn = eff_int(nint/100.0);
- local AA = _A(intn,per);
- local BB = _B(intn,bep);
- local CC = _C(intn,pmt,bep);
-
- return rnd(-(fv + (AA * CC))/(AA + 1),prec);
- }
-
- # compute Periodic Payment from preset data
- function PMT() {
- return pmt = _PMT(n,i,pv,fv);
- }
-
- # Compute Periodic Payment from:
- # 1. Number of periods
- # 2. Nominal Interest
- # 3. Present Value
- # 4. Future Value
- function _PMT(per,nint,pv,fv) {
- local intn = eff_int(nint/100.0);
- local AA = _A(intn,per);
- local BB = _B(intn,bep);
-
- return rnd(-(fv + pv * (AA + 1))/(AA * BB),prec);
- }
-
- # compute Future Value from preset data
- function FV() {
- return fv = _FV(n,i,pv,pmt);
- }
-
- # Compute Future Value from:
- # 1. Number of periods
- # 2. Nominal Interest
- # 3. Present Value
- # 4. Periodic Payments
- function _FV(per,nint,pv,pmt) {
- local intn = eff_int(nint/100.0);
- local AA = _A(intn,per);
- local CC = _C(intn,pmt,bep);
-
- return rnd(-(pv + AA * (pv + CC)),prec);
- }
-
- # compute Nominal Interest Rate from Effective Interest Rate
- function nom_int(inte) {
- local nint;
-
- if ( disc ) nint = CF * ((1 + inte)^(PF/CF) - 1);
- else nint = log((1 + inte)^PF);
- return nint;
- }
-
- # Compute Effective Interest Rate from Nominal Interest Rate
- function eff_int(nint) {
- local inte;
-
- if ( disc ) inte = (1 + nint/CF)^(CF/PF) - 1;
- else inte = exp(nint/PF) - 1;
- return inte;
- }
-
- # function to add commas to numbers
- function addcomma(x) {
- local num;
- local spat;
- local bnum = /{_d}{3,3}([,.]|$)/;
-
- if ( x < 0 ) return "-" ∩ addcomma(-x);
- num = sprintf("%.14g",x); # num is dddddd.dd
- spat = num ~~ /\./ ? /{_d}{4,4}[.,]/ : /{_d}{4,4}(,|$)/;
- while ( num ~~ spat ) sub(bnum,",&",num);
- return num;
- }
-
- # return 'x' rounded to 'places' past decimal
- # if 'places' == 0, return 'x'
- function rnd(x,places) {
- local pwr, r, inc;
-
- if ( places >= 0 ) {
- pwr = 10 ^ places;
- r = x * pwr;
- inc = abs(int(10 * fract(r))) >= 5 ? signum(x) : 0;
- r = int(r + inc) / pwr;
- } else r = x;
- return r;
- }
-
- # return absolute value of 'x'
- function abs(x) {
- return x > 0 ? x : -x;
- }
-
- # return sign of 'x'
- # returns:
- # 1 ==> x > 0
- # 0 ==> x == 0
- # -1 ==> x < 0
- function signum(x) {
- return x == 0 ? 0 : x > 0 ? 1 : -1;
- }
-
- # calculation used in interest computation
- function fi(per,nint,pv,pmt,fv) {
- return _A(nint,per) * (pv + _C(nint,pmt,bep)) + pv + fv;
- }
-
- # calculation used in interest computation
- function fip(per,nint,pv,pmt,fv) {
- local AA = _A(nint,per);
- local CC = _C(nint,pmt,bep);
- local D = (AA + 1.0)/(1.0 + nint);
-
- return per * (pv + CC) * D - (AA * CC)/nint;
- }
-
- function prompt() {
- printf("<>");
- }
-
- function set_default() {
- # flag whether accrueing interest at beginning or end of period
- # FALSE --> end
- # TRUE --> beginning
- bep = FALSE;
-
- # flag for discrete or continuous interest
- # TRUE --> discrete
- # FALSE --> continuous
- disc = TRUE;
-
- # set compounding, CF, and payment, PF, frequency
- CF = PF = 1;
-
- # standard loan quantities:
- # number of periods: n
- n = 0;
- # annual interest: i
- i = 0;
- # Present Value: pv
- pv = 0;
- # Payment: pmt
- pmt = 0;
- # Future Value: fv
- fv = 0;
- }
-
- # function to return the current number of GLOBAL variables defined in utility
- function var_number(display) {
- local cnt, j, jj;
-
- for ( jj = cnt = 1 ; jj ; cnt++ ) {
- j = ud_sym(cnt,jj);
- if ( display ) print cnt ∩ " : " ∩ jj ∩ " ==>" ∩ j ∩ "<==";
- }
- return cnt - 1;
- }
-