Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Question Need to modify code to compute annual percentage rate (APR)

Discussion in 'Scripting' started by dotnetdude, Nov 1, 2022.

Thread Status:
Not open for further replies.
  1. dotnetdude

    dotnetdude

    Joined:
    Nov 1, 2022
    Posts:
    2
    The FFIEC has a website tool which is used to compute the APR for mortgage loans. This tool essential is used to audit banks across the USA. I'm developing a website that does irregular amortization schedules for mortgage loans. My page needs to be able to compute the correct APR given a set of payment streams just exactly like the tool.

    If you are interested in seeing the tool, it is here at this link:
    https://www.ffiec.gov/examtools/FFIEC-Calculators/APR/#/accountdata

    This purpose of my posting here is to get some help in modifying the code that I have which already correctly computes the APR for the given example in their help document. This pdf can be downloaded through the help link on the above page. To see the tool work, it's best to download the document so you can see the example, however I'll type it right here for you. You can find this sample on page 6 of the document. (APR Tool Formulas)

    To do the example, simply go to the above page and click the next button. Then on the next page, enter 975 for amount financed, and enter 10 for the disclosed APR. Leave the radio buttons on installment and monthly. Click continue and on the next page input 340 for the payment and 3 for the number of payments. Click continue and on the next page you will see the results of the calculation. The APR reads at 27.48 %.

    I have code which when I run in visual studio it will calculate this number. The problem is that this code is for one payment stream. The stream is 3 payments of $340 over the 3 months.
    As you can see, the tool accepts multiple payment streams. They don't provide any code in their help document, just the general equation which shows how iteration is done.

    Here are the 2 functions which work together to solve the general equation. This can be found at the back of the pdf document. If you send this to the function you will get the correct answer at 27.48%. These are the paramaters as described in the params of the code from left to right.

    apr1 = findAPRGEQ(975, 340, 3, 12, 10, 0, 1)

    Code (CSharp):
    1.   Public Overridable Function generalEquation(ByVal period As Integer, ByVal payment As Double, ByVal initialPeriods As Double, ByVal fractions As Double, ByVal rate As Double) As Double
    2.         Dim retval As Double = 0
    3.         For x As Integer = 0 To period - 1
    4.             Dim jj As Decimal = (1.0 + fractions * rate)
    5.             Dim kk As Decimal = Math.Pow(1 + rate, initialPeriods + x)
    6.             retval += payment / ((1.0 + fractions * rate) * Math.Pow(1 + rate, initialPeriods + x))
    7.         Next x
    8.         Return retval
    9.     End Function
    10.     '''
    11.    ''' <param name="amount"> The initial amount A </param>
    12.     ''' <param name="payment"> The periodic payment P </param>
    13.    ''' <param name="payments"> The total number of payments n </param>
    14.     ''' <param name="ppy"> The number of payment periods per year </param>
    15.    ''' <param name="APRGuess"> The guess to start estimating from, 10% is 0.1, not 0.001 </param>
    16.     ''' <param name="odddays"> Odd days, as a fraction of a pay period.  10 days of a month is 0.33333... </param>
    17.    ''' <param name="full"> Full pay periods before the first payment.  Usually 1. </param>
    18.     ''' <returns> The calculated APR </returns>
    19.    Public Overridable Function findAPRGEQ(ByVal amount As Double, ByVal payment As Double, ByVal payments As Integer, ByVal ppy As Double, ByVal APRGuess As Double, ByVal odddays As Double, ByVal full As Double) As Double
    20.        Dim result As Double = APRGuess
    21.        Dim tempguess As Double = APRGuess
    22.        Do
    23.            result = tempguess
    24.            'Step 1
    25.             Dim i As Double = tempguess / (100 * ppy)
    26.             Dim A1 As Double = generalEquation(payments, payment, full, odddays, i)
    27.             'Step 2
    28.            Dim i2 As Double = (tempguess + 0.1) / (100 * ppy)
    29.            Dim A2 As Double = generalEquation(payments, payment, full, odddays, i2)
    30.            'Step 3
    31.             tempguess = tempguess + 0.1 * (amount - A1) / (A2 - A1)
    32.         Loop While Math.Abs(result * 10000 - tempguess * 10000) > 1
    33.         Return result
    34.     End Function
    So how can this code be amended to allow any number of payment streams?
    What I tried to do was add an outer loop (y) and send the payment amounts and number of payments into the function in couple of arraylists. This is not getting the correct answers. I have a program which calculates the correct APR and the numbers are way off that my code generates. Is there someone here who understands this math formula and how to make it work with multiple payment streams? Can it be made to kick out the same APR as the tool does for a loan with multiple payment streams?


    Code (CSharp):
    1.  
    2. Public Overridable Function generalEquation1(ByVal period As Integer, ByVal numpmts As ArrayList, ByVal payment As ArrayList, ByVal initialPeriods As Double, ByVal fractions As Double, ByVal rate As Double) As Double
    3.         Dim retval As Double = 0
    4.         Dim x As Integer = 0
    5.         Dim z As Integer = 0
    6.         For y = 0 To numpmts.Count - 1 'number of payment streams
    7.            For x = 0 To numpmts(y)
    8.                If x = numpmts(y) Then
    9.                    x = 0
    10.                    Exit For
    11.                End If
    12.                retval += payment(y) / ((1.0 + fractions * rate) * Math.Pow(1 + rate, initialPeriods + x))
    13.                z = z + 1
    14.            Next x
    15.        Next y
    16.        Return retval
    17.    End Function
    18.  
    19.    '''
    20.     ''' <param name="amount"> The initial amount A </param>
    21.    ''' <param name="payment"> The periodic payment P </param>
    22.     ''' <param name="payments"> The total number of payments n </param>
    23.    ''' <param name="ppy"> The number of payment periods per year </param>
    24.     ''' <param name="APRGuess"> The guess to start estimating from, 10% is 0.1, not 0.001 </param>
    25.    ''' <param name="odddays"> Odd days, as a fraction of a pay period.  10 days of a month is 0.33333... </param>
    26.     ''' <param name="full"> Full pay periods before the first payment.  Usually 1. </param>
    27.    ''' <returns> The calculated APR </returns>
    28.     Public Overridable Function findAPRGEQ1(ByVal amount As Double, ByVal payment As ArrayList, ByVal payments As ArrayList, ByVal ppy As Double, ByVal APRGuess As Double, ByVal odddays As Double, ByVal full As Double) As Double
    29.         Dim result As Double = APRGuess
    30.         Dim tempguess As Double = APRGuess
    31.         Dim totpmts As Integer = 0
    32.         Dim info As Decimal = 0
    33.         For i = 0 To payments.Count - 1
    34.             totpmts += payments(i)
    35.         Next
    36.         Do
    37.             result = tempguess
    38.             'Step 1
    39.            Dim i As Double = tempguess / (100 * ppy)
    40.            Dim A1 As Double = generalEquation1(totpmts, payments, payment, full, odddays, i)
    41.            'Step 2
    42.             Dim i2 As Double = (tempguess + 0.1) / (100 * ppy)
    43.             Dim A2 As Double = generalEquation1(totpmts, payments, payment, full, odddays, i2)
    44.             'Step 3
    45.            tempguess = tempguess + 0.1 * (amount - A1) / (A2 - A1)
    46.            Console.Write(tempguess)
    47.            info = Math.Abs(result * 10000 - tempguess * 10000) > 1
    48.        Loop While Math.Abs(result * 10000 - tempguess * 10000) > 1
    49.        Return result
    50.    End Function
    51.  
     
    Last edited: Nov 1, 2022
  2. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,622
    May I ask what this has to do with Unity? This forum is for C# scripting in the Unity engine.
     
    Bunny83 likes this.
  3. dotnetdude

    dotnetdude

    Joined:
    Nov 1, 2022
    Posts:
    2
    Hello, nothing with Unity really. I'm came here because it appears that this forum would be a good place to ask my question since this forum deals with math and coding in C# and Visual Basic. I have already asked my question on other forums, and so far I'm not finding coders who understand mathematical equations and have the know how to implement them into code.
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,954
    This is just the standard problem of moving from the one to the many.

    In C# one would make an object to do the thing, make a collection of objects upon which you want that thing done, then go iterate the collection and do the thing. That's ... it.

    I have no idea how to do it in modern BASIC, as my serious use of BASIC tapered off around the time of QBASIC under Windows95.
     
  5. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    6,015
    This is a developer forum for making (most often) video games in Unity, specifically in C#. It's really not the place to be asking questions about your... financial applications.
     
  6. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,622
    Then you are on the wrong forum completely.

    I'll close this thread.
     
Thread Status:
Not open for further replies.