Conversation
Removing text from single amount tab
majimmy88
reviewed
Jul 10, 2026
| // frequency modes stay consistent. | ||
| // `objective` is written in the rate per PAYMENT period (g), applied | ||
| // against `n` (a count of payment periods). | ||
| const objective = (g: number): number => { |
There was a problem hiding this comment.
NIT: I think something more descriptive than g would be better
Collaborator
Author
There was a problem hiding this comment.
Do you think that the long comments absolves the short variable since there is so much math going on in the calculations? That is what I was leaning towards.
There was a problem hiding this comment.
Gotcha, i think its more a personal preference. I like reading code and not having to remember assignments to letters or acronyms esp if it gets long. I'm fine going either way since your comments are also very clear.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The interest-rate solver returned a "no interest rate produces these values" warning for some solvable inputs, specifically when the correct rate exceeded 1,000% annual. This happened most often at high compounding frequencies. This PR switches the rate search to per-period space so the solver is frequency-independent, and adds a hard floor so solved rates at or below -100% are never displayed.
Problem
When solving for the interest rate, identical cash flows would solve at one compounding frequency and fail at another. Example:
Root cause
The solver scanned for a rate by looking for a sign change across a range, then bisecting. It scanned in annual-rate space and reused the input-field validation cap (
CONSTRAINTS.annualRate.max, 1,000%) as its search ceiling. That cap limits what a user may type into the rate field; it should never have limited what the solver can compute. The same per-period rate annualizes to a larger number at higher frequencies (243.27% weekly is the same underlying rate as 1,707.54% daily), so any correct rate above 1,000% fell outside the search window and was reported as unsolvable.Changes
g) rather than annual space. The per-period rate is frequency-independent, so the solver is equally capable at every compounding frequency and the scan resolution stays constant. The solvedgis annualized for display via a newgToAnnualhelper (the inverse of the existingannualToG). Both "same" and "different" payment-frequency modes are covered.Product decision
Per stakeholder sign-off: the rate input field stays capped at 1,000% to guard against typos, but the solved output is uncapped on the high side. A typed 1,707% is likely a mistake; a computed 1,707% is a real answer.
Note on the floor
The floor also closes a gap that predated this PR. The scan branch was implicitly bounded, but the
pmt === 0branch was not, so it could display rates below -100% at high compounding frequencies (for example around -1,374% for a daily case). Both paths are now covered.Testing
Verified against representative cases:
pmt = 0sub-100% case at daily compounding is now suppressed (previously showed roughly -1,374%)pmt = 0, FV 0 total-loss case still shows -100.00%No other calculator behavior changes. The
G_HIper-period ceiling (1,000% per period) preserves the solver's prior reach and is tunable if a tighter bound is ever wanted.Want this as a
.mdfile to attach to the PR, or is this good to paste into the description?