home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / qtawk / finna.exp < prev    next >
Text File  |  1990-05-16  |  27KB  |  927 lines

  1. # Financial Calculator
  2. # Copyright (C) 1990 Terry D. Boldt, All Rights Reserved
  3. #
  4. # This version for use WITHOUT ANSI.SYS display driver
  5. #
  6. #  This is  a complete    financial computation  utility to  solve for  the five
  7. # standard financial values: n, %i, PV, PMT and FV
  8. #
  9. #    n     == number of payment periods
  10. #    %i  == nominal interest charged
  11. #    PV  == Present Value
  12. #    PMT == Periodic Payment
  13. #    FV  == Future Value
  14. #
  15. #  In addition, two additional parameters may be specified:
  16. #
  17. #    1) Compounding frequency, CF. The compounding frequency may be discrete
  18. #     or continuous and may be different from the Payment Frequency
  19. #
  20. #    2) Payment Frequency, PF.
  21. #
  22. #  Canadian  and  European  style  mortgages  can  be  handled    in  a simple,
  23. # straight-forward manner. Standard financial sign conventions are used:
  24. #
  25. #       "Money paid out is Negative, Money received is Positive"
  26. #
  27. #  Time value of money:
  28. #
  29. #  If you borrow money, you can expect    to pay rent or interest for its  use;
  30. # conversely you expect to receive rent interest on money you loan or invest.
  31. # When you rent property, equipment,  etc., rental payments are normal;  this
  32. # is  also  true  when    renting  or  borrowing    money.    Therefore,  money  is
  33. # considered to have a "time value". Money available now, has a greater value
  34. # than money available at some future date bacause of its rental value or the
  35. # interest that it can produce during the intervening period.
  36. #
  37. #  Simple Interest:
  38. #
  39. #  If you loaned $800 to  a friend with an agreement  that at the end of  one
  40. # year he would  would repay you  $896, the "time  value" you placed  on your
  41. # $800 (principal) was $96 (interest) for  the one year period (term) of  the
  42. # loan. This  relationship of  principal, interest,  and time  (trm) is  most
  43. # frequently expressed as an Annual  Percentage Rate (APR). In this  case the
  44. # APR  was  12.0%  [(96/800)*100].  This  example  illustrates the four basic
  45. # factors involved  in a  simple ineterst  case. The  time period (one year),
  46. # rate (12.0%  APR), present  value of    the principal  ($800) and  the future
  47. # value of the principal including interest ($896).
  48. #
  49. #  Compound Interest:
  50. #
  51. #  In many case the ineterst charge is computed periodically during the  term
  52. # of  the  agreement.  For  example,  money  left  is a savings account earns
  53. # interest that  is periodically  added to  the principal  and in  turn earns
  54. # additional interest during succeeding periods. The accumulation of interest
  55. # during  the  investment  period  represents  compound interest. If the loan
  56. # agreement you  made with  your friend  had specified    a "compound  interest
  57. # rate" of  12% (compounded  monthly) the  $800 principal  would have  earned
  58. # $101.46 interest for the  one year period. The  value of the original  $800
  59. # would be increased  by 1% the  first month to  $808 which in    turn would be
  60. # increased  by  1%  to  816.08  the  second month,reaching a future value of
  61. # $901.46 after the twlefth iteration. The monthly compounding of the nominal
  62. # annual rate (NAR) of 12% produces an effective Annual Percentage Rate (APR)
  63. # of 12.683% [(101.46/800)*100].  Interest may be  compounded at any  regular
  64. # interval; annually, semiannually, monthly, weekly, daily, even continuously
  65. # (a specification in some financial models).
  66. #
  67. #  Periodic Payments:
  68. #
  69. #  When money is loaned for longer  periods of time, it is customary  for the
  70. # agreement to require the borrower  to make periodic payments to  the lender
  71. # during the term of the loan. The payments may be only large enough to repay
  72. # the interest,  with the  principal due  at the  end of  the loan period (an
  73. # interest only loan), or large enough    to fully repay both the interest  and
  74. # principal during the term of the loan (a fully amoritized loan). Many loans
  75. # fall somewhere between, with payments that do not fully cover repayment  of
  76. # both the principal and interst. These loans require a larger final  payment
  77. # (balloon)  to  complete  their  amortization.  Payments  may    occur  at the
  78. # beginning or end of a payment period. If you and your friend had agreed  on
  79. # monthly repayment of    the $800 loan  at 12% NAR  compounded monthly, twelve
  80. # payments of $71.08 for a total of $852.96 would be required to amortize the
  81. # loan. The $101.46  interest from the    annual plan is    more than the  $52.96
  82. # under the monthly plan because under the monthly plan your friend would not
  83. # have had the use of $800 for a full year.
  84. #
  85. #  Finacial Transactions:
  86. #
  87. #  The    above  paragraphs  introduce  the  basic  factors  that  govern  most
  88. # financial  transactions;  the  time  period,    interest rate, present value,
  89. # payments and    the future  value. In  addition, certain  conventions must be
  90. # adhered to: the interest rate must be relative to the compounding frequency
  91. # and payment periods, and the term must be expressed as the total number  of
  92. # payments (or compounding periods if there are no payments). Loans,  leases,
  93. # mortgages, annuities, savings plans, appreciation, and compound growth  are
  94. # amoung the many financial problems that can be defined in these terms. Some
  95. # transactions do not involve payments, but  all of the other factors play  a
  96. # part in "time value of money" transactions. When any one of the five  *four
  97. # - if no payments are involved)  factors is unknown, it can be  derived from
  98. # formulas using the known factors.
  99. #
  100. # Standard Financial Conventions Are:
  101. #
  102. #  Money RECEIVED is a    POSITIVE value and is  represented by an arrow    above
  103. # the line
  104. #
  105. #  Money PAID OUT is  a NEGATIVE value and  is represented by an  arrow below
  106. # the line.
  107. #
  108. #  If payments are  a part of  the transaction, the  number of payments  must
  109. # equal the number of periods (n).
  110. #
  111. #  Payments may be  represented as occuring  at the end  or beginning of  the
  112. # periods.
  113. #
  114. #  Diagram  or    visualize  the    positive  and  negative cash flows (cash flow
  115. # diagrams):
  116. #
  117. #
  118. #                                  FV*
  119. #       1   2   3   4   .   .   .   .   .   .   .   .   .   n │
  120. # Period ┌───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘
  121. #     │
  122. #     
  123. #     PV
  124. #
  125. #     Appreciation
  126. #     Depreciation
  127. #     Compound Growth
  128. #     Savings Account
  129. #
  130. ##############################################################################
  131. #
  132. #                                 FV
  133. #     PV = 0                             
  134. #                                 │
  135. # Period ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┘
  136. #     │ 1 │ 2 │ 3 │ 4 │ . │ . │ . │ . │ . │ . │ . │ . │ . │ n
  137. #                                                        
  138. #    PMT PMT PMT PMT PMT PMT PMT PMT PMT PMT PMT PMT PMT PMT
  139. #
  140. #     Annuity (series of payments)
  141. #     Pension Fund
  142. #     Savings Plan
  143. #     Sinking Fund
  144. #
  145. ##############################################################################
  146. #
  147. #     PV 
  148. #     │                            FV=0
  149. # Period └───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
  150. #       1 │ 2 │ 3 │ 4 │ . │ . │ . │ . │ . │ . │ . │ . │ . │ n │
  151. #                                                              
  152. #        PMT PMT PMT PMT PMT PMT PMT PMT PMT PMT PMT PMT PMT PMT
  153. #
  154. #     Amortization
  155. #     Direct Reduction Loan
  156. #     Mortgage (fully amortized)
  157. #
  158. ##############################################################################
  159. #
  160. #                                  FV*
  161. #        PMT PMT PMT PMT PMT PMT PMT PMT PMT PMT PMT PMT PMT  │ +
  162. #                                                               PMT
  163. #       1 │ 2 │ 3 │ 4 │ . │ . │ . │ . │ . │ . │ . │ . │ . │ n │
  164. # Period ┌───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘
  165. #     │
  166. #     
  167. #     PV
  168. #
  169. #     Annuity
  170. #     Lease (with buy back or residual)*
  171. #     Loan or Mortgage (with balloon)*
  172. #
  173. ##############################################################################
  174. #
  175. # The basic financial equation used is:
  176. #
  177. #  1) PV*(1 + i)^n + PMT*[(1+i)^n - 1]/i + FV = 0
  178. #
  179. #  In  the  above  form,  equation  1)    is  suitable for the ordinary annuity
  180. # condition, when payments are made at    the end of each period. To  enable 1)
  181. # to solve the annuity due condition when payments are made at the  beginning
  182. # of each period, a small modification is required. When this modification is
  183. # added, equation 1) becomes:
  184. #
  185. #  2) PV*(1 + i)^n + PMT*(1+iX)*[(1+i)^n - 1]/i + FV = 0
  186. #
  187. #    where:  X = 0 for ordinary annuity condition
  188. #         X = 1 for annuity due condition
  189. #
  190. # With a simple alegebraic re-arrangement, 2) becomes:
  191. #
  192. #  3) [PV + PMT*(1 + iX)/i][(1 + i)^n - 1] + PV + FV = 0
  193. #
  194. # or
  195. #
  196. #  4) (PV + C)*A + PV + FV = 0
  197. #
  198. # where:
  199. #  5) A = (1 + i)^n - -1
  200. #
  201. #  6) B = (1 + iX)/i
  202. #
  203. #  7) C = PMT*B
  204. #
  205. # The form of equation 4) simplifies the calculation procedure for all five
  206. # variables, which are readily solved as follows:
  207. #
  208. #  8) n = ln[(C - FV)/(C + PV)]/ln((1 + i)
  209. #
  210. #  9) PV = -[FV + A*C]/(A + 1)
  211. #
  212. # 10) PMT = -[FV + PV*(A + 1)]/[A*B]
  213. #
  214. # 11) FV = -[PV + A*(PV + C)]
  215. #
  216. # Equations 5), 6) and 7) are computed by functions:
  217. #
  218. #  _A
  219. #  _B
  220. #  _C
  221. #
  222. # respectively. Equations 8), 9), 10) and 11) are computed by functions:
  223. #
  224. #  _N
  225. #  _PV
  226. #  _PMT
  227. #  _FV
  228. #
  229. # respectively.
  230. #
  231. # The solution for interest is broken into two cases:
  232. #
  233. #  PMT == 0
  234. #    i = [FV/PV]^(1/n) - 1
  235. #
  236. #  PMT != 0
  237. #    Since equation 3) cannot be solved explicitly for i in this case, an
  238. #    iterative technique must be employed. Newton's method, using exact
  239. #    expressions for the function of i and its derivative, are employed. The
  240. #    expressions are:
  241. #
  242. # 12) i[k+1] = i[k] - f(i[k])/f'(i[k])
  243. #    where: i[k+1] == (k+1)st iteration of i
  244. #           i[k]   == kth iteration of i
  245. #    and:
  246. #
  247. # 13) f(i) = A*(PV+C) + PV + FV
  248. #
  249. # 14) f'(i) = n*D*(PV+C) - (A*C)/i
  250. #
  251. # 15) D = (1 + i)^(n-1) = (A+1)/(1+i)
  252. #
  253. #    To start the iterative solution for i, an initial guess must be made
  254. #    for the value of i. The closer this guess is to the actual value,
  255. #    the fewer iterations will have to be made, and the greater the
  256. #    probability that the required solution will be obtained. The initial
  257. #    guess for i is obtained as follows:
  258. #
  259. #    if PMT*FV >= 0, then PV case
  260. #    if PMT*FV <  0, then FV case
  261. #
  262. #     PV case:
  263. #         | n*PMT + PV + FV |
  264. # 16)      i[0] = | ----------------|
  265. #         |    n*PV       |
  266. #
  267. #           = abs[(n*PMT + PV + FV)/(n*PV)]
  268. #
  269. #     FV case:
  270. #      a) PV != 0
  271. #
  272. #             |        FV - n*PMT         |
  273. # 17)          i[0] = |---------------------------|
  274. #             | 3*[PMT*(n-1)^2 + PV - FV] |
  275. #
  276. #           = abs[(FV-n*PMT)/(3*(PMT*(n-1)^2+PV-FV))]
  277. #      b) PV == 0
  278. #
  279. #             |        FV + n*PMT         |
  280. # 18)          i[0] = |---------------------------|
  281. #             | 3*[PMT*(n-1)^2 + PV - FV] |
  282. #
  283. #           = abs[(FV+n*PMT)/(3*(PMT*(n-1)^2+PV-FV))]
  284. #
  285. #  As well as being able to select either an ordinary annuity or annuity  due
  286. # situation, this utility also enables solutions to be obtained when:
  287. #
  288. #  a)  the  compounding  frequency,  CF,  is  not  identical  to  the payment
  289. # frequency, PF, and/or,
  290. #
  291. #  b) Interest is compounded in either discrete intervals or is  continuously
  292. # compounded.
  293. #
  294. #
  295. #  The Compounding Frequency  and Payment Frequency  are defaulted to  1. The
  296. # default is for discrete interest intervals.
  297. #
  298. #  When a solution  for n, PV,    PMT or FV  is required, the  nominal interest
  299. # rate, i, must first be converted to the effective interest rate per payment
  300. # period. This rate, ieff, is then used to compute the selected variable.  To
  301. # convert i to ieff, the following expressions are used:
  302. #
  303. #  Discrete interest periods:
  304. #
  305. # 19) ieff = (1 + i/CF)^(CF/PF) - 1
  306. #
  307. #  Continuous Interest
  308. #
  309. # 20) ieff = e^(i/PF) - 1 = exp(i/PF) - 1
  310. #
  311. #  When interest is computed, the computation produces the effective interest
  312. # rate, ieff. This value must then be converted to the nominal interest rate.
  313. # Function  _I    below  returns    the  nominal  interest rate NOT the effective
  314. # interest rate. ieff is converted to i using the following expressions:
  315. #
  316. #  Discrete Case:
  317. #
  318. #     i = CF*[(1+ieff)^(PF/CF) - 1]
  319. #
  320. #  Continuous Case:
  321. #
  322. #     i = ln[(1+ieff)^PF]
  323. #
  324. # Note: in the following examples, the user input is preceeded by the prompt
  325. # "<>". The result of evaluating the input expression is then displayed.
  326. # I have taken the liberty of including comments in the example
  327. # input/output sessions by preceeding with '#'. Thus, for the line:
  328. # <>n=5     #set number of periods
  329. # the comment that setting the number of periods is not really input.
  330. #
  331. # Example 1: Simple Interest
  332. # Find annual simple interest rate (%) for an $800 loan to be repayed at the
  333. # end of one year with a single payment of $896.
  334. # <>n=1
  335. # 1
  336. # <>pv=-800
  337. # -800
  338. # <>fv=896
  339. # 896
  340. # <>i=_I(n,pv,pmt,fv)
  341. # 12
  342. #
  343. # Example 2: Compound Interest
  344. # Find the future value of $800 after one year at a nominal rate of 12%
  345. # compounded monthly. No payments are specified, so the payment frequency is
  346. # set equal to the compounding frequency.
  347. # <>d
  348. # <>n=12
  349. # 12
  350. # <>CF=PF=12
  351. # 12
  352. # <>i=12
  353. # 12
  354. # <>pv=-800
  355. # -800
  356. # <>fv=_FV(n,i,pv,pmt)
  357. # 901.46
  358. #
  359. # Example 3: Periodic Payment:
  360. # Find the monthly end-of-period payment required to fully amortize the loan
  361. # in Example 2. A fully amortized loan has a future value of zero.
  362. # <>fv=0
  363. # 0
  364. # <>pmt=_PMT(n,i,pv,fv)
  365. # 71.08
  366. #
  367. # Example 4: Conventional Mortgage
  368. # Find the number of monthly payments necessary to fully amortize a loan of
  369. # $100,000 at a nominal rate of 13.25% compounded monthly, if end-of-period
  370. # payments of $1125.75 are made.
  371. # <>d
  372. # <>CF=PF=12
  373. # 12
  374. # <>i=13.25
  375. # 13.25
  376. # <>pv=100000
  377. # 100,000
  378. # <>pmt=-1125.75
  379. # -1,125.75
  380. # <>n=_N(i,pv,pmt,fv)
  381. # 360.1
  382. #
  383. # Example 5: Final Payment
  384. # Using the data in example 4, find the amount of the final payment if n is
  385. # changed to 360. The final payment will be equal to the regular payment plus
  386. # any balance, future value, remaining at the end of period number 360.
  387. # <>n=360
  388. # 360
  389. # <>fv=_FV(n,i,pv,pmt)
  390. # -108.87
  391. # <>pmt+fv
  392. # -1,234.62
  393. #
  394. # Example 6: Balloon Payment
  395. # On long term loans, small changes in the periodic payments can generate
  396. # large changes in the future value. If the monthly payment in example 5 is
  397. # rounded down to $1125, how much addtional (balloon) payment will be due
  398. # with the final regular payment.
  399. # <>pmt=-1125
  400. # -1,125
  401. # <>fv=_FV(n,i,pv,pmt)
  402. # -3,579.99
  403. #
  404. # Example 7: Canadian Mortgage
  405. # Find the monthly end-of-period payment necessary to fully amortize a 25 year
  406. # $85,000 loan at 11% compounded semi-annually.
  407. # <>d
  408. # <>CF=2
  409. # 2
  410. # <>PF=12
  411. # 12
  412. # <>n=300
  413. # 300
  414. # <>i=11
  415. # 11
  416. # <>pv=85000
  417. # 85,000
  418. # <>pmt=_PMT(n,i,pv,fv)
  419. # -818.15
  420. #
  421. # Example 8: European Mortgage
  422. # The "effective annual rate (EAR)" is used in some countries (especially
  423. # in Europe) in lieu of the nominal rate commonly used in the United States
  424. # and Canada. For a 30 year $90,000 mortgage at 14% (EAR), compute the monthly
  425. # end-of-period payments. When using an EAR, the compounding frequency is
  426. # set to 1.
  427. # <>d
  428. # <>PF=12
  429. # 12
  430. # <>n=30*12
  431. # 360
  432. # <>i=14
  433. # 14
  434. # <>pv=90000
  435. # 90,000
  436. # <>pmt=_PMT(n,i,pv,fv)
  437. # -1,007.88
  438. #
  439. # Example 9: Bi-weekly Savings
  440. # Compute the future value, fv, of bi-weekly savings of $100 for 3 years at a
  441. # nominal annual rate of 5.5% compounded daily. (Set payment to
  442. # beginning-of-period, bep = TRUE)
  443. # <>d
  444. # <>bep=TRUE
  445. # 1
  446. # <>CF=365
  447. # 365
  448. # <>PF=26
  449. # 26
  450. # <>n=3*26
  451. # 78
  452. # <>i=5.5
  453. # 5.5
  454. # <>pmt=-100
  455. # -100
  456. # <>fv=_FV(n,i,pv,pmt)
  457. # 8,489.32
  458. #
  459. # Example 10: Present Value - Annuit Due
  460. # What is the present value of $500 to be received at the beginning of each
  461. # quarter over a 10 year period if money is being discounted at 10% nominal
  462. # annual rate compounded monthly?
  463. # <>d
  464. # <>bep=TRUE
  465. # 1
  466. # <>CF=12
  467. # 12
  468. # <>PF=4
  469. # 4
  470. # <>n=4*10
  471. # 40
  472. # <>i=10
  473. # 10
  474. # <>pmt=500
  475. # 500
  476. # <>pv=_PV(n,i,pmt,fv)
  477. # -12,822.64
  478. #
  479. # Example 11: Effective Rate - 365/360 Basis
  480. # Compute the effective annual rate (%APR) for a nominal annual rate of 12%
  481. # compounded on a 365/360 basis used by some Savings & Loan Associations.
  482. # <>d
  483. # <>n=365
  484. # 365
  485. # <>CF=365
  486. # 365
  487. # <>PF=360
  488. # 360
  489. # <>i=12
  490. # 12
  491. # <>pv=-100
  492. # -100
  493. # <>fv=_FV(n,i,pv,pmt)
  494. # 112.94
  495. # <>fv+pv
  496. # 12.94
  497. #
  498. #
  499. # Example 12: Mortgage with "Points"
  500. # What is the true APR of a 30 year, $75,000 loan at a nominal rate of 13.25%
  501. # compounded monthly, with monthly end-of-period payments, if 3 "points"
  502. # are charged? The pv must be reduced by the dollar value of the points
  503. # and/or any lenders fees to establish an effective pv. Because payments remain
  504. # the same, the true APR will be higher than the nominal rate. Note, first
  505. # compute the payments on the pv of the loan amount.
  506. # <>d
  507. # <>n=30*12
  508. # 360
  509. # <>i=13.25/12
  510. # 1.1041666666667
  511. # <>pv=75000
  512. # 75,000
  513. # <>pmt=_PMT(n,i,pv,fv)
  514. # -844.33
  515. # <>pv -= pv * .03
  516. # 72,750
  517. # <>CF=PF=12
  518. # 12
  519. # <>i=_I(n,pv,pmt,fv)
  520. # 13.692689279058
  521. #
  522. #
  523. # Example 13: Equivalent Payments
  524. # Find the equivalent monthly payment required to amortize a 20 year $40,000
  525. # loan at 10.5% nominal annual rate compounded monthly, with 10 annual
  526. # payments of $5029.71 remaining. Compute the pv of the remaining annual
  527. # payments, then change n, the number of periods, and the payment frequency,
  528. # PF, to a monthly basis and compute the equivalent monthly pmt.
  529. # <>d
  530. # <>CF=12
  531. # 12
  532. # <>n=10
  533. # 10
  534. # <>i=10.5
  535. # 10.5
  536. # <>pmt=-5029.71
  537. # -5,029.71
  538. # <>pv=_PV(n,i,pmt,fv)
  539. # 29,595.88
  540. # <>PF=12
  541. # 12
  542. # <>n=120
  543. # 120
  544. # <>pmt=_PMT(n,i,pv,fv)
  545. # -399.35
  546. #
  547. # Example 14: Perpetuity - Continuous Compounding
  548. # If you can purchase a single payment annuity with an initial investment of
  549. # $60,000 that will be invested at 15% nominal annual rate compounded
  550. # continuously, what is the maximum monthly return you can receive without
  551. # reducing the $60,000 principal? If the principal is not disturbed, the
  552. # payments can go on indefinitely (a perpetuity). Note that the term,n, of
  553. # a perpetuity is immaterial. It can be any non-zero value.
  554. # <>d
  555. # <>disc = FALSE
  556. # 0
  557. # <>n=12
  558. # 12
  559. # <>PF=12
  560. # 12
  561. # <>i=15
  562. # 15
  563. # <>fv=60000
  564. # 60,000
  565. # <>pv=-60000
  566. # -60,000
  567. # <>pmt=_PMT(n,i,pv,fv)
  568. # 754.71
  569. #
  570. #
  571. # reference: PPC ROM User's Manual
  572. #         pages 148 - 164
  573. #
  574. BEGIN {
  575.     # ratio used in iterative solution for interest
  576.     ratio = 1e4;
  577.  
  578.     # precesion of roundoff for n, pv, pmt and fv
  579.     prec = 2;
  580.  
  581.     stderr = "stderr";
  582.  
  583.     Yes  = /^{_w}*[Yy](es)?{_w}*$/;    # Yes answer
  584.     No     = /^{_w}*[Nn]o?{_w}*$/;    # No answer
  585.     Quit = /^{_w}*[Qq](uit)?({_w}+[Nn]o?)?{_w}*$/;    # define regular expression To  Quit
  586.     Status = /^{_w}*[Ss](tatus)?{_w}*$/;
  587.     Default = /^{_w}*[Dd](efault)?{_w}*$/;
  588.     Help = /^{_w}*[Hh](elp)?{_w}*$/;
  589.  
  590.     quit_status = TRUE;
  591.  
  592.     # find number of variables defined in calculator progam
  593.     # any new variables defined by user will be in addition to this number
  594.     # the number, vcnt, is then used in displaying status
  595.     vcnt = var_number(FALSE);
  596.  
  597. #    display_cpyr;
  598.     set_default;
  599.     prt_instructions;
  600.     prompt;
  601. }
  602.  
  603. Quit {
  604.     if ( NF > 1 ) {
  605.     switch ( $2 ) {
  606.         case Yes:
  607.         quit_status = TRUE;
  608.         break;
  609.         case No:
  610.         quit_status = FALSE;
  611.         break;
  612.     }
  613.     }
  614.     exit 2;
  615. }
  616.  
  617. Status {
  618.     prt_status;
  619.     prompt;
  620.     next;
  621. }
  622.  
  623. Default {
  624.     set_default;
  625.     prompt;
  626.     next;
  627. }
  628.  
  629. Help {
  630.     prt_instructions;
  631.     prompt;
  632.     next;
  633. }
  634.  
  635.     {
  636.     line = $0;
  637.     if ( $0 !~ /;$/ ) line ∩= ';'; #check for trailing ';'
  638.     print '\t' ∩ addcomma(execute(line,TRUE,TRUE));
  639.     prompt;
  640. }
  641.  
  642. END {
  643.     if ( quit_status ) display_cpyr;
  644. }
  645.  
  646. function display_cpyr() {
  647.     print "Financial Calculator Copyright\n(C) 1990 Terry D. Boldt, All Rights Reserved";
  648. }
  649.  
  650. function prt_status() {
  651.     local cd = disc ? "Discrete (disc = TRUE)" : "Continuous (disc = FALSE)";
  652.     local eb = bep ? "Beginning of Period (bep = TRUE)" : "End of Period (bep = FALSE)";
  653.     local j, jj, ostr;
  654.  
  655.     display_cpyr;
  656.     print "Current Financial Calculator Status:";
  657.     print "Compounding Frequency: (CF) " ∩ CF;
  658.     print "Payment     Frequency: (PF) " ∩ PF;
  659.     print "Compounding: " ∩ cd;
  660.     print "Payments: " ∩ eb;
  661.     print "Number of Payment Periods (n): " ∩ addcomma(n);
  662.     print "Interest per Payment Period (i): " ∩ ci;
  663.     print "Present Value (pv): " ∩ addcomma(pv);
  664.     print "Periodic Payment (pmt): " ∩ addcomma(pmt);
  665.     print "Future Value (fv): " ∩ addcomma(fv);
  666.     print "User Defined Variables:";
  667.     j = vcnt;
  668.     for ( ostr = ud_sym(j++,jj) ; jj ; ostr = ud_sym(j++,jj) )
  669.     print hl_color ∩ jj ∩ nl_color ∩ " == " ∩ addcomma(ostr);
  670. }
  671.  
  672. function prt_instructions() {
  673.     display_cpyr;
  674.     print "To compute Loan Quantities:";
  675.     print "_N(i,pv,pmt,fv) ==> to compute # payment periods";
  676.     print "_I(n,pv,pmt,fv) ==> to compute interest";
  677.     print "_PV(n,i,pmt,fv) ==> to compute Present Value";
  678.     print "_PMT(n,i,pv,fv) ==> to compute Payment";
  679.     print "_FV(n,i,pv,pmt) ==> to compute Future Value\n";
  680.     print "Q(uit)? to Quit";
  681.     print "S(tatus)? to Display Status of Computations";
  682.     print "D(efault)? to Re-Initialize";
  683.     print "H(elp) to Display This Help";
  684. }
  685.  
  686. # Compute constant used in calculations
  687. function _A(nint,per) {
  688.     return (1.0 + nint) ^ per - 1;
  689. }
  690.  
  691. # Compute constant used in calculations
  692. function _B(nint,beg) {
  693.     if ( nint == 0 ) {
  694.     fprintf(stderr,"Zero Interest.\n");
  695.     next;
  696.     }
  697.     return (1.0 + nint * beg)/nint;
  698. }
  699.  
  700. # Compute constant used in calculations
  701. function _C(nint,pmt,beg) {
  702.     return pmt * _B(nint,beg);
  703. }
  704.  
  705. # compute Number of Periods from preset data
  706. function N() {
  707.     return n = _N(i,pv,pmt,fv);
  708. }
  709.  
  710. # Compute number of periods from:
  711. #   1. Nominal Interest
  712. #   2. Present Value
  713. #   3. Periodic Payment
  714. #   4. Future Value
  715. function _N(nint,pv,pmt,fv) {
  716.     local intn = eff_int(nint/100.0);
  717.     local CC = _C(intn,pmt,bep);
  718.  
  719.     return rnd(log((CC - fv)/(CC + pv))/log(1 + intn),prec);
  720. }
  721.  
  722. # compute Interest from preset data
  723. function I() {
  724.     return i = _I(n,pv,pmt,fv);
  725. }
  726.  
  727. # Compute Nominal Interest from:
  728. #   1. Number of periods
  729. #   2. Present Value
  730. #   3. Periodic Payment
  731. #   4. Future Value
  732. function _I(per,pv,pmt,fv) {
  733.     local inte;
  734.     local a, ik, dik;
  735.  
  736.     if ( pmt == 0 ) {
  737.     inte = ((abs(fv) + 0.0)/abs(pv))^(1/per) - 1;
  738.       } else {
  739.     if ( (pmt * fv) < 0 ) {
  740.         if ( pv ) a = -1.0; else a = 1.0;
  741.         inte = abs((fv + a * n * pmt)/(3 * ( (n-1)^2 * pmt + pv - fv) ));
  742.       } else {
  743.         if ( pv*pmt < 0 ) {
  744.         inte = abs((n * pmt + pv + fv + 0.0)/(n * pv));
  745.           } else {
  746.         a = abs((pmt + 0.0)/(abs(pv) + abs(fv)));
  747.         inte = a + 1/(a * per^3);
  748.         }
  749.     }
  750.     do {
  751.         dik = fi(per,inte,pv,pmt,fv)/fip(per,inte,pv,pmt,fv);
  752.         inte -= dik;
  753.     } while ( int(ratio * (dik/inte)) );
  754.     }
  755.     return 100.0 * nom_int(inte);
  756. }
  757.  
  758. # compute Present value from preset data
  759. function PV(n,i,pmt,fv) {
  760.     return pv = _PV(n,i,pmt,fv);
  761. }
  762.  
  763. # Compute Present Value from:
  764. #   1. Number of periods
  765. #   2. Nominal Interest
  766. #   3. Periodic Payment
  767. #   4. Future Value
  768. function _PV(per,nint,pmt,fv) {
  769.     local intn = eff_int(nint/100.0);
  770.     local AA = _A(intn,per);
  771.     local BB = _B(intn,bep);
  772.     local CC = _C(intn,pmt,bep);
  773.  
  774.     return rnd(-(fv + (AA * CC))/(AA + 1),prec);
  775. }
  776.  
  777. # compute Periodic Payment from preset data
  778. function PMT() {
  779.     return pmt = _PMT(n,i,pv,fv);
  780. }
  781.  
  782. # Compute Periodic Payment from:
  783. #   1. Number of periods
  784. #   2. Nominal Interest
  785. #   3. Present Value
  786. #   4. Future Value
  787. function _PMT(per,nint,pv,fv) {
  788.     local intn = eff_int(nint/100.0);
  789.     local AA = _A(intn,per);
  790.     local BB = _B(intn,bep);
  791.  
  792.     return rnd(-(fv + pv * (AA + 1))/(AA * BB),prec);
  793. }
  794.  
  795. # compute Future Value from preset data
  796. function FV() {
  797.     return fv = _FV(n,i,pv,pmt);
  798. }
  799.  
  800. # Compute Future Value from:
  801. #   1. Number of periods
  802. #   2. Nominal Interest
  803. #   3. Present Value
  804. #   4. Periodic Payments
  805. function _FV(per,nint,pv,pmt) {
  806.     local intn = eff_int(nint/100.0);
  807.     local AA = _A(intn,per);
  808.     local CC = _C(intn,pmt,bep);
  809.  
  810.     return rnd(-(pv + AA * (pv + CC)),prec);
  811. }
  812.  
  813. # compute Nominal Interest Rate from Effective Interest Rate
  814. function nom_int(inte) {
  815.     local nint;
  816.  
  817.     if ( disc ) nint = CF * ((1 + inte)^(PF/CF) - 1);
  818.       else nint = log((1 + inte)^PF);
  819.     return nint;
  820. }
  821.  
  822. # Compute Effective Interest Rate from Nominal Interest Rate
  823. function eff_int(nint) {
  824.     local inte;
  825.  
  826.     if ( disc ) inte = (1 + nint/CF)^(CF/PF) - 1;
  827.       else inte = exp(nint/PF) - 1;
  828.     return inte;
  829. }
  830.  
  831. # function to add commas to numbers
  832. function addcomma(x) {
  833.     local num;
  834.     local spat;
  835.     local bnum = /{_d}{3,3}([,.]|$)/;
  836.  
  837.     if ( x < 0 ) return "-" ∩ addcomma(-x);
  838.     num = sprintf("%.14g",x);        # num is dddddd.dd
  839.     spat = num ~~ /\./ ? /{_d}{4,4}[.,]/ : /{_d}{4,4}(,|$)/;
  840.     while ( num ~~ spat ) sub(bnum,",&",num);
  841.     return num;
  842. }
  843.  
  844. # return 'x' rounded to 'places' past decimal
  845. # if 'places' == 0, return 'x'
  846. function rnd(x,places) {
  847.     local pwr, r, inc;
  848.  
  849.     if ( places >= 0 ) {
  850.     pwr = 10 ^ places;
  851.     r = x * pwr;
  852.     inc = abs(int(10 * fract(r))) >= 5 ? signum(x) : 0;
  853.     r = int(r + inc) / pwr;
  854.     } else r = x;
  855.     return r;
  856. }
  857.  
  858. # return absolute value of 'x'
  859. function abs(x) {
  860.     return x > 0 ? x : -x;
  861. }
  862.  
  863. # return sign of 'x'
  864. #  returns:
  865. #   1  ==> x >    0
  866. #   0  ==> x == 0
  867. #  -1  ==> x <    0
  868. function signum(x) {
  869.     return x == 0 ? 0 : x > 0 ? 1 : -1;
  870. }
  871.  
  872. # calculation used in interest computation
  873. function fi(per,nint,pv,pmt,fv) {
  874.     return _A(nint,per) * (pv + _C(nint,pmt,bep)) + pv + fv;
  875. }
  876.  
  877. # calculation used in interest computation
  878. function fip(per,nint,pv,pmt,fv) {
  879.     local AA = _A(nint,per);
  880.     local CC = _C(nint,pmt,bep);
  881.     local D = (AA + 1.0)/(1.0 + nint);
  882.  
  883.     return per * (pv + CC) * D    - (AA * CC)/nint;
  884. }
  885.  
  886. function prompt() {
  887.     printf("<>");
  888. }
  889.  
  890. function set_default() {
  891.     # flag whether accrueing interest at beginning or end of period
  892.     # FALSE --> end
  893.     # TRUE  --> beginning
  894.     bep = FALSE;
  895.  
  896.     # flag for discrete or continuous interest
  897.     # TRUE  --> discrete
  898.     # FALSE --> continuous
  899.     disc = TRUE;
  900.  
  901.     # set compounding, CF, and payment, PF, frequency
  902.     CF = PF = 1;
  903.  
  904.     # standard loan quantities:
  905.     # number of periods: n
  906.     n = 0;
  907.     # annual interest: i
  908.     i = 0;
  909.     # Present Value: pv
  910.     pv = 0;
  911.     # Payment: pmt
  912.     pmt = 0;
  913.     # Future Value: fv
  914.     fv = 0;
  915. }
  916.  
  917. # function to return the current number of GLOBAL variables defined in utility
  918. function var_number(display) {
  919.     local cnt, j, jj;
  920.  
  921.     for ( jj = cnt = 1 ; jj ; cnt++ ) {
  922.     j = ud_sym(cnt,jj);
  923.     if ( display ) print cnt ∩ " : " ∩ jj ∩ " ==>" ∩ j ∩ "<==";
  924.     }
  925.     return cnt - 1;
  926. }
  927.