Results 1 to 1 of 1

Thread: Loan Calculator

  1. #1

    Thread Starter
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,897

    Loan Calculator

    Here is some code for a simple loan calculator. The class can save and load loans from XML files.

    The code to test needs a form, with one button and a datagridview.
    Code:
        'test LoanCalc
        Dim foo As New LoanCalc(300000, 3.73D, 360, "testloan")
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            DataGridView1.DataSource = foo.Schedule
        End Sub
    the class
    Code:
    Public Class LoanCalc
    
        'payment
        '           iA
        ' P = ------------
        '      1-((1+i)^-n)
        '
        '
        'loan balance after n paymnets
        'Balance = A(1+i)^n-P/i((1+i)^n-1)
        '
        'P is payment, i is interest rate, A is loan amount, n is the number of payments
    
        Private _amt As Decimal = 0 'loan amount
        Private _term As Integer = 0 'term of loan in months
        Private _rate As Decimal = 0 'interest rate / period (rate / 12)
        Private _payment As Decimal = 0 'payment
        Private _totInt As Decimal = 0 'will hold total interest after schedule runs
        Private _schedule As DataTable
        Private NameOfLoan As String = ""
    
        Private Shared ReadOnly zeroPercent As Decimal = 1D / 1000000000 'a kludge
    
        ''' <summary>
        ''' create loan object
        ''' </summary>
        ''' <param name="loanmAmt">the amount of the loan</param>
        ''' <param name="interestRate">interest rate, e.g. 4.5 or .045 for 4.5%</param>
        ''' <param name="TermMonths">loan length in months</param>
        ''' <remarks></remarks>
        Public Sub New(loanmAmt As String, interestRate As String, TermMonths As String, Optional LoanName As String = "Loan")
            Me._amt = Decimal.Parse(loanmAmt)
            Me._rate = Decimal.Parse(interestRate)
            Me._term = Integer.Parse(TermMonths)
            Me.InitCommon(LoanName)
        End Sub
    
        ''' <summary>
        ''' create loan object
        ''' </summary>
        ''' <param name="loanmAmt">the amount of the loan</param>
        ''' <param name="interestRate">interest rate, e.g. 4.5 or .045 for 4.5%</param>
        ''' <param name="TermMonths">loan length in months</param>
        ''' <remarks></remarks>
        Public Sub New(loanmAmt As Decimal, interestRate As Decimal, TermMonths As Integer, Optional LoanName As String = "Loan")
            Me._amt = loanmAmt
            Me._rate = interestRate
            Me._term = TermMonths
            Me.InitCommon(LoanName)
        End Sub
    
        Private Sub InitCommon(nm As String)
            Me.NameOfLoan = nm
            If Me._rate >= 1 Then
                Me._rate = Me._rate / 100D
            End If
            Me._rate /= 12D 'convert to monthly rate
            If Me._rate = 0D Then Me._rate = zeroPercent
            Me._payment = CDec(-((Me._rate * Me._amt) / (1 - ((1 + Me._rate) ^ -Me._term))))
            Me.doSchedule()
        End Sub
    
        Public Function LoanAmount() As Decimal
            Return Me._amt
        End Function
    
        Public Function InterestRate() As Decimal
            Return Me._rate * 12D
        End Function
    
        Public Function TermMonths() As Decimal
            Return Me._term
        End Function
    
        Public Function TermYears() As Decimal
            Return Me._term / 12D
        End Function
    
        Public Function Payment() As Decimal
            Return Me._payment
        End Function
    
        Public Function TotalInterest() As Decimal
            Return Me._totInt
        End Function
    
        Public Function Schedule() As DataTable
            Return Me._schedule
        End Function
    
        Private Sub doSchedule()
            Me.LOANxml = New XElement(Me.loanCont)
            Me.LOANxml.<loaninfo>.<name>.Value = Me.NameOfLoan
            Me.LOANxml.<loaninfo>.<amount>.Value = Me._amt.ToString("c2")
            Me.LOANxml.<loaninfo>.<term>.Value = Me._term.ToString
            Me.LOANxml.<loaninfo>.<rate>.Value = (Me._rate * 12D).ToString("p4")
            Me.LOANxml.<loaninfo>.<payment>.Value = (-Me._payment).ToString
    
            Dim amort As New XElement(Me.loanAmort)
            Dim begbal As Decimal = Me._amt
            Dim pad As Integer = Me._term.ToString.Length
            Me._totInt = 0D
    
            For np As Integer = 1 To Me._term
                Dim balAfter As Decimal = Me.BalanceAfterXpayments(np)
                Dim prin As Decimal = begbal - balAfter
                Dim int As Decimal = -Me._payment - prin
                Me._totInt += int
                Dim apay As New XElement(loanSched)
                apay.<num>.Value = np.ToString.PadLeft(pad, " "c) 'make payment number sortable
                apay.<begbal>.Value = begbal.ToString("c2")
                apay.<interest>.Value = int.ToString("c2")
                apay.<principal>.Value = prin.ToString("c2")
                apay.<endbal>.Value = balAfter.ToString("c2")
                amort.Add(apay)
                begbal = balAfter
            Next
            Me.LOANxml.Add(amort)
            Dim tempDS As New DataSet
            tempDS.ReadXml(amort.CreateReader)
            ' Me.PopulateLoanInfo(Me.LOANxml) 'for testing XML
            Me._schedule = tempDS.Tables(0).Copy
        End Sub
    
        Private Function BalanceAfterXpayments(numOfPaymnets As Integer) As Decimal
            'Balance = A(1+i)^n-P/i((1+i)^n-1)
            Dim onePlusIupN As Double = (1 + Me._rate) ^ numOfPaymnets
            Return CDec((Me._amt * onePlusIupN) - ((-Me._payment / Me._rate) * (onePlusIupN - 1)))
        End Function
    
        Private LOANxml As XElement
    
        Private loanCont As XElement = <loan>
                                           <loaninfo>
                                               <name></name>
                                               <amount></amount>
                                               <term></term>
                                               <rate></rate>
                                               <payment></payment>
                                           </loaninfo>
                                           <!-- schedule follows -->
                                       </loan>
    
        Private loanAmort As XElement = <amortization>
                                        </amortization>
    
        Private loanSched As XElement = <sched>
                                            <num></num>
                                            <begbal></begbal>
                                            <interest></interest>
                                            <principal></principal>
                                            <endbal></endbal>
                                        </sched>
    
        Public Sub SaveScheduleXML(path As String)
            If Me.LOANxml IsNot Nothing Then
                Me.LOANxml.Save(path)
            End If
        End Sub
    
        Public Sub LoadXMLLoan(path As String)
            Dim xe As XElement = XElement.Load(path)
            Me.PopulateLoanInfo(xe)
        End Sub
    
        Private Sub PopulateLoanInfo(theLoan As XElement)
            'sample
            '
            '<loaninfo>
            '  <name>Test this</name>
            '  <amount>$300,000.00</amount>
            '  <term>360</term>
            '  <rate>3.73 %</rate>
            '  <payment>$1,385.94</payment>
            '</loaninfo>
            Me.NameOfLoan = theLoan.<loaninfo>.<name>.Value
            Me._amt = Decimal.Parse(theLoan.<loaninfo>.<amount>.Value.Replace("$", "").Replace(",", ""))
            Me._term = Integer.Parse(theLoan.<loaninfo>.<term>.Value)
            Me._rate = Decimal.Parse(theLoan.<loaninfo>.<rate>.Value.Replace("%", "").Trim)
            Me._rate /= 100D 'convert rate from percent
            Me._rate /= 12D 'and then monthly
            If Me._rate = 0D Then Me._rate = zeroPercent
            Me._payment = Decimal.Parse(theLoan.<loaninfo>.<payment>.Value.Replace("$", "").Replace(",", ""))
            Me._payment = -Me._payment
        End Sub
    End Class
    Last edited by dbasnett; Jun 5th, 2016 at 07:40 AM. Reason: fixed zero percent
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width