FlashAlpha Python SDK: Open-Source Tools for Options Analytics

FlashAlpha Python SDK: Open-Source Tools for Options Analytics

The definitive guide to building options analytics with Python. Install the FlashAlpha SDK, explore five open-source GitHub repos, and build production-grade tools - GEX dashboards, 0DTE trading bots, IV scanners, vol surface monitors, and more. Includes 20+ code examples, production patterns, and a complete method reference.

T
Tomasz Dobrowolski Quant Engineer
Mar 25, 2026
46 min read
Python SDK OpenSource OptionsAnalytics API GammaExposure Volatility

The Problem: Options Analytics Is Hard to Build Yourself

Consider what you need to build a real-time gamma exposure dashboard from scratch:

  • Options data. A Polygon.io or OPRA feed runs $500-$5,000/month depending on granularity. You need every strike, every expiry, every quote - not just the top-of-book.
  • Greeks computation. Black-Scholes looks simple until you handle American exercise, dividend adjustments, and the fact that you need a volatility surface (which itself requires greeks to calibrate).
  • Exposure aggregation. Summing gamma across thousands of strikes, adjusting for open interest, and attributing flows to dealer hedging requires assumptions about positioning that take months to validate.
  • Infrastructure. Intraday data means running compute during market hours, handling exchange outages, managing caches, and keeping latency under control.
  • Ongoing maintenance. Options markets evolve. 0DTE volumes tripled in 2024. New weekly expirations appear constantly. Your code needs to keep up.

FlashAlpha eliminates all of this. One API key, one SDK, one line of code - and you get institutional-grade analytics that would take a team of quant engineers months to replicate. The five open-source repos on GitHub give you working code to learn from, modify, and deploy.

Here is what you can build:

  • A multi-symbol GEX dashboard that scans SPY, QQQ, TSLA, and NVDA every 15 minutes for regime changes and key levels
  • A 0DTE morning pre-flight that checks pin risk, expected move, theta acceleration, and vol context before you place a single trade
  • An IV rank scanner that monitors 50 tickers for volatility risk premium opportunities
  • A vol surface monitor that detects skew shifts and butterfly arbitrage violations in real time
  • A production scheduler that runs all of the above on cron with error recovery and logging

Every example in this guide uses real API responses with correct field names. Every script runs against the live API. No synthetic data, no delayed feeds.


1. Getting Started in 60 Seconds

Install the SDK, create a client, and make your first call. The entire process takes less than a minute.

pip install flashalpha
from flashalpha import FlashAlpha

fa = FlashAlpha("YOUR_API_KEY")

# Your first call  -  gamma exposure for SPY
gex = fa.gex("SPY")
print(f"Net GEX: ${gex['net_gex']:,.0f}")
print(f"Gamma flip: {gex['gamma_flip']}")
print(f"Regime: {'Positive  -  mean reverting' if gex['net_gex'] > 0 else 'Negative  -  trending'}")

That is it. No HTTP setup, no headers, no JSON parsing. The SDK handles authentication via X-Api-Key, retries on transient failures, and raises typed exceptions for every error condition.

To see how rich the responses are, here is what you get from the exposure_levels() endpoint - the five structural levels that define dealer positioning:

levels = fa.exposure_levels("SPY")
lvl = levels["levels"]

# Every key level in a single call
print(f"Gamma flip:          {lvl['gamma_flip']}")        # Where net GEX crosses zero
print(f"Call wall:           {lvl['call_wall']}")          # Strongest call gamma  -  resistance
print(f"Put wall:            {lvl['put_wall']}")           # Strongest put gamma  -  support
print(f"Max positive gamma:  {lvl['max_positive_gamma']}") # Peak stabilizing force
print(f"Max negative gamma:  {lvl['max_negative_gamma']}") # Peak destabilizing force
print(f"Highest OI strike:   {lvl['highest_oi_strike']}")  # Maximum open interest
print(f"0DTE magnet:         {lvl['zero_dte_magnet']}")    # Intraday gravitational pull

These are not chart patterns or moving averages. These are structural levels created by options market maker hedging - billions of dollars of mechanical order flow that activates when price approaches these strikes. The gamma flip level alone is one of the most powerful intraday signals available: above it, dealers buy dips (stabilizing); below it, dealers sell dips (destabilizing).

Get your API key: Sign up at flashalpha.com/pricing. The free tier gives you 5 requests per day - enough to run every example in this guide and start building.

PyPI: pypi.org/project/flashalpha
SDK source: github.com/FlashAlpha-lab/flashalpha-python


2. The Python SDK: Architecture & Complete Reference

