flashalpha-historical
Python SDK for the FlashAlpha Historical API — point-in-time replay of every live analytics endpoint. Ask what GEX, gamma flip, VRP, narrative, max pain, or the full stock summary looked like at any minute back to 2018-04-16, in the same response shape as the live API.
Coverage: SPY 2018-04-16 → today, with daily extensions; more symbols added on demand.
pip install flashalpha-historical
Requires Python 3.10+. Same X-Api-Key you use for api.flashalpha.com.
Alpha plan or higher on every endpoint.
Quickstart
from flashalpha_historical import FlashAlphaHistorical
hx = FlashAlphaHistorical("YOUR_API_KEY")
# One snapshot — what dealer positioning looked like during the COVID crash
snap = hx.exposure_summary("SPY", at="2020-03-16T15:30:00")
print(snap["regime"], snap["exposures"]["net_gex"])
# → 'negative_gamma' -2633970601
The at= parameter accepts strings ("2026-03-05T15:30:00" or
"2026-03-05" → defaults to 16:00 ET), datetime objects, or date objects.
Backtesting
The SDK ships with replay utilities that turn any endpoint into an iterator over a date / minute range. Holiday calendar is built in (NYSE 2018-2026); gap days are skipped silently by default.
Daily replay
from flashalpha_historical import FlashAlphaHistorical, Backtester, iter_days
hx = FlashAlphaHistorical("YOUR_API_KEY")
def strategy(at, snap):
"""Short vol when VRP rich AND dealers long gamma."""
vrp = snap["volatility"]["vrp"]
regime = snap["exposure"]["regime"]
return {
"signal": "short_strangle" if vrp > 5 and regime == "positive_gamma" else None,
"vrp": vrp,
"regime": regime,
}
bt = Backtester(hx, method="stock_summary", symbol="SPY")
results = bt.run(iter_days("2024-01-02", "2024-03-29"), strategy)
# Convert to DataFrame
import pandas as pd
df = pd.DataFrame(bt.to_records(results))
Minute-level replay
from flashalpha_historical import iter_minutes, replay
# Walk every 15 minutes through one trading day
for at, snap in replay(hx, "exposure_summary", "SPY",
iter_minutes("2025-01-15", "2025-01-15", step_minutes=15)):
print(at, snap["regime"], snap["gamma_flip"], snap["exposures"]["net_gex"])
Quota note: every call counts against your daily plan quota (shared with the live API). 1-minute replay = 390 calls per analytic per day — coarsen with
step_minutes=15orstep_minutes=30for development loops.
API
Every analytics method takes a required at keyword argument.
Coverage
| Method | Endpoint |
|---|---|
tickers() |
GET /v1/tickers |
tickers(symbol="SPY") |
GET /v1/tickers?symbol=SPY |
Market data
| Method | Endpoint |
|---|---|
stock_quote(ticker, at=...) |
/v1/stockquote/{ticker} |
option_quote(ticker, at=..., expiry=, strike=, type=) |
/v1/optionquote/{ticker} |
surface(symbol, at=...) |
/v1/surface/{symbol} |
Exposure analytics
| Method | Endpoint |
|---|---|
gex(symbol, at=..., expiration=, min_oi=) |
/v1/exposure/gex/{symbol} |
dex(symbol, at=..., expiration=) |
/v1/exposure/dex/{symbol} |
vex(symbol, at=..., expiration=) |
/v1/exposure/vex/{symbol} |
chex(symbol, at=..., expiration=) |
/v1/exposure/chex/{symbol} |
exposure_summary(symbol, at=...) |
/v1/exposure/summary/{symbol} |
exposure_levels(symbol, at=...) |
/v1/exposure/levels/{symbol} |
narrative(symbol, at=...) |
/v1/exposure/narrative/{symbol} |
zero_dte(symbol, at=..., strike_range=) |
/v1/exposure/zero-dte/{symbol} |
Composite & vol
| Method | Endpoint |
|---|---|
stock_summary(symbol, at=...) |
/v1/stock/{symbol}/summary |
volatility(symbol, at=...) |
/v1/volatility/{symbol} |
adv_volatility(symbol, at=...) |
/v1/adv_volatility/{symbol} |
vrp(symbol, at=...) |
/v1/vrp/{symbol} |
max_pain(symbol, at=..., expiration=) |
/v1/maxpain/{symbol} |
Errors
from flashalpha_historical import (
FlashAlphaHistoricalError, # base
AuthenticationError, # 401
TierRestrictedError, # 403 — needs Alpha plan
InvalidAtError, # 400 — bad `at` format
NoDataError, # 404 — outside coverage / inside gap
SymbolNotFoundError, # 404 — symbol not at this `at`
NoCoverageError, # 404 — symbol not in historical dataset
InsufficientDataError, # 404 — surface grid too sparse
RateLimitError, # 429
ServerError, # 5xx
)
try:
hx.exposure_summary("SPY", at="2017-01-01") # before coverage starts
except NoDataError as e:
print("gap:", e)
Known gaps from live (intentional, documented)
optionquote.bidSize/askSize— always0(minute table has no sizes)optionquote.volume/gex.call_volume/put_volume— always0optionquote.svi_vol—nullwithsvi_vol_gated: "backtest_mode"narrative.data.top_oi_changes— empty array (no prior-day OI diff yet)gex.call_oi_change/put_oi_change— alwaysnullstock_summary.macro.vix_futures/fear_and_greed—nullvrp.macro.hy_spread— hard-coded3.5- 0DTE intraday greeks (delta/gamma/theta/iv) often
0/null— chain still listed for OI analysis
License
MIT
Metadata
Release files for flashalpha-historical 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| flashalpha_historical-0.1.0.tar.gz | 15.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| flashalpha_historical-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 30.8 kB
Release files / flashalpha_historical-0.1.0.tar.gz
| Download URL | flashalpha_historical-0.1.0.tar.gz |
|---|---|
| Size | 15.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3bcdd266116b9284ef3b9c53584220f27c4bf0bd5ea737f84c440167efb6c935
|
|
BLAKE2b-256 checksum How to use checksums |
4b0a8087db06dcafb8fe6e19017935165c754ef5b65fc5707e4e7e56aed40bf1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.13
|
Release files / flashalpha_historical-0.1.0-py3-none-any.whl
| Download URL | flashalpha_historical-0.1.0-py3-none-any.whl |
|---|---|
| Size | 15.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7b44fa6bea35f85a3d34cd576919e6bdcfe5dfcf35e799ce6d8396c62d926472
|
|
BLAKE2b-256 checksum How to use checksums |
fb2a92d29aabacbe7867971aebd08b531ec9d8462347bdb7e669348013645680
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.13
|