Header menu logo FSharp.Finance.Personal

US APR calculation

Basic example

The following example shows a loan of $5,000.00 taken out on 10th January 1978 and repaid in 24 monthly instalments:

#r "nuget:FSharp.Finance.Personal"

open FSharp.Finance.Personal
open Apr
open Calculation
open DateDay
open UnitPeriod

let startDate = Date(1978, 1, 10)

let principal = 5000_00L<Cent>

let transfers =
    Monthly (1, 1978, 2, 10)
    |> generatePaymentSchedule 24 Duration.Unlimited Direction.Forward
    |> Array.map(fun d -> { TransferType = Payment; TransferDate = d; Value = 230_00L<Cent> })

let aprMethod = CalculationMethod.UsActuarial 4

let solution = Apr.calculate aprMethod principal startDate transfers

solution
Found (0.0968570806228181514918096852M, 8, 0.000001M)

This result is of an Array.Solution type. Found means that it was able to find a solution. The APR, expressed as a decimal, is returned as the first item of the tuple. The APR is more usefully shown as a percentage, which can easily be done as follows:

solution |> toPercent aprMethod
ValueSome (Percent 9.6900M)

Notes

Multiple items
namespace FSharp

--------------------
namespace Microsoft.FSharp
namespace FSharp.Finance
namespace FSharp.Finance.Personal
module Apr from FSharp.Finance.Personal
<summary> calculating the APR according to various country-specific regulations </summary>
module Calculation from FSharp.Finance.Personal
<summary> convenience functions and options to help with calculations </summary>
module DateDay from FSharp.Finance.Personal
<summary> a .NET Framework polyfill equivalent to the DateOnly structure in .NET Core </summary>
module UnitPeriod from FSharp.Finance.Personal
<summary> an unambiguous way to represent regular date intervals and generate schedules based on them note: unit-period definitions are based on US federal legislation but the definitions are universally applicable </summary>
val startDate: Date
Multiple items
[<Struct>] type Date = new: year: int * month: int * day: int -> Date val Year: int val Month: int val Day: int member AddDays: i: int -> Date member AddMonths: i: int -> Date member AddYears: i: int -> Date member ToDateTime: unit -> DateTime override ToString: unit -> string static member (-) : d1: Date * d2: Date -> TimeSpan ...
<summary> the date at the customer's location - ensure any time-zone conversion is performed before using this - as all calculations are date-only with no time component, summer time or other such time artefacts </summary>

--------------------
Date ()
new: year: int * month: int * day: int -> Date
val principal: int64<Cent>
Multiple items
module Cent from FSharp.Finance.Personal.Calculation
<summary> utility functions for base currency unit values </summary>

--------------------
[<Measure>] type Cent
<summary> the base unit of a currency (cent, penny, øre etc.) </summary>
val transfers: Transfer array
union case Config.Monthly: MonthMultiple: int * Year: int * Month: int * Day: int -> Config
<summary> (multi-)monthly: every n months starting on the date given by year, month and day, which tracks month-end (see config) </summary>
val generatePaymentSchedule: count: int -> maxDuration: Duration -> direction: Direction -> unitPeriodConfig: Config -> Date array
<summary> generate a payment schedule based on a unit-period config </summary>
[<Struct>] type Duration = | Unlimited | Maximum of Length: int<DurationDay> * FromDate: Date
<summary> a length of time in whole days measured from a start date </summary>
union case Duration.Unlimited: Duration
<summary> unrestricted length of time </summary>
[<Struct>] type Direction = | Forward | Reverse
<summary> direction in which to generate the schedule: forward works forwards from a given date and reverse works backwards </summary>
union case Direction.Forward: Direction
<summary> create a schedule starting on the given date </summary>
Multiple items
module Array from FSharp.Finance.Personal.Calculation
<summary> functions for working with arrays </summary>

--------------------
module Array from Microsoft.FSharp.Collections
val map: mapping: ('T -> 'U) -> array: 'T array -> 'U array
val d: Date
[<Struct>] type TransferType = | Advance | Payment
<summary> whether a transfer is an advance or a payment </summary>
union case TransferType.Payment: TransferType
<summary> incoming transfer </summary>
val aprMethod: CalculationMethod
[<Struct>] type CalculationMethod = | UnitedKingdom of UkPrecision: int | UsActuarial of UsPrecision: int | UnitedStatesRule
<summary> the calculation method used to determine the APR </summary>
union case CalculationMethod.UsActuarial: UsPrecision: int -> CalculationMethod
<summary> calculates the APR according to the US CFPB actuarial method to the stated decimal precision (note that this is two places more than the percent precision) </summary>
val solution: Solution
val calculate: method: CalculationMethod -> advanceValue: int64<Cent> -> advanceDate: Date -> transfers: Transfer array -> Solution
<summary> calculates the APR to a given precision for a single-advance transaction where the consummation date, first finance-charge earned date and advance date are all the same </summary>
val toPercent: aprMethod: CalculationMethod -> aprSolution: Solution -> Percent voption
<summary> converts an APR solution to a percentage, if possible </summary>

Type something to start searching.