diff --git a/docs/exampleAmortisation.fsx b/docs/exampleAmortisation.fsx index 480b75c..f63d7e2 100644 --- a/docs/exampleAmortisation.fsx +++ b/docs/exampleAmortisation.fsx @@ -37,7 +37,8 @@ let scheduleParameters = Principal = 1500_00L PaymentSchedule = RegularSchedule ( UnitPeriodConfig = UnitPeriod.Monthly(1, 2022, 11, 31), - PaymentCount = 5 + PaymentCount = 5, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [||] diff --git a/docs/exampleAprUs.fsx b/docs/exampleAprUs.fsx index 255c2a8..cf4ae99 100644 --- a/docs/exampleAprUs.fsx +++ b/docs/exampleAprUs.fsx @@ -32,7 +32,7 @@ let principal = 5000_00L let transfers = Monthly (1, 1978, 2, 10) - |> generatePaymentSchedule 24 Direction.Forward + |> generatePaymentSchedule 24 ValueNone Direction.Forward |> Array.map(fun d -> { TransferType = Payment; TransferDate = d; Amount = 230_00L }) let aprMethod = CalculationMethod.UsActuarial 4 diff --git a/docs/examplePaymentSchedule.fsx b/docs/examplePaymentSchedule.fsx index 01b3254..7c6be36 100644 --- a/docs/examplePaymentSchedule.fsx +++ b/docs/examplePaymentSchedule.fsx @@ -37,7 +37,8 @@ let scheduleParameters = Principal = 10000_00L PaymentSchedule = RegularSchedule ( UnitPeriodConfig = UnitPeriod.Monthly(1, 2024, 3, 7), - PaymentCount = 36 + PaymentCount = 36, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [||] diff --git a/src/Amortisation.fs b/src/Amortisation.fs index 5ab575b..7f12153 100644 --- a/src/Amortisation.fs +++ b/src/Amortisation.fs @@ -550,7 +550,7 @@ module Amortisation = | RegularFixedSchedule regularFixedSchedules -> regularFixedSchedules |> Array.map(fun rfs -> - UnitPeriod.generatePaymentSchedule rfs.PaymentCount UnitPeriod.Direction.Forward rfs.UnitPeriodConfig + UnitPeriod.generatePaymentSchedule rfs.PaymentCount ValueNone UnitPeriod.Direction.Forward rfs.UnitPeriodConfig |> Array.map(fun d -> { PaymentDay = OffsetDay.fromDate sp.AsOfDate d diff --git a/src/Apr.fs b/src/Apr.fs index 1e0ef73..7d3ef1d 100644 --- a/src/Apr.fs +++ b/src/Apr.fs @@ -111,7 +111,7 @@ module Apr = let transferDates = transfers |> Array.map _.TransferDate let transferCount = transfers |> Array.length let unitPeriod = transferDates |> UnitPeriod.detect UnitPeriod.Direction.Reverse (UnitPeriod.Month 1) - let schedule = UnitPeriod.generatePaymentSchedule ((transferCount + 1) * multiple) UnitPeriod.Direction.Reverse unitPeriod |> Array.filter(fun d -> d >= termStart) + let schedule = UnitPeriod.generatePaymentSchedule ((transferCount + 1) * multiple) ValueNone UnitPeriod.Direction.Reverse unitPeriod |> Array.filter(fun d -> d >= termStart) let scheduleCount = schedule |> Array.length let lastWholeMonthBackIndex = 0 let lastWholeUnitPeriodBackIndex = (scheduleCount - 1) % multiple @@ -139,7 +139,7 @@ module Apr = let transferDates = transfers |> Array.map _.TransferDate let transferCount = transfers |> Array.length let frequency = transferDates |> UnitPeriod.detect UnitPeriod.Direction.Reverse UnitPeriod.SemiMonth - let schedule = UnitPeriod.generatePaymentSchedule (transferCount + 2) UnitPeriod.Direction.Reverse frequency |> Array.filter(fun d -> d >= termStart) + let schedule = UnitPeriod.generatePaymentSchedule (transferCount + 2) ValueNone UnitPeriod.Direction.Reverse frequency |> Array.filter(fun d -> d >= termStart) let scheduleCount = schedule |> Array.length let offset = scheduleCount - transferCount [| 0 .. (transferCount - 1) |] diff --git a/src/CustomerPayments.fs b/src/CustomerPayments.fs index 8a36ef3..9273192 100644 --- a/src/CustomerPayments.fs +++ b/src/CustomerPayments.fs @@ -112,7 +112,7 @@ module CustomerPayments = [] type CustomerPaymentSchedule = /// a regular schedule based on a unit-period config with a specific number of payments with an auto-calculated amount - | RegularSchedule of UnitPeriodConfig: UnitPeriod.Config * PaymentCount: int + | RegularSchedule of UnitPeriodConfig: UnitPeriod.Config * PaymentCount: int * MaxDuration: Duration voption /// a regular schedule based on one or more unit-period configs each with a specific number of payments of a specified amount | RegularFixedSchedule of RegularFixedSchedule array /// just a bunch of payments diff --git a/src/DateDay.fs b/src/DateDay.fs index cb667dd..48d5e3d 100644 --- a/src/DateDay.fs +++ b/src/DateDay.fs @@ -38,6 +38,12 @@ module DateDay = /// a duration of a number of days [] type DurationDay + [] + type Duration = { + Length: int + FromDate: Date + } + /// day of month, bug: specifying 29, 30, or 31 means the dates will track the specific day of the month where /// possible, otherwise the day will be the last day of the month; so 31 will track the month end; also note that it is /// possible to start with e.g. (2024, 02, 31) and this will yield 2024-02-29 29 2024-03-31 2024-04-30 etc. diff --git a/src/FSharp.Finance.Personal.fsproj b/src/FSharp.Finance.Personal.fsproj index c279552..929f86a 100644 --- a/src/FSharp.Finance.Personal.fsproj +++ b/src/FSharp.Finance.Personal.fsproj @@ -33,7 +33,7 @@ true FSharp.Finance.Personal - 0.14.3 + 0.15.0 Simon Treanor F# Personal Finance Library https://github.com/simontreanor/FSharp.Finance.Personal diff --git a/src/PaymentSchedule.fs b/src/PaymentSchedule.fs index db11771..6915a61 100644 --- a/src/PaymentSchedule.fs +++ b/src/PaymentSchedule.fs @@ -121,10 +121,10 @@ module PaymentSchedule = if startDate > unitPeriodConfigStartDate then [||] else - generatePaymentSchedule rfs.PaymentCount Direction.Forward rfs.UnitPeriodConfig |> Array.map (OffsetDay.fromDate startDate) + generatePaymentSchedule rfs.PaymentCount ValueNone Direction.Forward rfs.UnitPeriodConfig |> Array.map (OffsetDay.fromDate startDate) ) |> Array.concat - | RegularSchedule (unitPeriodConfig, paymentCount) -> + | RegularSchedule (unitPeriodConfig, paymentCount, maxDuration) -> if paymentCount = 0 then [||] else @@ -132,7 +132,7 @@ module PaymentSchedule = if startDate > unitPeriodConfigStartDate then [||] else - generatePaymentSchedule paymentCount Direction.Forward unitPeriodConfig |> Array.map (OffsetDay.fromDate startDate) + generatePaymentSchedule paymentCount maxDuration Direction.Forward unitPeriodConfig |> Array.map (OffsetDay.fromDate startDate) /// calculates the number of days between two offset days on which interest is chargeable let calculate toleranceOption sp = diff --git a/src/Rescheduling.fs b/src/Rescheduling.fs index 7ccfea1..8b902c8 100644 --- a/src/Rescheduling.fs +++ b/src/Rescheduling.fs @@ -51,7 +51,7 @@ module Rescheduling = | RegularFixedSchedule regularFixedSchedules -> regularFixedSchedules |> Array.map(fun rfs -> - UnitPeriod.generatePaymentSchedule rfs.PaymentCount UnitPeriod.Direction.Forward rfs.UnitPeriodConfig + UnitPeriod.generatePaymentSchedule rfs.PaymentCount ValueNone UnitPeriod.Direction.Forward rfs.UnitPeriodConfig |> Array.map(fun d -> { PaymentDay = OffsetDay.fromDate sp.StartDate d; PaymentDetails = ScheduledPayment (ScheduledPaymentType.Rescheduled rfs.PaymentAmount) }) ) |> Array.concat diff --git a/src/UnitPeriod.fs b/src/UnitPeriod.fs index dfec05b..8bfdafd 100644 --- a/src/UnitPeriod.fs +++ b/src/UnitPeriod.fs @@ -196,14 +196,14 @@ module UnitPeriod = | invalidConfig -> fix invalidConfig /// generates a suggested number of payments to constrain the loan within a certain duration - let maxPaymentCount (maxLoanLength: int) (startDate: Date) (config: Config) = + let maxPaymentCount (maxDuration: int) (config: Config) (startDate: Date) = let offset y m td = ((TrackingDay.toDate y m td) - startDate).Days |> fun f -> int f * 1 match config with - | Single d -> maxLoanLength - offset d.Year d.Month d.Day - | Daily d -> maxLoanLength - offset d.Year d.Month d.Day - | Weekly (multiple, d) when multiple > 0 -> (maxLoanLength - offset d.Year d.Month d.Day) / (multiple * 7) - | SemiMonthly (y, m, d1, _) -> (maxLoanLength - offset y m (int d1)) / 15 - | Monthly (multiple, y, m, d) when multiple > 0 -> (maxLoanLength - offset y m (int d)) / (multiple * 30) + | Single d -> maxDuration - offset d.Year d.Month d.Day + | Daily d -> maxDuration - offset d.Year d.Month d.Day + | Weekly (multiple, d) when multiple > 0 -> (maxDuration - offset d.Year d.Month d.Day) / (multiple * 7) + | SemiMonthly (y, m, d1, _) -> (maxDuration - offset y m (int d1)) / 15 + | Monthly (multiple, y, m, d) when multiple > 0 -> (maxDuration - offset y m (int d)) / (multiple * 30) | _ -> 0 |> int @@ -216,8 +216,12 @@ module UnitPeriod = | Reverse /// generate a payment schedule based on a unit-period config - let generatePaymentSchedule count direction unitPeriodConfig = + let generatePaymentSchedule count maxDuration direction unitPeriodConfig = if count = 0 then [||] else + let limitedCount = + match maxDuration with + | ValueSome { Duration.Length = d; Duration.FromDate = fd } -> maxPaymentCount d unitPeriodConfig fd + | ValueNone -> count let adjustMonthEnd (monthEndTrackingDay: int) (d: Date) = if d.Day > 15 && monthEndTrackingDay > 28 then TrackingDay.toDate d.Year d.Month monthEndTrackingDay @@ -237,13 +241,13 @@ module UnitPeriod = startDate.AddMonths c |> adjustMonthEnd monthEndTrackingDay startDate.AddMonths (c + offset) |> fun d -> TrackingDay.toDate d.Year d.Month td2 |> adjustMonthEnd monthEndTrackingDay |]) - >> Array.take count + >> Array.take limitedCount | Monthly (multiple, year, month, td) -> let startDate = TrackingDay.toDate year month td Array.map (fun c -> startDate.AddMonths (c * multiple) |> adjustMonthEnd td) match direction with - | Direction.Forward -> [| 0 .. (count - 1) |] |> generate unitPeriodConfig - | Direction.Reverse -> [| 0 .. -1 .. -(count - 1) |] |> generate unitPeriodConfig |> Array.sort + | Direction.Forward -> [| 0 .. (limitedCount - 1) |] |> generate unitPeriodConfig + | Direction.Reverse -> [| 0 .. -1 .. -(limitedCount - 1) |] |> generate unitPeriodConfig |> Array.sort /// for a given interval and array of dates, devise the unit-period config let detect direction interval (transferDates: Date array) = diff --git a/tests/ActualPaymentTests.fs b/tests/ActualPaymentTests.fs index dc6ce7b..7380d2b 100644 --- a/tests/ActualPaymentTests.fs +++ b/tests/ActualPaymentTests.fs @@ -67,7 +67,8 @@ module ActualPaymentTests = Principal = 1500_00L PaymentSchedule = RegularSchedule ( UnitPeriodConfig = UnitPeriod.Monthly(1, 2022, 11, 31), - PaymentCount = 5 + PaymentCount = 5, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [||] @@ -113,7 +114,8 @@ module ActualPaymentTests = Principal = 1500_00L PaymentSchedule = RegularSchedule ( UnitPeriodConfig = UnitPeriod.Monthly(1, 2022, 11, 31), - PaymentCount = 5 + PaymentCount = 5, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [||] @@ -159,7 +161,8 @@ module ActualPaymentTests = Principal = 1500_00L PaymentSchedule = RegularSchedule ( UnitPeriodConfig = UnitPeriod.Monthly(1, 2022, 11, 15), - PaymentCount = 5 + PaymentCount = 5, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [||] @@ -205,7 +208,8 @@ module ActualPaymentTests = Principal = 1500_00L PaymentSchedule = RegularSchedule ( UnitPeriodConfig = UnitPeriod.Monthly(1, 2022, 11, 15), - PaymentCount = 5 + PaymentCount = 5, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [||] @@ -275,7 +279,8 @@ module ActualPaymentTests = Principal = 1500_00L PaymentSchedule = RegularSchedule ( UnitPeriodConfig = UnitPeriod.Monthly(1, 2022, 11, 15), - PaymentCount = 5 + PaymentCount = 5, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [||] @@ -345,7 +350,8 @@ module ActualPaymentTests = Principal = 1500_00L PaymentSchedule = RegularSchedule ( UnitPeriodConfig = UnitPeriod.Monthly(1, 2022, 11, 15), - PaymentCount = 5 + PaymentCount = 5, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [||] @@ -420,7 +426,8 @@ module ActualPaymentTests = Principal = 1500_00L PaymentSchedule = RegularSchedule ( UnitPeriodConfig = UnitPeriod.Monthly(1, 2022, 11, 15), - PaymentCount = 5 + PaymentCount = 5, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [||] @@ -493,7 +500,8 @@ module ActualPaymentTests = Principal = 1500_00L PaymentSchedule = RegularSchedule ( UnitPeriodConfig = UnitPeriod.Weekly(2, startDate.AddDays 14), - PaymentCount = 11 + PaymentCount = 11, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [||] @@ -567,7 +575,8 @@ module ActualPaymentTests = Principal = 1500_00L PaymentSchedule = RegularSchedule ( UnitPeriodConfig = UnitPeriod.Monthly(1, 2022, 11, 15), - PaymentCount = 5 + PaymentCount = 5, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [||] @@ -642,7 +651,8 @@ module ActualPaymentTests = Principal = 1500_00L PaymentSchedule = RegularSchedule ( UnitPeriodConfig = UnitPeriod.Monthly(1, 2022, 11, 15), - PaymentCount = 5 + PaymentCount = 5, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [||] @@ -716,7 +726,8 @@ module ActualPaymentTests = Principal = 1500_00L PaymentSchedule = RegularSchedule ( UnitPeriodConfig = UnitPeriod.Monthly(1, 2022, 11, 15), - PaymentCount = 5 + PaymentCount = 5, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [||] @@ -790,7 +801,8 @@ module ActualPaymentTests = Principal = 1500_00L PaymentSchedule = RegularSchedule ( UnitPeriodConfig = UnitPeriod.Monthly(1, 2022, 11, 15), - PaymentCount = 5 + PaymentCount = 5, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [||] @@ -866,7 +878,8 @@ module ActualPaymentTests = Principal = 250_00L PaymentSchedule = RegularSchedule ( UnitPeriodConfig = UnitPeriod.Monthly(1, 2024, 2, 22), - PaymentCount = 4 + PaymentCount = 4, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [||] @@ -914,7 +927,8 @@ module ActualPaymentTests = Principal = 2500_00L PaymentSchedule = RegularSchedule ( UnitPeriodConfig = UnitPeriod.Weekly(1, Date(2022, 5, 6)), - PaymentCount = 24 + PaymentCount = 24, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [| Fee.CabOrCsoFee (Amount.Percentage (Percent 154.47m, ValueNone, ValueSome RoundDown)) |] @@ -985,7 +999,8 @@ module ActualPaymentTests = Principal = 2500_00L PaymentSchedule = RegularSchedule ( UnitPeriodConfig = UnitPeriod.Weekly(1, Date(2022, 5, 6)), - PaymentCount = 24 + PaymentCount = 24, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [| Fee.CabOrCsoFee (Amount.Percentage (Percent 154.47m, ValueNone, ValueSome RoundDown)) |] @@ -1033,7 +1048,8 @@ module ActualPaymentTests = Principal = 2500_00L PaymentSchedule = RegularSchedule ( UnitPeriodConfig = UnitPeriod.Weekly(1, Date(2022, 5, 6)), - PaymentCount = 24 + PaymentCount = 24, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [| Fee.CabOrCsoFee (Amount.Percentage (Percent 154.47m, ValueNone, ValueSome RoundDown)) |] @@ -1082,7 +1098,8 @@ module ActualPaymentTests = Principal = 2500_00L PaymentSchedule = RegularSchedule ( UnitPeriodConfig = UnitPeriod.Weekly(1, Date(2022, 5, 6)), - PaymentCount = 24 + PaymentCount = 24, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [| Fee.CabOrCsoFee (Amount.Percentage (Percent 154.47m, ValueNone, ValueSome RoundDown)) |] @@ -1132,7 +1149,8 @@ module ActualPaymentTests = Principal = 2500_00L PaymentSchedule = RegularSchedule ( UnitPeriodConfig = UnitPeriod.Weekly(1, Date(2024, 1, 14)), - PaymentCount = 24 + PaymentCount = 24, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [| Fee.CabOrCsoFee (Amount.Percentage (Percent 154.47m, ValueNone, ValueSome RoundDown)) |] @@ -1182,7 +1200,8 @@ module ActualPaymentTests = Principal = 2500_00L PaymentSchedule = RegularSchedule ( UnitPeriodConfig = UnitPeriod.Weekly(1, Date(2024, 1, 14)), - PaymentCount = 24 + PaymentCount = 24, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [| Fee.CabOrCsoFee (Amount.Percentage (Percent 154.47m, ValueNone, ValueSome RoundDown)) |] @@ -1230,7 +1249,7 @@ module ActualPaymentTests = AsOfDate = Date(2024, 3, 2) StartDate = Date(2023, 8, 20) Principal = 250_00L - PaymentSchedule = RegularSchedule(UnitPeriod.Config.Monthly(1, 2023, 9, 5), 4) + PaymentSchedule = RegularSchedule(UnitPeriod.Config.Monthly(1, 2023, 9, 5), 4, ValueNone) FeesAndCharges = { Fees = [||] FeesAmortisation = Fees.FeeAmortisation.AmortiseProportionately diff --git a/tests/ActualPaymentTestsExtra.fs b/tests/ActualPaymentTestsExtra.fs index d810718..d8833ac 100644 --- a/tests/ActualPaymentTestsExtra.fs +++ b/tests/ActualPaymentTestsExtra.fs @@ -118,7 +118,7 @@ module ActualPaymentTestsExtra = let pir = match sp.Interest.PromotionalRates with [||] -> "()" | pirr -> pirr |> Array.map(fun pr -> $"""({pr.DateRange.Start.ToString()}-{pr.DateRange.End.ToString()}__{Interest.Rate.serialise pr.Rate})""") |> String.concat ";" |> fun s -> $"({s})" let upc, pc = match sp.PaymentSchedule with - | RegularSchedule(unitPeriodConfig, paymentCount) -> + | RegularSchedule(unitPeriodConfig, paymentCount, maxDuration) -> (UnitPeriod.Config.serialise unitPeriodConfig), paymentCount | _ -> failwith "Not implemented" let acm = sp.Calculation.AprMethod @@ -185,7 +185,8 @@ module ActualPaymentTestsExtra = Principal = aa PaymentSchedule = RegularSchedule ( UnitPeriodConfig = upc, - PaymentCount = pc + PaymentCount = pc, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = f @@ -236,7 +237,8 @@ module ActualPaymentTestsExtra = Principal = aa PaymentSchedule = RegularSchedule ( UnitPeriodConfig = upc, - PaymentCount = pc + PaymentCount = pc, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = f @@ -326,7 +328,8 @@ module ActualPaymentTestsExtra = Principal = 800_00L PaymentSchedule = RegularSchedule ( UnitPeriodConfig = UnitPeriod.Monthly(1, 2023, 8, 1), - PaymentCount = 5 + PaymentCount = 5, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [| Fee.CabOrCsoFee (Amount.Percentage (Percent 150m, ValueNone, ValueSome RoundDown)) |] @@ -401,7 +404,8 @@ module ActualPaymentTestsExtra = Principal = 800_00L PaymentSchedule = RegularSchedule ( UnitPeriodConfig = UnitPeriod.Weekly(2, Date(2022, 3, 26)), - PaymentCount = 12 + PaymentCount = 12, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [| Fee.CabOrCsoFee (Amount.Percentage (Percent 150m, ValueNone, ValueSome RoundDown)) |] @@ -478,7 +482,8 @@ module ActualPaymentTestsExtra = Principal = 800_00L PaymentSchedule = RegularSchedule ( UnitPeriodConfig = UnitPeriod.Weekly(2, Date(2022, 3, 26)), - PaymentCount = 12 + PaymentCount = 12, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [| Fee.CabOrCsoFee (Amount.Percentage (Percent 150m, ValueNone, ValueSome RoundDown)) |] @@ -562,7 +567,8 @@ module ActualPaymentTestsExtra = Principal = 800_00L PaymentSchedule = RegularSchedule ( UnitPeriodConfig = UnitPeriod.Weekly (8, Date(2023, 11, 23)), - PaymentCount = 19 + PaymentCount = 19, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [| Fee.CabOrCsoFee (Amount.Percentage (Percent 164m, ValueNone, ValueSome RoundDown)) |] @@ -637,7 +643,8 @@ module ActualPaymentTestsExtra = Principal = 200_00L PaymentSchedule = RegularSchedule ( UnitPeriodConfig = UnitPeriod.Monthly (1, 2022, 9, 15), - PaymentCount = 7 + PaymentCount = 7, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [||] @@ -712,7 +719,8 @@ module ActualPaymentTestsExtra = Principal = 800_00L PaymentSchedule = RegularSchedule ( UnitPeriodConfig = UnitPeriod.Weekly(2, Date(2022, 3, 26)), - PaymentCount = 12 + PaymentCount = 12, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [| Fee.CabOrCsoFee (Amount.Percentage (Percent 150m, ValueNone, ValueSome RoundDown)) |] @@ -789,7 +797,8 @@ module ActualPaymentTestsExtra = Principal = 800_00L PaymentSchedule = RegularSchedule ( UnitPeriodConfig = UnitPeriod.Weekly(2, Date(2022, 3, 26)), - PaymentCount = 12 + PaymentCount = 12, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [| Fee.CabOrCsoFee (Amount.Percentage (Percent 150m, ValueNone, ValueSome RoundDown)) |] @@ -872,7 +881,8 @@ module ActualPaymentTestsExtra = Principal = 800_00L PaymentSchedule = RegularSchedule ( UnitPeriodConfig = UnitPeriod.Weekly(2, Date(2022, 3, 26)), - PaymentCount = 12 + PaymentCount = 12, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [| Fee.CabOrCsoFee (Amount.Percentage (Percent 150m, ValueNone, ValueSome RoundDown)) |] diff --git a/tests/AprUsActuarialTests.fs b/tests/AprUsActuarialTests.fs index 0c1e052..8792b4a 100644 --- a/tests/AprUsActuarialTests.fs +++ b/tests/AprUsActuarialTests.fs @@ -25,7 +25,7 @@ module AprUsActuarialTests = let consummationDate = advanceDate let firstFinanceChargeEarnedDate = consummationDate let advances = [| { TransferType = Advance; TransferDate = consummationDate; Amount = advanceAmount } |] - let payments = intervalSchedule |> UnitPeriod.generatePaymentSchedule paymentCount Direction.Forward |> Array.map(fun d -> { TransferType = Payment; TransferDate = d; Amount = payment }) + let payments = intervalSchedule |> UnitPeriod.generatePaymentSchedule paymentCount ValueNone Direction.Forward |> Array.map(fun d -> { TransferType = Payment; TransferDate = d; Amount = payment }) UsActuarial.generalEquation consummationDate firstFinanceChargeEarnedDate advances payments |> getAprOr 0m |> Percent.fromDecimal |> Percent.round 2 @@ -64,7 +64,7 @@ module AprUsActuarialTests = let consummationDate = advanceDate let firstFinanceChargeEarnedDate = consummationDate let advances = [| { TransferType = Advance; TransferDate = consummationDate; Amount = advanceAmount } |] - let payments = intervalSchedule |> generatePaymentSchedule regularPaymentCount Direction.Forward |> Array.map(fun d -> { TransferType = Payment; TransferDate = d; Amount = regularPaymentAmount }) + let payments = intervalSchedule |> generatePaymentSchedule regularPaymentCount ValueNone Direction.Forward |> Array.map(fun d -> { TransferType = Payment; TransferDate = d; Amount = regularPaymentAmount }) let payments' = Array.concat [| [| firstPayment |]; payments |] UsActuarial.generalEquation consummationDate firstFinanceChargeEarnedDate advances payments' |> getAprOr 0m |> Percent.fromDecimal |> Percent.round 2 @@ -88,7 +88,7 @@ module AprUsActuarialTests = let consummationDate = advanceDate let firstFinanceChargeEarnedDate = consummationDate let advances = [| { TransferType = Advance; TransferDate = consummationDate; Amount = advanceAmount } |] - let payments = intervalSchedule |> generatePaymentSchedule regularPaymentCount Direction.Forward |> Array.map(fun d -> { TransferType = Payment; TransferDate = d; Amount = regularPaymentAmount }) + let payments = intervalSchedule |> generatePaymentSchedule regularPaymentCount ValueNone Direction.Forward |> Array.map(fun d -> { TransferType = Payment; TransferDate = d; Amount = regularPaymentAmount }) let payments' = Array.concat [| payments; [| lastPayment |] |] UsActuarial.generalEquation consummationDate firstFinanceChargeEarnedDate advances payments' |> getAprOr 0m |> Percent.fromDecimal |> Percent.round 2 @@ -112,7 +112,7 @@ module AprUsActuarialTests = let consummationDate = advanceDate let firstFinanceChargeEarnedDate = consummationDate let advances = [| { TransferType = Advance; TransferDate = consummationDate; Amount = advanceAmount } |] - let payments = intervalSchedule |> generatePaymentSchedule regularPaymentCount Direction.Forward |> Array.map(fun d -> { TransferType = Payment; TransferDate = d; Amount = regularPaymentAmount }) + let payments = intervalSchedule |> generatePaymentSchedule regularPaymentCount ValueNone Direction.Forward |> Array.map(fun d -> { TransferType = Payment; TransferDate = d; Amount = regularPaymentAmount }) let payments' = Array.concat [| [| firstPayment |]; payments; [| lastPayment |] |] UsActuarial.generalEquation consummationDate firstFinanceChargeEarnedDate advances payments' |> getAprOr 0m |> Percent.fromDecimal |> Percent.round 2 diff --git a/tests/EdgeCaseTests.fs b/tests/EdgeCaseTests.fs index f1fe528..119dbf3 100644 --- a/tests/EdgeCaseTests.fs +++ b/tests/EdgeCaseTests.fs @@ -425,7 +425,7 @@ module EdgeCaseTests = AsOfDate = Date(2024, 3, 12) StartDate = Date(2022, 6, 22) Principal = 500_00L - PaymentSchedule = RegularSchedule(UnitPeriod.Config.Monthly(1, 2022, 7, 15), 6) + PaymentSchedule = RegularSchedule(UnitPeriod.Config.Monthly(1, 2022, 7, 15), 6, ValueNone) FeesAndCharges = { Fees = [||] FeesAmortisation = Fees.FeeAmortisation.AmortiseProportionately @@ -545,7 +545,7 @@ module EdgeCaseTests = AsOfDate = Date(2024, 3, 12) StartDate = Date(2021, 12, 26) Principal = 150000L - PaymentSchedule = RegularSchedule(UnitPeriod.Config.Monthly(1, 2022, 1, 7), 6) + PaymentSchedule = RegularSchedule(UnitPeriod.Config.Monthly(1, 2022, 1, 7), 6, ValueNone) FeesAndCharges = { Fees = [||] FeesAmortisation = Fees.FeeAmortisation.AmortiseProportionately @@ -598,7 +598,7 @@ module EdgeCaseTests = AsOfDate = Date(2024, 3, 14) StartDate = Date(2024, 2, 2) Principal = 25000L - PaymentSchedule = RegularSchedule(UnitPeriod.Config.Monthly(1, 2024, 2, 22), 4) + PaymentSchedule = RegularSchedule(UnitPeriod.Config.Monthly(1, 2024, 2, 22), 4, ValueNone) FeesAndCharges = { Fees = [||] FeesAmortisation = Fees.FeeAmortisation.AmortiseProportionately @@ -680,7 +680,7 @@ module EdgeCaseTests = AsOfDate = Date(2024, 3, 14) StartDate = Date(2024, 2, 2) Principal = 25000L - PaymentSchedule = RegularSchedule(UnitPeriod.Config.Monthly(1, 2024, 2, 22), 4) + PaymentSchedule = RegularSchedule(UnitPeriod.Config.Monthly(1, 2024, 2, 22), 4, ValueNone) FeesAndCharges = { Fees = [||] FeesAmortisation = Fees.FeeAmortisation.AmortiseProportionately @@ -762,7 +762,7 @@ module EdgeCaseTests = AsOfDate = Date(2024, 4, 5) StartDate = Date(2023, 5, 5) Principal = 25000L - PaymentSchedule = RegularSchedule(UnitPeriod.Config.Monthly(1, 2023, 5, 10), 4) + PaymentSchedule = RegularSchedule(UnitPeriod.Config.Monthly(1, 2023, 5, 10), 4, ValueNone) FeesAndCharges = { Fees = [||] FeesAmortisation = Fees.FeeAmortisation.AmortiseProportionately diff --git a/tests/FeesAndChargesTests.fs b/tests/FeesAndChargesTests.fs index 6bcfc0f..728ddd9 100644 --- a/tests/FeesAndChargesTests.fs +++ b/tests/FeesAndChargesTests.fs @@ -32,7 +32,8 @@ module FeesAndChargesTests = Principal = 1500_00L PaymentSchedule = RegularSchedule ( UnitPeriodConfig = UnitPeriod.Monthly(1, 2022, 11, 31), - PaymentCount = 5 + PaymentCount = 5, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [||] @@ -112,7 +113,8 @@ module FeesAndChargesTests = Principal = 1500_00L PaymentSchedule = RegularSchedule ( UnitPeriodConfig = UnitPeriod.Monthly(1, 2022, 11, 31), - PaymentCount = 5 + PaymentCount = 5, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [||] @@ -192,7 +194,8 @@ module FeesAndChargesTests = Principal = 1500_00L PaymentSchedule = RegularSchedule ( UnitPeriodConfig = UnitPeriod.Monthly(1, 2022, 11, 31), - PaymentCount = 5 + PaymentCount = 5, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [||] diff --git a/tests/InterestTests.fs b/tests/InterestTests.fs index 3b31b35..e42abd7 100644 --- a/tests/InterestTests.fs +++ b/tests/InterestTests.fs @@ -82,7 +82,8 @@ module InterestTests = Principal = 499_00L PaymentSchedule = RegularSchedule ( UnitPeriodConfig = UnitPeriod.Monthly(1, 2023, 2, 14), - PaymentCount = 4 + PaymentCount = 4, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [||] @@ -127,7 +128,8 @@ module InterestTests = Principal = 499_00L PaymentSchedule = RegularSchedule ( UnitPeriodConfig = UnitPeriod.Monthly(1, 2023, 2, 14), - PaymentCount = 4 + PaymentCount = 4, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [||] diff --git a/tests/PaymentScheduleTests.fs b/tests/PaymentScheduleTests.fs index 3a0888f..a5ad5cf 100644 --- a/tests/PaymentScheduleTests.fs +++ b/tests/PaymentScheduleTests.fs @@ -32,7 +32,8 @@ module PaymentScheduleTests = Principal = principal PaymentSchedule = RegularSchedule ( UnitPeriodConfig = UnitPeriod.Weekly(2, startDate.AddDays(int offset)), - PaymentCount = 11 + PaymentCount = 11, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [| Fee.FacilitationFee (Amount.Percentage (Percent 189.47m, ValueNone, ValueSome RoundDown)) |] @@ -122,7 +123,8 @@ module PaymentScheduleTests = Principal = principal PaymentSchedule = RegularSchedule ( UnitPeriodConfig = (startDate.AddDays(int offset) |> fun d -> UnitPeriod.Monthly(1, d.Year, d.Month, d.Day * 1)), - PaymentCount = paymentCount + PaymentCount = paymentCount, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [||] @@ -1372,7 +1374,8 @@ module PaymentScheduleTests = Principal = 300_00L PaymentSchedule = RegularSchedule ( UnitPeriodConfig = UnitPeriod.Daily(Date(2023, 1, 3)), - PaymentCount = 1 + PaymentCount = 1, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [||] @@ -1407,3 +1410,93 @@ module PaymentScheduleTests = let expected = ValueSome (336_00L, 336_00L) actual |> should equal expected + + [] + let ``2) Term must not exceed maximum duration`` () = + let sp = { + AsOfDate = Date(2024, 5, 8) + StartDate = Date(2024, 5, 8) + Principal = 1000_00L + PaymentSchedule = RegularSchedule ( + UnitPeriodConfig = UnitPeriod.Monthly(1, 2024, 5, 8), + PaymentCount = 7, + MaxDuration = ValueSome { Length = 183; FromDate = Date(2024, 5, 8) } + ) + FeesAndCharges = { + Fees = [||] + FeesAmortisation = Fees.FeeAmortisation.AmortiseProportionately + FeesSettlementRefund = Fees.SettlementRefund.ProRata ValueNone + Charges = [| Charge.LatePayment (Amount.Simple 10_00L) |] + ChargesHolidays = [||] + ChargesGrouping = OneChargeTypePerDay + LatePaymentGracePeriod = 3 + } + Interest = { + StandardRate = Interest.Rate.Daily (Percent 0.8m) + Cap = interestCapExample + InitialGracePeriod = 0 + PromotionalRates = [||] + RateOnNegativeBalance = ValueSome <| Interest.Rate.Annual (Percent 8m) + } + Calculation = { + AprMethod = Apr.CalculationMethod.UnitedKingdom 3 + RoundingOptions = RoundingOptions.recommended + MinimumPayment = DeferOrWriteOff 50L + PaymentTimeout = 3 + } + } + + let actual = + voption { + let! schedule = sp |> calculate BelowZero + schedule.Items |> Formatting.outputListToHtml "out/PaymentSchedule002.md" + return schedule.LevelPayment, schedule.FinalPayment + } + + let expected = ValueSome (269_20L, 269_11L) + actual |> should equal expected + + [] + let ``3) Term must not exceed maximum duration`` () = + let sp = { + AsOfDate = Date(2024, 5, 8) + StartDate = Date(2024, 5, 8) + Principal = 1000_00L + PaymentSchedule = RegularSchedule ( + UnitPeriodConfig = UnitPeriod.Monthly(1, 2024, 5, 8), + PaymentCount = 7, + MaxDuration = ValueSome { Length = 184; FromDate = Date(2024, 5, 8) } + ) + FeesAndCharges = { + Fees = [||] + FeesAmortisation = Fees.FeeAmortisation.AmortiseProportionately + FeesSettlementRefund = Fees.SettlementRefund.ProRata ValueNone + Charges = [| Charge.LatePayment (Amount.Simple 10_00L) |] + ChargesHolidays = [||] + ChargesGrouping = OneChargeTypePerDay + LatePaymentGracePeriod = 3 + } + Interest = { + StandardRate = Interest.Rate.Daily (Percent 0.8m) + Cap = interestCapExample + InitialGracePeriod = 0 + PromotionalRates = [||] + RateOnNegativeBalance = ValueSome <| Interest.Rate.Annual (Percent 8m) + } + Calculation = { + AprMethod = Apr.CalculationMethod.UnitedKingdom 3 + RoundingOptions = RoundingOptions.recommended + MinimumPayment = DeferOrWriteOff 50L + PaymentTimeout = 3 + } + } + + let actual = + voption { + let! schedule = sp |> calculate BelowZero + schedule.Items |> Formatting.outputListToHtml "out/PaymentSchedule003.md" + return schedule.LevelPayment, schedule.FinalPayment + } + + let expected = ValueSome (251_08L, 250_99L) + actual |> should equal expected diff --git a/tests/QuoteTests.fs b/tests/QuoteTests.fs index 0408575..d4f23fb 100644 --- a/tests/QuoteTests.fs +++ b/tests/QuoteTests.fs @@ -34,7 +34,8 @@ module QuoteTests = Principal = 1200_00L PaymentSchedule = RegularSchedule ( UnitPeriodConfig = UnitPeriod.Weekly(2, startDate.AddDays 15), - PaymentCount = 11 + PaymentCount = 11, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [| Fee.CabOrCsoFee (Amount.Percentage (Percent 189.47m, ValueNone, ValueSome RoundDown)) |] @@ -115,7 +116,8 @@ module QuoteTests = Principal = 1200_00L PaymentSchedule = RegularSchedule ( UnitPeriodConfig = UnitPeriod.Weekly(2, startDate.AddDays 15), - PaymentCount = 11 + PaymentCount = 11, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [| Fee.CabOrCsoFee (Amount.Percentage (Percent 189.47m, ValueNone, ValueSome RoundDown)) |] @@ -196,7 +198,8 @@ module QuoteTests = Principal = 1200_00L PaymentSchedule = RegularSchedule ( UnitPeriodConfig = UnitPeriod.Weekly(2, startDate.AddDays 15), - PaymentCount = 11 + PaymentCount = 11, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [| Fee.CabOrCsoFee (Amount.Percentage (Percent 189.47m, ValueNone, ValueSome RoundDown)) |] @@ -277,7 +280,8 @@ module QuoteTests = Principal = 1200_00L PaymentSchedule = RegularSchedule ( UnitPeriodConfig = (startDate.AddDays 15 |> fun sd -> UnitPeriod.Monthly(1, sd.Year, sd.Month, sd.Day * 1)), - PaymentCount = 5 + PaymentCount = 5, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [||] @@ -354,7 +358,8 @@ module QuoteTests = Principal = 1200_00L PaymentSchedule = RegularSchedule ( UnitPeriodConfig = (startDate.AddDays 15 |> fun sd -> UnitPeriod.Monthly(1, sd.Year, sd.Month, sd.Day * 1)), - PaymentCount = 5 + PaymentCount = 5, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [||] @@ -431,7 +436,8 @@ module QuoteTests = Principal = 1200_00L PaymentSchedule = RegularSchedule ( UnitPeriodConfig = UnitPeriod.Weekly(2, startDate.AddDays 15), - PaymentCount = 11 + PaymentCount = 11, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [| Fee.CabOrCsoFee (Amount.Percentage (Percent 189.47m, ValueNone, ValueSome RoundDown)) |] @@ -512,7 +518,8 @@ module QuoteTests = Principal = 1200_00L PaymentSchedule = RegularSchedule ( UnitPeriodConfig = UnitPeriod.Weekly(2, startDate.AddDays 15), - PaymentCount = 11 + PaymentCount = 11, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [| Fee.CabOrCsoFee (Amount.Percentage (Percent 189.47m, ValueNone, ValueSome RoundDown)) |] @@ -591,7 +598,8 @@ module QuoteTests = Principal = 1200_00L PaymentSchedule = RegularSchedule ( UnitPeriodConfig = UnitPeriod.Weekly(2, startDate.AddDays 15), - PaymentCount = 11 + PaymentCount = 11, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [| Fee.CabOrCsoFee (Amount.Percentage (Percent 189.47m, ValueNone, ValueSome RoundDown)) |] @@ -671,7 +679,8 @@ module QuoteTests = Principal = 500_00L PaymentSchedule = RegularSchedule ( UnitPeriodConfig = UnitPeriod.Weekly(2, Date(2023, 6, 30)), - PaymentCount = 10 + PaymentCount = 10, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [| Fee.CabOrCsoFee (Amount.Percentage (Percent 150m, ValueNone, ValueSome RoundDown)) |] @@ -747,7 +756,8 @@ module QuoteTests = Principal = 1200_00L PaymentSchedule = RegularSchedule ( UnitPeriodConfig = UnitPeriod.Weekly(2, Date(2022, 12, 12)), - PaymentCount = 11 + PaymentCount = 11, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [| Fee.CabOrCsoFee (Amount.Percentage (Percent 150m, ValueNone, ValueSome RoundDown)) |] @@ -831,7 +841,8 @@ module QuoteTests = Principal = 1200_00L PaymentSchedule = RegularSchedule ( UnitPeriodConfig = UnitPeriod.Weekly(2, Date(2022, 12, 12)), - PaymentCount = 11 + PaymentCount = 11, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [| Fee.CabOrCsoFee (Amount.Percentage (Percent 150m, ValueNone, ValueSome RoundDown)) |] @@ -913,7 +924,8 @@ module QuoteTests = Principal = 400_00L PaymentSchedule = RegularSchedule ( UnitPeriodConfig = UnitPeriod.Monthly(1, 2024, 2, 28), - PaymentCount = 4 + PaymentCount = 4, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [||] @@ -988,7 +1000,8 @@ module QuoteTests = Principal = 1500_00L PaymentSchedule = RegularSchedule ( UnitPeriodConfig = UnitPeriod.Monthly(1, 2022, 11, 15), - PaymentCount = 5 + PaymentCount = 5, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [||] @@ -1068,7 +1081,8 @@ module QuoteTests = Principal = 1500_00L PaymentSchedule = RegularSchedule ( UnitPeriodConfig = UnitPeriod.Monthly(1, 2022, 11, 15), - PaymentCount = 5 + PaymentCount = 5, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [||] @@ -1147,7 +1161,8 @@ module QuoteTests = Principal = 1500_00L PaymentSchedule = RegularSchedule ( UnitPeriodConfig = UnitPeriod.Monthly(1, 2022, 11, 15), - PaymentCount = 5 + PaymentCount = 5, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [||] @@ -1226,7 +1241,8 @@ module QuoteTests = Principal = 1500_00L PaymentSchedule = RegularSchedule ( UnitPeriodConfig = UnitPeriod.Monthly(1, 2022, 11, 15), - PaymentCount = 5 + PaymentCount = 5, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [||] @@ -1305,7 +1321,8 @@ module QuoteTests = Principal = 1500_00L PaymentSchedule = RegularSchedule ( UnitPeriodConfig = UnitPeriod.Monthly(1, 2022, 11, 15), - PaymentCount = 5 + PaymentCount = 5, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [||] @@ -1385,7 +1402,8 @@ module QuoteTests = Principal = 1500_00L PaymentSchedule = RegularSchedule ( UnitPeriodConfig = UnitPeriod.Monthly(1, 2022, 11, 15), - PaymentCount = 5 + PaymentCount = 5, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [||] @@ -1465,7 +1483,8 @@ module QuoteTests = Principal = 1500_00L PaymentSchedule = RegularSchedule ( UnitPeriodConfig = UnitPeriod.Monthly(1, 2022, 11, 15), - PaymentCount = 5 + PaymentCount = 5, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [||] @@ -1545,7 +1564,8 @@ module QuoteTests = Principal = 1500_00L PaymentSchedule = RegularSchedule ( UnitPeriodConfig = UnitPeriod.Monthly(1, 2022, 11, 15), - PaymentCount = 5 + PaymentCount = 5, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [||] @@ -1625,7 +1645,8 @@ module QuoteTests = Principal = 250_00L PaymentSchedule = RegularSchedule ( UnitPeriodConfig = UnitPeriod.Monthly(1, 2023, 1, 20), - PaymentCount = 4 + PaymentCount = 4, + MaxDuration = ValueNone ) FeesAndCharges = { Fees = [||] @@ -1671,7 +1692,7 @@ module QuoteTests = AsOfDate = Date(2024, 3, 4) StartDate = Date(2018, 2, 3) Principal = 230_00L - PaymentSchedule = RegularSchedule(UnitPeriod.Config.Monthly(1, 2018, 2, 28), 3) + PaymentSchedule = RegularSchedule(UnitPeriod.Config.Monthly(1, 2018, 2, 28), 3, ValueNone) FeesAndCharges = { Fees = [||] FeesAmortisation = Fees.FeeAmortisation.AmortiseProportionately @@ -1719,7 +1740,7 @@ module QuoteTests = AsOfDate = Date(2024, 3, 4) StartDate = Date(2018, 2, 3) Principal = 230_00L - PaymentSchedule = RegularSchedule(UnitPeriod.Config.Monthly(1, 2018, 2, 28), 3) + PaymentSchedule = RegularSchedule(UnitPeriod.Config.Monthly(1, 2018, 2, 28), 3, ValueNone) FeesAndCharges = { Fees = [||] FeesAmortisation = Fees.FeeAmortisation.AmortiseProportionately @@ -1767,7 +1788,7 @@ module QuoteTests = AsOfDate = Date(2024, 3, 7) StartDate = Date(2024, 2, 2) Principal = 25000L - PaymentSchedule = RegularSchedule(UnitPeriod.Config.Monthly(1, 2024, 2, 22), 4) + PaymentSchedule = RegularSchedule(UnitPeriod.Config.Monthly(1, 2024, 2, 22), 4, ValueNone) FeesAndCharges = { Fees = [||] FeesAmortisation = Fees.FeeAmortisation.AmortiseProportionately @@ -1815,7 +1836,7 @@ module QuoteTests = AsOfDate = Date(2024, 3, 7) StartDate = Date(2023, 9, 2) Principal = 25000L - PaymentSchedule = RegularSchedule(UnitPeriod.Config.Monthly(1, 2023, 9, 22), 4) + PaymentSchedule = RegularSchedule(UnitPeriod.Config.Monthly(1, 2023, 9, 22), 4, ValueNone) FeesAndCharges = { Fees = [||] FeesAmortisation = Fees.FeeAmortisation.AmortiseProportionately @@ -1861,7 +1882,7 @@ module QuoteTests = AsOfDate = Date(2024, 4, 5) StartDate = Date(2023, 5, 5) Principal = 25000L - PaymentSchedule = RegularSchedule(UnitPeriod.Config.Monthly(1, 2023, 5, 10), 4) + PaymentSchedule = RegularSchedule(UnitPeriod.Config.Monthly(1, 2023, 5, 10), 4, ValueNone) FeesAndCharges = { Fees = [||] FeesAmortisation = Fees.FeeAmortisation.AmortiseProportionately diff --git a/tests/SettlementTests.fs b/tests/SettlementTests.fs index 5eb9edc..1c247f4 100644 --- a/tests/SettlementTests.fs +++ b/tests/SettlementTests.fs @@ -30,7 +30,7 @@ module SettlementTests = AsOfDate = Date(2024, 3, 19) StartDate = Date(2023, 11, 28) Principal = 25000L - PaymentSchedule = RegularSchedule(UnitPeriod.Config.Monthly(1, 2023, 12, 22), 4) + PaymentSchedule = RegularSchedule(UnitPeriod.Config.Monthly(1, 2023, 12, 22), 4, ValueNone) FeesAndCharges = { Fees = [||] FeesAmortisation = Fees.FeeAmortisation.AmortiseProportionately @@ -106,7 +106,7 @@ module SettlementTests = AsOfDate = Date(2024, 3, 29) StartDate = Date(2023, 11, 28) Principal = 25000L - PaymentSchedule = RegularSchedule(UnitPeriod.Config.Monthly(1, 2023, 12, 22), 4) + PaymentSchedule = RegularSchedule(UnitPeriod.Config.Monthly(1, 2023, 12, 22), 4, ValueNone) FeesAndCharges = { Fees = [||] FeesAmortisation = Fees.FeeAmortisation.AmortiseProportionately @@ -182,7 +182,7 @@ module SettlementTests = AsOfDate = Date(2024, 3, 29) StartDate = Date(2023, 11, 28) Principal = 25000L - PaymentSchedule = RegularSchedule(UnitPeriod.Config.Monthly(1, 2023, 12, 22), 4) + PaymentSchedule = RegularSchedule(UnitPeriod.Config.Monthly(1, 2023, 12, 22), 4, ValueNone) FeesAndCharges = { Fees = [||] FeesAmortisation = Fees.FeeAmortisation.AmortiseProportionately diff --git a/tests/UnitPeriodConfigTests.fs b/tests/UnitPeriodConfigTests.fs index 7af74b8..167c4a0 100644 --- a/tests/UnitPeriodConfigTests.fs +++ b/tests/UnitPeriodConfigTests.fs @@ -64,7 +64,7 @@ module UnitPeriodConfigTests = AsOfDate = Date(2024, 3, 5) StartDate = Date(2022, 5, 5) Principal = 100000L - PaymentSchedule = RegularSchedule(Weekly(2, Date(2022, 5, 13)), 12) + PaymentSchedule = RegularSchedule(Weekly(2, Date(2022, 5, 13)), 12, ValueNone) FeesAndCharges = { Fees = [| Fee.CabOrCsoFee (Amount.Percentage (Percent 154.47m, ValueNone, ValueSome RoundDown)) |] FeesAmortisation = Fees.FeeAmortisation.AmortiseProportionately @@ -140,7 +140,7 @@ module UnitPeriodConfigTests = AsOfDate = Date(2024, 3, 5) StartDate = Date(2023, 4, 13) Principal = 70000L - PaymentSchedule = RegularSchedule(Weekly(2, Date(2023, 4, 20)), 12) + PaymentSchedule = RegularSchedule(Weekly(2, Date(2023, 4, 20)), 12, ValueNone) FeesAndCharges = { Fees = [| Fee.CabOrCsoFee (Amount.Percentage (Percent 154.47m, ValueNone, ValueSome RoundDown)) |] FeesAmortisation = Fees.FeeAmortisation.AmortiseProportionately @@ -203,7 +203,7 @@ module UnitPeriodConfigTests = AsOfDate = Date(2024, 3, 5) StartDate = Date(2023, 1, 20) Principal = 65000L - PaymentSchedule = RegularSchedule(Weekly(2, Date(2023, 2, 2)), 11) + PaymentSchedule = RegularSchedule(Weekly(2, Date(2023, 2, 2)), 11, ValueNone) FeesAndCharges = { Fees = [| Fee.CabOrCsoFee (Amount.Percentage (Percent 154.47m, ValueNone, ValueSome RoundDown)) |] FeesAmortisation = Fees.FeeAmortisation.AmortiseProportionately @@ -295,7 +295,7 @@ module UnitPeriodConfigTests = AsOfDate = Date(2024, 3, 5) StartDate = Date(2022, 10, 13) Principal = 50000L - PaymentSchedule = RegularSchedule(Weekly(2, Date(2022, 10, 28)), 11) + PaymentSchedule = RegularSchedule(Weekly(2, Date(2022, 10, 28)), 11, ValueNone) FeesAndCharges = { Fees = [| Fee.CabOrCsoFee (Amount.Percentage (Percent 154.47m, ValueNone, ValueSome RoundDown)) |] FeesAmortisation = Fees.FeeAmortisation.AmortiseProportionately