A pure-Java port of QuantLib — the de-facto open-source library for quantitative finance — being systematically rebuilt from C++ v1.42.1 with tier-stratified, cross-validated precision (EXACT / TIGHT / LOOSE) against the pinned C++ source.
Tip
📦 Released — JQuantLib 1.42.1.1 is on Maven Central.
Add it to any Java ≥ 25 project:
<dependency>
<groupId>cc.sosonline.jquantlib</groupId>
<artifactId>jquantlib</artifactId>
<version>1.42.1.1</version>
</dependency>Gradle: implementation("cc.sosonline.jquantlib:jquantlib:1.42.1.1"). Versioning: the first
three segments track the C++ QuantLib release the port targets; the fourth is the Java-port
revision (fixes between upstream releases). The publish process is documented in
RELEASING.md.
JQuantLib provides Java developers and quants with the mathematical, statistical, and modelling toolset needed to value equities, options, futures, swaps, fixed-income instruments, and a wide range of derivatives. It mirrors QuantLib's C++ API as closely as Java idioms allow, offering a smooth bridge for organizations running JVM-based pricing infrastructure.
The original Java port began ~2007, stalled in 2021, and is now being revived as a multi-phase, precision-first migration from C++ QuantLib v1.42.1.
PQuantLib is the Python sibling of JQuantLib — a 100%-Python port of the same C++ QuantLib v1.42.1, released on PyPI (repo: jlmoya/pquantlib). Both projects:
- Pin the same C++ ground truth (
v1.42.1@099987f0) - Use the same migration patterns (subagent-driven, worktree-parallel, tier-stratified tolerances, probe-based cross-validation, direct-to-main per cluster)
- Share the same
migration-harness/design (C++ submodule + probe directory + JSON reference values) - Pass the same test-suite scope (faithful ports of C++
test-suite/*.cppfiles)
The two projects are independent but borrow heavily from each other's plans; a bug surfaced in one port is checked in the other.
This is not a maintenance branch. It is a systematic, full-fidelity port with five operating principles:
| Principle | What it means in practice |
|---|---|
| C++ is source of truth | Where Java diverges from QuantLib v1.42.1 — signatures, implementations, constants, behavior — the Java code is updated to match C++. The pre-existing Java API is starting material, not a design to preserve. |
| Cross-validation before commit | Every functional change is backed by a C++ "probe" (a small program linked against the pinned QuantLib submodule) that emits reference values to JSON. Java tests load those JSONs and assert against them. No expected value is invented inline. |
| Tier-stratified tolerances | Comparisons land in one of three tiers — EXACT (bit-identical via Double.doubleToRawLongBits), TIGHT (abs 1e-14 + rel 1e-12), LOOSE (abs 1e-8 + rel 1e-8). Per-test exceptions require an inline written justification. |
| Bulletproof, not fast | Every commit compiles and passes the full suite. One stub fix = one commit. No --no-verify, no skipped hooks. Mid-port architectural divergence becomes a separate align(...) commit, never bundled. |
| Direct-to-main | Solo single-owner repo; no PR overhead. Each phase ends with a signed git tag (jquantlib-phase<N>-complete) and a completion document under docs/migration/. |
2026-05-29 — Full C++ v1.42.1 ql/ surface functional coverage. All 2024 C++ classes are accounted for via the reproducible audit migration-harness/check_coverage.py: 1933 ported & C++-cross-validated, 91 allowlisted with a written rationale (case-rename / inner-class / C++-template-idiom / traits-folded / commented-out-upstream), 0 unflagged. Full suite green (676 test classes / 3678 tests). Generic numerics are kept native by evidence — the C++ cross-validation pins internal algorithmic state (MINPACK fjac/fvec, exact Sobol, bit-exact transcendentals), so a different-algorithm library fails our existing tests; even the Levenberg–Marquardt lineage-match (Hipparchus) fails substitution. Nothing was re-baselined away from C++. This is functional coverage, not a 1:1-class claim. Detail: docs/migration/full-cpp-surface-completion.md.
2026-05-31 — Parity-safe performance optimization (observer registry). Profiling pinned the dominant cost in the slowest test (LiborMarketModelTest, ~537 s) not to the LMM math but to the Observable base class: DefaultObservable held observers in a CopyOnWriteArrayList, which copies its whole backing array on every register/unregister — O(n²) as observer lists grow during calibration. Replacing it with a plain ArrayList guarded by the instance monitor + snapshot-on-notify — preserving the exact iteration-during-mutation and multi-thread semantics CoW gave (ObservableTest.testMultiThreadingGlobalSettings), and touching zero floating-point — cut that test 537 s → 5.94 s (~90×) and the full suite from ~21 min to ~12 min, with all 3678 tests bit-identical. Commit 5baabea2; detail: docs/migration/perf-observer-optimization.md.
| Phase | Tag | What landed | Tests | Date |
|---|---|---|---|---|
| 1 | jquantlib-phase1-complete |
Finished 80 started stubs across 61 existing packages | — | 2026-04-24 |
| 2a | jquantlib-phase2a-complete |
MINPACK + LM, Heston QuadraticExponential, 56 numerical-suspect markers swept | 626/0/0/25 | 2026-04-24 |
| 2b | jquantlib-phase2b-complete |
One-factor model Parameter-ref refactor (Vasicek, HullWhite, BK, CIR), Simplex 1D, SABR sentinel fix | 632/0/0/22 | 2026-04-25 |
| 2c | jquantlib-phase2c-complete |
Chi-squared CDF + CIR.discountBondOption, SABR α-default, HullWhite latent items, BK tree-pricing | 649/0/0/22 | 2026-04-25 |
| 2d | jquantlib-phase2d-complete |
CapHelper via BlackCalibrationHelper, Heston NCCS scheme, SABR Halton via XABR | 649/0/0/22 | 2026-04-26 |
| 2e | jquantlib-phase2e-complete |
G2 model body (scanner WIP: 1 → 0), BlackCapFloorEngine, full Swaption infra (Black/Tree/Discretized), SwaptionHelper | 656/0/0/22 | 2026-04-26 |
| 2f | jquantlib-phase2f-complete |
Cap engines (Bachelier branch), G2.swaption integral, Heston BroadieKaya + NCCS tightening | 675/0/0/22 | 2026-04-26 |
| 2g | jquantlib-phase2g-complete |
Brent.solveImpl pre-loop alignment → +19 LOOSE→TIGHT promotions; FdHullWhite/FdG2 deferred to 2h on framework gap | 675/0/0/22 | 2026-04-26 |
| 2h | jquantlib-phase2h-complete |
Full Fdm* finite-difference framework (~3826 LOC, 30 classes); FdHullWhiteSwaptionEngine + FdG2 TIGHT 8.4e-15 (bit-exact) + bonus BicubicSpline Address-mapping fix |
677/0/0/22 | 2026-04-27 |
| 2i | jquantlib-phase2i-complete |
CORE-MATH correctly-rounded JQuantMath.exp; FdHullWhite tier LOOSE → within(3e-12); A3 finding (Apple libm not always correctly-rounded) |
684/0/0/22 | 2026-04-28 |
| 2i.5 | jquantlib-phase2i.5-complete |
JQuantMath.cos + .sin via Dint64 (u128 emulation); NCCS A19 partial — Math.log floor identified |
687/0/0/22 | 2026-04-28 |
| 2i.6 | jquantlib-phase2i.6-complete |
JQuantMath.log (CORE-MATH, 1203-case bit-exact first-shot); NCCS A19 re-fire pinned gammaFunction_.logValue Lanczos as actual residual |
688/0/0/22 | 2026-04-30 |
| 2j | jquantlib-phase2j-complete |
Gaussian1D family partial (P2J-10 trim): full model layer + 3 of 5 engines (Standard SwaptionEngine LOOSE, CapFloorEngine LOOSE, Jamshidian TIGHT) + 3 MF prereqs; Nonstandard + FloatFloat + MarkovFunctional deferred (4× A16 fires) | 792/0/0/22 | 2026-05-02 |
| 2j.5 | jquantlib-phase2j.5-complete |
Full Gaussian1D family completion: 5/5 engines + MarkovFunctional (split tier) + 4 niche-engine instruments + GaussHermiteIntegration family + AtmSmileSection + 11 align-fix commits | 801/0/0/22 | 2026-05-02 |
| 2k | jquantlib-phase2k-complete |
Gaussian1D feature completion: SabrInterpolatedSmileSection + BasketGeneratingEngine + TqrEigenDecomposition lifted + MF.CustomSmileFactory; all 4 MarkovFunctional smile branches operational | 809/0/0/22 | 2026-05-02 |
| 2l | jquantlib-phase2l-complete |
Fdm framework completeness: BiCGStab + GMRES + 6 new schemes (9 total) + Bermudan/American/dividend step conditions + vanillaComposite wiring + new math.ode package |
812/0/0/22 | 2026-05-02 |
| 2m | jquantlib-phase2m-complete |
3 Fdm-dependent vanilla engines (FdBlackScholesVanilla + FdHestonHullWhiteVanilla + FdSabrVanilla) + AndreasenHuge LocalVol family (3 classes). 8 commits across 4 parallel worktrees including 2 align prereqs. | 816/0/0/22 | 2026-05-08 |
| 2n | jquantlib-phase2n-complete |
JQuantMath.pow correctly-rounded via CORE-MATH cr_pow — 100% bit-exact (2,763/2,763 oracle cases). Qint64 (256-bit u128-pair) infra. 8 commits including 29-file/57-site Math.pow → JQuantMath.pow swap. JQuantMath now covers all 5 transcendentals: exp/log/sin/cos/pow. |
818/0/0/22 | 2026-05-08 |
| 2o | jquantlib-phase2o-complete |
HestonModel rho constraint aligned to C++ v1.42.1 (BoundaryConstraint(-1,1)); BlackFormula stdDevDerivative shifted-strike guards relaxed; SABRInterpolation.op + XABRInterpolationImpl pre-apply shift; SabrInterpolatedSmileSection Scenario C activated (21 cases LOOSE). |
818/0/0/22 | 2026-05-08 |
| 2p | jquantlib-phase2p-complete |
First subsystem-port phase — Inflation zero family. New package org.jquantlib.termstructures.inflation (InflationTraits + Interpolated/PiecewiseZeroInflationCurve + ZeroCouponInflationSwapHelper). New cashflow classes + ZeroCouponInflationSwap. Plus 2 align prereqs. Java inflation coverage 30% → 60%. |
822/0/0/22 | 2026-05-08 |
| 2q | jquantlib-phase2q-complete |
Inflation YoY + CPI + Seasonality + CapFlooredYoY closeout. 10 commits across 3 worktrees. Java inflation surface coverage 60% → 85%. | 832/0/0/22 | 2026-05-08 |
| 2r | jquantlib-phase2r-complete |
Inflation 100% core surface coverage. YoYOptionletVolatilitySurface family + 4 inflation cap/floor instruments + InflationCapFloorEngines (Black/UnitDisplaced/Bachelier) + 3 YoY optionlet pricers + FDNewtonSafe solver + YoYInflationIndex.fixing past-path align. 8 commits across 3 worktrees. Java inflation core surface 85% → 100%. | 853/0/0/22 | 2026-05-08 |
| 2s | jquantlib-phase2s-complete |
Experimental inflation closeout — Polynomial2DSpline + GenericIndexes + KInterpolated/Piecewise YoYOptionletVol + YoY Optionlet Stripper family + CPI/YoY CapFloorTermPriceSurface + InterpolatingCPICapFloorEngine. Inflation subsystem fully complete. | 888/0/0/22 | 2026-05-08 |
| 2t | jquantlib-phase2t-complete |
First test-suite phase under rigor directive — inflation.cpp ported (2,323 LOC → 31 @Test methods). InflationCommonVars test fixture + inflationPeriod sub-annual bug fix. | 919/0/0/40 | 2026-05-08 |
| 2u | jquantlib-phase2u-complete |
Inflation test-suite expansion (44%→86%): 4 cpp files ported + 5 L0 Phase 2x aligns + Track F body fills with 4 infrastructure aligns. 11 commits across 6 worktrees. | 933/0/0/37 | 2026-05-08 |
| 2v | jquantlib-phase2v-complete |
Inflation 100% (production + test-suite). CPIBond + 12 missing CPI index classes + GlobalBootstrap + lazy-baseDate ctor + YYIIS discount-curve overload + 2 remaining test-suite ports. 7 commits + 1 manual recovery. | 950/0/0/39 | 2026-05-08 |
| 2x | jquantlib-phase2x-complete |
Small infrastructure aligns + WeakReferenceObservable batched notification. mvn test wall-clock 30+ min → 59.5s (32x speedup). | 951/0/0/38 | 2026-05-08 |
| 3a | jquantlib-phase3a-complete |
First Phase-3 subsystem (greenfield credit termstructures): 3 abstract bases + FlatHazardRate + 3 interpolated curves + PiecewiseDefaultCurve + ProbabilityTraits + DefaultProbabilityHelper non-CDS + defaultprobabilitycurves.cpp test port. New package org.jquantlib.termstructures.credit. |
973/0/0/45 | 2026-05-08 |
| 3b | jquantlib-phase3b-complete |
CreditDefaultSwap instrument + Protection/Claim/FaceValueClaim + MidPointCdsEngine + 3 CDS helpers + creditdefaultswap.cpp test skeleton + 4 of 7 Phase 3a CDS-deferred tests un-ignored. | 1004/0/0/51 | 2026-05-08 |
| 3c | jquantlib-phase3c-complete |
IntegralCdsEngine + MakeCreditDefaultSwap + DateGeneration.CDS + Schedule rule + WeekendsOnly + IterativeBootstrap refinement. 7 of 8 deferred tests un-ignored. Drive-by fixes: Settings.TODAYS_PAYMENTS, InterpolatedDiscountCurve 2 bugs. | 1018/0/0/44 | 2026-05-09 |
| 3d | jquantlib-phase3d-complete |
IsdaCdsEngine (480 LOC sophisticated) + IterativeBootstrap config + Actual360(true) + 3 of 6 deferred un-ignores. Credit production 100% v1.42.1. | 1024/0/0/41 | 2026-05-09 |
| 3e | jquantlib-phase3e-complete |
DONE_WITH_CONCERNS — 4 pre-existing PiecewiseYieldCurve bugs fixed + 3 Markit test bodies fully ported (461 LOC). Tests stay @Ignore'd pending Phase 3f. | 1024/0/0/41 | 2026-05-09 |
| 3f | jquantlib-phase3f-complete |
Array(double[]) copy-vs-reference fix (Path A, 73 LOC). testIsdaEngine bootstrap drift improved 100× (~1% → 1.4e-4). | 1024/0/0/41 | 2026-05-09 |
| 3g | jquantlib-phase3g-complete |
Discount.maxValueAfter ungated negative-rates fix (key finding: bug was Discount traits, NOT IsdaCdsEngine). 2 EUR Markit tests un-ignored + passing. | 1062/0/0/38 | 2026-05-09 |
| 3h | jquantlib-phase3h-complete |
First marketmodels (LMM) slice — Track A (Utilities + EvolutionDescription + CurveState + 3 curvestates + 4 drift calculators) + Track B (3 correlations + MTBrownianGenerator + AccountingEngine + MarketModelDiscounter + MultiProduct + Evolver align). MersenneTwisterUniformRng latent unsigned-long bug fixed. New packages: org.jquantlib.model.marketmodels.*. ~3,600 LOC C++ ported. 7 commits across 2 parallel worktrees. |
1087/0/0/38 | 2026-05-09 |
| 3i–5e.5b | jquantlib-phase5e5b-CFC-c-checkpoint |
Rolled-up retro for the 545-commit gap — see docs/migration/phase3i-through-5e5b-rolledup-completion.md. Covers Phase 3i+ marketmodels evolvers/products/callability, Phase 4a-4o.5 ql/experimental/ ports (~63K LOC C++), Phase 5a-5e.5b test-suite/ ports (~79K LOC C++ scope). Per-sub-phase completion docs slipped Phase 3i+; resumes from 5e.5b-CFC-c onward. |
2959/0/0/598 | 2026-05-14 |
| 5e.5b-CFC-c | jquantlib-phase5e5b-CFC-c-checkpoint |
align(time.Schedule) post-BDC dedup fix in Backward/Forward loops (mirrors C++ schedule.cpp:229-233 / :326-330). Root-caused via probe-instrumentation diff after BlackON cap/floor body-fills surfaced 6.7e-7 drift. 20-LOC fix unblocked 2 tests; no regression across 2957 other tests. New BlackON diagnostic probe added. |
2959/0/0/598 | 2026-05-14 |
| 5e.5b-CFC-d | jquantlib-phase5e5b-CFC-d-checkpoint |
OvernightLeg structural body-fills + Schedule characterization tests + align(time.calendars) Juneteenth port to GovernmentBondImpl + new Market.SOFR + SofrImpl. Surfaced latent Juneteenth bug — helper existed but never wired into GovernmentBond. Plus overnight_leg_caps_floors probe with cross-validated NPV. testOvernightLegWithCapsAndFloors @Ignore'd pending Cubic-extrapolation root cause. |
2961/0/0/594 | 2026-05-14 |
| 5e.5b-CFC-d-final | jquantlib-phase5e5b-CFC-d-final |
Continuation of CFC-d: Juneteenth wired into all 3 main US calendars (Settlement/NYSE/GovernmentBond). BlackFormula forward-derivative + RS/Chambers ports (5 new tests). AmortizingFixedRateBond body-fill (1). FixedRateBond/FixedRateLeg arbitrary-schedule support (1). InterpolatedZeroCurve flat-forward extrapolation fix closed the residual 2.7e-7 drift; testOvernightLegWithCapsAndFloors now PASSES (1). Surefire JVM heap 2g eliminated NoClassDefFoundError flakiness. Plus body-fills: MultipleResetsCouponsTest (2), MultipleResetsSwapTest (3), ZeroCouponSwapTest (6). | 2961/0/0/575 | 2026-05-14 |
| CFC-d-181 → 321 sweep | (untagged — on main) |
**Massive @Ignore-clearing sweep across ~180 commits via ~50 parallel background agents. Foundational align fixes: Period.eq/le/ge/neq strict-unit comparison (CFC-d-318); Distribution constant-dx invariant (CFC-d-319); SinCosKernel sin(±Inf) → NaN parity (CFC-d-295); InflationCapFloor cached values refreshed under A3 carve-out (CFC-d-321). Production landings: MCLookback, MCEuropeanGjrGarch, GjrGarchModel/Process/AnalyticEngine, VarianceSwap/MC/Replicating, DiscountingPerpetualFutures, FlatHazardRate, Brlcdi/Business252, StochasticCollocationInvCDF, AdaptiveRungeKutta 1D/Complex, Concentrating1dMesher, TridiagonalOperator SOR, SVD wide-matrix, IncrementalStatistics Welford, FdBlackScholesVanillaEngine localVol, LocalVolSurface Dupire, ProjectedConstraint, HullWhite.FixedReversion, NoArbSabrModel + D0Interpolator + absorption tables, VannaVolgaBarrier + DoubleBarrier engines, FdExtOUJumpVanilla + FdSimpleExtOUStorage, VanillaStorageOption, LFM Sobol LDS, FFTVarianceGamma, TreeVanillaSwap, Swaption(OIS), BlackSwaptionEngine OIS, CappedFlooredCmsCoupon, CEVRNDCalculator delta>=2, MCEuropeanHeston SLV, SabrSwaptionVolatilityCube (919 LOC), HestonStochasticLocalVolProcess.evolve, FdmHestonExpressCondition, DigitalOption Greeks bumping, CatBondAdditional, Asian Average-Strike engines, Heston calibration, SABR FlochKennedy, XABR ParameterTransformation, GemanRoncoroniProcess MC, HHHW testCallableEquityPricing, HHW testHestonHullWhiteCalibration, CmsNormal.testFairRate, AssetSwap.specializedBond, CallableFixedRateBond ex-coupon ctor, FdHestonVanilla leverageFct, HestonSLV LocalVol. End state: all 138 initial @Ignore annotations cleared. |
3010/0/0/1 | 2026-05-20 |
| Path A — Phase 1 closure (D5) | (untagged — on d5-D-marketmodel worktree) |
**Post-certification-audit D5-RED → essentially GREEN remediation. 16 of 17 prereq TODOs closed across rounds A1–A6 (~135 commits, ~15,000 LOC of production code, ~200 net @Test methods added). Production-port landings: QdPlus + QdFp American engines (12 schemes), AbcdCalibration + MarketModelTestSetup, CotSwapFromFwdCorrelation, MultiCompositeQuote + CompositeInstrument, calendar greenfield (Russia/Israel/Mexico/NZ/SouthKorea/Denmark/China.SSE+IB), daycounter ports (Thirty365/Actual366/Actual36525/Actual364, ECB+ASX helpers, ActualActual ISMA_Impl, DateParser strftime), Array(size,start,step)+resize, FFTVanillaEngine, FdBlackScholesShoutEngine, FdBlackScholesBarrierEngine + escrowed dividend model, NelsonSiegel (weights,opt,l2) ctor, InterpolatedPiecewiseForwardSpreadedTermStructure, BondHelper bond-helper fitting, ExpSinhIntegral + FilonIntegral + TwoDimensionalIntegral + TanhSinhIntegral, GenericLongstaffSchwartzRegression + ProxyGreekEngine, ConstantLossModel, GlobalBootstrap, BjerksundStenslandApproximationEngine v1.42.1 rewrite, AnalyticEuropeanEngine (process,discountCurve) ctor + dispatch. 6 latent production bugs found & fixed via faithful porting: (a) AndreasenHugeVolatilityInterpl put/call payoff swap — latent since 2007 port (commit 958afc29); (b) TanhSinhIntegral missing level-0 integer-multiple nodes (commit 844d75ed); (c) MethodOfLinesScheme missing bcSet.setTime() call (commit 214f7b8a); (d) PathwiseVegasOuterAccountingEngine Jacobian transpose (commit 462b8456); (e) QdPlusAmericanEngine xMax NaN-at-spot-0 (commit b8f4d88a); (f) Money.greater/greaterEqual infinite-recursion (commit 35510f03). Residual ~75–80 still-genuinely-missing-by-name tests catalogued in phase1-closure-remaining.md. |
3213 methods / 0 fail (in-progress) | 2026-05-20 |
| Phase 1 genuine closure (JDK 25) | jquantlib-phase1-complete-jdk25 (0e72b77a) |
Closed P1.1/P1.2/P1.3/P1.4 carve-outs on JDK 25 LTS base. MultiCurve + LocalBootstrap + GlobalBootstrap + SpreadBootstrapTraits + InterpolatedSpreadDiscountCurve + PiecewiseSpreadYieldCurve + ConvexMonotone helper hierarchy + AverageBMALeg + multiple marketmodel test ports. Missing-by-name vs C++ v1.42.1 test-suite: 0. 20+ latent production bugs surfaced and fixed. Memory leak hypothesis (#565) resolved as external corrupted node_modules. | 3270/0/0/24 | 2026-05-22 |
| JDK 25 modernization W1-W4 | jquantlib-jdk25-modernized-w1-w4 (683bf14e) |
JDK 25 LTS upgrade (source/target/release 25, surefire 3.5.2, junit 4.13.2, slf4j 2.0.16) + 4-wave syntax modernization. W1 cosmetic (312 var + 1327 diamond / 367 files); W2 pattern matching + switch expressions (74 instanceof + 52 switch + 5 switch-with-patterns / 105 files, -361 LOC); W3 records for DTOs (15 records, -385 LOC); W4 sealed type hierarchies (Exercise/Payoff/Dividend + nits). Each wave: implementer → spec-compliance reviewer → code-quality reviewer → fix-up → FF. W5 virtual threads + W6 Vector API deferred (no existing Executor / Vector API still incubator on JDK 25). | 3270/0/0/24 | 2026-05-22 |
| Phase 2 forward closure — L1 | jquantlib-phase2-l1-complete (899f60e7) |
math/utilities/time/patterns layer. 5 clusters L1-A..E: time + simple math pilot (6 calendars + OneDayCounter + BernsteinPolynomial + PascalTriangle), 13 copulas + Copula SAM (probe-validated), 12 optimization + RNGs (bit-exact MT(42) probes), 25 distributions/integrals/stats/matrixutils/ode, math root + interpolation factories. Bonus production fix: CubicInterpolation Akima derivative (was throwing "not implemented yet"). | ~3370+/0/0 | 2026-05-22 |
| Phase 2 forward closure — L2 | jquantlib-phase2-l2-complete (6f6ecf22) |
termstructures + indexes layer. 4 clusters L2-A..D: 11 indexes (BBSW + Aonia + root), 7 termstructures/yield (CPIBondHelper, FxSwapRateHelper, 4 fitting methods), 6 ZABR family via sealed interface + AtmAdjustedSmileSection, 26 indexes/ibor remainder (multi-currency). RUBCurrency added. | ~3420+/0/0 | 2026-05-22 |
| Phase 2 forward closure — L3 | jquantlib-phase2-l3-complete (3c5c3862) |
instruments + pricingengines layer. 4 clusters L3-A..D: 14 instruments + 9 SKIP (StickyRatchet/YoY/FixedVsFloatingSwap), 7 Italian bonds (BTP/CCTEU/Rendistato), 5 swaption family (G2SwaptionEngine, BlackStyleSwaptionSpec sealed), 34 + 1 SKELETON pricingengines Make-factories + MC engines. Bonus fixes: FellerConstraint replaces broken VolatilityConstraint stub (L4-A); Vasicek.r0() public accessor. | ~3500+/0/0 | 2026-05-22 |
| JQuantLib migration complete | jquantlib-migration-complete (4549eb7f) |
Phase 2 L4 + L5 closure. L4 11 classes (FellerConstraint + Brownian generators + Gaussian1d CachedSwapKey record + historical analysis). L5 mostly triage with aggressive SKIP-with-rationale: RecursiveLossModel + FdOrnsteinUhlenbeckVanillaEngine ported, all others either already-present, v1.42.1-deprecated, or no-Java/no-C++-caller (see phase2-skips-audit.md). 5 latent production bugs surfaced and fixed during Phase 2. C++ v1.42.1 → Java JDK 25 LTS migration certified. |
3531/0/0/24 | 2026-05-22 |
| Phase 2 SKIPs resolved | jquantlib-phase2-skips-resolved (205f8b4b) |
Per user decision, ported all 13 Category D + E items from the SKIPs audit. D1: CubicInterpolation Harmonic/SplineOM1/SplineOM2 + 4 factories. D2: AbcdInterpolation wrapper. D3: 5 vol-cube classes + SabrSwaptionVolatilityCube hook refactor. D4: HybridSimulatedAnnealing + 16 functors. E1: FdBlackScholesAsianEngine SKELETON → functional. 5 sub-clusters across 5 worktrees. Known deferred SKIP-E1-FOLLOWUP: FdBlackScholesAsianEngine multi-fixing accuracy (~50% drift vs Levy 1997, single-fixing-vs-vanilla agreement proves rollback+mesher correct). | 3569/0/0/24 | 2026-05-23 |
| Phase 2 L6 (test-suite parity) | jquantlib-phase2-l6-test-suite-parity-complete (1ffd209f) |
Test-suite parity round. L6-A: stats + riskstats ports (5 @Test). L6-B: InflationCapFlooredCouponTest (2 tests, 840 sub-cases). L6-C: 4 marketmodel SMM tests confirmed already-ported. L6-D: commodityunitofmeasure + cdsoption (2 tests). align(math.statistics) bonus: 3 production-side bugs in GenericRiskStatistics killed (regret Expression→ComposedFunction, averageShortfall predicate Bind1st→Bind2nd, shortfall Clipped→lambda) + GaussianStatsHolder for GenericGaussianStatistics typedef parity. 3 latent production-bug fixes from L6 alone, 8 in total this Phase 2 session. Plus aggregator distributionManagement fix (mirrors jquantlib-parent for mvn deploy from repo root). |
3574/0/0/24 | 2026-05-23 |
| Phase 2 complete | jquantlib-phase2-complete (3d005e9c) |
SKIP-E1-FOLLOWUP closed. Root cause was a test-fixture transcription error (q↔r swap) in the original SKIP-E1 smoke test — engine was correct all along, proven by standalone C++ probe at same swapped setup yielding bit-identical NPVs to Java. All 5 Levy 1997 reference cases pass at 3-4e-3 (well inside 2.0e-2 ceiling). Test-only fix; no production code touched. Phase 2 forward closure declared genuinely complete with zero deferred items. | 3574/0/0/24 | 2026-05-23 |
| JQuantLib truly complete | jquantlib-truly-complete (54ca6d72) |
Phase 3 closure addressing ~115 pre-existing pending items from the 545-commit Phase 3i-5e.5b rolled-up period. 5 sub-clusters: P3-A Fdm toMatrix() (5 PORT sum-of-decomp + 1 DESIGN-INTENT FdmBatesOp QL_FAIL parity); P3-B mcbasket MultiPath Phase 4i.5 closure (all 5 UOE throws closed + 2 cross-val tests); P3-C 19 Coupon cap/floor stubs DESIGN-INTENT per C++ aggregate-rate base + relocated base→subclass + 25 tests; P3-D 47 PORT + 13 DESIGN-INTENT + 1 BLOCKED (PseudoSqrt Hypersphere ConjugateGradient hang — routes to Higham/Principal) + 4 latent bug fixes (TimeGrid(Array) 3 + 21-LIBOR/DiscountingBondEngine dummy-handle pattern); P3-E true @Ignore count = 2 (not 42; 40 were JavaDoc/import noise), 3 stale-calendar tests deleted (-1075 LOC), 29 import cleanups, 2 KEPT-with-rationale (AndreasenHuge A3 precision + BermudanTreeDiagJavaProbe diagnostic). 4 more latent production-bug fixes (12 total this whole session). | 3613/0/0/24 | 2026-05-23 |
| Phase 3-F TODO/FIXME triage | (4 commits, last bf80e089 and the inline 2f58a064) |
Audit + aggressive cleanup of the 835 TODO/FIXME/XXX marker occurrences across production code. P3F-A: 378 stale '// TODO: message' tags after QL.require msgs (mechanical sweep, 131 files). P3F-B: 73+ XXX::OBS / XXX:registerWith observer-cleanup leftovers (-304 LOC, 43 files). P3F-C: ~91 vague FIXME author opinions + concrete fixes (DynamicProxyInvocationHandler reflection-chain deletion fulfilling 18-year @Richard-Gomes FIXME; SobolRsg 1L = 1L; <<= shift collapsed to single C++-idiom expression). P3F-D: 217+ TODO Auto-generated method stub + 'Check with Richard' (Richard left ~2021) + dead bug-tracker URLs. P3F-final: 13 trailing markers inline. Final state: 835 → 13 (98.4% cleanup); the 13 KEPT are legitimate Phase-deferral references (Phase 4o.5 EnergySwap, Phase 4i.5 IrregularSwaption, Phase 5d.5 IborLeg JavaDoc), CORE-MATH provenance notes (LogKernel + PowKernel UB documentation), explicit upstream-C++ FIXME documentation (OneFactorStudentCopula + ExponentialForwardCorrelation), JavaDoc placeholder patterns, and journal page-range citations. |
3613/0/0/24 | 2026-05-23 |
| Console-noise cleanup | (5 commits: de95bb17, 3282157f, 1a97b04f, 642fdeca, 14086930) |
Eliminated all stderr-flood + compile-warning noise during test runs. LibraryException constructors no longer call QL.error(this) (was unconditionally dumping ERROR + stack trace for every constructed instance — including ones caught for fast-path/slow-path control flow like LfmCovarianceProxy.integratedCovariance → numerical fallback, IterativeBootstrap retries, observer-failure chains). DefaultObservable.notifyObservers observer-failure log now routes via SLF4J WARN (configurable) instead of QL.error → stderr. 78 @SuppressWarnings({"deprecation","unchecked"}) annotations on legitimate-internal-use sites (Array/Matrix subclasses accessing Cells.$ raw backing, generic-erasure casts after Class.newInstance(), raw-type bridge code). |
3610/0/0/21 | 2026-05-23 |
| JQuantLib FINAL | jquantlib-final (4c93962a) |
Final state pointer — re-pointed 2026-06-03 to the current tip. Now subsumes the full C++ v1.42.1 ql/ surface functional-coverage milestone (0646ee75), the parity-safe observer-registry perf optimization (5baabea2, suite wall BlackScholesDividendLattice escrowed-spot fix (f4bad451/4c93962a, converges to QuantLib AnalyticDividendEuropeanEngine). Re-verified green: mvn -pl jquantlib test = Tests run 3719, Failures 0, Errors 0, Skipped 21, BUILD SUCCESS on JDK 25 LTS. Only main remains (all worktrees + transient branches removed local+remote). |
3719/0/0/21 | 2026-06-03 |
Current state. Anchored on the full-surface functional-coverage milestone 0646ee75 (tag jquantlib-cpp-surface-functional-coverage; tag jquantlib-final @ 4c93962a). Since then:
- Parity-safe perf — observer-registry optimization
5baabea2(Date.clonecandidate profiled and declined; seedocs/migration/perf-observer-optimization.md). BlackScholesDividendLatticeescrowed-spot fix (f4bad451/4c93962a).- FD American discrete-dividend engine fix —
FDDividendAmericanEnginehad silently ignored discrete dividends (a phantom-generic porting bug); now correct and cross-validated. Seedocs/migration/fd-dividend-american-fix.md. jquantlib-showcase— a new interactive Spring Boot demo app (see Showcase).
Suite: mvn -pl jquantlib test = 3721 tests / 0 failures / 0 errors / 21 skipped, BUILD SUCCESS on JDK 25 LTS. Scanner WIP-stub count: 0 genuinely-pending. JDK: 25 LTS. Repo hygiene: only main remains (no worktrees or transient branches).
3 documented carve-outs (explicit; NOT silent deferrals):
- PseudoSqrt Hypersphere/LowerDiagonal —
hypersphereOptimizeis ported (from C++pseudosqrt.cpp:141-263); JavaConjugateGradientdoesn't converge on the ill-conditioned target. UOE replaced with descriptive deferred-port message routing users toHigham/Principalalternatives. Closure requires Java optimizer hardening pass. - AndreasenHugeVolatilityInterplTest#testFlatVolCalibration — A3 precision finding: observed residual range
2e-9..3e-8vs spec1e-10. Per CLAUDE.md, not loosening tolerance. Closure requires production-side LM/TridiagonalOperator precision work. - BermudanTreeDiagJavaProbe — class-level
@Ignoreas legitimate diagnostic probe (not a regression test).
13 latent production-bug fixes surfaced and fixed this session: see docs/migration/phase2-skips-audit.md and docs/migration/phase2-L6-completion.md for full details.
Phase 1 certification audit — 2026-05-20: D1 YELLOW (suite green 3010/0/0/1 in 17m23s; ~45 slow-test gates pending discussion), D2 / D4 GREEN, D3 / D6 AMBER (now remediated), D5 RED (280 missing C++ tests across 49 files — under active remediation). Pre-Phase-2 NO-GO until D5 closes.
Each phase has a binding design doc, an executable plan doc, a progress log, and a completion doc — all under
docs/migration/.
Every phase follows a uniform shape, refined since Phase 2a:
brainstorm → design → plan → execute (subagent-driven) → review → tag → memory
A binding spec (docs/migration/phase<N>-design.md) is approved before any code is written. Sections include scope (in/out), approach comparison, worktree topology, tolerance & probe discipline, pause triggers (A1–A19), decision log.
A bite-sized, checkbox-tracked task list (docs/migration/phase<N>-plan.md) with exact file paths, code snippets, and expected test-count deltas per task. No "TODO" or "TBD" — every step is concrete.
Each phase runs across 2–4 git worktrees (named jquantlib-<phase>-A, -B, -C, ...). A controller dispatches one fresh subagent per task with two-stage review:
- Spec compliance review — does the code match the spec exactly?
- Code quality review — strengths, blockers, and improvements.
Independent worktrees run in parallel; dependent ones serialize.
Eighteen-and-counting documented conditions where the controller stops and asks the human. The most consequential have been:
- A3 (reference is itself wrong) — fired in Phase 2i; Apple libm
std::expshown not always correctly-rounded; resolution = use CORE-MATHcr_expdirectly as oracle. - A4 (needs new class outside scoped packages) — fired in Phase 2e (Swaption was a near-empty stub) and 2g (Fdm framework absent), each cleanly redirected.
- A13 (transcendental ULP slack) — fired in Phase 2f; led to Phase 2i's CORE-MATH transcendental track.
- A19 (post-swap tier promotion fails) — fired in Phase 2i (FdHullWhite — non-transcendental floor) and Phase 2i.5 (NCCS — Math.log floor); each pinpoints the next residual to address.
Phase ends with git tag -a jquantlib-phase<N>-complete, a completion doc, and a refresh of long-lived project memory.
A recurring discovery from Phase 2f onwards: the JVM's java.lang.Math transcendentals carry up to ~1 ULP of slack relative to a correctly-rounded reference. That slack compounds through Fourier inversions, ADI schemes, and root-finders, and limits how tight an EXACT-tier comparison can ever be.
Phase 2i and 2i.5 attack the floor head-on by porting CORE-MATH — an academic correctly-rounded transcendental library (BSD/MIT, Sibidanov et al., Inria) — into a new package org.jquantlib.math.transcendental.JQuantMath.
| Primitive | Status | Source | Note |
|---|---|---|---|
JQuantMath.exp |
✅ Phase 2i | CORE-MATH src/binary64/exp/exp.c |
Bit-exact across 508 probe cases including all 51 hard-cases DB entries |
JQuantMath.cos |
✅ Phase 2i.5 | CORE-MATH src/binary64/cos/cos.c |
Bit-exact across 1,381 probe cases incl. Payne-Hanek stress through 2^50·π |
JQuantMath.sin |
✅ Phase 2i.5 | CORE-MATH src/binary64/sin/sin.c |
Bit-exact across 1,376 probe cases |
JQuantMath.log |
✅ Phase 2i.6 | CORE-MATH src/binary64/log/log.c |
Bit-exact across 1,203 probe cases first-shot. Sister long[4] dint64-style helpers (log_dint.h is bit-incompatible with sin/cos's dint.h) |
JQuantMath.pow |
✅ Phase 2n | CORE-MATH src/binary64/pow/pow.c |
Bit-exact across 2,763 probe cases. Stage-1 doubles + Stage-2 Dint64 Ziv chain (Stage-3 Qint64 deferred — no oracle case demands it). Production-wired at 29 files / 57 sites. |
JQuantMath.lgamma |
❌ Blocked | No correctly-rounded source available | CORE-MATH does not have lgamma; msun/glibc options either non-correctly-rounded or license-incompatible. NCCS EXACT remains blocked. |
Two supporting types in org.jquantlib.math.transcendental emulate the C source's extended-precision integers:
Dint64— emulatesunsigned __int128(dint64_tin CORE-MATH source). Package-private; validated across 100 probe cases. Used byLogKernel(log),SinCosKernel(sin+cos), andPowKernel(pow stage-2 Ziv chain).Qint64— emulates 256-bit u128-pair arithmetic (qint64_t). Package-private; validated across 322 probe cases / 16 ops. Foundation for pow's stage-3 Ziv (deferred — not exercised by current oracle) and any futurelgammaport.
This was a hard-won lesson:
- JVM
Math.exp(HotSpot) ≈ 1-ULP slack - FreeBSD msun
e_exp.c≈ same 1-ULP slack as JVM (Phase 2i pre-pivot BLOCKED finding) - Apple libm
std::exp(macOS arm64) — almost correctly-rounded but not provably so; ~50/2^64 hard cases are still 1 ULP off (Phase 2i A3 finding, verified via 300-bit mpmath) - CORE-MATH
cr_exp— correctly-rounded by design across all IEEE-754 rounding modes
Probe oracles for transcendentals therefore #include "coremath/exp.c" directly and call cr_exp(x) — not the platform <cmath>.
| Resource | Detail |
|---|---|
| Pinned C++ submodule | QuantLib v1.42.1 @ 099987f0ca2c11c505dc4348cdb9ce01a598e1e5 |
| Migration harness | migration-harness/ — CMake-built C++17 probes linked against the submodule |
| Probe references | migration-harness/references/ — JSON files keyed by test_group, consumed via ReferenceReader |
| Java module under port | jquantlib/ (Maven; Java 11; JUnit 4) |
| Stub scanner | tools/stub-scanner/scan_stubs.py — emits docs/migration/stub-inventory.json and worklist.md |
| Phase docs | docs/migration/ — design, plan, progress, completion per phase |
jquantlib/ ← this repo root
├── jquantlib/ ← Maven module under active port
│ ├── src/main/java/org/jquantlib/ ← production code
│ │ └── math/transcendental/ ← Phase 2i-2n (JQuantMath, ExpKernel, LogKernel, SinCosKernel, PowKernel, Dint64, Qint64)
│ └── src/test/java/ ← JUnit 4 tests cross-validated against probes
├── jquantlib-helpers/ ← helper classes
├── jquantlib-contrib/ ← third-party contributions
├── jquantlib-samples/ ← sample applications
│
├── migration-harness/ ← C++ ground-truth scaffolding
│ ├── cpp/
│ │ ├── CMakeLists.txt
│ │ ├── quantlib/ ← pinned QuantLib v1.42.1 submodule
│ │ └── probes/ ← per-feature C++ probes emitting JSON
│ │ └── transcendental/
│ │ └── coremath/ ← vendored CORE-MATH algorithm sources
│ ├── references/ ← generated reference JSONs
│ ├── setup.sh / generate-references.sh / verify-harness.sh
│ └── README.md
│
├── docs/migration/ ← phase design, plan, progress, completion docs
├── tools/stub-scanner/ ← Python scanner for in-progress stubs
└── README.md ← (this file)
# Test the Java module (run from the inner module — not the root)
cd jquantlib && mvn test
# Expected: Tests run: 3721, Failures: 0, Errors: 0, Skipped: 21
# Snapshot the stub scanner
python3 tools/stub-scanner/scan_stubs.py
# Expected: 0 stubs
# Verify the C++ harness is functional
./migration-harness/verify-harness.sh# (re-)build the C++ harness and emit all references/*.json
bash migration-harness/setup.sh
bash migration-harness/generate-references.shmvn clean verify install
# Sample apps live under jquantlib-samples/The repo includes jquantlib-showcase/, an interactive Spring Boot web application
that demonstrates the library in the browser: option pricing with live Greeks, a
cross-engine comparison (closed-form, lattice, finite differences, Monte Carlo), Monte
Carlo convergence (pseudo-random vs Sobol), implied volatility, barrier / Asian /
discrete-dividend exotics, fixed-rate bonds, interpolated yield curves, market calendars,
and a live runner for the bundled jquantlib-samples programs.
# 1. One-time: install the library artifacts into your local Maven repo (from the repo root)
mvn -pl jquantlib,jquantlib-helpers,jquantlib-samples -am install -DskipTests
# 2. Run the showcase
cd jquantlib-showcase
mvn spring-boot:runThen open http://localhost:8080. Alternatively, build a self-contained jar and run it:
cd jquantlib-showcase
mvn -DskipTests package
java -jar target/jquantlib-showcase-1.0.0.jarRequires JDK 25; uses the latest Spring Boot 4.0.x. Front-end libraries are vendored,
so it runs fully offline. Full demo list and architecture:
jquantlib-showcase/README.md.
Phase 2n ✅ complete — JQuantMath.pow correctly-rounded (100% bit-exact 2,763/2,763 vs CORE-MATH cr_pow); Qint64 256-bit infra; 57-site production swap. JQuantMath now covers all 5 transcendentals: exp/log/sin/cos/pow. The next priorities, in autonomous-mode dispatch order:
- HestonModel rho constraint align —
PositiveConstraint→BoundaryConstraint(-1,1)to match C++ v1.42.1 (Phase 2m Track B carry-forward) - AndreasenHuge calibration — Phase 2m Track D ported the surfaces but not the calibration loop
- SABRInterpolation shifted-strike support — Phase 2k Track A Scenario C unblocker
U128.javashared util — consolidate u128 helpers acrossDint64,Qint64,LogKernel,PowKernel,GaussianQuadrature.TqrEigen- Douglas ADI / FdmAffineModelTermStructure — FdHullWhite real floor (Phase 2i WI-2 B-1 A19)
- PowKernel stage-3 (Qint64 chain + exact_pow) — only if a future test surfaces a hard-rounding case stage-2 fails
JQuantMath.lgamma— still blocked; CORE-MATH has no lgamma. NCCS EXACT path still gated on this.- C++ test-suite Java equivalents — every C++ engine test deserves a Java equivalent (~150-200K LOC of tests)
- Phase 3+ subsystems —
experimental/,models/marketmodels/,termstructures/credit/,inflation/
Binding exit criterion: every C++ class, function, header, and test from QuantLib v1.42.1 has a faithful Java equivalent. Realistic path to "done" is ~50-100+ phases.
| Module | Role |
|---|---|
jquantlib-parent |
Root parent POM + aggregator (lives at the repo root) |
jquantlib |
Main module — the library itself (mirrors QuantLib/C++). Published to Maven Central as cc.sosonline.jquantlib:jquantlib |
jquantlib-helpers |
Helper classes |
jquantlib-contrib |
Third-party contributions |
jquantlib-samples |
Sample code |
jquantlib-showcase |
Interactive Spring Boot demo web app (see Showcase) |
This repository is currently a single-owner, direct-to-main migration project. Outside contributions are welcomed via issues, but the operational model assumes one engineer driving the port through subagent-assisted pipelines. If you'd like to help with a specific package or audit a phase, open an issue first to coordinate.
JQuantLib is released under the BSD License — see LICENSE.TXT. Vendored CORE-MATH source files retain their original MIT license headers under migration-harness/cpp/probes/transcendental/coremath/.