Header menu logo FSharp.Finance.Personal

Actuarial-Interest Calculations

Definition

Actuarial interest is a method of calculating interest where the interest is accrued during the schedule. The initial interest balance is zero, and each time a scheduled payment is due or an actual payment is made, the interest is calculated based on the outstanding principal balance and the number of days it has been outstanding. Payments are applied in the order charges -> interest -> fees -> principal, but as interest is not front loaded (as in the add-on interest method), this means each payment pays off the interest in full and then the principal balance is reduced. This means that the principal balance is lower than under the add-on interest method, and therefore the interest accrued is lower. Calculating the interest this way is the simplest method of calculating interest.

Relevant Code

The Scheduling module contains the functions that create the basic schedule. The basic schedule is a basic schedule that allows us to calculate the interest accrued over the schedule as well as the level and final payments.

Let's start by defining the parameters. Let's define a loan of £1000 advanced on 22 April 2025, paid back over 4 months starting one month after the advance date. The loan has a daily interest rate of 0.798% and a cap of 0.8% per day as well as a cap of 100% of the principal amount. Interest is calculated using the actuarial method.

let bp: BasicParameters = {
    EvaluationDate = Date(2025, 4, 22)
    StartDate = Date(2025, 4, 22)
    Principal = 1000_00L<Cent>
    ScheduleConfig =
        AutoGenerateSchedule {
            UnitPeriodConfig = Monthly(1, 2025, 5, 22)
            ScheduleLength = PaymentCount 4
        }
    PaymentConfig = {
        LevelPaymentOption = LowerFinalPayment
        Rounding = RoundUp
    }
    FeeConfig = ValueNone
    InterestConfig = {
        Method = Interest.Method.Actuarial
        StandardRate = Interest.Rate.Daily(Percent 0.798m)
        Cap = {
            TotalAmount = Amount.Percentage(Percent 100m, Restriction.NoLimit)
            DailyAmount = Amount.Percentage(Percent 0.8m, Restriction.NoLimit)
        }
        Rounding = RoundDown
        AprMethod = Apr.CalculationMethod.UnitedKingdom 3
    }
}

Then we call the Scheduling.calculateBasicSchedule function to generate the schedule:

let actuarialInterestSchedule = calculateBasicSchedule bp
Day Scheduled payment Actuarial interest Interest portion Principal portion Interest balance Principal balance Total actuarial interest Total interest Total principal
0 0.00 0.0000 0.00 0.00 0.00 1,000.00 0.0000 0.00 0.00
30 417.72 239.4000 239.40 178.32 0.00 821.68 239.4000 239.40 178.32
61 417.72 203.2672 203.26 214.46 0.00 607.22 442.6672 442.66 392.78
91 417.72 145.3685 145.36 272.36 0.00 334.86 588.0357 588.02 665.14
122 417.69 82.8377 82.83 334.86 0.00 0.00 670.8733 670.85 1,000.00

As there is no initial interest balance, the principal starts to be paid off immediately, and the total interest accrued is therefore lower.


Add-on-interest comparison (click to expand) To illustrate this, we can compare the actuarial-interest schedule with an add-on-interest schedule:
let addOnInterestSchedule =
    calculateBasicSchedule {
        bp with
            InterestConfig.Method = Interest.Method.AddOn
    }
Day Scheduled payment Actuarial interest Interest portion Principal portion Interest balance Principal balance Total actuarial interest Total interest Total principal
0 0.00 0.0000 0.00 0.00 816.56 1,000.00 0.0000 0.00 0.00
30 454.15 239.4000 454.15 0.00 362.41 1,000.00 239.4000 454.15 0.00
61 454.15 247.3800 362.41 91.74 0.00 908.26 486.7800 816.56 91.74
91 454.15 217.4374 0.00 454.15 0.00 454.11 704.2174 816.56 545.89
122 454.11 112.3377 0.00 454.11 0.00 0.00 816.5552 816.56 1,000.00

Here, the schedule has calculated an initial interest balance of £816.56. We can see that the interest balance is paid off before the principal, meaning that the full principal remains outstanding for two months. Given that interest is accrued on the principal balance only (no interest on interest), maintaining a higher principal balance for longer means that the interest accrued is higher than it would be if the principal was paid off first.

