An interactive, fast, and practical Implied Volatility Surface Explorer for SPY and similar options from the CBOE quotes dashboard. Implied Volatility is calculated using the Bisection method and optimized with SIMD and Rayon and ported to the web with WASM. Surfaces are plotted using Plotly.
To run locally, add below to Cargo.toml:
[lib]
crate-type = ["cdylib"]
Next, compile from Rust to WASM with (if your machine doesn't support WASM, remove the RUSTFLAGS):
RUSTFLAGS='-C target-feature=+simd128' wasm-pack build --target web
This will generate a pkg
directory. Then, run the website locally:
npx serve
You may view the sample data or upload the most recent SPY data from CBOE. To do this, visit the CBOE delayed quotes website:
Then, update the Volume, Expiration Type, Options Range, Size, and Expiration filters as desired and scroll to the bottom to Download CSV.
Finally, download the CSV file and upload it to the website.
To run the Rust benchmark locally, comment out these lines in the Cargo.toml
[lib]
crate-type = ["cdylib"]
and then run
cargo bench
Similarily, for tests:
cargo test
Calculated on a Macbook M1:
Calculating implied volatility for ~25000 options (~25x speed-up):
bs::implied_vol()
(single): ~25.2msvol32x8::implied_vol()
(SIMD and multithreaded): ~1ms
Calculating interest rate using Put-Call parity for ~25000 options (~2x speed-up):
bs::parity_interest_rate()
(single): ~91.683 µsvol32x8::parity_interest_rate()
(SIMD and multithreaded): ~56.079 µs
- In real-life applications, the implied volatility calculation should happen in the backend in order to full utilize SIMD instructions and multithreading. Instead of being converted to WASM, the Rust code can be deployed in a backend system and connected to the frontend with HTTP or another protocol.
- If the Rust -> WASM is kept, multithreading can be utilized in the frontend by enabling
SharedArrayBuffer
in the browser, adding wasm-bindgen-rayon, and re-compiling to WASM. - Support other historical or realtime market data feeds.