Newbie with humble contribution

For everything that's not in any way related to PureBasic. General chat etc...
bart
New User
New User
Posts: 8
Joined: Sun Feb 01, 2004 5:32 am
Contact:

Newbie with humble contribution

Post by bart »

Hi I am new to PB and this forum and really am enjoying the learning curve,I thought i would make a very small contribution something i needed the other day borrowing money,lol
I hope it is usefull to someone as so much of the code in this forum is GOLD!

thanks, bart

Code: Select all

;Simple Loans Calculator,  Calculates Compound Interest the way Banks do/should!!
;Submitted by Bart


;fortnightly repayments are based on true fortnights 2.16666 per calender month
;fortnights = two weeks:  i believe americans dont use the term fortnight
;have fun,bart


; PureBasic Visual Designer v3.90 build 1360


;- Window Constants
;
Enumeration
  #Window_03
EndEnumeration

;- Gadget Constants
;
Enumeration
  #CButton_0
  #CButton_1
  
  #CText_0
  #CText_1
  #CText_2
  #CText_3
  #CText_4
  #CText_5
  
  
  #CString_0
  #CString_1
  #CString_2
  #CString_3
  #CString_4
  #CString_5
EndEnumeration
  
  
 
  


Procedure Open_Window_0()
  If OpenWindow(#Window_03, 216, 0, 204, 450,  #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_SizeGadget | #PB_Window_TitleBar , "Loans Calculator")
    If CreateGadgetList(WindowID())
      ButtonGadget(#CButton_0, 10, 190, 80, 40, "Calculate")
      TextGadget(#CText_0, 10, 30, 80, 30, "Interest Rate %")
      TextGadget(#CText_1, 10, 70, 80, 30, "Repayment Period  (Years)")
      TextGadget(#CText_2, 10, 120, 70, 30, "Amount To Borrow          $")
      StringGadget(#CString_0, 90, 20, 90, 30, "")
      StringGadget(#CString_1, 90, 70, 90, 30, " ")
      StringGadget(#CString_2, 90, 120, 90, 30, " ")
      TextGadget(#CText_3, 10, 260, 80, 40, "Fortnightly  Repayments $")
      TextGadget(#CText_4, 10, 320, 70, 40, "Monthly Repayments $")
      TextGadget(#CText_5, 10, 380, 80, 40, "Yearly Total Repayments $")
      StringGadget(#CString_3, 90, 260, 90, 30, "")
      StringGadget(#CString_4, 90, 320, 90, 30, "")
      StringGadget(#CString_5, 90, 380, 90, 30, "")
      ButtonGadget(#CButton_1, 110, 190, 80, 40, "Clear")
      
    EndIf
  EndIf
EndProcedure
Open_Window_0()

Repeat

 EventID = WaitWindowEvent()
    
    If EventID = #PB_EventGadget


Select EventGadgetID()

 
Case #CButton_0
 
    SetGadgetText(#CString_3,"")
    SetGadgetText(#CString_4,"")
    SetGadgetText(#CString_5,"")
      
    R.f=ValF(GetGadgetText(#CString_0));interest
    N.f=ValF(GetGadgetText(#CString_1));number of periods
    P.f=ValF(GetGadgetText(#CString_2));principal
    F.f;fortnight
    M.f;month
    Y.f;year
    
    
   ; avoid divide by zero's
    If R>0 And N>0 And P>0
     
   a.f
   
   r=r/12
   
   N=N*12
   
   a=((P*r)/100)*( Pow( (1 + r/100), n ) / ( Pow( ( 1 + r/100), n) - 1))
    
   F=(a*12)/26
   
   Y=a*12
    SetGadgetText(#CString_3,StrF(F))
    SetGadgetText(#CString_4,StrF(a))
    SetGadgetText(#CString_5,StrF(Y))
    
    
  Else

    
       MessageRequester("Notice", "Please Fill In All Fields", 0)
       
       
       
  EndIf





Case #CButton_1
     SetGadgetText(#CString_0,"")
     SetGadgetText(#CString_1,"")
     SetGadgetText(#CString_2,"")
     SetGadgetText(#CString_3,"")
     SetGadgetText(#CString_4,"")
     SetGadgetText(#CString_5,"")

     

EndSelect



EndIf

  Until EventID = #PB_EventCloseWindow

End
BillNee
User
User
Posts: 93
Joined: Thu Jan 29, 2004 6:01 am
Location: Homosassa, FL

Post by BillNee »

Hi - well designed program. I don't get the "(Years)" to appear in the repayment portion and assumed it to be in months; coming up with some great payments that way! BTW most banks will round up the monthly payment to be sure to get all the interest; a payment of 99.597 will be 99.60 even. The slight extra then gets deducted from the principal. Maybe you could include a "Total Payment" result and really scare people.
Bill Nee
TerryHough
Enthusiast
Enthusiast
Posts: 781
Joined: Fri Apr 25, 2003 6:51 pm
Location: NC, USA
Contact:

Re: Newbie with humble contribution

Post by TerryHough »

bart wrote:something i needed the other day borrowing money,lol
Nice start, Bart!

But may I caution you. Your results are not correct for the "fortnight" payment amount. (We Americans know the term, but we call them "bi-weekly" payments instead).

Loan payments (amortization of a loan) must be computed directly for each selected payment period. You took the computed monthly payment, annualized that and then divided by 26 payments). That overlooks the effect of the more frequent payment's reduction in principal for each subsequent period.

Example: Given a $100000 loan at 7% for 30 years;
Your "fortnightly" payment computes to $307.06. The more generally accepted calculation result is $306.92.
Your month payment rounded is $665.30 and that is the correct number as generally accepted.

So, you may wish to tweak your code a bit to directly compute the payment amount for a "fortnight" payment period.

:D The first program I write in any new language I work with is a complete Loan Amortization and Amortiztion Schedule Printout routine. I've probably done it in 25 or more languages just to test the language and to learn how to use the new lanquage. Since I specialize in financial applications, I have found this exercise allows me to test the language for use in my day-to-day programming.

Welcome to PB and the Forum

Terry
bart
New User
New User
Posts: 8
Joined: Sun Feb 01, 2004 5:32 am
Contact:

loans

Post by bart »

Thanks for the great comments guys

I really didnt get into it as heavy as i should ,i just checked the results against the loans calculator in MSworks which gives the monthly result
as correct ,i got lazy on the bi-weekly side ill confess but it suited my purpose for the time,


bart
bart
New User
New User
Posts: 8
Joined: Sun Feb 01, 2004 5:32 am
Contact:

Post by bart »

Thanks for the observation Terry,
this code does the right thing to the numbers

Code: Select all











;Simple Loans Calculator,  Calculates Compound Interest the way Banks do/should!!
;Submitted by Bart


;fortnightly repayments are based on true fortnights 2.16666 per calender month
;fortnights = two weeks:  i believe americans dont use the term fortnight
;have fun,bart


; PureBasic Visual Designer v3.90 build 1360


;- Window Constants
;
Enumeration
  #Window_03
EndEnumeration

;- Gadget Constants
;
Enumeration
  #CButton_0
  #CButton_1
  
  #CText_0
  #CText_1
  #CText_2
  #CText_3
  #CText_4
  #CText_5
  #CText_6
  #CString_0
  #CString_1
  #CString_2
  #CString_3
  #CString_4
  #CString_5
  #CString_6

EndEnumeration
  
  
  
  
 
  


Procedure Open_Window_0()
  If OpenWindow(#Window_03, 216, 0, 204, 520,  #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_SizeGadget | #PB_Window_TitleBar , "Pure Loans Calculator")
    If CreateGadgetList(WindowID())
      ButtonGadget(#CButton_0, 10, 190, 80, 40, "Calculate")
      TextGadget(#CText_0, 10, 30, 80, 30, "Interest Rate %")
      TextGadget(#CText_1, 10, 70, 80, 30, "Repayment Period  (Years)")
      TextGadget(#CText_2, 10, 120, 70, 30, "Amount To Borrow          $")
      StringGadget(#CString_0, 90, 20, 90, 30, "")
      StringGadget(#CString_1, 90, 70, 90, 30, " ")
      StringGadget(#CString_2, 90, 120, 90, 30, " ")
      TextGadget(#CText_3, 10, 260, 80, 40, "Fortnightly  Repayments $")
      TextGadget(#CText_4, 10, 320, 70, 40, "Monthly Repayments $")
      TextGadget(#CText_5, 10, 380, 80, 40, "Yearly Total Repayments $")
      TextGadget(#CText_6, 10, 440, 80, 40, " Total Repayments $")
      StringGadget(#CString_3, 90, 260, 90, 30, "")
      StringGadget(#CString_4, 90, 320, 90, 30, "")
      StringGadget(#CString_5, 90, 380, 90, 30, "")
      StringGadget(#CString_6, 90, 440, 90, 30, "")
      ButtonGadget(#CButton_1, 110, 190, 80, 40, "Clear")
            
    EndIf
  EndIf
EndProcedure

Open_Window_0()

      
Repeat

 EventID = WaitWindowEvent()
    
    If EventID = #PB_EventGadget


Select EventGadgetID()

 
Case #CButton_0
 
    SetGadgetText(#CString_3,"")
    SetGadgetText(#CString_4,"")
    SetGadgetText(#CString_5,"")
      
    R.f=ValF(GetGadgetText(#CString_0));interest
    N.f=ValF(GetGadgetText(#CString_1));number of periods
    P.f=ValF(GetGadgetText(#CString_2));principal
    F.f;fortnight
    M.f;month
    Y.f;year
    A.f
    AA.f
    RR.f
    NN.f
    T.f
   ; avoid divide by zero's
    If R>0 And N>0 And P>0
     
  
   
   For rep = 0 To 1
   
   If rep=0:x=12:EndIf
   If rep=1:x=26:EndIf

   
   RR=R/x
   
   NN=N*x
   
   A=((P*RR)/100)*( Pow( (1 + RR/100), NN ) / ( Pow( ( 1 + RR/100), NN) - 1))
   
   If rep = 0:AA=A:EndIf
   If rep = 1:F=A:EndIf
   

   Next rep
  
   
   Y=AA*12
   T=Y*N
    
   SetGadgetText(#CString_3,StrF(F))
   SetGadgetText(#CString_4,StrF(AA))
   SetGadgetText(#CString_5,StrF(Y))
   SetGadgetText(#CString_6,StrF(T))

    
  Else

    
       MessageRequester("Notice", "Please Fill In All Fields", 0)
       
       
       
  EndIf





Case #CButton_1
     SetGadgetText(#CString_0,"")
     SetGadgetText(#CString_1,"")
     SetGadgetText(#CString_2,"")
     SetGadgetText(#CString_3,"")
     SetGadgetText(#CString_4,"")
     SetGadgetText(#CString_5,"")
     SetGadgetText(#CString_6,"")

     

EndSelect



EndIf

  Until EventID = #PB_EventCloseWindow

End
TerryHough
Enthusiast
Enthusiast
Posts: 781
Joined: Fri Apr 25, 2003 6:51 pm
Location: NC, USA
Contact:

Post by TerryHough »

Good job, bart... Keep on learning and improving your PB skills.

When dealing with this type of financial work, accuracy is very
important. It requires dealing with "real" numbers, not floats.
Banks don't actually deal in fractions of cents, at least the good
ones (Boy, the stories I could tell about the program problems
in the past.)

FWIW, here is your code modified a bit to gain more accuracy, cull
unnecessary code, show the real "fortnight" totals, and reflect my
coding style (good or bad).

I don't usually open windows in a procedure, although there is notihing
wrong with that. Just be sure to check for success of the procedure so
you can bypass other code if it fails.(I've not ever actually had a window
creation fail, but just to be safe.)

I am not being critical, just presenting a slightly different approach. I
hope you can learn from my changes.

Code: Select all

;Simple Loans Calculator,  Calculates Compound Interest the way Banks do/should!!
;Submitted by Bart

;fortnightly repayments are based on true fortnights 2.16666 per calender month
;fortnights = two weeks:  i believe americans dont use the term fortnight
;have fun,bart

; PureBasic Visual Designer v3.90 build 1360

;- Gadget Constants
Enumeration
#CButton_0
#CButton_1
#CButton_2

#CText_0
#CText_1
#CText_2
#CText_3
#CText_4
#CText_5
#CText_6
#CText_7
#CText_8

#CString_0
#CString_1
#CString_2
#CString_3
#CString_4
#CString_5
#CString_6
#CString_7
#CString_8
EndEnumeration

; Rounding procedure --------------------------------------
Procedure.s Rounding(a.f,b1.f)
  Rounded.f = ((a * Pow(10,b1)) + 0.05) / Pow(10,b1)
  ; Now we have the rounded number ready for truncation to the
  ; desired number of decimal places.
  ; StrF(x,d) truncates without rounding, the above was necessary.
  
  ; The real number can't reliably be stored in a float, so we
  ; must store it in a string.
  A$ = StrF(Rounded,b1) ; Real number stored in a string
  Rounded = ValF(A$)    ; Convert the actual number back to a float
                        ; but accuracy still suffers.
  ProcedureReturn A$
EndProcedure
; ---------------------------------------------------------

; Main program code ---------------------------------------
If OpenWindow(0, 216, 0, 304, 520, #PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_SizeGadget|#PB_Window_TitleBar, "Pure Loans Calculator")
  CreateGadgetList(WindowID())
  ButtonGadget(#CButton_0, 10, 190, 80, 40, "Calculate")
  ButtonGadget(#CButton_1,110, 190, 80, 40, "Clear")
  ButtonGadget(#CButton_2,210, 190, 80, 40, "Exit")
  TextGadget  (#CText_0,   10,  30, 80, 30, "Interest Rate %")
  TextGadget  (#CText_1,   10,  70, 80, 30, "Repayment Period  (Years)")
  TextGadget  (#CText_2,   10, 120, 70, 30, "Amount To Borrow          $")
  StringGadget(#CString_0, 90,  20, 90, 30, "",  #ES_RIGHT)
  StringGadget(#CString_1, 90,  70, 90, 30, " ", #ES_RIGHT)
  StringGadget(#CString_2, 90, 120, 90, 30, " ", #ES_RIGHT)
  TextGadget  (#CText_7,   90, 300, 90, 40, "Fortnightly",#PB_Text_Center)
  TextGadget  (#CText_8,  190, 300, 90, 40, "Monthly",#PB_Text_Center)
  TextGadget  (#CText_3,   10, 320, 80, 40, "Repayment Amount $")
  TextGadget  (#CText_5,   10, 380, 80, 40, "Yearly Total Repayments $")
  TextGadget  (#CText_6,   10, 440, 80, 40, "Total Repayments $")
  StringGadget(#CString_3, 90, 320, 90, 30, "", #ES_RIGHT)
  StringGadget(#CString_4,190, 320, 90, 30, "", #ES_RIGHT)
  StringGadget(#CString_5, 90, 380, 90, 30, "", #ES_RIGHT)
  StringGadget(#CString_6, 90, 440, 90, 30, "", #ES_RIGHT)
  StringGadget(#CString_7,190, 380, 90, 30, "", #ES_RIGHT)
  StringGadget(#CString_8,190, 440, 90, 30, "", #ES_RIGHT)
  
  ; Main program event loop -------------------------------  
  Repeat
    EventID = WaitWindowEvent()
    If EventID = #PB_EventGadget
      Select EventGadgetID()
        Case #CButton_0
          R.f = ValF(GetGadgetText(#CString_0));interest
          N.f = ValF(GetGadgetText(#CString_1));number of periods
          P.f = ValF(GetGadgetText(#CString_2));principal
          ; Avoid dividing by zero
          If R>0 And N>0 And P>0
          
            ; Compute a monthly payment -----------------------
            x    = 12               ; Payments per year
            AA.s = Rounding(((P*(R/x))/100)*(Pow((1 + (R/x)/100), N*x) / ( Pow( ( 1 + (R/x)/100), N*x) - 1)),2)
            Y.s  = Rounding(ValF(AA)*x,2) ; Total annual payment at monthly payment
            T.s  = Rounding(ValF(Y)*N,2)  ; Total payments on loan
            ; -------------------------------------------------
          
            ; Compute a fortnightly payment -------------------
            x    = 26               ; Payments per year
            F.s  = Rounding(((P*(R/x))/100)*(Pow((1 + (R/x)/100), N*x) / ( Pow( ( 1 + (R/x)/100), N*x) - 1)),2)
            FY.s = Rounding(ValF(F)*x,2)  ; Total annual payment at monthly payment
            FT.s = Rounding(ValF(FY)*N,2) ; Total payments on loan
            ; -------------------------------------------------
          
            SetGadgetText(#CString_3, F)
            SetGadgetText(#CString_4,AA)
            SetGadgetText(#CString_5,FY)
            SetGadgetText(#CString_6,FT)
            SetGadgetText(#CString_7, Y)
            SetGadgetText(#CString_8, T)
          
        Else
          MessageRequester("Notice", "Please Fill In All Fields", 0)
        EndIf
        
        Case #CButton_1
          SetGadgetText(#CString_0,"")
          SetGadgetText(#CString_1,"")
          SetGadgetText(#CString_2,"")
          SetGadgetText(#CString_3,"")
          SetGadgetText(#CString_4,"")
          SetGadgetText(#CString_5,"")
          SetGadgetText(#CString_6,"")
          SetGadgetText(#CString_7,"")
          SetGadgetText(#CString_8,"")

        Case #CButton_2
          Quit = #TRUE
          
      EndSelect
    EndIf
  Until Quit = #TRUE Or EventID = #PB_EventCloseWindow
  ; End of program event loop -----------------------------
  
EndIf
End
Enjoy,
Terry
bart
New User
New User
Posts: 8
Joined: Sun Feb 01, 2004 5:32 am
Contact:

Post by bart »

Thanks Terry
Its great to see different styles and everything helps to continue the learning curve, im trying your code now and seems great.
Bart
naw
Enthusiast
Enthusiast
Posts: 573
Joined: Fri Apr 25, 2003 4:57 pm

Please, Please, Please

Post by naw »

Bart (anyone),

Please, Please, Please add in a field for "Additional Voluntary Contributions".

I have an Interest Only Mortgage and Make extra Capital Repayments, I'd like to be able to see if my additional payments pay off the whole loan by the end of the term (and indeed if I can reduce the term of the loan)

I think it would be safe to assume Daily / Bi-Weekly / Monthly Recalcs by my lender.

Geeze, I wish I could do it myself, but my maths are dreadful and I dont want to get it wrong - you guys sound like you know what you're doing...

Ta - N
Ta - N
bart
New User
New User
Posts: 8
Joined: Sun Feb 01, 2004 5:32 am
Contact:

Post by bart »

Naw ,
the calculations you need can be done with the code at this post
all you need to do is take the current balance of your loan deduct the
additional payment and recalculate the balance as a new loan adjusting the period until it matches your current monthly repayment amount this should give you an approximation of the years left to go,if you need to do hyperthetical future repayments the math essentials are in the code

,have fun

bart
Post Reply