home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / DMX23.ZIP / DMXAMORT.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1990-02-14  |  7.8 KB  |  265 lines

  1. Program DMXAMORT;
  2.  
  3. {$V- }
  4.  
  5. (*
  6.     This program uses the DMX unit to generate an amortization schedule.
  7.  
  8.     Two DMX objects are used:
  9.  
  10.         The SelectWindow object uses a single-record editor to input
  11.         the financial parameters Year, Month, Amount, Rate, and Years
  12.         to calculate the loan amortization sheet.
  13.         SELECTOR uses this object-type.
  14.  
  15.         The AmortWindow object is a descendant of DMXviewer, so as to
  16.         scroll through the table without allowing changes.  The DataAt
  17.         virtual function is modified to calculate each record as it
  18.         needs to be displayed.  This can be slow on an 8088 CPU.
  19.         The advantage to this is that the entire table does not need to
  20.         be kept in memory.
  21.         AMORT uses this object-type.
  22.  
  23.     This program is meant only as a demonstration for various uses of
  24.     the DMX objects.
  25.  
  26.     This program is designed for MONTHLY payments only.  BI-WEEKLY mortgages
  27.     have a radically different schedule --although you may certainly modify
  28.     this program to accommodate week numbers instead of month names.
  29.  
  30.  *)
  31.  
  32.  
  33. uses   Dos, Crt, DMX2;
  34.  
  35.  
  36. type   AmortRec     =  record
  37.                          Year       : word;
  38.                          MonthName  : string [12];
  39.                          Principal  : real;
  40.                          Interest   : real;
  41.                          Balance    : real;
  42.                        end;
  43.  
  44.        SelectRec    =  record
  45.                          Year,Month : word;
  46.                          Principal  : real;
  47.                          Interest   : real;
  48.                          Years      : word;
  49.                        end;
  50.  
  51.        SelectWindow = object (DMXwindow)
  52.                         Info        : SelectRec;
  53.                         procedure PickIt;
  54.                       end;
  55.  
  56.        AmortWindow  = object (DMXviewer)
  57.                         linedata    :  AmortRec;
  58.                         Total       :  real;
  59.                         Rate        :  real;
  60.                         Payment     :  real;
  61.                         Years       :  word;
  62.                         Periods     :  word;
  63.                         FirstMonth  :  word;
  64.                         FirstYear   :  word;
  65.                         LastPayment :  word;
  66.                         LastTotal   :  real;
  67.  
  68.                         function  DataAt (recnum : longint) : pointer;
  69.                                   virtual;
  70.                         procedure Amortize (prin,interest :real; ys,y,m :word);
  71.                       end;
  72.  
  73.  
  74. const  maintitle   =  ' year   month           principal        interest          balance    ';
  75.        baseformat  =  ' WWWW │ ____________ ║($R,RRR,RRR.RR)│($R,RRR,RRR.RR)║($RR,RRR,RRR.RR)';
  76.  
  77.        spectitle   =  '  year   month       amount       rate    years ';
  78.        specformat  =  '  WWWW |  WW  ║ $rr,rrr,rrr.rr ║ %rr.rr |   WW  ';
  79.  
  80.        cr          =  #13;
  81.        Esc         =  #27;
  82.        F9          =  'C';
  83.  
  84.        Months      :  array [0..11] of string [12] =
  85.                              ('January  ',
  86.                               'February ',
  87.                               'March    ',
  88.                               'April    ',
  89.                               'May      ',
  90.                               'June     ',
  91.                               'July     ',
  92.                               'August   ',
  93.                               'September',
  94.                               'October  ',
  95.                               'November ',
  96.                               'December ');
  97.  
  98.  
  99.  
  100. var    Key,ext     :  char;
  101.        DOScolors   :  word;          { original colors }
  102.  
  103.        SELECTOR    :  SelectWindow;  { selector object }
  104.        AMORT       :  AmortWindow;   { viewer object }
  105.  
  106.  
  107.   { ─────────────────────────────────────────────────────────────────────── }
  108.  
  109.  
  110. function  Radical (number,exponent : real) : real;
  111. { returns the value of number raised to the power of exponent }
  112. begin
  113.   Radical := exp (Ln (abs (number)) * abs (exponent))
  114. end;
  115.  
  116.  
  117.   { ─────────────────────────────────────────────────────────────────────── }
  118.  
  119.  
  120. function  AmortPMT (prin,interest,term : real) : real;
  121. { amount of the periodic payment on the loan }
  122. begin
  123.   AmortPMT := prin * (interest / (1 - (1 / (Radical (1 + interest,term)))));
  124. end;
  125.  
  126.  
  127.   { ─────────────────────────────────────────────────────────────────────── }
  128.  
  129.  
  130. function  AmortWindow.DataAt (recnum : longint) : pointer;
  131. { The original descendant of this method returns a pointer }
  132. { to where the record would be stored in memory.           }
  133. { This virtual method pretends to retrieve the next record }
  134. { by calculating the record contents in LINEDATA.          }
  135. { The function then returns a pointer to LINEDATA.         }
  136. { RECNUM is actually the payment number, minus zero.       }
  137. var  i,j  : word;
  138. begin
  139.   With linedata do
  140.     begin
  141.     If LastPayment <> recnum then
  142.       begin
  143.       If LastPayment > recnum then
  144.         begin
  145.         LastPayment := 0;
  146.         LastTotal   := Total;
  147.         end
  148.        else
  149.         Inc (LastPayment);
  150.       For i := LastPayment to recnum do
  151.         begin
  152.         Interest   :=  Rate * LastTotal;
  153.         Principal  :=  Payment - Interest;
  154.         LastTotal  :=  LastTotal - Principal;
  155.         If recnum = pred (recordlimit) then
  156.           Balance := 0.0
  157.          else
  158.           Balance :=  LastTotal;
  159.         end;
  160.       LastPayment := recnum;
  161.       end;
  162.     Year       := ((recnum + FirstMonth) div 12) + FirstYear;
  163.     MonthName  :=  Months [(recnum + FirstMonth) mod 12];
  164.     end;
  165.  
  166.   DataAt := addr (linedata);
  167. end;
  168.  
  169.  
  170.   { ─────────────────────────────────────────────────────────────────────── }
  171.  
  172.  
  173. procedure AmortWindow.Amortize (prin,interest : real;  ys,y,m : word);
  174. { This method initializes the amortization variables, and then runs EditData. }
  175. var  void : byte;
  176. begin
  177.   FirstYear   :=  y;
  178.   FirstMonth  :=  m;
  179.  
  180.   Total       :=  prin;
  181.   Rate        :=  interest / 100 / 12;
  182.   Years       :=  ys;
  183.   Periods     :=  Years * 12;
  184.   LastPayment :=  32000;
  185.  
  186.   Payment := AmortPMT (Total,Rate,Periods);
  187.  
  188.   Window (6,2,75,24);
  189.   WindBorder (LightCyan);
  190.  
  191.   TextAttr := bordercolor;
  192.   ClrScr;
  193.   GotoXY (2,23);
  194.   write ('Your monthly payment is:   $', Payment:1:2);
  195.   ClrPosition;  { reset current record pointer }
  196.   OpenBuffer (void, sizeof (AmortRec) * Periods);
  197.  
  198.   EditData (void, Key,ext, [Esc],[]);
  199. end;
  200.  
  201.  
  202.   { ─────────────────────────────────────────────────────────────────────── }
  203.  
  204.  
  205. procedure SelectWindow.PickIt;
  206. begin
  207.   showzeroes  := True;  { make any zero amounts visible }
  208.   With Info do
  209.     begin
  210.     Year      := 1990;
  211.     Month     :=  1;
  212.     Principal := 10000.00;
  213.     Interest  := 10;
  214.     Years     := 30;
  215.     end;
  216.  
  217.   Repeat
  218.     Window (17,9,64,13);
  219.     TextAttr  := bordercolor;
  220.     WindBorder (Yellow);
  221.     ClrScr;
  222.     GotoXY (10,5);
  223.     write ('press F9 to calculate mortgage');
  224.  
  225.     OpenBuffer (Info, sizeof (Info));
  226.     EditData (Info, Key,ext, [Esc],[F9]);
  227.  
  228.     If (ext = F9) then With Info do
  229.       begin
  230.       If (Principal > 0) and (Interest > 0)
  231.         and
  232.          (Years > 1) and (Month > 0) and (Month <= 12)
  233.        then
  234.         begin
  235.         AMORT.Amortize (Principal,Interest, Years,Year, Month - 1);
  236.         Key := #0;
  237.         end
  238.        else
  239.         begin
  240.         Sound (1000);  Delay (100);  NoSound;
  241.         end;
  242.       end;
  243.   Until Key = Esc;
  244. end;  { PickIt }
  245.  
  246.  
  247.   { ─────────────────────────────────────────────────────────────────────── }
  248.  
  249.  
  250. Begin
  251.   DOScolors := TextAttr;  { save the original screen color }
  252.   TextAttr  := LightGray;
  253.   ClrScr;
  254.  
  255.   AMORT.Init (maintitle, baseformat, 2,2, $3B,$3F,$70);
  256.   SELECTOR.Init (spectitle, specformat, 2,2, $3E,$3F,$70);
  257.  
  258.   SELECTOR.Pickit;
  259.  
  260.   TextAttr := DOScolors;  { close the program in the original colors }
  261.   Window (1,1,80,25);
  262.   ClrScr;
  263. End.
  264.  
  265.