Skip to content

BUG: rate returning incorrect value #126

Open

Description

@jestover

Describe the issue:

I found a situation where npf.rate is not returning the same thing as my BA II Plus financial calculator or npf.irr. Even setting guess to the correct value does not get the expected answer.

Reproduce the code example:

import numpy_financial as npf
# This returns -1.8964420585461792
npf.rate(8, -440_000, 263_175, 25_500) 
# This returns 0.5838779110248231 - Matches financial calculator
npf.irr([-440_000, 263_175, 263_175, 263_175, 263_175, 263_175, 263_175, 263_175, 263_175 + 25_500])
# Still returns -1.8964420585461792
npf.rate(8, -440_000, 263_175, 25_500, 0, 0.5838779110248231)

Error message:

No response

Runtime information:

print(numpy.version)
1.26.4
print(sys.version)
3.12.3 (main, Apr 9 2024, 08:09:14) [Clang 15.0.0 (clang-1500.3.9.4)]
print(numpy.show_runtime())
WARNING: threadpoolctl not found in system! Install it by pip install threadpoolctl. Once installed, try np.show_runtime again for more detailed build information
[{'numpy_version': '1.26.4',
'python': '3.12.3 (main, Apr 9 2024, 08:09:14) [Clang 15.0.0 '
'(clang-1500.3.9.4)]',
'uname': uname_result(system='Darwin', node='HCOB-003406.local', release='23.4.0', version='Darwin Kernel Version 23.4.0: Fri Mar 15 00:12:49 PDT 2024; root:xnu-10063.101.17~1/RELEASE_ARM64_T6020', machine='arm64')},
{'simd_extensions': {'baseline': ['NEON', 'NEON_FP16', 'NEON_VFPV4', 'ASIMD'],
'found': ['ASIMDHP'],
'not_found': ['ASIMDFHM']}}]
None

Context for the issue:

No response

Activity

  1. Kai-Striega commented on Jun 14, 2024

    @Kai-Striega
    Member

    Hi @jestover,

    Thanks for reporting this, I'll take a look at it.

    What version of NumPy-Financial are you using?

  2. jestover commented on Jun 18, 2024

    @jestover
    Author

    I'm using version 1.0.0

  3. lcrmorin commented on Sep 19, 2026

    @lcrmorin

    The main policy question is whether to restrict the default search to r > -1, and how guess should guide selection when multiple roots exist. We should also handle the zero-rate limit explicitly and check the equation residual before accepting convergence.

    I tested Brent, TOMS 748, and bisection on a sign-changing bracket [0, 2]. All found 0.583877911024823 for the corrected inputs.

    Would Brent’s method or safeguarded Newton with bisection fallback be worth considering? The latter could reuse the existing derivative without adding a SciPy dependency.

  4. lcrmorin commented on Sep 28, 2026

    @lcrmorin

    I’ve opened #158 to enforce r > -1 for returned rates. Lower roots can satisfy the equation algebraically, but don’t make sense as compounding rates for conventional loans or investments.

    The change keeps Newton for ordinary cases and falls back to bracketed bisection when it converges outside that domain. Guesses at or below −1 are rejected.

    The corrected example returns 0.583877911, and the original inputs return 1.671183828.

    All tests pass locally.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions