If you've ever tried to compute the volatility risk premium yourself, you know the pain: source options chains, compute ATM IV, calculate realized vol across multiple windows, fit a term structure, decompose put vs call wing premiums, condition on dealer positioning, score strategy suitability. That's 3-6 months of engineering before you display a single number on a dashboard.
One API call replaces all of it.
What the Endpoint Returns
GET /v1/vrp/{symbol} returns the full VRP picture in a single JSON response:
| Section | What It Tells You |
|---|---|
| VRP core | ATM IV, realized vol (5d/10d/20d/30d), VRP spread per window, z-score, percentile |
| Directional | Put-wing vs call-wing IV, downside VRP vs upside VRP |
| Term structure | VRP by DTE bucket (7d, 14d, 30d) — which expiration is richest |
| GEX-conditioned | Gamma regime, harvest score (0-1), interpretation |
| Strategy scores | Short straddle, strangle, iron condor, calendar, jade lizard scored 0-100 |
| Regime | Positive/negative gamma, VRP regime, net GEX, gamma flip |
| Macro | VIX, VIX 3M, term slope, 10Y yield, HY spread, fed funds |
| Risk | Dealer flow risk score, warnings array, net harvest score |
No manual IV computation. No realized vol calculation. No regime detection logic. Pre-computed and updated throughout the trading day.
Quick Start
pip install flashalpha
from flashalpha import FlashAlpha
fa = FlashAlpha("YOUR_KEY")
vrp = fa.vrp("SPY")
print(f"ATM IV: {vrp['vrp']['atm_iv']:.1f}%")
print(f"20d RV: {vrp['vrp']['rv_20d']:.1f}%")
print(f"VRP spread: {vrp['vrp']['vrp_20d']:.1f}%")
print(f"Z-score: {vrp['vrp']['z_score']:.2f}")
print(f"Percentile: {vrp['vrp']['percentile']:.0f}th")
print(f"Harvest score: {vrp['net_harvest_score']:.2f}")
print(f"Best strategy: {max(vrp['strategy_scores'], key=lambda k: vrp['strategy_scores'][k] or 0)}")
Or with curl:
curl -H "X-Api-Key: YOUR_KEY" \
"https://lab.flashalpha.com/v1/vrp/SPY"
Free tier: 10 requests/day, no credit card. Get your key.
Building the Dashboard Piece by Piece
1. The VRP Gauge: Rich or Thin?
The z-score tells you how many standard deviations the current VRP is from its 252-day mean. The percentile gives the same information on a 0-100 scale.
vrp_data = vrp['vrp']
if vrp_data['z_score'] > 1.5:
signal = "RICH" # Top ~7% of historical observations
color = "#16a34a"
elif vrp_data['z_score'] > 0.5:
signal = "MODERATE"
color = "#ca8a04"
elif vrp_data['z_score'] > -0.5:
signal = "FAIR"
color = "#6b7280"
else:
signal = "THIN" # Premium compressed, don't sell
color = "#dc2626"
print(f"VRP Signal: {signal}")
print(f"Z-score: {vrp_data['z_score']:.2f} ({vrp_data['percentile']}th percentile)")
2. Multi-Window Realized Vol
The response includes realized vol across four windows and the VRP spread for each. If VRP is rich at 5d but thin at 30d, the premium is driven by recent calm, not structural richness.
for window in ['5d', '10d', '20d', '30d']:
iv = vrp_data['atm_iv']
rv = vrp_data[f'rv_{window}']
spread = vrp_data[f'vrp_{window}']
print(f" {window}: IV {iv:.1f}% - RV {rv:.1f}% = VRP {spread:+.1f}%")
3. Directional Decomposition
Most VRP analysis treats the premium as symmetric. It isn't. The directional object decomposes VRP into put-side and call-side using 25-delta wing IVs.
d = vrp['directional']
print(f"Put wing IV: {d['put_wing_iv_25d']:.1f}%")
print(f"Call wing IV: {d['call_wing_iv_25d']:.1f}%")
print(f"Downside VRP: {d['downside_vrp']:+.1f}%")
print(f"Upside VRP: {d['upside_vrp']:+.1f}%")
if d['downside_vrp'] > d['upside_vrp'] + 1.0:
print("Put side richer - short put spreads or jade lizards")
elif d['upside_vrp'] > d['downside_vrp'] + 1.0:
print("Call side richer - covered calls or call credit spreads")
else:
print("Balanced - symmetric structures (straddles, iron condors)")
When put-side VRP is 5% and call-side is 1%, selling an iron condor is wrong because the premium is concentrated on one side. This is what separates a useful VRP dashboard from a basic IV-vs-RV chart.
4. VRP Term Structure
Which expiration has the richest premium per unit of time:
print("VRP Term Structure:")
for bucket in vrp['term_vrp']:
bar = "█" * int(bucket['vrp'] * 3)
print(f" {bucket['dte']:3d} DTE: IV {bucket['iv']:.1f}% - RV {bucket['rv']:.1f}% = VRP {bucket['vrp']:+.1f}% {bar}")
richest = max(vrp['term_vrp'], key=lambda b: b['vrp'])
print(f"\nRichest bucket: {richest['dte']} DTE ({richest['vrp']:+.1f}% VRP)")
5. Strategy Scores
Five premium-selling structures scored 0-100 based on current VRP, gamma regime, directional skew, and macro context:
scores = vrp['strategy_scores']
ranked = sorted(scores.items(), key=lambda x: x[1] or 0, reverse=True)
print("Strategy Suitability:")
for name, score in ranked:
if score is not None:
bar = "█" * (score // 5)
print(f" {name:20s} {score:3d}/100 {bar}")
Iron condor scores high when VRP is elevated and balanced, gamma is positive, and VIX term structure is in contango. Jade lizard scores high when put-side VRP is disproportionately rich. Calendar spreads score high when the term VRP curve is steep. The API does the scoring logic. Your dashboard just renders it.
6. The Harvest Score: Should You Sell Premium?
This is the most important number. It combines VRP richness with the gamma regime into a single 0-1 composite.
gex = vrp['gex_conditioned']
regime = vrp['regime']
print(f"Gamma regime: {regime['gamma']}")
print(f"VRP regime: {regime['vrp_regime']}")
print(f"Harvest score: {gex['harvest_score']:.2f}")
print(f"Interpretation: {gex['interpretation']}")
print(f"Net GEX: ${regime['net_gex']:,.0f}")
print(f"Gamma flip: {regime['gamma_flip']}")
if gex['harvest_score'] > 0.7:
print("FAVORABLE for premium selling")
elif gex['harvest_score'] > 0.4:
print("ACCEPTABLE with caution")
else:
print("UNFAVORABLE - consider sitting out")
Elevated VRP in a negative gamma environment is a trap. The premium is rich because the risk is real. The harvest score catches this. TSLA might show a z-score of 2.14 (93rd percentile) but a harvest score of only 0.52 because dealers are short gamma. SPY might show a lower z-score of 1.42 but a harvest score of 0.78 because dealers are long gamma and pinning price. Your dashboard should surface this distinction.
7. Risk Flags
print(f"Dealer flow risk: {vrp['dealer_flow_risk']}/100")
if vrp['warnings']:
for w in vrp['warnings']:
print(f" ⚠ {w}")
else:
print("No active warnings")
Warnings include negative_gamma, FOMC, earnings, and low_liquidity. Display prominently. They override any positive VRP signal.
Multi-Symbol Scanner
Scan your universe and sort by harvest score:
from flashalpha import FlashAlpha
fa = FlashAlpha("YOUR_KEY")
universe = ["SPY", "QQQ", "IWM", "TSLA", "NVDA", "AAPL", "AMZN", "META", "GOOGL", "MSFT"]
results = []
for sym in universe:
try:
v = fa.vrp(sym)
results.append({
'symbol': sym,
'z_score': v['vrp']['z_score'],
'percentile': v['vrp']['percentile'],
'harvest_score': v['net_harvest_score'],
'best_strategy': max(v['strategy_scores'], key=lambda k: v['strategy_scores'][k] or 0),
'warnings': v['warnings'],
'dealer_risk': v['dealer_flow_risk']
})
except Exception as e:
print(f"Skipping {sym}: {e}")
results.sort(key=lambda r: r['harvest_score'], reverse=True)
print(f"\n{'Symbol':>6} {'Harvest':>8} {'Z-Score':>8} {'Pctl':>5} {'Risk':>5} {'Strategy':>20}")
print("-" * 65)
for r in results:
warn = " ⚠" if r['warnings'] else ""
print(f"{r['symbol']:>6} {r['harvest_score']:>8.2f} {r['z_score']:>+8.2f} {r['percentile']:>4.0f}% {r['dealer_risk']:>5} {r['best_strategy']:>20}{warn}")
Example output:
Symbol Harvest Z-Score Pctl Risk Strategy
-----------------------------------------------------------------
SPY 0.78 +1.42 84% 22 iron_condor
AAPL 0.71 +0.34 58% 18 iron_condor
QQQ 0.65 +0.88 71% 35 short_strangle
NVDA 0.61 +1.67 88% 41 jade_lizard
TSLA 0.52 +2.14 93% 58 short_strangle ⚠
TSLA has the richest raw VRP but the lowest harvest score. The API already factored in the dangerous gamma regime. Your dashboard shows what matters: not just "is premium rich" but "is it safe to harvest."
Using with AI Agents (MCP)
FlashAlpha provides an MCP server. Connect it to Claude, Cursor, or any MCP-compatible agent:
{
"mcpServers": {
"flashalpha": {
"url": "https://lab.flashalpha.com/mcp",
"headers": {
"X-Api-Key": "YOUR_KEY"
}
}
}
}
The agent can query VRP data, interpret z-scores and strategy scores, and generate trade recommendations grounded in live data. The AI becomes the dashboard.
Why Not Compute VRP Yourself?
You can. Here's what it takes:
- Options chain data source ($200-2,500/mo)
- ATM IV calculation with skew and forward price handling
- Realized vol across 4 windows with split/dividend adjustment
- Rolling z-score and percentile (252-day lookback)
- Directional decomposition (25-delta wing extraction)
- Term structure fitting across DTE buckets
- Gamma regime conditioning (net GEX, dealer positioning) — itself a major project
- Strategy scoring model (VRP + skew + gamma + macro + event risk)
- Infrastructure to run intraday for your universe
That's 3-6 months of engineering. The VRP endpoint exists so you don't have to.
API Reference
GET /v1/vrp/{symbol}
Headers:
X-Api-Key: YOUR_KEY
Response: Full VRP analysis (see field table above)
Rate limits:
Free: 10 req/day
Basic: 250 req/day
Growth: 2,500 req/day
Alpha: Unlimited
The VRP endpoint is available on all plans including the free tier for basic VRP data. Full strategy scores, GEX conditioning, and macro context require Growth or Alpha.
- Get API key — free tier, no credit card
-
Python SDK —
pip install flashalpha - Full VRP endpoint docs
- GitHub examples
Related guides:
Top comments (0)