Calculation Details

Scheduling.calculateBasicSchedule is the function that generates the schedule. Here is a summary of the calculation steps:

  1. Generate payment days: generate the payment days based on the unit-period (e.g. monthly) and the first payment date
  2. Estimate total interest: estimate the total interest and level payment to improve the solver performance
  3. Solve for payment values: use the bisection method to determine the level payments required
  4. Tweak final payment: ensure the final payment fully amortises the schedule

Let's look at each of these items in more detail.

Step 1: Generate payment days

Here we take the schedule config from the parameters and generate the payment days. In this example, the schedule is auto-generated, so the Scheduling.generatePaymentMap function takes the start date of the schedule, the unit period and the first payment date, and generates the payment days. It is also possible to specify the payment days manually or specify multiple ranges of dates at different intervals. However, the auto-generated schedule is the most common use case, and ensures respect for varying month lengths and month-end tracking dates. We'll also get extract a couple of values for later use.

let paymentMap = generatePaymentMap bp.StartDate bp.ScheduleConfig
let paymentDays = paymentMap |> Map.keys |> Seq.toArray

let finalScheduledPaymentDay = Array.last paymentDays
let paymentCount = Array.length paymentDays
Payment days = 30, 61, 91, 122

Step 2: Estimate the total interest

To make the iteration more efficient, we use an initial guess for the payment value, which is calculated based on the estimated total interest and the number of payments.

let roughInterest =
    let dailyInterestRate =
        bp.InterestConfig.StandardRate |> Interest.Rate.daily |> Percent.toDecimal

    Cent.toDecimalCent bp.Principal
    * dailyInterestRate
    * decimal finalScheduledPaymentDay
    * Fraction.toDecimal (Fraction.Simple(2, 3))

let roughPayment =
    calculateLevelPayment bp.Principal 0L<Cent> roughInterest paymentCount bp.PaymentConfig.Rounding
    |> Cent.toDecimalCent
    |> decimal
Estimated interest total = 649.04
Initial payment guess = 412.26

Step 3: Solve for payment values

Determining the payment values requires the use of a solver, because payment values determine how much principal is paid off each unit-period, and therefore how much interest is accrued, which in turn affects the payment values. We use the bisection method (Array.solveBisection) for this. This method runs a generator function (Scheduling.generatePaymentValue) on the schedule, which calculates the final principal balance for a given payment value. The bisection method then iteratively narrows down the level payment value until the final principal balance is close to zero (usually just below zero, so the final payment can be slightly smaller).

let generatePaymentValue (bp: BasicParameters) paymentDays firstItem roughPayment =
    let scheduledPayment =
        roughPayment
        |> Cent.round bp.PaymentConfig.Rounding
        |> fun rp -> ScheduledPayment.quick (ValueSome rp) ValueNone

    let schedule =
        paymentDays
        |> Array.fold
            (fun basicItem pd -> generateItem bp bp.InterestConfig.Method scheduledPayment basicItem pd)
            firstItem

    let principalBalance = decimal schedule.PrincipalBalance
    principalBalance, ScheduledPayment.total schedule.ScheduledPayment |> Cent.toDecimal

let initialBasicItem = {
    BasicItem.zero with
        PrincipalBalance = bp.Principal
}

