Skip to content

Weculp/volatility-surface

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Volatility Surface

An interactive 3D implied‑volatility surface visualizer for any US‑listed equity, built as a standalone page for vikalpthukral.com/volatility-surface.

The frontend is a single self‑contained index.html (Tailwind + Plotly via CDN). The backend is a tiny FastAPI service that fetches options chains from Yahoo Finance via yfinance, cleans them, and caches them in memory.


Features

Visualization

  • 3D surface plot of implied volatility across strike × days‑to‑expiration
  • Bilinear resampling + Gaussian blur for adjustable surface smoothing (0–5)
  • 4 Z‑axis metrics on the same mesh: Implied Vol, Total Variance (σ²·T), Volume, Open Interest
  • 4 camera presets: ISO, TOP (heatmap), SKEW (front view of smile), TERM (side view of term structure)
  • Side‑by‑side mini‑charts:
    • ATM Term Structure (IV vs DTE for the strike closest to spot)
    • Volatility Skew slice for any selected expiry, with spot‑price marker

UI / UX

  • Dark / Light theme with automatic OS preference detection (prefers-color-scheme) and localStorage persistence
  • 10 color palettes: Cyan, Blue, Pink, Orange, Green, Amber (custom neon ramps) + Plasma, Viridis, Inferno, Turbo (Plotly built‑ins). Selected palette re‑themes the UI accent and both mini‑charts.
  • Glassmorphism control panels with backdrop blur
  • Quick‑select chips for common DTE ranges (0‑30d, 30‑60d, 60‑90d, 90‑180d, 180d+, ALL) and moneyness windows (±5%, ±10%, ±20%, ±35%, ±50%)
  • Live spot price, contract count, and freshness indicator in the header

Data

  • Two‑tier caching: 10 minutes for options chains, 1 hour for the risk‑free rate, all in memory
  • Yahoo rate‑limit bypass via curl_cffi Chrome browser impersonation
  • Cleaned chain: NaN IVs dropped, zero‑volume / zero‑OI contracts removed, IVs clamped to (0.01, 5.0) to kill illiquid noise
  • Pre‑computed bid/ask mid in every contract row (ready for v3 Greeks)
  • Live risk‑free rate from ^IRX (13‑week US T‑bill), with manual override
  • Dividend yield included in the payload

Export

  • PNG export at 1920×1080 of the current view
  • CSV export of the cleaned options chain with bid/ask/mid

Project structure

volatility-surface/
├── main.py              # FastAPI backend (yfinance + caching)
├── requirements.txt     # Python dependencies
├── Dockerfile           # Production container image
├── fly.toml             # Fly.io app configuration
├── .dockerignore        # Files excluded from the Docker build context
├── .gitignore           # Files excluded from git
├── index.html           # Standalone frontend (single file, drop into GH Pages)
├── README.md            # This file
└── DEPLOY.md            # Step‑by‑step deployment guide

Tech stack

Layer Choice Why
Frontend Vanilla HTML + Tailwind (CDN) + Plotly.js (CDN) Zero build step, single file, ships to any static host.
3D rendering Plotly.js surface trace Best‑in‑class 3D surface support out of the box.
Backend FastAPI + Uvicorn Async, tiny, fast, automatic OpenAPI.
Data source yfinance + curl_cffi Free Yahoo Finance options chains. curl_cffi impersonates Chrome to bypass anti‑bot rate limiting.
Caching In‑memory dict with TTL Simple, no external dependency, perfect for a single long‑lived process.
Production runtime Docker on Fly.io Always‑on, scale‑to‑zero, free SSL, custom domains, ~$0–3/month for this workload.

API

Method Path Description TTL
GET / Health check
GET /api/options/{ticker} Cleaned options chain (calls + puts) for the given ticker 10 min
GET /api/risk-free-rate Latest 13‑week T‑bill yield from ^IRX 1 hour

Sample payload — /api/options/SPY

{
  "cached": false,
  "ticker": "SPY",
  "spot": 658.93,
  "dividendYield": 0.0106,
  "fetched_at": "2026-04-07T00:10:06.923157+00:00",
  "calls": [
    {
      "strike": 650.0,
      "expiration": "2026-04-17",
      "dte": 11,
      "iv": 0.1542,
      "volume": 12834,
      "openInterest": 23410,
      "bid": 12.30,
      "ask": 12.45,
      "mid": 12.375
    }
  ],
  "puts": [...]
}

Local development

Prerequisites

  • Python 3.10+ (tested with 3.12)
  • pip
  • (Optional) Node-style live server, or any HTTP server, for the frontend

1. Backend

cd volatility-surface
python -m venv .venv

# Windows
.venv\Scripts\activate
# macOS / Linux
source .venv/bin/activate

pip install -r requirements.txt
python main.py

The API is now live at http://127.0.0.1:8000. Test it:

http://127.0.0.1:8000/
http://127.0.0.1:8000/api/options/SPY
http://127.0.0.1:8000/api/risk-free-rate

2. Frontend

The frontend cannot be opened directly via file:// because it makes fetch() calls. Serve it over HTTP from a second terminal:

cd volatility-surface
python -m http.server 5500

Then open http://localhost:5500/.

The frontend auto‑detects localhost and points at http://127.0.0.1:8000 automatically — no config needed for local dev.

Environment variables

Variable Default Purpose
HOST 127.0.0.1 (local), 0.0.0.0 (Docker) Bind address for uvicorn
PORT 8000 (local), 8080 (Docker) Bind port for uvicorn
ALLOWED_ORIGINS http://localhost:5500,http://127.0.0.1:5500 Comma‑separated CORS allowlist. Set to * for "allow all" (not recommended in production).

Configuration

Pointing the frontend at a custom backend URL

The frontend resolves its API base in this order:

  1. <meta name="api-base" content="..."> in the HTML <head>. If you set this to a non‑empty value, it wins.
  2. If running on localhost / 127.0.0.1, defaults to http://127.0.0.1:8000.
  3. Otherwise, defaults to https://api.vikalpthukral.com.

For your own deployment, change the meta tag (recommended) or the fallback URL inside the <script> block:

<meta name="api-base" content="https://api.yourdomain.com" />

Deployment

See DEPLOY.md for the full step‑by‑step guide covering:

  • Splitting the project into two repos (frontend on GitHub Pages, backend on Fly.io)
  • Building and deploying the Docker image
  • Configuring a custom subdomain (api.vikalpthukral.com) with auto‑provisioned SSL
  • Locking down CORS to your production origin
  • Optional: GitHub Actions workflow for auto‑deploy on push

Roadmap (v3 ideas)

  • Black‑Scholes Greeks surfaces (Δ, Γ, ν, Θ) — backend already returns mid + dividend + risk‑free rate
  • SVI / SSVI parametric surface fit
  • Earnings & dividend markers on the DTE axis
  • Compare mode (two tickers side‑by‑side)
  • Shareable URL with state encoded in query params
  • 30‑day constant‑maturity IV (VIX‑style interpolation)
  • Implied move calculator (front‑month straddle → expected move)

License

MIT. Data via Yahoo Finance — for educational and research use only. This project is not affiliated with, endorsed by, or sponsored by Yahoo, Verizon Media, or any exchange.

Author

Built by Vikalp Thukralvikalpthukral.com

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors