A Cartesi application that prices European vanilla options using the Black-Scholes-Merton analytical engine from QuantLib running inside a deterministic RISC-V machine.
Send a JSON payload describing an option; receive back the fair value and full set of first-order Greeks.
| Output | Description |
|---|---|
price |
Option fair value (NPV) |
delta |
∂V/∂S — sensitivity to underlying price |
gamma |
∂²V/∂S² — rate of change of delta |
theta |
∂V/∂t per calendar day |
vega |
∂V/∂σ per 1 percentage-point move in volatility |
rho |
∂V/∂r per 1 percentage-point move in rate |
- Docker (with QEMU/binfmt for
linux/riscv64) - Cartesi CLI (
npm install -g @cartesi/cli)
(This is optional, only if you want to update it!!! You can use the wheels provided in the repo) This compiles QuantLib's Python bindings under QEMU emulation. It takes a few hours on first run.
caffeinate -i ./build-wheels.sh # macOS: keeps machine awake
# or on Linux:
./build-wheels.shThe wheel is saved to ./wheels/QuantLib-1.25-cp310-cp310-linux_riscv64.whl.
Docker Desktop (macOS): Set Memory ≥ 4 GB and Swap ≥ 4 GB in
Settings → Resources before running the script.
cartesi buildcartesi runSend a JSON object as the input payload:
cartesi send generic \
--input='{"option_type":"call","spot":100,"strike":100,"risk_free_rate":0.05,"volatility":0.20,"maturity_days":365}'curl http://localhost:8080/inspect/ \
-X POST \
-H 'Content-Type: application/json' \
-d '{"option_type":"put","spot":95,"strike":100,"risk_free_rate":0.05,"volatility":0.25,"maturity_days":90}'| Field | Type | Required | Description |
|---|---|---|---|
option_type |
string | ✅ | "call" or "put" |
spot |
number | ✅ | Current underlying price |
strike |
number | ✅ | Strike price |
risk_free_rate |
number | ✅ | Continuously compounded rate (e.g. 0.05 = 5%) |
volatility |
number | ✅ | Annualised implied vol (e.g. 0.20 = 20%) |
maturity_days |
integer | ✅ | Calendar days to expiry |
dividend_rate |
number | ❌ | Continuous dividend yield, default 0.0 |
{
"option_type": "call",
"spot": 100,
"strike": 100,
"risk_free_rate": 0.05,
"dividend_rate": 0.0,
"volatility": 0.2,
"maturity_days": 365,
"price": 10.450584,
"delta": 0.636831,
"gamma": 0.018762,
"theta": -0.017478,
"vega": 0.375247,
"rho": 0.532325
}On error the application emits a Report with a plain-text description and rejects the input.
.
├── dapp.py # Application logic
├── Dockerfile # Cartesi machine image definition
├── requirements.txt # Python dependencies (references ./wheels)
├── build-wheels.sh # Builds the riscv64 QuantLib wheel via Docker/QEMU
└── wheels/ # Pre-built riscv64 wheels
QuantLib is not available as a pre-built Python wheel for linux/riscv64. build-wheels.sh solves this by:
- Running a
cartesi/python:3.10-slim-jammycontainer under QEMU riscv64 emulation - Installing
libquantlib0-devfrom Ubuntu's apt repository - Downloading QuantLib-SWIG source and generating the C++ wrapper with SWIG
- Compiling the extension with
pip wheeland saving the.whlto./wheels/
At runtime the Cartesi machine uses libquantlib0v5 (installed via the Dockerfile) as the shared library backing the wheel.
Reusing the wheel in another project: The wheel alone is not self-contained — it dynamically links against
libQuantLib.so.0. If you copywheels/QuantLib-1.25-cp310-cp310-linux_riscv64.whlinto another Cartesi project you must also addlibquantlib0v5to that project's Dockerfile:apt-get install -y --no-install-recommends libquantlib0v5