Skip to content

Interest.fs: variable/stepped rate schedules and interest-only periods#55

Draft
Copilot wants to merge 4 commits into
mainfrom
copilot/extend-interest-fs-support
Draft

Interest.fs: variable/stepped rate schedules and interest-only periods#55
Copilot wants to merge 4 commits into
mainfrom
copilot/extend-interest-fs-support

Conversation

Copy link
Copy Markdown

Copilot AI commented Apr 28, 2026

Two common product structures — tracker/stepped-rate schedules and interest-only phases — were not modelable in the library. This PR adds both as first-class, composable features.

Variable/Stepped Rate Schedules

Interest.BasicConfig gains a RateSchedule: RateSchedule field ((Date * Rate) array). Each entry overrides StandardRate from its effective date forward; promotional rates still take priority. Empty array = existing behaviour.

InterestConfig = {
    StandardRate = Rate.Annual(Percent 2.5m)  // applies before first step
    RateSchedule = [|
        Date(2025, 1, 1), Rate.Annual(Percent 3.5m)  // rate step at 12 months
        Date(2026, 1, 1), Rate.Annual(Percent 4.5m)  // further step at 24 months
    |]
    // ...
}

RateSchedule.effectiveRate picks the most recent entry with effectiveDate ≤ currentDate, sorting defensively against unsorted input.

Interest-Only Periods

AutoGenerateSchedule gains a RepaymentType field:

type RepaymentType =
    | CapitalAndInterest          // standard amortisation (default)
    | InterestOnly                // all payments = interest; final payment repays principal
    | Mixed of interestOnlyPeriods: int  // first N periods IO, remaining C&I via bisection
  • CapitalAndInterest: existing bisection-based level payment, unchanged.
  • InterestOnly: each scheduled payment = capped interest accrued; the final payment additionally clears the outstanding principal.
  • Mixed n: first n payment items are interest-only; the remaining items are generated via the standard bisection solver starting from the full (unreduced) principal balance.

Both features compose naturally — a tracker mortgage with a 2-year interest-only period:

ScheduleConfig = AutoGenerateSchedule {
    UnitPeriodConfig = Monthly(1, 2024, 2, 1)
    ScheduleLength = PaymentCount 300
    RepaymentType = Mixed 24
}
InterestConfig = {
    StandardRate = Rate.Annual(Percent 2.5m)
    RateSchedule = [| Date(2026, 1, 1), Rate.Annual(Percent 3.5m) |]
    // ...
}

Backward Compatibility

All existing record constructions require the two new fields. Defaults for existing code: RateSchedule = [||] and RepaymentType = RepaymentType.CapitalAndInterest.

Copilot AI changed the title [WIP] Extend Interest.fs for variable rate schedules and interest-only periods Interest.fs: variable/stepped rate schedules and interest-only periods Apr 28, 2026
Copilot AI requested a review from simontreanor April 28, 2026 23:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Interest.fs: variable/stepped rate schedules and interest-only periods

2 participants