Documentation
Everything you need to fit arbitrage-free implied volatility surfaces with Volptima.
Overview
Volptima provides CVI (Convex Volatility Interpolation), a volatility surface fitter built on convex optimization. Instead of starting from a parametric model, CVI formulates the calibration as a sparse quadratic program, enforcing no-butterfly and no-calendar arbitrage as hard constraints, and more generally encoding the structural properties of the volatility surface. You send market data (bid/ask quotes in vol or price space) and get back a fitted surface you can interpolate at any strike. Those two spaces are the two APIs: the Vol API (you supply implied volatilities) or the Price API (you supply raw option prices), both returning the same fitted CVI surface, so only the input differs.
You reach either API through one of two interfaces: the Python API Client (which fits locally via grafit or in the cloud) or grafit directly (Rust, with Python and C bindings) for non-Python or low-level use.
Beyond CVI, the library also provides a fast American option pricer (supporting discrete cash dividends) with smooth greeks.
Plug and Play
Volptima works out of the box. There is no model to choose, and no need to tune hyperparameters: the defaults are sensible and work across assets. From market quotes to volatility surfaces. It just works.
Two APIs
Both APIs drive the same core CVI fitter; they differ only in what you feed it. The Vol API takes implied volatilities and feeds CVI directly. The Price API adds a layer on top of CVI: it takes raw option prices and backs the vols out for you (and the forward and discount factor too, when omitted) before fitting.
Vol API
implied vols in
- Input: bid/ask implied European volatilities
- Forward and discount factor required
Price API
option prices in
- Input: bid/ask option prices
- Forward and discount factor calibrated when omitted
- European or American exercise
- American expiries: discount factor required, cash dividends supported
CVI vol surface
The same surface either way; its per-expiry parameters are listed in What You Get below.
Pricing & greeks
optional
Reprice each listed option to its CVI fair value, with greeks off the surface. See Pricing & Greeks.
The Vol API is European only and needs the forward and discount factor up front. The Price API also handles American exercise, calibrates the forward and discount factor from the quotes when you omit them (though an American expiry must still pin its discount factor), and accepts cash dividends for American expiries.
Market Data
Volptima does not provide market data. Typically you pass a snapshot of all the listed option quotes of a given underlying through the Price API, along with expectations of future cash dividends for American options.
What You Get
Whichever API you use, the fitter takes market data and returns a fitted volatility surface with these parameters per expiry:
| Field | Description |
|---|---|
atm_vol | At-the-money implied volatility |
s | Normalized ATM skew parameter |
c_array | Normalized convexity array (smile curvature at each node) |
std_dev_array | Standard deviation nodes where the smile is evaluated |
anchor_atm_vol | Reference volatility used for normalization |
The fitted surface is arbitrage-free by construction: no butterfly arbitrage (PDF ≥ 0) and no calendar arbitrage (total variance non-decreasing).
Two Interfaces
API Client
One Python API with two interchangeable backends: local (grafit) or cloud. The simplest way to get started, and the recommended path.
- Python-only interface
- Cloud fitting (REST API) or local fitting (via grafit)
- Built-in Plotly dashboard
Read the docs →
Grafit
The same Rust engine that powers the local backend, used directly via Python, C, and more. For when you need low-level control or non-Python languages.
- Python, C/C++ bindings (other languages coming soon)
- JSON-in / JSON-out API
- No network dependency
Read the docs →
Architecture
How a request flows from your code to the fitter:
Your Python Code
VolptimaClient
volptima-api-client
CloudBackend
HTTPS to cloud
LocalBackend
In-process Rust
Cloud API
Hosted API
Grafit
Rust engine
or
or
Your Code
Python, C, C++, ...
Grafit
JSON in / JSON out
Use the Rust engine directly via language bindings, no Python SDK needed
SaaS clients use the API Client with CloudBackend (cloud fitting, no local install). Grafit clients can use the API Client with LocalBackend, or call Grafit directly from any supported language.
Typical Workflow: Shared Discount Factor
A discount factor is the same for every underlying denominated in a given currency, yet it is hard to back out from a single name's American quotes. A common pattern: first fit the most liquid European product in the currency (for example SPX for USD) with the Price API and let it calibrate the forward and discount factor from the quotes. Then reuse that discount factor for the other underlyings in the same currency: pin it on each fit (required for American expiries) and supply cash dividends for American names, so every surface shares one consistent, market-implied discount factor.
SPX European options
most liquid USD product
Price API
calibrates the discount factor
Implied discount factor
USD curve, per tenor
inject the discount factor
Other underlyings, same currency
single-name American fits: pin the discount factor + add cash dividends
Advanced Workflow: Multi-Snapshot Forward & Discount-Factor Stabilization
Fitting one snapshot at a time can leave the forward and discount factor noisy, especially before events when market makers widen their quotes. The forward/spot basis, though, is far more stable than the forward itself (the forward moves with the spot), so the basis can be stabilized across multiple snapshots and recombined with the live spot for a clean forward. The discount factor, generally stable too, is handled the same way. This sits on top of the single-snapshot Price API.
Forward = spot × basis
spot is noisy, the basis is stable
Stabilize the basis + DF
across multiple snapshots
Clean forward + discount factor
basis recombined with the live spot