Payment Schedule Examples
Basic Example #1
The following example shows the scheduled for a car loan of £10,000 taken out on 7 February 2024 with 36 monthly repayments:
#r "nuget:FSharp.Finance.Personal"
open FSharp.Finance.Personal
open Calculation
open DateDay
open Scheduling
open UnitPeriod
let parameters = {
EvaluationDate = Date(2024, 02, 07)
StartDate = Date(2024, 02, 07)
Principal = 10000_00L<Cent>
ScheduleConfig =
AutoGenerateSchedule {
UnitPeriodConfig = Monthly(1, 2024, 3, 7)
ScheduleLength = PaymentCount 36
}
PaymentConfig = {
LevelPaymentOption = LowerFinalPayment
Rounding = RoundUp
}
FeeConfig = ValueNone
InterestConfig = {
Method = Interest.Method.Actuarial
StandardRate = Interest.Rate.Annual <| Percent 6.9m
Cap = Interest.Cap.zero
Rounding = RoundDown
AprMethod = Apr.CalculationMethod.UnitedKingdom 3
}
}
let schedule = parameters |> calculateBasicSchedule
schedule
|
It is possible to format the Items
property as an HTML table:
let html = schedule |> BasicSchedule.toHtmlTable
$"""<div class="schedule">{html}</div>"""
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 | 10,000.00 | 0.0000 | 0.00 | 0.00 |
29 | 308.29 | 54.8219 | 54.82 | 253.47 | 0.00 | 9,746.53 | 54.8219 | 54.82 | 253.47 |
60 | 308.29 | 57.1173 | 57.11 | 251.18 | 0.00 | 9,495.35 | 111.9393 | 111.93 | 504.65 |
90 | 308.29 | 53.8503 | 53.85 | 254.44 | 0.00 | 9,240.91 | 165.7896 | 165.78 | 759.09 |
121 | 308.29 | 54.1543 | 54.15 | 254.14 | 0.00 | 8,986.77 | 219.9439 | 219.93 | 1,013.23 |
151 | 308.29 | 50.9661 | 50.96 | 257.33 | 0.00 | 8,729.44 | 270.9099 | 270.89 | 1,270.56 |
182 | 308.29 | 51.1569 | 51.15 | 257.14 | 0.00 | 8,472.30 | 322.0668 | 322.04 | 1,527.70 |
213 | 308.29 | 49.6500 | 49.64 | 258.65 | 0.00 | 8,213.65 | 371.7168 | 371.68 | 1,786.35 |
243 | 308.29 | 46.5815 | 46.58 | 261.71 | 0.00 | 7,951.94 | 418.2984 | 418.26 | 2,048.06 |
274 | 308.29 | 46.6005 | 46.60 | 261.69 | 0.00 | 7,690.25 | 464.8989 | 464.86 | 2,309.75 |
304 | 308.29 | 43.6132 | 43.61 | 264.68 | 0.00 | 7,425.57 | 508.5121 | 508.47 | 2,574.43 |
335 | 308.29 | 43.5159 | 43.51 | 264.78 | 0.00 | 7,160.79 | 552.0280 | 551.98 | 2,839.21 |
366 | 308.29 | 41.9642 | 41.96 | 266.33 | 0.00 | 6,894.46 | 593.9922 | 593.94 | 3,105.54 |
394 | 308.29 | 36.4934 | 36.49 | 271.80 | 0.00 | 6,622.66 | 630.4856 | 630.43 | 3,377.34 |
425 | 308.29 | 38.8106 | 38.81 | 269.48 | 0.00 | 6,353.18 | 669.2962 | 669.24 | 3,646.82 |
455 | 308.29 | 36.0304 | 36.03 | 272.26 | 0.00 | 6,080.92 | 705.3265 | 705.27 | 3,919.08 |
486 | 308.29 | 35.6359 | 35.63 | 272.66 | 0.00 | 5,808.26 | 740.9624 | 740.90 | 4,191.74 |
516 | 308.29 | 32.9400 | 32.93 | 275.36 | 0.00 | 5,532.90 | 773.9024 | 773.83 | 4,467.10 |
547 | 308.29 | 32.4243 | 32.42 | 275.87 | 0.00 | 5,257.03 | 806.3267 | 806.25 | 4,742.97 |
578 | 308.29 | 30.8076 | 30.80 | 277.49 | 0.00 | 4,979.54 | 837.1343 | 837.05 | 5,020.46 |
608 | 308.29 | 28.2401 | 28.24 | 280.05 | 0.00 | 4,699.49 | 865.3745 | 865.29 | 5,300.51 |
639 | 308.29 | 27.5403 | 27.54 | 280.75 | 0.00 | 4,418.74 | 892.9148 | 892.83 | 5,581.26 |
669 | 308.29 | 25.0597 | 25.05 | 283.24 | 0.00 | 4,135.50 | 917.9745 | 917.88 | 5,864.50 |
700 | 308.29 | 24.2352 | 24.23 | 284.06 | 0.00 | 3,851.44 | 942.2096 | 942.11 | 6,148.56 |
731 | 308.29 | 22.5705 | 22.57 | 285.72 | 0.00 | 3,565.72 | 964.7801 | 964.68 | 6,434.28 |
759 | 308.29 | 18.8739 | 18.87 | 289.42 | 0.00 | 3,276.30 | 983.6540 | 983.55 | 6,723.70 |
790 | 308.29 | 19.2000 | 19.20 | 289.09 | 0.00 | 2,987.21 | 1,002.8540 | 1,002.75 | 7,012.79 |
820 | 308.29 | 16.9412 | 16.94 | 291.35 | 0.00 | 2,695.86 | 1,019.7952 | 1,019.69 | 7,304.14 |
851 | 308.29 | 15.7985 | 15.79 | 292.50 | 0.00 | 2,403.36 | 1,035.5937 | 1,035.48 | 7,596.64 |
881 | 308.29 | 13.6300 | 13.63 | 294.66 | 0.00 | 2,108.70 | 1,049.2237 | 1,049.11 | 7,891.30 |
912 | 308.29 | 12.3576 | 12.35 | 295.94 | 0.00 | 1,812.76 | 1,061.5813 | 1,061.46 | 8,187.24 |
943 | 308.29 | 10.6233 | 10.62 | 297.67 | 0.00 | 1,515.09 | 1,072.2045 | 1,072.08 | 8,484.91 |
973 | 308.29 | 8.5924 | 8.59 | 299.70 | 0.00 | 1,215.39 | 1,080.7970 | 1,080.67 | 8,784.61 |
1004 | 308.29 | 7.1225 | 7.12 | 301.17 | 0.00 | 914.22 | 1,087.9195 | 1,087.79 | 9,085.78 |
1034 | 308.29 | 5.1848 | 5.18 | 303.11 | 0.00 | 611.11 | 1,093.1042 | 1,092.97 | 9,388.89 |
1065 | 308.29 | 3.5813 | 3.58 | 304.71 | 0.00 | 306.40 | 1,096.6855 | 1,096.55 | 9,693.60 |
1096 | 308.19 | 1.7956 | 1.79 | 306.40 | 0.00 | 0.00 | 1,098.4811 | 1,098.34 | 10,000.00 |
Multiple items
namespace FSharp
--------------------
namespace Microsoft.FSharp
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>
<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>
<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>
<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>
<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 parameters: BasicParameters
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
[<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>
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>
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 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>
<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>
<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>
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>
<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>
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>
<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>
<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>
<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>
<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>
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.Annual: Percent -> Interest.Rate
<summary> the annual interest rate, or the daily interest rate multiplied by 365 </summary>
<summary> the annual interest rate, or the daily interest rate multiplied 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>
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 Cap from FSharp.Finance.Personal.Interest
<summary> caps on the total interest accruable </summary>
--------------------
[<Struct>] type Cap = { TotalAmount: Amount DailyAmount: Amount } member Html: string with get
<summary> caps on the total interest accruable </summary>
module Cap from FSharp.Finance.Personal.Interest
<summary> caps on the total interest accruable </summary>
--------------------
[<Struct>] type Cap = { TotalAmount: Amount DailyAmount: Amount } member Html: string with get
<summary> caps on the total interest accruable </summary>
val zero: Interest.Cap
<summary> no cap </summary>
<summary> no cap </summary>
union case Rounding.RoundDown: Rounding
<summary> round down to the specified precision (= floor) </summary>
<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>
<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>
<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>
<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 schedule: BasicSchedule
val calculateBasicSchedule: bp: BasicParameters -> BasicSchedule
<summary> calculates the number of days between two offset days on which interest is chargeable </summary>
<summary> calculates the number of days between two offset days on which interest is chargeable </summary>
val html: string
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>
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>
<summary> formats the schedule items as an HTML table (stats can be rendered separately) </summary>