let basicItems =
    let solution =
        Array.solveBisection
            (generatePaymentValue bp paymentDays initialBasicItem)
            100u
            roughPayment
            (LevelPaymentOption.toTargetTolerance bp.PaymentConfig.LevelPaymentOption)
            (ToleranceSteps.forPaymentValue paymentCount)

    match solution with
    | Solution.Found(paymentValue, _, _) ->
        let paymentMap' =
            paymentMap
            |> Map.map (fun _ sp -> {
                sp with
                    Original = sp.Original |> ValueOption.map (fun _ -> paymentValue |> Cent.fromDecimal)
            })

        paymentDays
        |> Array.scan
            (fun basicItem pd -> generateItem bp bp.InterestConfig.Method paymentMap'[pd] basicItem pd)
            initialBasicItem
    | _ -> [||]
Day Scheduled payment Actuarial interest Interest portion Principal portion Interest balance Principal balance Total actuarial interest Total interest Total principal
0 0.00 0.0000 0.00 0.00 0.00 1,000.00 0.0000 0.00 0.00
30 417.72 239.4000 239.40 178.32 0.00 821.68 239.4000 239.40 178.32
61 417.72 203.2672 203.26 214.46 0.00 607.22 442.6672 442.66 392.78
91 417.72 145.3685 145.36 272.36 0.00 334.86 588.0357 588.02 665.14
122 417.72 82.8377 82.83 334.89 0.00 -0.03 670.8733 670.85 1,000.03

Step 4: Tweak final payment

The final payment is adjusted (Scheduling.adjustFinalPayment) to ensure that the final principal balance is zero.

let items =
    basicItems
    |> adjustFinalPayment finalScheduledPaymentDay bp.ScheduleConfig.IsAutoGenerateSchedule
Day Scheduled payment Actuarial interest Interest portion Principal portion Interest balance Principal balance Total actuarial interest Total interest Total principal
0 0.00 0.0000 0.00 0.00 0.00 1,000.00 0.0000 0.00 0.00
30 417.72 239.4000 239.40 178.32 0.00 821.68 239.4000 239.40 178.32
61 417.72 203.2672 203.26 214.46 0.00 607.22 442.6672 442.66 392.78
91 417.72 145.3685 145.36 272.36 0.00 334.86 588.0357 588.02 665.14
122 417.69 82.8377 82.83 334.86 0.00 0.00 670.8733 670.85 1,000.00

As an extra step, the library calculates a number of statistics for the schedule, including the total interest accrued, the total fees and charges, the total payments made, and the final principal balance. The full output for this schedule, including stats, is available in the Output section in the page Unit-Test Outputs, under Compliance. This particular example is defined as ComplianceTest023.

Multiple items
namespace FSharp

--------------------
namespace Microsoft.FSharp
namespace FSharp.Finance
namespace FSharp.Finance.Personal
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 Scheduling from FSharp.Finance.Personal
<summary> functions for generating a regular payment schedule, with payment amounts, interest and APR </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 bp: BasicParameters
Multiple items
module BasicParameters from FSharp.Finance.Personal.Scheduling
<summary> parameters for creating a payment schedule </summary>

--------------------
[<Struct>] type BasicParameters = { EvaluationDate: Date StartDate: Date Principal: int64<Cent> ScheduleConfig: ScheduleConfig PaymentConfig: BasicConfig FeeConfig: BasicConfig voption InterestConfig: BasicConfig }
<summary> parameters for creating a payment schedule </summary>
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 static member (-) : d1: Date * d2: Date -> TimeSpan static member DaysInMonth: year: int * month: int -> int ...
<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
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>
Multiple items
module ScheduleConfig from FSharp.Finance.Personal.Scheduling
<summary> whether a payment plan is generated according to a regular schedule or is an irregular array of payments </summary>

--------------------
[<Struct>] type ScheduleConfig = | AutoGenerateSchedule of AutoGenerateSchedule: AutoGenerateSchedule | FixedSchedules of FixedSchedules: FixedSchedule array | CustomSchedule of CustomSchedule: PaymentMap
<summary> whether a payment plan is generated according to a regular schedule or is an irregular array of payments </summary>
Multiple items
union case ScheduleConfig.AutoGenerateSchedule: AutoGenerateSchedule: AutoGenerateSchedule -> ScheduleConfig
<summary> a schedule based on a unit-period config with a specific number of payments with an auto-calculated amount, optionally limited to a maximum duration </summary>

--------------------
[<Struct>] type AutoGenerateSchedule = { UnitPeriodConfig: Config ScheduleLength: ScheduleLength }
<summary> a regular schedule based on a unit-period config with a specific number of payments with an auto-calculated amount </summary>
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>
[<Struct>] type ScheduleLength = | PaymentCount of Payments: int | MaxDuration of StartDate: Date * Days: int<DurationDay> member Html: string with get
<summary> defines the length of a payment schedule, either by the number of payments or by the maximum duration </summary>
union case ScheduleLength.PaymentCount: Payments: int -> ScheduleLength
Multiple items
module LevelPaymentOption from FSharp.Finance.Personal.Scheduling
<summary> when calculating the level payments, whether the final payment should be lower or higher than the level payment </summary>

--------------------
[<Struct>] type LevelPaymentOption = | LowerFinalPayment | SimilarFinalPayment | HigherFinalPayment member Html: string with get
<summary> when calculating the level payments, whether the final payment should be lower or higher than the level payment </summary>
union case LevelPaymentOption.LowerFinalPayment: LevelPaymentOption
<summary> the final payment must be lower than the level payment </summary>
Multiple items
module Rounding from FSharp.Finance.Personal.Calculation
<summary> the type of rounding, specifying midpoint-rounding where necessary </summary>

--------------------
[<Struct>] type Rounding = | NoRounding | RoundUp | RoundDown | RoundWith of MidpointRounding member Html: string with get
<summary> the type of rounding, specifying midpoint-rounding where necessary </summary>
union case Rounding.RoundUp: Rounding
<summary> round up to the specified precision (= ceiling) </summary>
union case ValueOption.ValueNone: ValueOption<'T>
module Interest from FSharp.Finance.Personal
<summary> methods for calculating interest and unambiguously expressing interest rates, as well as enforcing regulatory caps on interest chargeable </summary>
[<Struct>] type Method = | Actuarial | AddOn member Html: string with get
<summary> the method used to calculate the interest </summary>
union case Interest.Method.Actuarial: Interest.Method
<summary> actuarial interest method, where interest is based on the principal balance and the number of days outstanding </summary>
Multiple items
module Rate from FSharp.Finance.Personal.Interest

--------------------
[<Struct>] type Rate = | Zero | Annual of Percent | Daily of Percent member Html: string with get
<summary> the interest rate expressed as either an annual or a daily rate </summary>
union case Interest.Rate.Daily: Percent -> Interest.Rate
<summary> the daily interest rate, or the annual interest rate divided by 365 </summary>
Multiple items
union case Percent.Percent: decimal -> Percent

--------------------
module Percent from FSharp.Finance.Personal.Calculation
<summary> utility functions for percent values </summary>

--------------------
[<Struct>] type Percent = | Percent of decimal member Html: string with get
<summary> a percentage, e.g. 42%, as opposed to its decimal representation 0.42m </summary>
Multiple items
module Amount from FSharp.Finance.Personal.Calculation
<summary> an amount specified either as a simple amount or as a percentage of another amount, optionally restricted to lower and/or upper limits </summary>

--------------------
[<Struct>] type Amount = | Percentage of Percent * Restriction | Simple of int64<Cent> | Unlimited member Html: string with get
<summary> an amount specified either as a simple amount or as a percentage of another amount, optionally restricted to lower and/or upper limits </summary>
union case Amount.Percentage: Percent * Restriction -> Amount
<summary> a percentage of the principal, optionally restricted </summary>
Multiple items
module Restriction from FSharp.Finance.Personal.Calculation
<summary> the type of restriction placed on a possible value </summary>

--------------------
[<Struct>] type Restriction = | NoLimit | LowerLimit of int64<Cent> | UpperLimit of int64<Cent> | WithinRange of MinValue: int64<Cent> * MaxValue: int64<Cent> member Html: string with get
<summary> the type of restriction placed on a possible value </summary>
union case Restriction.NoLimit: Restriction
<summary> does not constrain values at all </summary>
union case Rounding.RoundDown: Rounding
<summary> round down to the specified precision (= floor) </summary>
module Apr from FSharp.Finance.Personal
<summary> calculating the APR according to various country-specific regulations </summary>
[<Struct>] type CalculationMethod = | EuropeanUnion of EuPrecision: int | UnitedKingdom of UkPrecision: int | UsActuarial of UsPrecision: int | UnitedStatesRule member Html: string with get
<summary> the calculation method used to determine the APR </summary>
union case Apr.CalculationMethod.UnitedKingdom: UkPrecision: int -> Apr.CalculationMethod
<summary> calculates the APR according to UK FCA rules to the stated decimal precision (note that this is two places more than the percent precision) </summary>
val actuarialInterestSchedule: BasicSchedule
val calculateBasicSchedule: bp: BasicParameters -> BasicSchedule
<summary> calculates the number of days between two offset days on which interest is chargeable </summary>
Multiple items
module BasicSchedule from FSharp.Finance.Personal.Scheduling
<summary> a schedule of payments, with statistics </summary>

--------------------
type BasicSchedule = { EvaluationDay: int<OffsetDay> Items: BasicItem array Stats: InitialStats }
<summary> a schedule of payments, with statistics </summary>
val toHtmlTable: schedule: BasicSchedule -> string
<summary> formats the schedule items as an HTML table (stats can be rendered separately) </summary>
val addOnInterestSchedule: BasicSchedule
union case Interest.Method.AddOn: Interest.Method
<summary> add-on interest method, where the interest accrued over the loan is added to the initial balance and the interest is paid off before the principal balance </summary>
val paymentMap: Map<int<OffsetDay>,ScheduledPayment>
val generatePaymentMap: startDate: Date -> paymentSchedule: ScheduleConfig -> Map<int<OffsetDay>,ScheduledPayment>
<summary> generates a map of offset days and payments based on a start date and payment schedule </summary>
BasicParameters.StartDate: Date
<summary> the start date of the schedule, typically the day on which the principal is advanced </summary>
BasicParameters.ScheduleConfig: ScheduleConfig
<summary> the scheduled payments or the parameters for generating them </summary>
val paymentDays: int<OffsetDay> array
Multiple items
module Map from FSharp.Finance.Personal.Calculation
<summary> functions for working with maps </summary>

--------------------
module Map from Microsoft.FSharp.Collections

--------------------
type Map<'Key,'Value (requires comparison)> = interface IReadOnlyDictionary<'Key,'Value> interface IReadOnlyCollection<KeyValuePair<'Key,'Value>> interface IEnumerable interface IStructuralEquatable interface IComparable interface IEnumerable<KeyValuePair<'Key,'Value>> interface ICollection<KeyValuePair<'Key,'Value>> interface IDictionary<'Key,'Value> new: elements: ('Key * 'Value) seq -> Map<'Key,'Value> member Add: key: 'Key * value: 'Value -> Map<'Key,'Value> ...

--------------------
new: elements: ('Key * 'Value) seq -> Map<'Key,'Value>
val keys: table: Map<'Key,'T> -> System.Collections.Generic.ICollection<'Key> (requires comparison)
module Seq from Microsoft.FSharp.Collections
val toArray: source: 'T seq -> 'T array
val finalScheduledPaymentDay: int<OffsetDay>
Multiple items
module Array from FSharp.Finance.Personal.Calculation
<summary> functions for working with arrays </summary>

--------------------
module Array from Microsoft.FSharp.Collections
val last: array: 'T array -> 'T
val paymentCount: int
val length: array: 'T array -> int
val map: mapping: ('T -> 'U) -> array: 'T array -> 'U array
Multiple items
val string: value: 'T -> string

--------------------
type string = System.String
module String from Microsoft.FSharp.Core
val concat: sep: string -> strings: string seq -> string
val roughInterest: decimal<Cent>
val dailyInterestRate: decimal
BasicParameters.InterestConfig: Interest.BasicConfig
<summary> options relating to interest </summary>
Interest.BasicConfig.StandardRate: Interest.Rate
<summary> the standard rate of interest </summary>
val daily: _arg1: Interest.Rate -> Percent
<summary> calculates the daily interest rate from the annual one </summary>
val toDecimal: Percent -> decimal
<summary> convert a percent value to a decimal, e.g. 50% -&gt; 0.5 </summary>
val toDecimalCent: c: int64<Cent> -> decimal<Cent>
<summary> convert an integer cent value to a decimal cent value, e.g. for precise interest calculation, 1234¢ -&gt; 1234.0000¢ </summary>
BasicParameters.Principal: int64<Cent>
<summary> the principal </summary>
Multiple items
val decimal: value: 'T -> decimal (requires member op_Explicit)

--------------------
type decimal = System.Decimal

--------------------
type decimal<'Measure> = decimal
Multiple items
module Fraction from FSharp.Finance.Personal.Calculation
<summary> a fraction expressed as a numerator and denominator </summary>

--------------------
[<Struct>] type Fraction = | Zero | Simple of Numerator: int * Denominator: int
<summary> a fraction </summary>
val toDecimal: _arg1: Fraction -> decimal
union case Fraction.Simple: Numerator: int * Denominator: int -> Fraction
<summary> a simple fraction expressed as a numerator and denominator </summary>
val roughPayment: decimal
val calculateLevelPayment: principal: int64<Cent> -> fee: int64<Cent> -> interest: decimal<Cent> -> paymentCount: int -> paymentRounding: Rounding -> int64<Cent>
BasicParameters.PaymentConfig: Payment.BasicConfig
<summary> options relating to scheduled payments </summary>
Payment.BasicConfig.Rounding: Rounding
<summary> how to round payments </summary>
val generatePaymentValue: bp: BasicParameters -> paymentDays: int<OffsetDay> array -> firstItem: BasicItem -> roughPayment: decimal -> decimal * decimal
val firstItem: BasicItem
val scheduledPayment: ScheduledPayment
val round: rounding: Rounding -> m: decimal -> int64<Cent>
<summary> derive a rounded cent value from a decimal according to the specified rounding method </summary>
val rp: int64<Cent>
Multiple items
module ScheduledPayment from FSharp.Finance.Personal.Scheduling

--------------------
type ScheduledPayment = { Original: int64<Cent> voption Rescheduled: RescheduledPayment voption PreviousRescheduled: RescheduledPayment array Adjustment: int64<Cent> Metadata: Map<string,obj> } member Html: string with get
<summary> any original or rescheduled payment, affecting how any payment due is calculated </summary>
val quick: originalAmount: int64<Cent> voption -> rescheduledAmount: RescheduledPayment voption -> ScheduledPayment
<summary> a quick convenient method to create a basic scheduled payment </summary>
union case ValueOption.ValueSome: 'T -> ValueOption<'T>
val schedule: BasicItem
val fold<'T,'State> : folder: ('State -> 'T -> 'State) -> state: 'State -> array: 'T array -> 'State
val basicItem: BasicItem
val pd: int<OffsetDay>
val generateItem: bp: BasicParameters -> interestMethod: Interest.Method -> scheduledPayment: ScheduledPayment -> previousItem: BasicItem -> day: int<OffsetDay> -> BasicItem
Interest.BasicConfig.Method: Interest.Method
<summary> the method for calculating interest </summary>
val principalBalance: decimal
BasicItem.PrincipalBalance: int64<Cent>
<summary> the principal balance carried forward </summary>
val total: sp: ScheduledPayment -> int64<Cent>
<summary> the total amount of the payment </summary>
BasicItem.ScheduledPayment: ScheduledPayment
<summary> the scheduled payment </summary>
val toDecimal: c: int64<Cent> -> decimal
<summary> raise to the standard currency unit, e.g. 1234¢ -&gt; $12.34 </summary>
val initialBasicItem: BasicItem
Multiple items
module BasicItem from FSharp.Finance.Personal.Scheduling
<summary> a scheduled payment item, with running calculations of interest and principal balance </summary>

--------------------
type BasicItem = { Day: int<OffsetDay> ScheduledPayment: ScheduledPayment ActuarialInterest: decimal<Cent> InterestPortion: int64<Cent> PrincipalPortion: int64<Cent> InterestBalance: int64<Cent> PrincipalBalance: int64<Cent> TotalActuarialInterest: decimal<Cent> TotalInterest: int64<Cent> TotalPrincipal: int64<Cent> }
<summary> a scheduled payment item, with running calculations of interest and principal balance </summary>
val zero: BasicItem
<summary> a default value with no data </summary>
val basicItems: BasicItem array
val solution: Solution
val solveBisection: generator: (decimal -> decimal * decimal) -> iterationLimit: uint -> initialGuess: decimal -> targetTolerance: TargetTolerance -> toleranceSteps: ToleranceSteps -> Solution
<summary> iteratively solves for a given input using a generator function until the output hits zero or within a set tolerance, optionally relaxing the tolerance until a solution is found note: the generator function should return a tuple of the result and a relevant value (as the result is converging on zero it is not a very relevant value) </summary>
val toTargetTolerance: _arg1: LevelPaymentOption -> TargetTolerance
<summary> converts the level-payment option to a target tolerance for use in the bisection method solver </summary>
Payment.BasicConfig.LevelPaymentOption: LevelPaymentOption
<summary> what tolerance to use for the final principal balance when calculating the level payments </summary>
Multiple items
module ToleranceSteps from FSharp.Finance.Personal.Calculation
<summary> lower and upper bounds, as well as a step value, for tolerance when using the solver </summary>

--------------------
[<Struct>] type ToleranceSteps = { MinTolerance: decimal ToleranceStep: decimal MaxTolerance: decimal }
<summary> lower and upper bounds, as well as a step value, for tolerance when using the solver </summary>
val forPaymentValue: paymentCount: int -> ToleranceSteps
<summary> tolerance steps for solving for payment value </summary>
[<Struct>] type Solution = | Impossible | IterationLimitReached of PartialSolution: decimal * IterationLimit: int * MaxTolerance: decimal | Found of decimal * Iteration: int * Tolerance: decimal
<summary> the result obtained from the array solver </summary>
union case Solution.Found: decimal * Iteration: int * Tolerance: decimal -> Solution
<summary> a solution was found, returning the solution, the number of iterations required and the final tolerance used </summary>
val paymentValue: decimal
val paymentMap': Map<int<OffsetDay>,ScheduledPayment>
val map: mapping: ('Key -> 'T -> 'U) -> table: Map<'Key,'T> -> Map<'Key,'U> (requires comparison)
val sp: ScheduledPayment
ScheduledPayment.Original: int64<Cent> voption
<summary> any original payment </summary>
Multiple items
module ValueOption from Microsoft.FSharp.Core

--------------------
[<Struct>] type ValueOption<'T> = | ValueNone | ValueSome of 'T static member Some: value: 'T -> 'T voption static member op_Implicit: value: 'T -> 'T voption member IsNone: bool with get member IsSome: bool with get member Value: 'T with get static member None: 'T voption with get
val map: mapping: ('T -> 'U) -> voption: 'T voption -> 'U voption
val fromDecimal: m: decimal -> int64<Cent>
<summary> lower to the base currency unit, e.g. $12.34 -&gt; 1234¢ </summary>
val scan<'T,'State> : folder: ('State -> 'T -> 'State) -> state: 'State -> array: 'T array -> 'State array
Multiple items
module OffsetDay from FSharp.Finance.Personal.DateDay
<summary> functions for converting offset days to and from dates </summary>

--------------------
[<Measure>] type OffsetDay
<summary> the offset of a date from the start date, in days </summary>
module Unchecked from Microsoft.FSharp.Core.Operators
val defaultof<'T> : 'T
Multiple items
module InitialStats from FSharp.Finance.Personal.Scheduling
<summary> statistics resulting from the basic schedule calculations </summary>

--------------------
[<Struct>] type InitialStats = { InitialInterestBalance: int64<Cent> LastScheduledPaymentDay: int<OffsetDay> LevelPayment: int64<Cent> FinalPayment: int64<Cent> ScheduledPaymentTotal: int64<Cent> PrincipalTotal: int64<Cent> InterestTotal: int64<Cent> InitialApr: Percent InitialCostToBorrowingRatio: Percent }
<summary> final statistics based on the payments being made on time and in full </summary>
val items: BasicItem array
val adjustFinalPayment: finalScheduledPaymentDay: int<OffsetDay> -> isAutoGenerateSchedule: bool -> basicItems: BasicItem array -> BasicItem array
<summary> handle any principal balance overpayment (due to rounding) on the final payment of a schedule </summary>
property ScheduleConfig.IsAutoGenerateSchedule: bool with get

Type something to start searching.