Repository navigation
Description
Describe the issue:
When calculating the payment required to end with a remaining open balance, aka with a final_value, the calculated payments are larger than the payments required for a achieving final_value=0.
Workaround is inputting the final_value in a flipped state.
In the current state, if a positive pv means a outstanding loan, a negative fv means a remaining outstanding debt; whilst a positive fv implies having 'overpaid' the loan. This is confusing.
Either the algorithm is wrong, and the sign should be flipped; or the documentation should be updated to clarify that pv and fv signs have opposite meaning.
Reproduce the code example:
import numpy_financial as npf
interest_rate = 0.05 / 12
principal_loan = 200_000
compounding_periods = 360
payment_value_fv0 = npf.pmt(
interest_rate,
compounding_periods,
principal_loan,
0,
)
payment_value_fv50 = npf.pmt(
interest_rate,
compounding_periods,
principal_loan,
50_000,
)
payment_value_fvn50 = npf.pmt(
interest_rate,
compounding_periods,
principal_loan,
-50_000,
)
print("{:.2f}".format(payment_value_fv50))
print("{:.2f}".format(payment_value_fv0))
print("{:.2f}".format(payment_value_fvn50))
assert abs(payment_value_fv50) < abs(payment_value_fv0),\
"Payment with remaining balance should be lower than fully paying off loan, but found {:.2f} > {:.2f}".format(abs(payment_value_fv50),abs(payment_value_fv0))Error message:
-1133.72
-1073.64
-1013.57
Traceback (most recent call last):
File "[...]/debugPmt.py", line 28, in <module>
assert abs(payment_value_fv50) < abs(payment_value_fv0),\
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: Payment with remaining balance should be lower than fully paying off loan, but found 1133.72 > 1073.64
Runtime information:
2.1.1
3.12.6 (main, Sep 9 2024, 00:00:00) [GCC 14.2.1 20240801 (Red Hat 14.2.1-1)]
[{'numpy_version': '2.1.1',
'python': '3.12.6 (main, Sep 9 2024, 00:00:00) [GCC 14.2.1 20240801 (Red '
'Hat 14.2.1-1)]',
'uname': uname_result(system='Linux', node='[...]', release='6.10.9-200.fc40.x86_64', version='#1 SMP PREEMPT_DYNAMIC Sun Sep 8 17:23:55 UTC 2024', machine='x86_64')},
{'simd_extensions': {'baseline': ['SSE', 'SSE2', 'SSE3'],
'found': ['SSSE3',
'SSE41',
'POPCNT',
'SSE42',
'AVX',
'F16C',
'FMA3',
'AVX2'],
'not_found': ['AVX512F',
'AVX512CD',
'AVX512_KNL',
'AVX512_KNM',
'AVX512_SKX',
'AVX512_CLX',
'AVX512_CNL',
'AVX512_ICL']}},
{'architecture': 'Haswell',
'filepath': '/home/[...]/.local/lib/python3.12/site-packages/numpy.libs/libscipy_openblas64_-ff651d7f.so',
'internal_api': 'openblas',
'num_threads': 8,
'prefix': 'libscipy_openblas',
'threading_layer': 'pthreads',
'user_api': 'blas',
'version': '0.3.27'}]
None
Context for the issue:
No response
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsIn Progress
Activity
RlndVt commentedon Sep 22, 2024
FWIW libreoffice calc and MS Excel show the same behaviour. To stay in line with those implementations, updating the documentation may be the better solution.
I still find it a confusing configuration and would argue that having the PV and FV signs represent the same is more correct, but I can understand the argument that keeping the implementation inline with other is desirable.
Examining Calc's and Excel's documentation; Calc:
Excel:
A distinction is made between the two types of 'value'. PV describing the borrowed/invested amount, and FV the final cash balance. Again, I would argue confusing; but nonetheless correct distinction.
parikhvedant2003 commentedon Oct 21, 2024
Hey @RlndVt 😊,
I noticed your issue, and it's definitely an interesting one! I’d love to help clarify how the monthly payment value is calculated based on the code you shared.
To give you the best guidance, I need to know if the code you’re using is the standard implementation at your organization or if you’ve made any tweaks to it for your own purposes. As far as I can see, you’ve just used the
pmtfunction of thenumpy_financiallibrary in your code. So let me know about the given code so I can assist you well and sort this out! 🚀RlndVt commentedon Oct 29, 2024
Hi @parikhvedant2003
No guidance required thank you; I was confused by the different definitions of value. By implementing the definitions as described in Calc and Excel my code works as expected.
The code provided was just a minimal working example for my (originally) expected behaviour.
As I suggested in my previous post, I think updating the documentation is the solution.
shivkatira commentedon Nov 3, 2024
@RlndVt
Hey, how can we export Runtime information information as you stated in your issue description?
RlndVt commentedon Nov 3, 2024
From the create new bug report/issue interface:
naseweisssss commentedon Sep 26, 2026
Opened a PR hoping to clarify this
InessaPawson commentedon Sep 27, 2026
@RlndVt Since you confirmed that this is a documentation issue, not a bug, could you update the issue prefix and title? Something like
DOC: Clarify the sign convention for fv in pmt documentationwould work.[-]BUG: npf.pmt() algorithm future value sign is flipped.[/-][+]DOC: Clarify the sign convention for fv in pmt documentation.[/+]stefanv commentedon Oct 15, 2026
@RlndVt Is #157 to your satisfaction?