Smooth, arbitrage-aware option surface calibration for Rust.
The public crate is sanos. This repository also
contains the surrounding workspace tooling used to run calibrations, export surfaces,
and generate diagnostics.
- richer crate documentation with calibration galleries
- examples showing price fit, IV fit, density, and quality diagnostics
- benchmark-backed showcase examples from multiple market regimes
- reproducible release workflow for crates.io publication
sanos is designed for developers who want a native Rust surface-calibration engine:
- validated option market data types
- high-level calibration entry points
- queryable calibrated surfaces
- explicit no-arbitrage diagnostics
- optional serialization support
Selection driven by the latest benchmark results:
- best
excellentpositive-spread case - best
acceptablecase outsidetight_spread - best
excellentterm-structure case
Price fit:
IV fit:
Density:
Performance summary:
Price fit:
IV fit:
Density:
Performance summary:
Price fit:
IV fit:
Density:
Performance summary:
The current benchmark study reports:
- 30 snapshots analyzed
- 5 zero-spread snapshots
- 0 real failures
- 9 fragile stress cases still useful for tuning
Best config counts from the latest benchmark run:
| Config | Best snapshots |
|---|---|
tight_spread |
16 |
sparse_robust |
6 |
strong_wings |
4 |
extreme_stress |
2 |
zero_spread_vega |
2 |
[dependencies]
sanos = "0.2"Build and run with cargo run -p sanos-cli -- <command> ....
- Create a default calibration config:
cargo run -p sanos-cli -- init-config --out data/configs/default.jsonThis template is runnable out of the box (solver = "Microlp", objective = "HardBidAsk").
- Validate a snapshot:
cargo run -p sanos-cli -- validate-snapshot --snapshot data/snapshots/my_snapshot.json- Run calibration + JSON exports:
cargo run -p sanos-cli -- calibrate \
--snapshot data/snapshots/my_snapshot.json \
--config data/configs/default.json \
--out data/surfaces/my_run \
--n-maturities 41 \
--n-strikes 81This writes:
report.jsonq.jsonsurface.json(dense and pretty-printed, includesreconstructionto rebuildSanosSurface)diagnostics.json
- Validate and reconstruct a previously exported surface:
cargo run -p sanos-cli -- validate-surface --surface data/surfaces/my_run/surface.jsonThe top-level orchestrator is Python and does not create Rust dependencies on tools/.
python tools/sanos.py run --config default --snapshot my_snapshotCatalog run:
python tools/sanos.py run --config default --snapshot-catalog total_varianceCatalog run with per-snapshot config rules + fallback:
python tools/sanos.py run --config-catalog total_variance_robust --snapshot-catalog total_varianceCatalog run with automatic best-config scoring:
python tools/sanos.py run --config-catalog total_variance_robust --snapshot-catalog total_variance --selection-policy best-scoreShortcuts:
- Windows (from repo root):
sanos.cmd run --config default --snapshot my_snapshot - Linux/macOS (from repo root):
./sanos run --config default --snapshot my_snapshot
Single snapshot resolves:
data/configs/default.jsondata/snapshots/my_snapshot.json
Then it:
- Validates the snapshot.
- Runs calibration via Rust CLI.
- Writes JSON outputs in
data/surfaces/<snapshot>__<config>/. - Generates calibration quality plots in
data/images/<snapshot>__<config>/. - Generates a Markdown report in
data/reports/<snapshot>__<config>.md.
Catalog run resolves:
data/configs/default.jsondata/snapshots/catalogs/total_variance/*.json
Then it runs each snapshot and writes:
- Surfaces:
data/surfaces/catalogs/<catalog>/<snapshot>__<config>/ - Images:
data/images/catalogs/<catalog>/<snapshot>__<config>/ - Per-run reports:
data/reports/catalogs/<catalog>/<snapshot>__<config>.md - Batch summary report:
data/reports/catalogs/<catalog>/<catalog>__<config-or-catalog-label>__summary.md
If --config-catalog is used:
- Resolves
data/config_catalogs/<catalog>.json - Picks config candidates per snapshot name (regex rules), then tries them in order
--selection-policy first-successstops at first successful calibration--selection-policy best-scoreruns all successful candidates and picks the lowest score- Score favors: high inside bid/ask, low normalized residuals, smoother IV, low bid/ask and no-arb violations
- Records effective config and score used in the batch summary table
Optional flags:
--no-validate--no-plot--n-maturities--n-strikes--selection-policy--score-w-*(weights for the best-score objective)--keep-attempt-artifacts(desactive le nettoyage des essais non retenus)
convex_order_validation:"Error"(default) or"Warn".fit.kernel.omega:"Zero","One", or"Both"("Both"enforces both constraint blocks in the same LP).fit.initialization.mode:"None"(default) or"BackboneSynthetic".fit.initialization.feasibility_tol: non-negative finite tolerance for warm-start feasibility checks.fit.initialization.market_completion: Remark 2.8 completion config (defaults applied if omitted), used only whenmode = "BackboneSynthetic".
Minimal example:
{
"convex_order_validation": "Warn",
"fit": {
"kernel": { "omega": "One" },
"objective": "HardBidAsk",
"initialization": {
"mode": "None",
"price_proxy": "Mid",
"feasibility_tol": 1e-8,
"market_completion": {
"k1_ratio": 0.2,
"kN_ratio": 2.0,
"max_iters": 50,
"slope_margin": 1e-10,
"hard_caps": null,
"tol": 1e-10
}
}
}
}










