Black-Scholes Options Pricer in Rust and WASM
A Rust crate compiled to WebAssembly powers a live, in-browser European options pricer with real-time Greeks and no server round-trip.
The compiled module is 62 KB raw and 27 KB gzipped, loads when the demo enters view, and computes sub-millisecond on a device capable of loading the page.
- Problem boundaryA live browser pricer needs deterministic calculation, explicit handling of degenerate inputs, and a safe boundary for malformed data without a server round-trip.
- System boundaryRust is compiled with wasm-pack; a wasm_bindgen entry point deserializes input through serde-wasm-bindgen and the browser loads the module when the demo enters view.
- EvidenceA Rust crate compiled to WebAssembly provides browser-side European option prices and Greeks without a server round-trip.
- Known limitsEuropean options on a non-dividend-paying underlying; this is an educational tool, not financial advice.
- Compiled binary
- 62 KB raw
- Compressed binary
- 27 KB gzipped
- Unit tests
- 6 Rust unit tests
- Role
- Rust implementation, WASM boundary hardening, browser integration, and unit verification
- System boundary
- Rust is compiled with wasm-pack; a wasm_bindgen entry point deserializes input through serde-wasm-bindgen and the browser loads the module when the demo enters view.
- Primary constraint
- The model prices European options on a non-dividend-paying underlying.
- Strongest evidence
- A Rust crate compiled to WebAssembly provides browser-side European option prices and Greeks without a server round-trip.
The situation
A live browser pricer needs deterministic calculation, explicit handling of degenerate inputs, and a safe boundary for malformed data without a server round-trip.
Incorrect pricing or a malformed browser boundary would undermine an educational tool that presents option prices and Greeks.
Constraints
- The model prices European options on a non-dividend-paying underlying.
- Degenerate time-to-expiry and volatility inputs must return intrinsic value rather than NaN or a panic.
- Malformed input at the WASM boundary must return zeroed output rather than throw.
My responsibility
Rust implementation, WASM boundary hardening, browser integration, and unit verification
The system
Rust is compiled with wasm-pack; a wasm_bindgen entry point deserializes input through serde-wasm-bindgen and the browser loads the module when the demo enters view.
Architecture descriptionBrowser inputs pass through generated JavaScript glue to a Rust WebAssembly module that returns option prices and Greeks.
Critical decisions
01
Rust compiled to WASM
- Choice
- Use Rust as the specification and compile it to WebAssembly for the browser pricer.
- Alternatives considered
- Implement the calculation directly in JavaScript.
- Tradeoff
- JavaScript would be sufficient for this precision, while Rust makes boundary cases explicit and keeps the source as the specification.
02
Hardened input boundary
- Choice
- Return intrinsic value for T ≤ 0 or σ ≤ 0 and zeroed output for malformed WASM input.
- Alternatives considered
- Allow NaN, panic, or a thrown malformed-input error.
- Tradeoff
- The boundary avoids browser failures while making degenerate cases explicit.
Proof
WASM browser pricerA Rust crate compiled to WebAssembly provides browser-side European option prices and Greeks without a server round-trip.
- Evidence boundary
- Educational browser-side pricing demonstration using the Black-Scholes closed-form model.
- Known limits
- European options on a non-dividend-paying underlying; this is an educational tool, not financial advice.
Reflection
The compiled module is 62 KB raw and 27 KB gzipped, loads when the demo enters view, and computes sub-millisecond on a device capable of loading the page.
- A JavaScript implementation would be concise and sufficient for this precision, but Rust makes degenerate cases and the browser boundary explicit.
Black-Scholes live pricer
Rust compiled to WebAssembly: adjust the sliders to reprice in real time.