Skip to main content

Bismut-Elworthy-Li Malliavin weights for Monte Carlo Greeks: Rust core, Python API

Project description

elworthy

CI crates.io PyPI docs.rs license

Why elworthy over Numba

Numba @njit is excellent for general-purpose Python loop acceleration. Where elworthy is unique:

Property Numba pathwise elworthy BEL
Smooth payoff delta (call) correct, fast correct, ~equal speed
Digital / barrier delta silently returns 0 (Dirac in f') unbiased, hits analytic within stderr
Weight derivation user writes the integrator symbolic synthesis from the SDE
Output type Numba arrays (no autograd) plain NumPy → Torch / JAX backprop free

Demo: python python/benchmarks/demo_digital_payoff_correctness.py shows Numba pathwise digital delta = 0.000 (bias -0.0197) vs elworthy BEL 0.0198 (bias +0.0001) against analytic 0.0197.

A Rust JIT compiler that specialises Bismut-Elworthy-Li formulas into SIMD kernels for unbiased Monte Carlo Greeks on non-stationary SDEs. Python bindings ship on PyPI: pip install elworthy. The Python API returns per-path Malliavin weights as NumPy arrays so users compose payoffs in NumPy / PyTorch / JAX and stay inside their autodiff framework of choice.

Named after K. David Elworthy, co-author of the Bismut-Elworthy-Li integration-by-parts formula:

$$ \partial_x \mathbb{E}[f(X_T) \mid X_0 = x] = \mathbb{E}\left[ f(X_T) \cdot \frac{1}{T} \int_0^T \sigma^{-1}(X_s)^\top \partial_x X_s \mathrm{d}W_s \right]. $$

elworthy takes a symbolic SDE, symbolically differentiates its coefficients, synthesises the Malliavin weight for a requested Greek, and lowers the entire inner-loop body (state update + weight accumulation + payoff) to a single kernel via Cranelift. Each SIMD lane carries one independent Monte Carlo path.

Status

v0.1. Ships:

  • Full scalar Cranelift JIT with exp, log, sin, cos, sqrt via libm.
  • 2-lane SIMD VectorKernel (Cranelift F64X2) covering every Fun variant per lane; F64X4 scaffolded behind the simd_avx2 feature flag with runtime CPU detection.
  • In-memory structural-hash kernel cache + disk-persisted AST cache at $XDG_CACHE_HOME/elworthy/.
  • Euler-Maruyama and Milstein discretisations for scalar SDEs; multi-dimensional Euler driver with full-truncation clamping for CIR/variance-type components.
  • Greek drivers:
    • Delta, constant-flow Bismut-Elworthy-Li (GBM / ABM).
    • Delta, general tangent-flow Bismut-Elworthy-Li (any scalar SDE).
    • Delta, multi-dim pathwise tangent flow (Heston and friends).
    • Rho, vega, and arbitrary parameter Greeks, pathwise (smooth payoffs, any scalar SDE).
    • Rho and vega for GBM via the likelihood-ratio Malliavin weight, valid for non-smooth payoffs (digitals, barriers); derivation machine-checked with SymPy.

Architecture

elworthy/
├── elworthy-expr/      symbolic AST, canonicalisation, CSE
├── elworthy-diff/      automatic symbolic differentiation
├── elworthy-weight/    Bismut-Elworthy-Li weight synthesis
├── elworthy-codegen/   Expr -> Cranelift IR lowering + scalar interpreter
├── elworthy-rt/        kernel cache, SIMD RNG, Monte Carlo driver
└── elworthy/           CLI + examples

Each subcrate has its own README.

Performance

On a development laptop (x86_64, single core, release profile):

Scenario throughput (M path-steps/s) speedup vs interpreter
GBM price, tree-walking interpreter 6.8 1.0x
GBM price, scalar Cranelift JIT 150 22x
GBM price, 2-lane SIMD JIT 187 27x
GBM price + Bismut-Elworthy-Li delta 152 22x
Heston price (2-D) 55 8x
Heston price + pathwise delta (2-D, full Jacobian) 16 2.3x

Kernel cache hit: 64 ns per retrieval vs ~100 us for a cold Cranelift compile, a 1500x speedup on calibration inner loops.

Cross-validation. The JIT+BEL stack is cross-validated against Black-Scholes closed form (inline, libm::erf) and the independent blackscholes crate (v0.24). On a European call at S_0 = K = 100, r = 0.05, sigma = 0.2, T = 1, 200 000 Milstein paths x 512 steps, elworthy's Monte Carlo price and Bismut-Elworthy-Li delta agree with both analytic references within four Monte Carlo standard errors. Full table in BENCHMARK.md.

Reproduce with:

cargo test --release -p elworthy-rt --test benchmark -- --nocapture --ignored

See BENCHMARK.md for full methodology, caveats, and reproducibility notes.

Install

cargo add elworthy-rt elworthy-expr

Or the CLI:

cargo install elworthy

Quick start (CLI)

elworthy gbm       --backend jit --paths 10000
elworthy gbm-delta --paths 40000

Expected output for gbm-delta at default parameters:

price   ~ 105.12xx (stderr 0.14xx) | closed form 105.1271
delta   ~   1.05xx (stderr 0.02xx) | closed form 1.0513   [Bismut-Elworthy-Li]

SELinux note (Fedora / RHEL)

The JIT backend requires execmem permission so Cranelift can map newly generated code as executable. Under SELinux enforcing this is denied by default for user binaries and you will see

Error: cranelift module error: Backend error: unable to make memory readable+executable

Workarounds:

  • Run via cargo test (the test harness domain already grants execmem).
  • Temporarily relax policy with sudo setsebool -P selinuxuser_execheap 1.
  • Use --backend interp for a JIT-free run.

Ubuntu, Debian, macOS, and most CI runners do not hit this restriction.

Next milestones

  • VectorKernel4 (AVX2 F64X4) behind the simd_avx2 feature.
  • General-SDE Malliavin parameter weight (without relying on a closed-form transition density).
  • Gamma via second-order Bismut-Elworthy-Li.
  • QuantLib reference benchmarks for Heston delta.

Licence

Apache License 2.0. See LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

elworthy-0.1.3.tar.gz (74.1 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

elworthy-0.1.3-cp310-abi3-win_amd64.whl (200.5 kB view details)

Uploaded CPython 3.10+Windows x86-64

elworthy-0.1.3-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.2 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ x86-64

elworthy-0.1.3-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.0 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ ARM64

elworthy-0.1.3-cp310-abi3-macosx_11_0_arm64.whl (301.2 kB view details)

Uploaded CPython 3.10+macOS 11.0+ ARM64

elworthy-0.1.3-cp310-abi3-macosx_10_12_x86_64.whl (309.2 kB view details)

Uploaded CPython 3.10+macOS 10.12+ x86-64

File details

Details for the file elworthy-0.1.3.tar.gz.

File metadata

  • Download URL: elworthy-0.1.3.tar.gz
  • Upload date:
  • Size: 74.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for elworthy-0.1.3.tar.gz
Algorithm Hash digest
SHA256 efc07eef0c921af3b0153af1f5b2c35a9f6ce0b016efc944e315c64fff8a469d
MD5 887cd12c5df986568095189a0ce2e0f6
BLAKE2b-256 036e77858b7e84ef263671c150d803f67aefdefdb7f188e6f1c95d4ed8803524

See more details on using hashes here.

Provenance

The following attestation bundles were made for elworthy-0.1.3.tar.gz:

Publisher: release.yml on alejandro-soto-franco/elworthy

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file elworthy-0.1.3-cp310-abi3-win_amd64.whl.

File metadata

  • Download URL: elworthy-0.1.3-cp310-abi3-win_amd64.whl
  • Upload date:
  • Size: 200.5 kB
  • Tags: CPython 3.10+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for elworthy-0.1.3-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 bc067896afa595536a5a470ed4dd6fb453e49ac22bf544eb2cc34e45582edc63
MD5 6e138f6eb3e7a8c396d06a7b879156f6
BLAKE2b-256 a0f596887829e5d2e3fe1f5e59764f0b58a23f42246ce2ffdad73d6e100ab1b3

See more details on using hashes here.

Provenance

The following attestation bundles were made for elworthy-0.1.3-cp310-abi3-win_amd64.whl:

Publisher: release.yml on alejandro-soto-franco/elworthy

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file elworthy-0.1.3-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for elworthy-0.1.3-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 0490bf6ea8308ff368c5c348b8fb1d125f999e35883384e8143226876af8baca
MD5 f56488353bf2b190994238e64ba16d27
BLAKE2b-256 0750e136fdf7536ffe22db004870aa2e829c50f62c8e98207dc1a8061168fd56

See more details on using hashes here.

Provenance

The following attestation bundles were made for elworthy-0.1.3-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on alejandro-soto-franco/elworthy

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file elworthy-0.1.3-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for elworthy-0.1.3-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 59ef3ca44675336b8b3f187c03d11ef9333086874d4114045c7f82f1ccd6c592
MD5 d42ace3bbb30b718beee214cf39b84f3
BLAKE2b-256 7cc4ab9cd47023b0b9025ee32cbd84bca2356791bbf078e4f53d5ad7956478ae

See more details on using hashes here.

Provenance

The following attestation bundles were made for elworthy-0.1.3-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on alejandro-soto-franco/elworthy

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file elworthy-0.1.3-cp310-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for elworthy-0.1.3-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 2f615b44d5a387f4191335ceb8732a8faa65c0f8d255b60f92d097be94f05cfb
MD5 7c88b97d07fe88297802784635aeaecb
BLAKE2b-256 902f7d2035c7b88414d39dbe562a89865d03b8007cf42d68d6e6a3729fb0a20d

See more details on using hashes here.

Provenance

The following attestation bundles were made for elworthy-0.1.3-cp310-abi3-macosx_11_0_arm64.whl:

Publisher: release.yml on alejandro-soto-franco/elworthy

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file elworthy-0.1.3-cp310-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for elworthy-0.1.3-cp310-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 ed122f9eaf08bd348264f7fad42dc4bc6b2e6b450b10a657b1edb4d7e5f043f2
MD5 810d07af34eb354cc64fdcca72b38cbf
BLAKE2b-256 1ea241ee81106b50e5d5900d783ddc98851c7969fcd112a5f002cbfbb2c61779

See more details on using hashes here.

Provenance

The following attestation bundles were made for elworthy-0.1.3-cp310-abi3-macosx_10_12_x86_64.whl:

Publisher: release.yml on alejandro-soto-franco/elworthy

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page