Skip to content
sunix2131Public

About

Loan schedules and early repayments calculated in whole cents. C++ library and CLI.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

4 Commits

Folders and files

Repository files navigation

LoanPlan

C++ library and CLI for monthly loan repayment schedules. It supports annuity, differentiated and interest-only payments, three day-count conventions, fixed fees and early repayments on scheduled dates.

An independent project using synthetic examples. No employer code or customer data.

Calculation model

Money stores signed 64-bit minor units. Decimal input is parsed exactly and output always uses two decimal places.

Interest is calculated with integer arithmetic and rounded half up once per period:

interest_minor = round_half_up(opening_minor × rate_parts × day_count / (1e9 × year_basis))

The annuity installment is the smallest whole-cent payment that repays the loan within the term under that rounding rule. Binary search simulates the same integer calculation used for the output rows. The payment must also exceed the highest initial period interest by one cent, so principal decreases even for very small loans. The last installment can be smaller; there is no balloon caused by rounding down a formula result.

The engine keeps these invariants:

opening[n + 1] == closing[n]
final principal == 0
initial principal == Σ principal payments + Σ extra repayments

Payment dates preserve an end-of-month start. For example, a schedule beginning on 2024-01-31 continues on 2024-02-29, 2024-03-31, and so on.

Supported inputs

  • positive principal with exact two-decimal storage;
  • annual interest rate expressed as a decimal percent;
  • 1–1200 monthly periods;
  • annuity, differentiated or interest-only repayment;
  • Actual/365, Actual/360 and 30E/360 day count (selected as 30_360 in JSON);
  • fixed fee per payment;
  • one or more partial repayments on payment dates.

Example: examples/annuity-with-prepayment.json.

{
  "principal": "250000.00",
  "annual_interest_rate_percent": "14.50",
  "term_months": 24,
  "start_date": "2026-09-15",
  "repayment_strategy": "annuity",
  "day_count": "actual_365",
  "fee_per_payment": "0.00",
  "events": [
    {
      "type": "partial_repayment",
      "date": "2027-03-15",
      "amount": "30000.00"
    }
  ]
}

Build and run

Requirements: CMake 3.24+, a C++23 compiler and Git. CMake fetches pinned versions of nlohmann/json and Catch2 during configuration.

cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build --parallel
ctest --test-dir build --output-on-failure

JSON output:

./build/loanplan calculate examples/annuity-with-prepayment.json

CSV output:

./build/loanplan calculate examples/annuity-with-prepayment.json --format csv

Invalid money, dates, rates and repayment events fail with a non-zero exit status instead of producing a partial schedule.

What is tested

  • exact money parsing and overflow;
  • leap-year and end-of-month dates;
  • zero-rate and tiny-principal schedules;
  • all three current repayment strategies;
  • final-payment rounding correction;
  • partial early repayment;
  • fees kept separate from principal;
  • day-count differences;
  • invalid event dates;
  • balance continuity and full-repayment invariants.

GitHub Actions builds with GCC and Clang. A separate job runs the test suite under AddressSanitizer and UndefinedBehaviorSanitizer.

Deliberate limitations

Payments are monthly; dates must stay within years 0001–9999. Rate input accepts up to nine decimal places of percent and rounds half up to one part per billion of the annual fraction. Monetary calculations use checked 128-bit intermediates and return signed 64-bit minor units.

Payment holidays, rate changes, balloon schedules, non-payment-date events, currency-specific decimal scales and business-day calendars are not implemented. Early repayments keep the annuity installment and shorten the term; differentiated schedules redistribute the remaining principal over the remaining dates. An early repayment larger than the remaining balance is capped, and no fees accrue after payoff.

About

Loan schedules and early repayments calculated in whole cents. C++ library and CLI.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages