DEV Community

tomasz dobrowolski
tomasz dobrowolski

Posted on • Originally published at flashalpha.com

Stop Maintaining Your Own SVI Fitting Code — Advanced Volatility API for Quant Teams

If your team maintains SVI fitting code, arbitrage checks, and variance surface infrastructure, FlashAlpha's Advanced Volatility endpoint replaces all of it with a single API call.


The Problem This Solves

Every quant team that trades options eventually builds a vol surface. The typical stack:

  1. Pull raw option chains from a market data vendor
  2. Filter out stale quotes, wide markets, zero-OI strikes
  3. Fit SVI parameters per expiry slice (and debug when the optimizer doesn't converge)
  4. Interpolate across expiries to build the full surface
  5. Check for butterfly and calendar arbitrage violations
  6. Compute derived quantities: variance swap fair values, higher-order greeks
  7. Cache and refresh on a schedule

That's 2,000-5,000 lines of code someone has to maintain. When the optimizer breaks on a low-liquidity name, someone debugs it. When OPRA changes a feed format, someone patches it. When a new expiry cycle starts and the calibration window shifts, someone adjusts it.

The Advanced Volatility endpoint does all of this in one request:

from flashalpha import FlashAlpha

fa = FlashAlpha("YOUR_API_KEY")
data = fa.adv_volatility("SPY")
Enter fullscreen mode Exit fullscreen mode

Everything below comes back in data.


1. Raw SVI Parameters Per Expiry

Gatheral's SVI parameterisation maps log-moneyness k to total implied variance:

w(k) = a + b(ρ(k - m) + √((k - m)² + σ²))
Enter fullscreen mode Exit fullscreen mode

You get the five raw parameters (a, b, rho, m, sigma) for every expiry with sufficient liquidity, plus the implied forward price and ATM total variance:

for s in data["svi_parameters"]:
    print(f"{s['expiry']} ({s['days_to_expiry']}d): "
          f"a={s['a']:.6f}  b={s['b']:.6f}  rho={s['rho']:.4f}  "
          f"fwd={s['forward']:.2f}  ATM IV={s['atm_iv']:.1f}%")
Enter fullscreen mode Exit fullscreen mode
2026-04-04 (10d): a=0.004521  b=0.031245  rho=-0.1823  fwd=581.25  ATM IV=17.9%
2026-04-17 (23d): a=0.005812  b=0.028901  rho=-0.2145  fwd=582.10  ATM IV=18.2%
2026-05-16 (52d): a=0.008234  b=0.025678  rho=-0.2534  fwd=584.30  ATM IV=19.1%
Enter fullscreen mode Exit fullscreen mode

With five numbers per slice, you can reconstruct the implied volatility smile at any arbitrary strike. Feed these into your local vol, stochastic vol, or exotic pricing models directly. No re-fitting.


2. Total Variance Surface Grid

A 2D grid of total variance w(k, T) and implied volatility across 41 log-moneyness points (-0.5 to +0.5 in 0.025 steps) and all available expiries. Pre-computed and ready for interpolation:

import numpy as np
import matplotlib.pyplot as plt

surface = data["total_variance_surface"]
k = np.array(surface["moneyness"])
iv = np.array(surface["implied_vol"])

plt.figure(figsize=(12, 5))
plt.imshow(iv, aspect="auto", cmap="RdYlBu_r",
           extent=[k[0], k[-1], len(surface["expiries"])-0.5, -0.5])
plt.colorbar(label="Implied Vol (%)")
plt.yticks(range(len(surface["expiries"])), surface["expiries"])
plt.xlabel("Log-Moneyness")
plt.title("SPY Implied Volatility Surface")
plt.tight_layout()
plt.show()
Enter fullscreen mode Exit fullscreen mode

Total variance is the natural quantity for no-arbitrage conditions and for computing Dupire local volatility via finite differences. No additional fitting step needed.


3. Arbitrage Detection

Two types of static arbitrage can hide in a fitted surface:

Butterfly arbitrage: the second derivative of total variance w.r.t. moneyness goes negative, implying a negative risk-neutral density. A butterfly spread at those strikes is a free lunch.

Calendar arbitrage: total variance decreases from one expiry to the next at the same moneyness. A calendar spread across those expiries is a free lunch.

The endpoint checks both and returns structured flags:

flags = data["arbitrage_flags"]
if flags:
    print(f"{len(flags)} violations:")
    for f in flags:
        print(f"  [{f['type']}] {f['expiry']}: {f['description']}")
else:
    print("✓ Surface is arbitrage-free")
Enter fullscreen mode Exit fullscreen mode

If you're pricing exotics off a surface with arb violations, your prices are wrong in a way that creates unbounded risk. This check runs automatically on every request.


4. Variance Swap Fair Values

The fair variance swap strike, computed via numerical integration of the SVI-fitted smile, tells you what the options market is pricing for realised variance at each expiry. The convexity adjustment (fair vol minus ATM IV) measures how much the wings contribute beyond ATM:

for vs in data["variance_swap_fair_values"]:
    print(f"{vs['expiry']}: Fair Vol={vs['fair_vol']:.2f}%  "
          f"ATM IV={vs['atm_iv']:.2f}%  "
          f"Convexity={vs['convexity_adjustment']:+.2f}pp")
Enter fullscreen mode Exit fullscreen mode
2026-04-04: Fair Vol=18.35%  ATM IV=17.85%  Convexity=+0.50pp
2026-04-17: Fair Vol=18.92%  ATM IV=18.20%  Convexity=+0.72pp
2026-05-16: Fair Vol=19.85%  ATM IV=19.10%  Convexity=+0.75pp
Enter fullscreen mode Exit fullscreen mode

A large convexity adjustment means the wings (particularly OTM puts) are priced richly. The market is paying up for tail protection. Track this over time and you have a clean signal for the vol risk premium embedded in the skew.


5. Greeks Surfaces

2D grids of second and third-order greeks across strikes and all expiries:

Greek What it measures Why it matters
Vanna (dDelta/dVol) How delta breaks when vol moves Crash feedback loop: spot drops, vol spikes, delta shifts, dealers sell
Charm (dDelta/dTime) How delta drifts overnight Explains weekend delta decay and expiry-day drift
Volga (dVega/dVol) Exposure to vol-of-vol Critical for pricing and hedging wing risk
Speed (dGamma/dSpot) How fast gamma shifts as spot moves Shows where gamma exposure flips rapidly
vanna = data["greeks_surfaces"]["vanna"]
strikes = np.array(vanna["strikes"])
values = np.array(vanna["values"])

plt.figure(figsize=(10, 5))
for i, expiry in enumerate(vanna["expiries"]):
    plt.plot(strikes, values[i], label=expiry, linewidth=1.5)
plt.axhline(0, color="gray", linewidth=0.5, linestyle="--")
plt.xlabel("Strike")
plt.ylabel("Vanna")
plt.title("SPY Vanna Surface")
plt.legend()
plt.tight_layout()
plt.show()
Enter fullscreen mode Exit fullscreen mode

The vanna surface is particularly valuable for understanding dealer hedging dynamics. When dealers are short vanna, a spot drop + vol spike forces them to sell shares, amplifying the move. The surface shows you exactly where these feedback loops are strongest.


What This Replaces

Component In-House FlashAlpha Alpha
SVI calibration per expiry 500-1,000 lines, optimizer tuning Included
Surface interpolation Custom spline code Pre-computed grid
Butterfly/calendar arb checks Often skipped or incomplete Automatic, every request
Variance swap fair values Numerical integration code Included
Higher-order greeks surfaces Finite difference code Pre-computed grids
Data pipeline + caching OPRA feed, filtering, scheduling One API call
Maintenance Ongoing engineer time $0

The Alpha plan costs $14,388/year ($1,199/mo billed annually). A single engineer maintaining vol surface infrastructure costs 10x that. A Bloomberg terminal costs $24,000/year and doesn't give you raw SVI parameters via API.


How to Evaluate

  1. Start with the free tier. Pull GEX, option quotes, stock quotes to verify data quality and latency. No credit card.
  2. Compare SVI fits. If you have your own calibration, pull the same expiry from both and compare. Fits use weighted least-squares with ATM bias and butterfly/calendar constraint enforcement.
  3. Check the arb flags. Run a few names and see if we catch violations your surface misses.
  4. Test integration. Structured JSON response. Pipe it into your existing models and verify.

If the fits are comparable to yours and the arb checks are at least as strict, you've eliminated a significant maintenance burden. If they're better, you've improved surface quality at the same time.


Getting Started

The Advanced Volatility endpoint is on the Alpha plan: unlimited API requests, SVI-smoothed IV on all option quotes, zero cache, and dedicated support.

Related guides:

Top comments (0)