home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
qtawk
/
fin.exp
< prev
next >
Wrap
Text File
|
1990-05-16
|
28KB
|
955 lines
# 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;
}