Skip to content

Conversation

@Thorium
Copy link
Contributor

@Thorium Thorium commented Sep 10, 2025

All the finance people (and chatbots) seem to be madly in love with XIRR functions. So here you go...

This PR adds Excel-compatible XIRR (Extended Internal Rate of Return) functionality to the FSharp.Finance.Personal library, enabling calculation of annualized returns for irregular cash flow schedules.

Instead of re-inventing the wheel, this adds a new dependency to fsprojects/ExcelFinancialFunctions.

Features Added

Core XIRR Module (src/Xirr.fs)

  • Xirr.xirr: Calculate XIRR with Excel's default guess of 0.1 (10%)
  • Xirr.xirrG: Calculate XIRR with custom initial guess parameter
  • Xirr.tryXirr: Safe calculation returning Result<decimal, string> for error handling

Excel Compatibility

Uses the ExcelFinancialFunctions library (v3.2.0) to ensure complete parity with Excel's XIRR function, including:

  • Identical convergence algorithm and precision
  • Default guess value of 0.1 matching Excel behavior
  • Same sign convention (negative=outflows, positive=inflows)

Input Validation

All functions validate that:

  • At least two cashflows are provided
  • At least one positive and one negative cashflow exists
  • Dates are not all identical
  • Throws ArgumentException for invalid inputs (except tryXirr which returns Result.Error)

Usage Example

open System
open FSharp.Finance.Personal

// Basic investment scenario
let cashflows = [ DateTime(2024, 1, 1), -10000m; DateTime(2025, 1, 1), 11000m ]
let rate = Xirr.xirr cashflows
printfn "XIRR = %.2f%%" (rate * 100m)  // Output: ~10.00%

// Salary advance scenario  
let salaryAdvance = [ DateTime(2024, 1, 1), 1000m; DateTime(2024, 1, 31), -1030m ]
let advanceRate = Xirr.xirr salaryAdvance  // ~43% annualized

// Safe error handling
match Xirr.tryXirr cashflows with
| Ok rate -> printfn "Success: %.2f%%" (rate * 100m)
| Error msg -> printfn "Failed: %s" msg

Testing

Comprehensive test suite (tests/XirrTests.fs) covers:

  • Basic investment scenarios with ~10% returns
  • Short-term salary advance calculations (~43% annualized)
  • Input validation for mixed signs requirement
  • Consistency between xirr and xirrG with same guess
  • Edge cases and error conditions

All 7 test cases pass successfully when run in isolation.

Documentation

  • Example script: docs/exampleXirr.fsx with comprehensive usage examples
  • README update: Added XIRR section with quick start example
  • XML documentation: Detailed function documentation with sign convention explanations

Integration Notes

  • Non-breaking: All changes are additive, no existing functionality modified
  • Version: Left at 2.4.7 to coordinate with other pending PRs
  • Dependencies: Adds ExcelFinancialFunctions package dependency
  • Isolation: Module is self-contained with no coupling to existing domain modules

The implementation follows the repository's existing patterns and conventions, using [<RequireQualifiedAccess>] module attributes and consistent error handling approaches.

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.

1 participant