Skip to content

Fix Merton kurtosis formula, GARCH standard errors, LSM order parameter, and SciPy compatibility; add regression tests#27

Open
SatishRockzz wants to merge 1 commit into
cantaro86:masterfrom
SatishRockzz:audit-fixes
Open

Fix Merton kurtosis formula, GARCH standard errors, LSM order parameter, and SciPy compatibility; add regression tests#27
SatishRockzz wants to merge 1 commit into
cantaro86:masterfrom
SatishRockzz:audit-fixes

Conversation

@SatishRockzz

Copy link
Copy Markdown

Summary

This PR fixes several verified bugs found during a systematic audit of the package, and adds a small regression test suite that locks the fixes in. Each fix was confirmed numerically (hand-derivation + Monte Carlo cross-check) before being applied.

Math / inference fixes

  • Merton kurtosis (Processes.py): the excess-kurtosis formula used 3*sigJ**3 where the 4th cumulant of compound-Poisson-normal jumps requires 3*sigJ**4 (λ·E[J⁴] = λ·(μJ⁴ + 6μJ²σJ² + 3σJ⁴)). With (λ=0.8, μJ=0.1, σJ=0.5, σ=0.2) the old code returned 5.074; the true value is 2.635 (MC-confirmed 2.639). The sibling VG/NIG formulas were verified correct — this was a lone typo.
  • GARCH standard errors (Processes.py): the objective minimized in fit_from_data was 2× the true Gaussian NLL (missing ½ factor), so the Hessian-based standard errors were understated by √2 (~29%), narrowing CIs and overstating significance. The optimum (MLE) is unchanged; only inference scales. This also makes the objective consistent with the class's own log_likelihood method.
  • LSM order parameter (BS_pricer.py): the Longstaff–Schwartz order argument was silently ignored — np.polyfit was hardcoded to degree 2, so basis-order sensitivity studies returned identical results for every order. Now passed through. The error message for call options was also corrected (calls are unsupported, not "invalid type").

Compatibility / correctness fixes

  • scp.mean(...)np.mean(...) in all five MC pricers (scipy.mean was removed from SciPy years ago; the MC methods crash on any current SciPy). from scipy.linalg.misc import LinAlgErrorfrom scipy.linalg import LinAlgError.
  • mesh_plt in the Merton/VG/NIG pricers called self.PDE_price(...), which doesn't exist on those classes → self.PIDE_price(...).
  • elif "MM": in VG fit_from_data is an always-true string literal, silently routing unknown method names into method-of-moments → proper comparison plus an explicit ValueError for unknown methods.
  • probabilities.py: Q1/Q2 docstrings said P(X<k) while the integral computes P(X>k); corrected. Added a comment explaining the cf(-1.0000000000001j) normalizer (numerics untouched).

New tests (tests/test_regressions.py)

Codifies the cross-method checks the notebooks already perform interactively: kurtosis vs the cumulant formula, put–call parity to 1e-8, MC within 3 standard errors of the closed form (seeded), LSM order sensitivity (order=2 vs 4 now differ under identical seeds), Merton closed-form vs Fourier inversion. 5/5 passing on NumPy 2.5 / SciPy 1.18.

No behavior changes outside the fixes; all public APIs unchanged.

🤖 Generated with Claude Code

Fixes from a systematic audit (all numerically verified):
- Merton kurtosis: 3*sigJ**3 -> 3*sigJ**4 (correct 4th cumulant; was ~2x off)
- GARCH fit: objective now true NLL (0.5 factor) so Hessian-based standard
  errors are no longer understated by sqrt(2); optimum unchanged
- LSM: 'order' parameter now passed to polyfit (was hardcoded to 2);
  honest error message for unsupported call options
- scipy compat: scp.mean -> np.mean in all five MC pricers;
  scipy.linalg.misc import -> scipy.linalg (runs on current SciPy)
- mesh_plt in Merton/VG/NIG pricers: PDE_price -> PIDE_price (method exists)
- VG fit_from_data: always-true `elif "MM":` -> proper comparison + else raise
- probabilities: Q1/Q2 docstrings corrected to P(X>k); normalizer comment

New tests/test_regressions.py locks in: kurtosis vs cumulant formula,
put-call parity, MC-vs-closed-form agreement, LSM order sensitivity,
Merton closed-vs-Fourier. 5/5 passing on NumPy 2.5 / SciPy 1.18.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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