The SDK is a thin wrapper - intentionally. It adds authentication, typed exceptions, and retry logic without hiding the API's response structure. What you get back from the SDK is exactly what the API returns, as Python dicts. No magic, no ORMs, no surprises.

Design Principles

  • Zero dependencies beyond requests. No framework lock-in, no heavy installs.
  • Typed exceptions. Every HTTP error code maps to a specific exception class with structured fields - not just a message string.
  • Automatic retries. Transient 5xx errors and network timeouts are retried with exponential backoff. You do not need to build retry logic.
  • Pass-through responses. The SDK does not reshape API responses. Field names in your code match the API docs exactly.

Complete Method Reference

CategoryMethodsMin. Plan
Exposure analyticsgex(), dex(), vex(), chex(), exposure_levels(), exposure_summary(), narrative()Free / Growth
0DTE analyticszero_dte()Growth
Market datastock_quote(), option_quote(), stock_summary(), surface()Free / Growth
Historical data (point-in-time replay on historical.flashalpha.com)historical_stock_quote(), historical_option_quote(), plus full mirror of every analytics method via FlashAlpha(..., base_url="https://historical.flashalpha.com") with at= paramAlpha
Pricing & greeksgreeks(), iv(), kelly()Free / Growth
Volatilityvolatility(), adv_volatility()Growth / Alpha
Referencetickers(), options(), symbols(), account(), health()Free

Error Handling: Real-World Patterns

The SDK raises specific exceptions for every API error code. This lets you build graceful degradation, plan upgrade prompts, and retry logic without parsing error messages.

from flashalpha import (
    FlashAlpha,
    AuthenticationError,    # 401  -  bad or missing API key
    TierRestrictedError,    # 403  -  endpoint requires a higher plan
    NotFoundError,          # 404  -  ticker not found
    RateLimitError,         # 429  -  daily quota exceeded
)

fa = FlashAlpha("YOUR_API_KEY")

def get_full_analysis(symbol):
    """Fetch what we can, degrade gracefully for plan limits."""
    result = {"symbol": symbol}

    # GEX is available on all plans
    try:
        result["gex"] = fa.exposure_levels(symbol)
    except NotFoundError:
        print(f"{symbol}: not found  -  skipping")
        return None
    except RateLimitError as e:
        print(f"Rate limited  -  retry after {e.retry_after}s")
        return None

    # 0DTE requires Growth plan  -  handle gracefully
    try:
        result["zero_dte"] = fa.zero_dte(symbol)
    except TierRestrictedError as e:
        print(f"0DTE requires {e.required_plan} (you have {e.current_plan})")
        result["zero_dte"] = None

    # Volatility requires Growth plan
    try:
        result["vol"] = fa.volatility(symbol)
    except TierRestrictedError:
        result["vol"] = None

    return result

# Run it
analysis = get_full_analysis("SPY")
if analysis:
    lvl = analysis["gex"]["levels"]
    print(f"SPY gamma flip: {lvl['gamma_flip']}, call wall: {lvl['call_wall']}")

This pattern - try the call, catch the specific exception, continue with what you have - is the recommended way to build multi-endpoint workflows. Your script keeps running even when some endpoints require a plan upgrade.

Building a Reusable Client Wrapper

For production code, wrap the SDK in a class that adds logging, caching, and default error handling:

import logging
from datetime import datetime, timedelta
from flashalpha import FlashAlpha, RateLimitError, NotFoundError

logger = logging.getLogger("flashalpha")

class FAClient:
    """Production wrapper with caching and error handling."""

    def __init__(self, api_key, cache_ttl_seconds=300):
        self.fa = FlashAlpha(api_key)
        self.cache = {}
        self.ttl = timedelta(seconds=cache_ttl_seconds)

    def _cached(self, key, fn):
        now = datetime.now()
        if key in self.cache:
            data, ts = self.cache[key]
            if now - ts < self.ttl:
                return data
        try:
            data = fn()
            self.cache[key] = (data, now)
            return data
        except RateLimitError as e:
            logger.warning(f"Rate limited  -  retry after {e.retry_after}s")
            if key in self.cache:
                return self.cache[key][0]  # Return stale data
            raise
        except NotFoundError:
            logger.warning(f"Not found: {key}")
            return None

    def levels(self, symbol):
        return self._cached(f"levels:{symbol}", lambda: self.fa.exposure_levels(symbol))

    def zero_dte(self, symbol):
        return self._cached(f"0dte:{symbol}", lambda: self.fa.zero_dte(symbol))

    def vol(self, symbol):
        return self._cached(f"vol:{symbol}", lambda: self.fa.volatility(symbol))

This gives you a 5-minute cache (configurable), graceful fallback to stale data on rate limits, structured logging, and a clean interface. Every production example later in this guide builds on this pattern.


3. Build a GEX Dashboard - Multi-Symbol Scanner

Repo: github.com/FlashAlpha-lab/gex-explained

Gamma exposure is the single most important metric for understanding how dealer hedging moves markets. When net GEX is positive, dealers buy dips and sell rips - stabilizing price and compressing realized volatility. When net GEX is negative, dealers do the opposite - amplifying moves and creating the trending, high-volatility days that blow up short premium positions.

The gex-explained repo teaches you the theory. Here, we will build the practical tool: a scanner that checks GEX regime, key levels, and hedging flows for your entire watchlist in a single run.

from flashalpha import FlashAlpha

fa = FlashAlpha("YOUR_API_KEY")
watchlist = ["SPY", "QQQ", "TSLA", "NVDA", "AAPL", "AMZN", "META", "AMD"]

print(f"{'Symbol':<8} {'Net GEX':>12} {'Regime':<12} {'Gamma Flip':>12} {'Call Wall':>11} {'Put Wall':>10}")
print("-" * 75)

for symbol in watchlist:
    try:
        levels = fa.exposure_levels(symbol)
        summary = fa.exposure_summary(symbol)
        lvl = levels["levels"]

        regime = "POSITIVE" if summary["net_gex"] > 0 else "NEGATIVE"
        net_gex_str = f"${summary['net_gex']:,.0f}"

        print(f"{symbol:<8} {net_gex_str:>12} {regime:<12} "
              f"{lvl['gamma_flip']:>12} {lvl['call_wall']:>11} {lvl['put_wall']:>10}")

        # Flag dangerous conditions
        if regime == "NEGATIVE":
            print(f"  >> WARNING: {symbol} in negative gamma  -  expect amplified moves")
        if lvl.get("zero_dte_magnet"):
            print(f"  >> 0DTE magnet at {lvl['zero_dte_magnet']}  -  watch for pin into close")

    except Exception as e:
        print(f"{symbol:<8} Error: {e}")

print("\n--- Key Takeaways ---")
print("Positive gamma = mean-reverting, fade extremes, sell premium")
print("Negative gamma = trending, buy breakouts, hedge tail risk")

This 25-line script replaces a Bloomberg terminal's GEX screen. Run it before the open to know which symbols are in positive gamma (safe to sell premium) and which are in negative gamma (dangerous for short options, good for directional plays).

What Each Field Means for Trading

  • Gamma flip - the most important level of the day. Above it, dealers stabilize price. Below it, dealers amplify moves. Trade differently on each side.
  • Call wall - the strike with the highest call gamma. Acts as resistance because dealers sell into rallies here. Breaks above the call wall often accelerate.
  • Put wall - the strike with the highest put gamma. Acts as support because dealers buy dips here. Breaks below the put wall trigger cascading selling.
  • Max positive gamma - the strike exerting the strongest stabilizing force. Price near this level tends to get "stuck" in a tight range.
  • Max negative gamma - the strike exerting the strongest destabilizing force. Price near this level tends to accelerate away from it.
  • 0DTE magnet - the strike where zero-day options create the strongest gravitational pull. Becomes dominant in the last 2 hours of trading.

For a deep-dive into trading GEX across multiple tickers, see GEX Trading Guide: SPY, TSLA, QQQ.

See these levels live for any symbol

Gamma flip, call wall, put wall, dealer hedging flows - updated in real time. Free account gets you started.

View SPY Dashboard

4. 0DTE Intraday Analytics - Morning Pre-Flight Check

Repo: github.com/FlashAlpha-lab/0dte-options-analytics

Zero-day-to-expiration options now account for over 40% of SPY options volume. Their gamma is 2-10x higher than weekly options. Their theta decay accelerates exponentially through the session. And their pin risk creates gravitational fields around high-OI strikes that can dominate price action in the final two hours.

The zero_dte() endpoint packs all of this into a single call. Here is a complete morning pre-flight script that checks every signal before you place your first 0DTE trade:

from flashalpha import FlashAlpha, TierRestrictedError

fa = FlashAlpha("YOUR_API_KEY")

def morning_preflight(symbol):
    """Complete 0DTE pre-flight check. Run at 9:35 AM ET."""
    print(f"\n{'='*60}")
    print(f"  0DTE PRE-FLIGHT: {symbol}")
    print(f"{'='*60}")

    zdte = fa.zero_dte(symbol)

    # 1. Regime  -  the single most important signal
    regime = zdte["regime"]
    print(f"\n[REGIME]")
    print(f"  Label:          {regime['label']}")
    print(f"  Gamma flip:     {regime['gamma_flip']}")
    print(f"  Spot vs flip:   {regime['spot_vs_flip']}")

    # 2. Pin risk  -  will price get stuck at a strike?
    pin = zdte["pin_risk"]
    print(f"\n[PIN RISK]")
    print(f"  Pin score:      {pin['pin_score']}/100")
    print(f"  Magnet strike:  ${pin['magnet_strike']}")
    print(f"  Distance:       {pin['distance_to_magnet_pct']:.2f}%")
    print(f"  Max pain:       ${pin['max_pain']}")
    print(f"  OI top 3:       {pin['oi_concentration_top3_pct']:.1f}%")

    # 3. Expected move  -  what is the market pricing in?
    em = zdte["expected_move"]
    print(f"\n[EXPECTED MOVE]")
    print(f"  Implied 1SD:    +-${em['implied_1sd_dollars']:.2f}")
    print(f"  Remaining 1SD:  +-${em['remaining_1sd_dollars']:.2f}")
    print(f"  Upper bound:    ${em['upper_bound']:.2f}")
    print(f"  Lower bound:    ${em['lower_bound']:.2f}")
    print(f"  Straddle:       ${em['straddle_price']:.2f}")

    # 4. Exposures  -  how much gamma is in 0DTE specifically?
    exp = zdte["exposures"]
    print(f"\n[0DTE EXPOSURES]")
    print(f"  Net GEX:        ${exp['net_gex']:,.0f}")
    print(f"  % of total:     {exp['pct_of_total_gex']:.1f}%")

    # 5. Theta decay  -  how fast is time value evaporating?
    decay = zdte["decay"]
    print(f"\n[DECAY]")
    print(f"  Theta/hr:       ${decay['theta_per_hour_remaining']:.2f}")
    print(f"  Gamma accel:    {decay['gamma_acceleration']:.4f}")
    print(f"  Charm:          {decay['charm_description']}")

    # 6. Vol context  -  is 0DTE IV cheap or expensive vs 7DTE?
    vol = zdte["vol_context"]
    print(f"\n[VOL CONTEXT]")
    print(f"  0DTE ATM IV:    {vol['zero_dte_atm_iv']:.1f}%")
    print(f"  7DTE ATM IV:    {vol['seven_dte_atm_iv']:.1f}%")
    print(f"  IV ratio:       {vol['iv_ratio_0dte_7dte']:.2f}")

    # 7. Meta
    print(f"\n[TIMING]")
    print(f"  Hours to close: {zdte['time_to_close_hours']:.1f}")
    print(f"  Expiration:     {zdte['expiration']}")

    # Decision framework
    print(f"\n{'='*60}")
    print(f"  TRADING SIGNALS")
    print(f"{'='*60}")

    if pin["pin_score"] >= 70:
        print(f"  HIGH PIN RISK  -  favor butterfly/iron fly around ${pin['magnet_strike']}")
    elif pin["pin_score"] >= 40:
        print(f"  MODERATE PIN  -  magnet at ${pin['magnet_strike']} may attract price into close")
    else:
        print(f"  LOW PIN RISK  -  directional plays viable, less magnetic pull")

    if vol["iv_ratio_0dte_7dte"] > 1.15:
        print(f"  0DTE IV ELEVATED  -  premium selling has edge, 0DTE vol overpriced vs 7DTE")
    elif vol["iv_ratio_0dte_7dte"] < 0.85:
        print(f"  0DTE IV CHEAP  -  premium buying has edge, consider straddles/strangles")

    if regime["label"] == "Negative Gamma":
        print(f"  NEGATIVE GAMMA  -  trending day likely, use momentum strategies")
    else:
        print(f"  POSITIVE GAMMA  -  mean-reverting, fade moves toward walls")

# Run for SPY and QQQ
try:
    morning_preflight("SPY")
    morning_preflight("QQQ")
except TierRestrictedError as e:
    print(f"\n0DTE analytics requires the {e.required_plan} plan.")
    print(f"You have: {e.current_plan}")
    print(f"Upgrade at: https://flashalpha.com/pricing")

This script gives you a complete decision framework in under 2 seconds. Every signal has a direct trading implication:

  • Pin score above 70 - price is likely to converge on the magnet strike. Sell premium around that level. Butterflies and iron flies centered at the magnet have the highest expected value.
  • IV ratio above 1.15 - 0DTE implied vol is expensive relative to 7DTE. The market is overpricing intraday risk. Sell 0DTE premium, or trade 7DTE for better value.
  • Negative gamma regime - dealers amplify moves instead of dampening them. Do not fight the trend. Momentum strategies and breakout plays work here.
  • Theta per hour remaining - tells you the actual dollars per hour being extracted from option holders. High theta + high pin score = sell premium into the close.

Related articles:

Growth plan unlocks 0DTE analytics

Pin risk, expected move, theta decay, gamma regime, vol context - everything you need for intraday 0DTE trading. 2,500 requests/day.

View Growth Plan

5. Volatility Surface & SVI - IV Scanner and Arbitrage Detection

Repo: github.com/FlashAlpha-lab/volatility-surface-python

An implied volatility surface maps IV across two dimensions - strike (moneyness) and expiration (time). It is the core data structure for options pricing, risk management, and relative value analysis. The volatility-surface-python repo provides Python scripts for building, calibrating, and analyzing IV surfaces.

Build a VRP Scanner Across Your Watchlist

The volatility risk premium (VRP) - the spread between implied and realized vol - is one of the most persistent edges in options markets. This script scans a watchlist for the best VRP opportunities:

from flashalpha import FlashAlpha, TierRestrictedError

fa = FlashAlpha("YOUR_API_KEY")
watchlist = ["SPY", "QQQ", "AAPL", "TSLA", "NVDA", "AMZN", "META", "AMD", "MSFT", "GOOGL"]

results = []
for symbol in watchlist:
    try:
        vol = fa.volatility(symbol)
        atm_iv = vol["atm_iv"]
        rv = vol["realized_vol"]
        spreads = vol["iv_rv_spreads"]

        results.append({
            "symbol": symbol,
            "atm_iv": atm_iv,
            "rv_20d": rv["rv_20d"],
            "vrp_20d": spreads["vrp_20d"],
            "assessment": spreads["assessment"],
        })
    except TierRestrictedError:
        print(f"{symbol}: volatility requires Growth plan  -  skipping")
        break
    except Exception as e:
        print(f"{symbol}: {e}")

# Sort by VRP  -  highest first (best premium selling opportunities)
results.sort(key=lambda x: x["vrp_20d"], reverse=True)

print(f"\n{'Symbol':<8} {'ATM IV':>8} {'RV 20d':>8} {'VRP 20d':>9} {'Assessment'}")
print("-" * 55)
for r in results:
    print(f"{r['symbol']:<8} {r['atm_iv']:>7.1f}% {r['rv_20d']:>7.1f}% "
          f"{r['vrp_20d']:>+8.1f}% {r['assessment']}")

print("\nPositive VRP = IV > RV = sell premium")
print("Negative VRP = RV > IV = buy premium or hedge")

The volatility() endpoint also returns full skew profiles across expirations, giving you the smile shape at each tenor:

vol = fa.volatility("SPY")

print(f"\nSPY Skew Profiles:")
print(f"{'Expiry':<12} {'25d Put':>8} {'ATM':>8} {'25d Call':>9} {'Skew':>8} {'Smile':>8}")
print("-" * 60)

for profile in vol["skew_profiles"]:
    print(f"{profile['expiry']:<12} {profile['put_25d_iv']:>7.1f}% {profile['atm_iv']:>7.1f}% "
          f"{profile['call_25d_iv']:>8.1f}% {profile['skew_25d']:>+7.1f}% "
          f"{profile['smile_ratio']:>7.2f}")

A skew of -5% means 25-delta puts are 5 percentage points more expensive than 25-delta calls - the market is pricing in more downside risk. A smile ratio above 1.0 means both wings are elevated relative to ATM - fat tails are being priced in. Tracking these across time reveals when the market shifts from complacency to fear.

SVI Parameters - What They Mean for Trading

FlashAlpha uses the Stochastic Volatility Inspired (SVI) model to fit total variance across strikes for each expiry. The SVI formula is:

SVI Total Variance $$ w(k) = a + b\left(\rho(k - m) + \sqrt{(k - m)^2 + \sigma^2}\right) $$

where \(k = \ln(K/F)\) is the log-moneyness. The five parameters each tell you something about the market's risk perception:

  • \(a\) - overall variance level. Higher \(a\) = the entire surface is elevated. Think VIX spike.
  • \(b\) - wing slope. Controls how fast IV rises as you move away from ATM. Higher \(b\) = fatter tails being priced in. This is the tail risk parameter.
  • \(\rho\) - skew direction. Negative \(\rho\) means puts are more expensive than calls (normal equity skew). A \(\rho\) moving toward zero means skew is flattening - often a complacency signal.
  • \(m\) - shifts the minimum variance point. When \(m\) is negative, the cheapest IV is below ATM - unusual and potentially a signal of dislocated pricing.
  • \(\sigma\) - curvature at the minimum. Higher \(\sigma\) = rounder bottom, more gradual smile. Lower \(\sigma\) = sharper V-shape, more aggressive kink near ATM.
from flashalpha import FlashAlpha

fa = FlashAlpha("YOUR_API_KEY")
adv_vol = fa.adv_volatility("SPY")

print("SPY SVI Parameters by Expiry:")
print(f"{'Expiry':<12} {'DTE':>5} {'a':>8} {'b':>8} {'rho':>8} {'m':>8} {'sigma':>8} {'RMSE':>10}")
print("-" * 70)

for exp in adv_vol["svi_parameters"][:6]:
    p = exp["params"]
    print(f"{exp['expiry']:<12} {exp['dte']:>5} {p['a']:>8.4f} {p['b']:>8.4f} "
          f"{p['rho']:>8.4f} {p['m']:>8.4f} {p['sigma']:>8.4f} {exp['fit_rmse']:>10.6f}")

print("\nTrading signals from SVI:")
print("  rho near 0    = flat skew, complacency, consider buying put skew")
print("  rho very neg  = steep skew, fear, consider selling put skew")
print("  b rising      = tail risk priced in, wings expensive")
print("  RMSE > 0.005  = poor fit, possible arbitrage in that expiry")

Arbitrage Detection

The volatility-surface-python repo includes a butterfly and calendar arbitrage detector. Butterfly arbitrage means the smile violates convexity - you can lock in a guaranteed profit by trading three strikes. Calendar arbitrage means total variance decreases with time - also a guaranteed profit. Both are rare in liquid names but occur regularly in less-traded tickers:

# From the volatility-surface-python repo: arbitrage_detection_butterfly_calendar.py
# Checks for butterfly spread and calendar spread arbitrage violations
# across the entire volatility surface. Flags any (strike, expiry)
# combinations where the SVI fit produces negative butterfly spread
# or non-monotonic total variance in time.

# See the full script at:
# https://github.com/FlashAlpha-lab/volatility-surface-python

Related articles:

Alpha plan unlocks SVI, VRP, and arbitrage detection

Advanced volatility endpoints with SVI parameterization, variance swaps, and full arbitrage checking. Unlimited requests.

View Alpha Plan

6. Production Patterns - From Scripts to Scheduled Systems

The examples above are scripts you run manually. To turn them into production tools, you need rate limit handling, caching, scheduling, error recovery, and logging. This section shows you how.

Rate Limit Handling

Every plan has a daily request quota. The SDK raises RateLimitError with a retry_after field when you hit it. The smart approach is to track usage and stop before you hit the limit:

class RateLimitTracker:
    """Track API usage to avoid hitting limits."""

    def __init__(self, fa, daily_limit):
        self.fa = fa
        self.daily_limit = daily_limit
        self.used = 0

    def call(self, method, *args, **kwargs):
        if self.used >= self.daily_limit - 10:  # Leave a buffer
            raise Exception(f"Approaching daily limit ({self.used}/{self.daily_limit})")
        result = getattr(self.fa, method)(*args, **kwargs)
        self.used += 1
        return result

# Usage
tracker = RateLimitTracker(fa, daily_limit=2500)  # Growth plan
levels = tracker.call("exposure_levels", "SPY")

Scheduled GEX Scanner - Every 15 Minutes During Market Hours

This is the pattern that turns a script into a trading tool. It runs a GEX scan every 15 minutes from 9:35 AM to 4:00 PM ET, logs results, and handles every failure mode:

import time
import logging
from datetime import datetime
import pytz
from flashalpha import FlashAlpha, RateLimitError, NotFoundError

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s [%(levelname)s] %(message)s",
    handlers=[
        logging.FileHandler("gex_scanner.log"),
        logging.StreamHandler()
    ]
)
logger = logging.getLogger("gex_scanner")

fa = FlashAlpha("YOUR_API_KEY")
ET = pytz.timezone("US/Eastern")
WATCHLIST = ["SPY", "QQQ", "TSLA", "NVDA"]
SCAN_INTERVAL = 900  # 15 minutes

def is_market_hours():
    now = datetime.now(ET)
    if now.weekday() >= 5:  # Weekend
        return False
    market_open = now.replace(hour=9, minute=35, second=0)
    market_close = now.replace(hour=16, minute=0, second=0)
    return market_open <= now <= market_close

def scan_once():
    for symbol in WATCHLIST:
        try:
            levels = fa.exposure_levels(symbol)
            lvl = levels["levels"]
            summary = fa.exposure_summary(symbol)
            regime = "POS" if summary["net_gex"] > 0 else "NEG"

            logger.info(
                f"{symbol}: {regime} gamma | flip={lvl['gamma_flip']} "
                f"call_wall={lvl['call_wall']} put_wall={lvl['put_wall']} "
                f"net_gex=${summary['net_gex']:,.0f}"
            )

            if regime == "NEG":
                logger.warning(f"{symbol} NEGATIVE GAMMA  -  amplified moves expected")

        except RateLimitError as e:
            logger.error(f"Rate limited  -  stopping scan. Retry after {e.retry_after}s")
            return False
        except NotFoundError:
            logger.warning(f"{symbol} not found  -  removing from watchlist")
        except Exception as e:
            logger.error(f"{symbol} error: {e}")
    return True

def main():
    logger.info("GEX scanner started")
    while True:
        if is_market_hours():
            logger.info("--- Running scan ---")
            if not scan_once():
                logger.error("Rate limited  -  sleeping 1 hour")
                time.sleep(3600)
                continue
        else:
            logger.info("Market closed  -  sleeping 5 minutes")
        time.sleep(SCAN_INTERVAL)

if __name__ == "__main__":
    main()

Deploy this on any server or even a Raspberry Pi. Set it up as a systemd service or a cron job. The log file gives you a complete history of GEX regime changes throughout the day - invaluable for post-market analysis.

Caching Strategy

Options data changes throughout the trading day, but not every second. A sensible caching strategy saves API calls without sacrificing accuracy:

  • Exposure levels: Cache for 5-15 minutes. Key levels shift slowly unless there is a major move.
  • 0DTE analytics: Cache for 2-5 minutes. Pin risk and expected move update more frequently, especially in the last hour.
  • Volatility data: Cache for 15-30 minutes. IV surfaces move slowly during normal trading.
  • Stock quotes: Cache for 30-60 seconds if you need near-real-time, or do not cache at all.

The FAClient wrapper shown in Section 2 implements this pattern. Adjust the TTL based on your trading frequency and plan limits.


7. What Each Repository Contains

FlashAlpha maintains five open-source repositories on GitHub. Each is self-contained - clone it, add your API key, and run any script independently.

flashalpha-python - The Official SDK

github.com/FlashAlpha-lab/flashalpha-python

For every Python developer using the API. This is the foundation - install it with pip install flashalpha and every other repo builds on it. Includes typed exceptions, automatic retries, and 96% test coverage across 94 tests.

gex-explained - Gamma Exposure Theory & Trading

github.com/FlashAlpha-lab/gex-explained

For traders who want to understand WHY gamma exposure moves markets, not just how to read the numbers. Starts with dealer hedging theory, builds up to multi-symbol GEX scanners. If you trade SPY, QQQ, or any high-options-volume name, start here.

ScriptDescription
compute_gex.pyCalculates GEX from a raw options chain
gamma_exposure_by_strike.pyPulls GEX by strike from the API
gamma_flip_level_tracker.pyTracks gamma flip, call wall, put wall, max pain, 0DTE magnet
call_wall_put_wall_finder.pyScans SPY, QQQ, AAPL, TSLA, NVDA for support/resistance
dealer_hedging_flow_analysis.pyEstimated dealer hedging flows at +/-1% spot moves
gex_trading_spy_tsla_qqq.pyFull GEX analysis across SPY, TSLA, QQQ
exposure_narrative_analysis.pyAI-generated exposure narrative
delta_vanna_charm_exposure.pyDEX, VEX, CHEX analysis

0dte-options-analytics - Zero-DTE Positioning & Strategies

github.com/FlashAlpha-lab/0dte-options-analytics

For intraday traders focused on 0DTE options. If you trade same-day SPY options, iron condors into the close, or 0DTE gamma scalps, this repo gives you the data-driven edge you need. Requires Growth plan.

ScriptDescription
0dte_pin_risk_analysis.pyPin score, magnet strike, OI concentration, max pain
0dte_expected_move_calculator.pyFull-day and remaining 1SD, straddle price
0dte_gamma_regime_tracker.pyPositive vs negative gamma, gamma flip, % of total GEX
0dte_dealer_hedging_flows.pyDealer hedging at +/-0.5% and +/-1% moves
0dte_theta_decay_monitor.pyNet theta, theta/hour, charm regime, gamma acceleration
0dte_spy_intraday_playbook.pyComplete intraday report
0dte_trading_strategies.py5 strategies: pin play, gamma scalp, vol crush, momentum fade, straddle
0dte_vol_context_analysis.py0DTE vs 7DTE IV ratio, VIX, vanna exposure

