Adding inflation rate to numpy NPV calc - #788
Conversation
jaredthomas68
left a comment
There was a problem hiding this comment.
I think this is a good start. However, there are a few other related values that we should be aware of in our implementation and documentation to be clear and help users properly analyze the results. The rate used as shown should probably be the WACC, but that is not mentioned anywhere in the documentation. If we want discount rate to be the expected rate of return on equity, then we need to also request the debt rate the, the tax rate, and the debt/equity ratio (or debt-equity split).
| | --------------------------------- | ---------------- | ----------------------------------------------------- | ----------- | | ||
| | `plant_life` | `int` | Operating life of the plant in years. Must be ≥ 0. | — | | ||
| | `discount_rate` | `float` | Discount rate (0–1). | — | | ||
| | `discount_rate` | `float` | Discount rate (0–1). Can be either a real or nominal rate depending on how `inflation_rate` is specified. | — | |
There was a problem hiding this comment.
It might be more clear to specify if we want real or nominal if we are always adjusting with the Fisher equation. So, instead of discount_rate, call it real_discount_rate if we are always adding in inflation to the discount rate.
There was a problem hiding this comment.
The way we are using discount_rate, I think it should probably be the weighted average cost of capital (WACC) unless we are also getting the debt rate and debt/equity ratio and the tax rate as inputs.
There was a problem hiding this comment.
numpy NPV is a very simple NPV calculation - finance parameters like debt to equity ratio or debt rate are not included.
There was a problem hiding this comment.
Understood on your views here, Jared! I think we should do this renaming of discount rate across all models simultaneously outside of this PR so I've made an issue here: #812
I agree with Elenya that the numpy NPV calc is so simplistic that other values like WACC might not come into play. Are you suggesting that we have a different input into the numpy NPV model, either in value or name?
|
|
||
| 3. Discounting | ||
| - Each series of cash flows is discounted using NumPy Financial’s `npf.npv(discount_rate, values)`. | ||
| - Each series of cash flows is discounted using NumPy Financial’s `npf.npv(effective_rate, values)`, where `effective_rate = (1 + discount_rate) * (1 + inflation_rate) - 1` is the Fisher-equation combination of the user-supplied real (or nominal) discount rate and inflation rate. When `inflation_rate` is left at its default of 0, this reduces to `discount_rate`, so the user can supply either a nominal discount rate alone or split it into a real discount rate plus an inflation rate. The multiplicative (Fisher) form matches the way ProFAST combines its real discount rate and `general_inflation` inputs. |
There was a problem hiding this comment.
I think this discussion is slightly confusing. See my comment above about calling the input real_discount_rate.
Co-authored-by: Jared Thomas <jaredthomas68@users.noreply.github.com>
Allow user to provide inflation rate to NumPy Financial NPV model
Resolves #339.
inflation_rateinput toNumpyFinancialNPVFinanceConfig. Defaults to0.0, validator-constrained to[0, 1].discount_ratevia the Fisher equation(1 + r_eff) = (1 + discount_rate) * (1 + inflation_rate)to match how ProFAST combines its real discount rate andgeneral_inflationinputs, keeping the two finance backends consistent.inflation_rate=0the effective rate reduces todiscount_rate, so existing configs and tests don't change.Section 1: Type of Contribution
Section 2: Draft PR Checklist
Type of Reviewer Feedback Requested (on Draft PR)
Structural feedback:
(1 + r_eff) = (1 + discount_rate) * (1 + inflation_rate)because it's the exact relationship between real and nominal rates and is what ProFAST uses internally.Implementation feedback:
inflation_rateis validated withrange_val(0, 1)to mirrordiscount_rate. Let me know if a different range (e.g. negative inflation) should be allowed.Other feedback:
Section 3: General PR Checklist
docs/files are up-to-date, or added when necessaryCHANGELOG.md"A complete thought. PR XYZ", where
XYZshould be replaced with the actual number.Section 4: Related Issues
Fully resolves #339.
Section 5: Impacted Areas of the Software
Section 5.1: New Files
Section 5.2: Modified Files
h2integrate/finances/numpy_financial_npv.pyh2integrate/finances/test/test_numpy_financial_npv.pySection 6: Additional Supporting Information
N/A
For typical project finance rates (real 5%, inflation 4%), the multiplicative form gives
r_eff = 0.092vs. the additive0.09results in a 0.2 pp difference.Section 7: Test Results, if applicable
Ruff lint + format clean on the two modified files.
Section 8 (Optional): New Model Checklist
N/A