PyQuantLib Documentation¶
Modern Python bindings for QuantLib
PyQuantLib provides Python bindings for QuantLib, the open-source library for quantitative finance.
Motivation¶
There are existing Python bindings for QuantLib:
QuantLib-SWIG: official bindings generated using SWIG
PyQL: bindings implemented using Cython
Both are mature projects. However, they introduce an additional language beyond C++ and Python: SWIG’s interface definition language or Cython’s hybrid syntax. This increases cognitive load when navigating binding code or keeping wrappers in sync with upstream QuantLib.
PyQuantLib is built on pybind11, with all bindings written in standard C++. No intermediate DSL or code generation step.
Pythonic API¶
Pass Python types directly to functions:
result = ql.DotProduct([1, 2, 3], [4, 5, 6])
transposed = ql.transpose([[1, 2], [3, 4]])
date = ql.Date(15, ql.June, 2025) # or datetime.date(2025, 6, 15)
Zero-Copy NumPy Integration¶
Buffer protocol for efficient, bidirectional data exchange:
arr = ql.Array([1, 2, 3, 4, 5])
np_view = np.array(arr, copy=False) # shared memory, no copy
Developer Experience¶
No additional language beyond C++ and Python (no SWIG, no Cython)
Type-safe bindings resolved at compile time (signature mismatches fail at build, not runtime)
Debugging with standard C++ tools (no generated code obscuring the call stack)
Wrapper code mirrors QuantLib headers and class structure
IDE autocompletion via
.pyitype stubs
API Design¶
PyQuantLib preserves QuantLib’s domain model – class names, method names, and inheritance hierarchy – so that QuantLib documentation, textbooks, and community knowledge transfer directly to Python. But not everything in QuantLib’s API is a QuantLib concept. Handle<T> wrappers, builder method chaining, and Null<Rate>() sentinels are C++ idioms solving problems Python does not have. PyQuantLib replaces each with its Python equivalent: plain objects instead of handles, keyword arguments instead of method chaining, None instead of null sentinels.
See API Design for the full story.
Performance¶
PyQuantLib uses pybind11, which provides a thin, low-overhead C++/Python boundary. Function calls are dispatched directly to QuantLib’s C++ implementation, with no runtime code generation or reflection.
In practice, the dominant cost in typical QuantLib usage (pricing, curve construction, calibration) remains the underlying C++ computation, not the binding layer. Where applicable, PyQuantLib supports zero-copy data exchange with NumPy arrays.
As with any Python binding, performance-critical loops should remain in C++. PyQuantLib is designed to expose QuantLib’s APIs efficiently, while preserving Python’s productivity for orchestration, configuration, and analysis.
Features¶
Pythonic API: Implicit conversion, hidden handles, native
datetime.dateNumPy integration: Zero-copy data exchange via buffer protocol
Type hints: IDE-friendly with complete
.pyistubsPython subclassing: Extend QuantLib classes without C++ recompilation
Modern tooling: scikit-build-core, CMake presets, CI/CD ready
Quick Example¶
import pyquantlib as ql
# Set evaluation date
today = ql.Date(15, 6, 2025)
ql.Settings.evaluationDate = today
# Market data
spot = ql.SimpleQuote(100.0)
rate = ql.SimpleQuote(0.05)
vol = ql.SimpleQuote(0.20)
# Term structures (pass quotes directly, handles created internally)
dc = ql.Actual365Fixed()
risk_free = ql.FlatForward(today, rate, dc)
dividend = ql.FlatForward(today, 0.0, dc)
volatility = ql.BlackConstantVol(today, ql.TARGET(), vol, dc)
# Black-Scholes process (pass objects directly)
process = ql.GeneralizedBlackScholesProcess(spot, dividend, risk_free, volatility)
# European call option
payoff = ql.PlainVanillaPayoff(ql.Call, 100.0)
exercise = ql.EuropeanExercise(today + ql.Period("1Y"))
option = ql.VanillaOption(payoff, exercise)
# Price with analytic Black-Scholes
option.setPricingEngine(ql.AnalyticEuropeanEngine(process))
print(f"NPV: {option.NPV():.4f}") # 10.4506
print(f"Delta: {option.delta():.4f}") # 0.6368
print(f"Gamma: {option.gamma():.4f}") # 0.0188
print(f"Vega: {option.vega():.4f}") # 37.5240
print(f"Theta: {option.theta():.4f}") # -6.4140
Documentation¶
Getting Started
API Reference
Architecture
- Architecture
- Internals
- Design Notes
- API Design
- The Interpolation Binding Saga
- The Settings Singleton Mystery
- The Hidden Handle Pattern
- The Bridge Pattern Trap
- The Python Subclassing Challenge
- The Protected Member Problem
- The Enum Singleton Problem
- The Cross-Translation-Unit Holder Problem
- The Diamond Inheritance Problem
- The Builder Pattern
- The Reference Member Trap
Development
Links¶
GitHub: github.com/quantales/pyquantlib
QuantLib: quantlib.org
Issues: Report a bug
License¶
BSD 3-Clause License. See LICENSE for details.
Acknowledgments¶
QuantLib: Quantitative finance library
pybind11: C++/Python bindings
scikit-build-core: Build system