volatility-surface-python - IV Surfaces, SVI, VRP & Arbitrage

github.com/FlashAlpha-lab/volatility-surface-python

For quants, vol traders, and anyone who trades options based on relative value rather than direction. If you sell premium based on VRP, trade skew, or look for mispriced wings, this repo is your toolkit. Growth plan for volatility, Alpha plan for SVI.

ScriptDescription
implied_volatility_surface.pyTotal variance surface grid
svi_calibration_example.pyRaw SVI parameters per expiry
variance_swap_pricing.pyFair variance, fair vol, convexity adjustment
volatility_skew_analysis.py10d/25d put/call skew, risk reversal
realized_vs_implied_volatility.pyRV across 5 windows, VRP
volatility_term_structure.pyContango/backwardation shape
arbitrage_detection_butterfly_calendar.pyButterfly and calendar arb violations
greeks_surface_vanna_charm.pyVanna, charm, volga, speed surfaces
iv_rank_scanner.pyMulti-symbol IV rank scanner
vol_risk_premium_analysis.pyDeep-dive VRP analysis
forward_implied_volatility.pyImplied forward prices

flashalpha-examples - Standalone Scripts for Every Endpoint

github.com/FlashAlpha-lab/flashalpha-examples

For developers who want quick, copy-paste examples for specific use cases. Each script is self-contained - no dependencies beyond the SDK. If you just want to pull greeks for an options chain or build a stock quote monitor, start here.

ScriptDescription
gex_by_strike.pyPer-strike gamma exposure breakdown for any ticker
exposure_summary_multi.pyNet GEX, DEX, VEX, CHEX for a watchlist of symbols
options_chain_greeks.pyFull chain with real-time greeks for a specific expiry
iv_surface_grid.pyBuild a strike x expiry IV grid from the surface endpoint
historical_option_prices.pyPull historical option prices for backtesting inputs
stock_quote_monitor.pyReal-time stock quote polling with change alerts
kelly_position_sizing.pyKelly criterion position sizing from API greeks
dealer_narrative.pyAI-generated dealer positioning narrative
multi_symbol_scanner.pyScan 50+ symbols for highest GEX, IV rank, VRP

8. API Plans - What You Can Build at Each Tier

Every plan includes access to the Python SDK, all five GitHub repos, and the Swagger UI. The difference is which endpoints you can call and how many requests you get per day.

PlanPriceRequests/DayWhat You Can Build
Free $0 5 GEX by strike, greeks, IV, stock/option quotes (live host only). Enough to learn the API, run the educational examples, and build proof-of-concept scripts.
Basic $79/mo or $756/yr (annual) 100 Everything in Free + exposure summary, narrative, Kelly criterion, exposure levels. Build a daily GEX scanner, a position sizing tool, or an end-of-day analytics dashboard.
Growth $299/mo or $2,868/yr (annual) 2,500 Everything in Basic + 0DTE analytics, volatility data, surfaces, exposure levels. Build a 0DTE trading bot, an IV scanner, a VRP monitor, or a scheduled intraday system. This is the plan for active traders.
Alpha $1,499/mo or $14,388/yr (annual) Unlimited Everything in Growth + advanced volatility (SVI parameters, variance swaps, arbitrage detection) + full Historical API replay on historical.flashalpha.com with point-in-time ?at= on every analytics endpoint. Build a vol surface monitor, a skew trading system, a backtest harness, or an institutional risk dashboard. No rate limits.

Which plan do you need? If you are learning or prototyping, Free is enough. If you trade options daily and want GEX levels before the open, Basic covers it. If you trade 0DTE or use volatility data for premium selling decisions, Growth is the sweet spot. If you are a quant building surface-level analytics or running a fund, Alpha removes all limits.

Explore the full API interactively

Try every endpoint in the Swagger UI - no signup required. See request/response shapes, test with your API key.

Open Swagger UI

9. Links & Resources

Repositories

Related Articles

Resources

Live Market Pulse

Get tick-by-tick visibility into market shifts with full-chain analytics streaming in real time.

Intelligent Screening

Screen millions of option pairs per second using your custom EV rules, filters, and setups.

Execution-Ready

Instantly send structured orders to Interactive Brokers right from your scan results.

Join the Community

Discord

Engage in real time conversations with us!

Twitter / X

Follow us for real-time updates and insights!

GitHub

Explore our open-source SDK, examples, and analytics resources!