### API Request Example Source: https://www.optiondata.io/docs/historical-option-trades-api A basic example of the SQL query structure used for requesting historical option trades. ```text api_key=YOUR_API_KEY&sql=SELECT date, time, symbol, put_call, strike, expiration_date, size, price, bid, ask FROM RawOptionTrades WHERE date = (SELECT max(date) FROM RawOptionTrades) AND symbol = 'AAPL' ORDER BY time DESC LIMIT 20 ``` -------------------------------- ### Install Node.js WebSocket package Source: https://www.optiondata.io/docs/realtime-websocket-quickstart Install the required ws package to enable WebSocket communication in your Node.js environment. ```shell npm install ws ``` -------------------------------- ### Connect to OptionData.io WebSocket stream (Python and Go) Source: https://www.optiondata.io/docs/realtime-option-trades-api/?lang=zh Connect to the OptionData.io real-time WebSocket stream and process incoming option trade messages. The Python example uses the `websockets` library, filters messages by daily volume and price (with special handling for SPY), and queues qualifying data; it also includes automatic reconnection with a 2-second backoff. The Go example uses `github.com/gorilla/websocket`, connects with a URL that specifies symbols and a premium filter, reads messages in a goroutine, and handles interrupt signals for graceful shutdown. ```python import asyncio import websockets import json import datetime from asyncio import Queue # Set your WebSocket URL here url = "wss://ws.optiondata.io?token=YOUR_API_KEY" # If this runs in a managed notebook with an HTTP proxy, allow the WebSocket # host through the proxy (for example: NO_PROXY=ws.optiondata.io,.optiondata.io). # Create a global queue for demonstration data_queue = Queue() async def connect(): """Connect to WebSocket and process messages.""" while True: try: async with websockets.connect(url, ping_interval=10, ping_timeout=15) as websocket: print(f'[{datetime.datetime.utcnow()}] WebSocket connection opened') try: while True: message = await websocket.recv() print(f"[{datetime.datetime.utcnow()}] Message received: {message[:200]}{'...' if len(message) > 200 else ''}") try: received_data = json.loads(message) option_symbol = received_data.get('option_symbol') if received_data.get('daily_volume', 0) > 1000 and ( (received_data.get('price', 0) > 0.02 and option_symbol != "SPY") or option_symbol == "SPY" ): if option_symbol: await data_queue.put(received_data) # Push to queue print(f"[{datetime.datetime.utcnow()}] Queued data for option_symbol: {option_symbol}") except json.JSONDecodeError as e: print(f"[{datetime.datetime.utcnow()}] Error parsing received data: {e}") except websockets.exceptions.ConnectionClosed as e: print(f"[{datetime.datetime.utcnow()}] WebSocket connection closed: {e}, reconnecting immediately.") except websockets.exceptions.WebSocketException as e: print(f"[{datetime.datetime.utcnow()}] WebSocket error: {e}, reconnecting immediately.") except Exception as e: print(f"[{datetime.datetime.utcnow()}] Unexpected error: {e}, reconnecting immediately.") print(f"[{datetime.datetime.utcnow()}] Waiting 2 seconds before reconnecting...") await asyncio.sleep(2) # Backoff before reconnecting to avoid hammering the server if __name__ == "__main__": try: asyncio.run(connect()) except KeyboardInterrupt: print("Shutting down...") ``` ```go package main import ( "fmt" "log" "os" "os/signal" "github.com/gorilla/websocket" ) func main() { // Define the URL of the WebSocket server url := "wss://ws.optiondata.io?symbols=AAPL,SPX&token=YOUR_API_KEY&premium=[300000,null]" // Connect to the WebSocket server c, _, err := websocket.DefaultDialer.Dial(url, nil) if err != nil { log.Fatalf("Failed to connect to WebSocket server: %v", err) } defer c.Close() // Handle interrupt signals to terminate gracefully interrupt := make(chan os.Signal, 1) signal.Notify(interrupt, os.Interrupt) fmt.Println("WebSocket connection opened") done := make(chan struct{}) // Goroutine for reading messages go func() { defer close(done) for { _, message, err := c.ReadMessage() if err != nil { log.Println("Error reading message:", err) return } fmt.Printf("Received message: %s\n", message) // Ideally, you would parse and handle the JSON message here } }() // Main loop for handling program exit for { select { case <-done: return case <-interrupt: log.Println("Interrupt received, closing WebSocket connection...") // To cleanly close the connection, send a close message and wait for the server to close the connection err := c.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, "")) if err != nil { log.Println("Error during closing WebSocket connection:", err) return } select { case <-done: } return } } } ``` -------------------------------- ### RAW Mode Data Example Source: https://www.optiondata.io/docs/realtime-option-trades-api Example of raw option trade records as they appear in the API. ```text // RAW MODE date time symbol strike put_call expiration_date premium size trade_count 2025-02-01 09:32:02 TSLA 330 CALL 2025-02-15 1000 2 1 2025-02-01 09:32:02 TSLA 330 CALL 2025-02-15 2000 3 1 ``` -------------------------------- ### RAW Data Input Example Source: https://www.optiondata.io/docs/basic-concepts Shows two raw option trades for TSLA $330 Call executed at the same second, with trade_count of 1 each. This is the input to the aggregation logic. ```Text date time symbol strike put_call expiration_date premium size trade_count 2025-02-01 09:32:02 TSLA 330 CALL 2025-02-15 1000 2 1 2025-02-01 09:32:02 TSLA 330 CALL 2025-02-15 2000 3 1 ``` -------------------------------- ### Test Mode Connection URL Source: https://www.optiondata.io/docs/realtime-option-trades-api Example URL for connecting to the API in test mode, which streams sample data without requiring an API token. ```text wss://ws.optiondata.io?test_mode=true&aggregation_mode=AGGREGATED&symbols=TSLA ``` -------------------------------- ### AGGREGATED Output Example Source: https://www.optiondata.io/docs/basic-concepts Shows the aggregated output after combining the two RAW trades, with size 5, premium 3000, and trade_count 2. This is the result of summing sizes, premiums, and counts, while averaging other fields. ```Text date time symbol strike put_call expiration_date premium size trade_count 2025-02-01 09:32:02 TSLA 330 CALL 2025-02-15 3000 5 2 ``` -------------------------------- ### JavaScript API Request Source: https://www.optiondata.io/docs/historical-option-trades-api Example of how to perform a POST request to the historical SQL endpoint using Axios and qs in JavaScript. ```javascript const axios = require('axios'); const qs = require('qs'); let data = qs.stringify({ 'api_key': 'YOUR_API_KEY', 'sql': "SELECT date, time, symbol, put_call, strike, expiration_date, size, price, bid, ask FROM RawOptionTrades WHERE date = (SELECT max(date) FROM RawOptionTrades) AND symbol = 'AAPL' ORDER BY time DESC LIMIT 20" }); let config = { method: 'post', maxBodyLength: Infinity, url: 'https://www.optiondata.io/api/historical/sql', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, data : data }; axios.request(config) .then((response) => { console.log(JSON.stringify(response.data)); }) .catch((error) => { console.log(error); }); ``` -------------------------------- ### Python API Request Source: https://www.optiondata.io/docs/historical-option-trades-api Example of how to perform a POST request to the historical SQL endpoint using Python's http.client. ```python import http.client conn = http.client.HTTPSConnection("www.optiondata.io") payload = "api_key=YOUR_API_KEY&sql=SELECT%20date%2C%20time%2C%20symbol%2C%20put_call%2C%20strike%2C%20expiration_date%2C%20size%2C%20price%2C%20bid%2C%20ask%20FROM%20RawOptionTrades%20WHERE%20date%20%3D%20(SELECT%20max(date)%20FROM%20RawOptionTrades)%20AND%20symbol%20%3D%20'AAPL'%20ORDER%20BY%20time%20DESC%20LIMIT%2020" headers = { 'Content-Type': 'application/x-www-form-urlencoded' } conn.request("POST", "/api/historical/sql", payload, headers) res = conn.getresponse() data = res.read() print(data.decode("utf-8")) ``` -------------------------------- ### curl examples for SPY and historical date Source: https://www.optiondata.io/docs/market-structure-api Example curl requests for the Market Structure API. The first fetches the active/latest snapshot for SPY; the second fetches a historical snapshot for 2026-07-24 using the date query parameter. Both require the Authorization header. ```shell curl "https://www.optiondata.io/api/v1/market-structure/SPY" \ -H "Authorization: Bearer YOUR_API_KEY" curl "https://www.optiondata.io/api/v1/market-structure/SPY?date=2026-07-24" \ -H "Authorization: Bearer YOUR_API_KEY" ``` -------------------------------- ### cURL API Request Source: https://www.optiondata.io/docs/historical-option-trades-api Example of how to perform a POST request to the historical SQL endpoint using cURL. ```shell curl -X POST https://www.optiondata.io/api/historical/sql \ -H "Content-Type: application/x-www-form-urlencoded" \ -H "Authorization: Bearer YOUR_API_KEY" \ --data-urlencode "sql=SELECT date, time, symbol, put_call, strike, expiration_date, size, price, bid, ask FROM RawOptionTrades WHERE date = (SELECT max(date) FROM RawOptionTrades) AND symbol = 'AAPL' ORDER BY time DESC LIMIT 20" ``` -------------------------------- ### AGGREGATED Mode Data Example Source: https://www.optiondata.io/docs/realtime-option-trades-api Example of aggregated option trade records, where trades at the same time and symbol are combined. ```text // AGGREGATED MODE date time symbol strike put_call expiration_date premium size trade_count 2025-02-01 09:32:02 TSLA 330 CALL 2025-02-15 3000 5 2 ``` -------------------------------- ### GET /api/v1/market-structure/{symbol} Source: https://www.optiondata.io/docs/market-structure-quickstart Retrieves the latest market-structure snapshot for a given option root symbol. Requires an API key sent as a bearer token. ```APIDOC ## GET /api/v1/market-structure/{symbol} ### Description Retrieves the latest precomputed market-structure snapshot for a given option root symbol. The snapshot includes structural GEX and open-interest levels, volatility context, and a lightweight flow overlay. ### Method GET ### Endpoint https://www.optiondata.io/api/v1/market-structure/{symbol} ### Parameters #### Path Parameters - **symbol** (string) - Required - The exact option root symbol (e.g., SPY, SPX, SPXW). #### Query Parameters - **date** (string, YYYY-MM-DD) - Optional - Request a retained historical snapshot for a specific date. ### Authentication Authorization: Bearer $OPTIONDATA_API_KEY ### Request Example curl "https://www.optiondata.io/api/v1/market-structure/SPY" \ -H "Authorization: Bearer $OPTIONDATA_API_KEY" ### Response #### Success Response (200) - **data.symbol_meta** (object) - Underlying description, prices, IV rank/percentile, skew, and term structure. - **data.structure** (object) - Spot, GEX/OI totals, Gamma Flip, walls, Max Pain, and expiration aggregates. - **data.flow** (object) - Lightweight session-flow overlay. - **data.intraday_gex** (object) - Latest intraday full-chain GEX summary when available. - **meta.effective_date** (string) - Trading date represented by the snapshot. - **meta.*_as_of** (string) - Freshness timestamps for the corresponding sections. #### Response Example (No explicit response example provided in the source.) ### Error Handling - **401** - Bearer key is missing or invalid. - **403** - Customer lacks active/trialing entitlement. - **404 SYMBOL_NOT_FOUND** - The exact option root is unknown. - **404 SNAPSHOT_NOT_FOUND** - The root exists, but no snapshot was retained for that date. - **429** - Rate limited; honor Retry-After. ``` -------------------------------- ### RAW vs AGGREGATED mode trade aggregation example Source: https://www.optiondata.io/docs/realtime-option-trades-api/?lang=zh Shows two real-time option trade records in RAW mode and the single aggregated record produced from them. In AGGREGATED mode, size and trade_count are summed (5 = 3 + 2), while other fields such as delta, iv, gamma, and theta are averaged. ```plaintext // RAW MODE date time symbol strike put_call expiration_date premium size trade_count 2025-02-01 09:32:02 TSLA 330 CALL 2025-02-15 1000 2 1 2025-02-01 09:32:02 TSLA 330 CALL 2025-02-15 2000 3 1 ``` ```plaintext // AGGREGATED MODE date time symbol strike put_call expiration_date premium size trade_count 2025-02-01 09:32:02 TSLA 330 CALL 2025-02-15 3000 5 2 ``` -------------------------------- ### GET /option-chain Source: https://www.optiondata.io/docs/option-chain-api Retrieves option chain data for a specified trading date. Returns core fields for each option contract, including prices, open interest, volume, implied volatility, and Greeks. ```APIDOC ## [GET] /option-chain ### Description Retrieves option chain data for a specified trading date. Returns core fields for each option contract, including prices, open interest, volume, implied volatility, and Greeks. ### Method GET ### Endpoint /option-chain ### Parameters #### Query Parameters - **date** (string) - Required - Trading date in YYYY-MM-DD format. ### Response #### Success Response (200) - **data** (array) - Array of option contract objects. - **meta** (object) - Metadata containing trading_date and as_of. #### Response Example { "data": [ { "symbol": "string", "option_symbol": "string", "put_call": "CALL | PUT", "strike": "number | null", "expiration_date": "string | null", "bid": "number | null", "ask": "number | null", "last_price": "number | null", "open_interest": "integer string | null", "open_interest_change": "integer string | null", "volume": "integer string | null", "implied_volatility": "number | null", "delta": "number | null", "gamma": "number | null", "theta": "number | null", "vega": "number | null" } ], "meta": { "trading_date": "YYYY-MM-DD", "as_of": "..." } } ``` -------------------------------- ### GET /api/v1/market-structure/:symbol Source: https://www.optiondata.io/docs/market-structure-api Retrieves a precomputed symbol-level snapshot of full-chain dealer-positioning structure (GEX), open interest walls, Max Pain, volatility context, five-minute session flow, and intraday GEX summaries. Requires a signed API key and is included with the realtime plan. ```APIDOC ## GET /api/v1/market-structure/:symbol ### Description Returns a precomputed, symbol-level snapshot of full-chain dealer-positioning structure (GEX), open interest walls, Max Pain, volatility context, and five-minute session flow plus intraday GEX summaries. ### Method GET ### Endpoint https://www.optiondata.io/api/v1/market-structure/:symbol ### Authentication Send your API key as a Bearer token in the Authorization header. The API key may be a raw Stripe customer id (cus_...) or a portal-minted apikey_... token. ### Parameters #### Path Parameters - **symbol** (string) - Required - Underlying option root (e.g. SPY, SPXW, AAPL). Uppercased server-side. #### Query Parameters - **date** (string) - Optional - YYYY-MM-DD retained historical snapshot. Omit for the active/latest snapshot. ### Request Example curl "https://www.optiondata.io/api/v1/market-structure/SPY" \ -H "Authorization: Bearer YOUR_API_KEY" curl "https://www.optiondata.io/api/v1/market-structure/SPY?date=2026-07-24" \ -H "Authorization: Bearer YOUR_API_KEY" ### Response #### Success Response (200) Top-level fields: - **data.symbol** (string) - Exact option root requested - **data.symbol_meta** (object) - Underlying metadata and volatility context - **data.flow** (object) - Lightweight traded-flow overlay for the symbol - **data.intraday_gex** (object | null) - Latest full-chain summary GEX and spot - **data.structure** (object) - Full-chain GEX, OI, levels, strike-by-expiration aggregates - **meta.effective_date** (string) - Snapshot trading date (YYYY-MM-DD) - **meta.structure_as_of** (string) - UTC time when structure metrics were produced - **meta.flow_as_of** (string) - UTC time of the flow overlay - **meta.intraday_gex_as_of** (string | null) - UTC time of the intraday GEX summary symbol_meta highlights: - **underlying_type** (STOCK | ETF | INDEX | null) - Underlying classification - **description** (string) - Company, fund, or index name - **open / high / low / close / last** (number) - Snapshot-date underlying prices - **iv30** (number | null) - Interpolated 30-day ATM implied volatility (decimal) - **iv_rank_1y / iv_percentile_1y** (number | null) - One-year IV rank / percentile as 0-1 fractions - **skew_25d_30d** (number | null) - 30-day 25-delta put/call skew - **iv_term_slope_30_90** (number | null) - 30-to-90-day IV term slope structure highlights: - **spot** (number) - Underlying price used for exposure calculations - **call_oi / put_oi** (number) - All-scope open-interest contract totals - **call_gex / put_gex** (number) - All-scope dollar GEX for a 1% move; put GEX is signed negative - **scopes.all / zero_dte / weekly / monthly** (object | null) - Levels scoped by DTE bucket - **gamma_flip** (number | null) - Nearest repriced zero-net-GEX underlying level - **max_pain** (number | null) - Strike with lowest multiplier-adjusted aggregate payout - **call_gex_wall / put_gex_wall** (number | null) - Strongest call/put GEX strike on the corresponding side of spot - **call_oi_wall / put_oi_wall** (number | null) - Highest call/put OI strike on the corresponding side of spot - **expirations** (array) - Full-chain strike aggregates grouped by expiration flow highlights: - **call_premium / put_premium** (number) - Session option premium by side (USD) - **bullish_dex / bearish_dex** (number) - Bullish and bearish delta-exposure flow totals - **trade_count** (number) - Option trades represented by the overlay - **traded_contract_count** (number) - Distinct contracts with trades intraday_gex highlights: - **spot** (number) - Latest positive underlying price used for the summary - **call_gex** (number) - Full-chain positive call dollar GEX, including zero-trade contracts - **put_gex** (number) - Full-chain signed-negative put dollar GEX, including zero-trade contracts #### Response Example (No explicit response example provided in the source.) ``` -------------------------------- ### GET /api/v1/market-structure/:symbol Source: https://www.optiondata.io/docs/market-structure-api Base endpoint for the Market Structure API. Returns a precomputed symbol-level snapshot of GEX, open interest walls, Max Pain, IV context, and session flow. Requires the realtime plan (trialing or active) and a signed API key. ```http GET https://www.optiondata.io/api/v1/market-structure/:symbol ``` -------------------------------- ### AI assistant prompt for OptionData docs Source: https://www.optiondata.io/docs/manage-api-key Copy this prompt and paste it into ChatGPT, Claude, Claude Code, Cursor, or Codex, then add your question. It instructs the model to read the public OptionData documentation first, without needing an API key. ```text You are helping me use OptionData (https://www.optiondata.io/), an OPRA-licensed U.S. equity options data API. Before answering, fetch these public files (no login required) and treat them as the source of truth: - https://www.optiondata.io/llms.txt — short product map (same content as https://www.optiondata.io/llm.txt) - https://www.optiondata.io/llms-full.txt — full API reference - https://www.optiondata.io/openapi.json — HTTP OpenAPI Do not invent endpoints, fields, tables, or limits. Prefer `Authorization: Bearer apikey_…` for HTTP APIs. Realtime uses `wss://ws.optiondata.io` with a `token` query parameter. Products: - Realtime trades WebSocket: wss://ws.optiondata.io - Historical SQL: POST https://www.optiondata.io/api/historical/sql - Option chain: POST https://www.optiondata.io/api/option-chain - Market structure: GET https://www.optiondata.io/api/v1/market-structure/{symbol} I am asking about: Manage Your API Key - Markdown: https://www.optiondata.io/md/manage-api-key/ - HTML docs: https://www.optiondata.io/docs/manage-api-key/ My question: ``` -------------------------------- ### AI Assistant Prompt for OptionData Queries Source: https://www.optiondata.io/docs/add-payment-method/?lang=zh Use this prompt to instruct AI models to reference OptionData's public documentation files as the source of truth before answering questions about the API. ```text You are helping me use OptionData (https://www.optiondata.io/), an OPRA-licensed U.S. equity options data API. Before answering, fetch these public files (no login required) and treat them as the source of truth: - https://www.optiondata.io/llms.txt — short product map (same content as https://www.optiondata.io/llm.txt) - https://www.optiondata.io/llms-full.txt — full API reference - https://www.optiondata.io/openapi.json — HTTP OpenAPI Do not invent endpoints, fields, tables, or limits. Prefer `Authorization: Bearer apikey_…` for HTTP APIs. Realtime uses `wss://ws.optiondata.io` with a `token` query parameter. Products: - Realtime trades WebSocket: wss://ws.optiondata.io - Historical SQL: POST https://www.optiondata.io/api/historical/sql - Option chain: POST https://www.optiondata.io/api/option-chain - Market structure: GET https://www.optiondata.io/api/v1/market-structure/{symbol} I am asking about: Add a Payment Method During Your Free Trial - Markdown: https://www.optiondata.io/md/add-payment-method/ - HTML docs: https://www.optiondata.io/docs/add-payment-method/ My question: ``` -------------------------------- ### Connect with Node.js client Source: https://www.optiondata.io/docs/realtime-websocket-quickstart A complete Node.js implementation for connecting to the authenticated realtime stream. Ensure the OPTIONDATA_API_KEY environment variable is set before running. ```javascript import WebSocket from 'ws'; const token = process.env.OPTIONDATA_API_KEY; if (!token) throw new Error('OPTIONDATA_API_KEY is required'); const params = new URLSearchParams({ token, symbols: 'AAPL,SPY', aggregation_mode: 'AGGREGATED', }); const ws = new WebSocket(`wss://ws.optiondata.io?${params}`); ws.on('open', () => console.log('Connected')); ws.on('message', (raw) => { const message = JSON.parse(raw.toString()); console.log(message); }); ws.on('close', (code, reason) => { console.log('Closed', code, reason.toString()); }); ws.on('error', (error) => console.error('WebSocket error', error.message)); ``` -------------------------------- ### Prompt for AI assistants to use OptionData public docs Source: https://www.optiondata.io/docs/?lang=zh Copy this prompt into ChatGPT, Claude, Claude Code, Cursor, or Codex, then add your question. It instructs the model to fetch the public files (llms.txt, llms-full.txt, openapi.json) as source of truth and to prefer Bearer token authentication for HTTP APIs. ```markdown You are helping me use OptionData (https://www.optiondata.io/), an OPRA-licensed U.S. equity options data API. Before answering, fetch these public files (no login required) and treat them as the source of truth: - https://www.optiondata.io/llms.txt — short product map (same content as https://www.optiondata.io/llm.txt) - https://www.optiondata.io/llms-full.txt — full API reference - https://www.optiondata.io/openapi.json — HTTP OpenAPI Do not invent endpoints, fields, tables, or limits. Prefer `Authorization: Bearer apikey_…` for HTTP APIs. Realtime uses `wss://ws.optiondata.io` with a `token` query parameter. Products: - Realtime trades WebSocket: wss://ws.optiondata.io - Historical SQL: POST https://www.optiondata.io/api/historical/sql - Option chain: POST https://www.optiondata.io/api/option-chain - Market structure: GET https://www.optiondata.io/api/v1/market-structure/{symbol} Per-page Markdown lives at https://www.optiondata.io/md/{slug} (for example https://www.optiondata.io/md/realtime-option-trades-api/). My question: ``` -------------------------------- ### Bounded SQL Query for RawOptionTrades Source: https://www.optiondata.io/docs/historical-sql-quickstart A sample SQL query that filters by date and symbol, selects specific columns, and limits the output to 20 rows. ```SQL SELECT date, time, symbol, put_call, strike, expiration_date, size, price, bid, ask FROM RawOptionTrades WHERE date = (SELECT max(date) FROM RawOptionTrades) AND symbol = 'AAPL' ORDER BY time DESC LIMIT 20 ``` -------------------------------- ### Go WebSocket Client for Option Trades Source: https://www.optiondata.io/docs/realtime-option-trades-api A Go implementation using the gorilla/websocket package to connect to the API with specific symbol and premium filters, including graceful shutdown handling. ```go package main import ( "fmt" "log" "os" "os/signal" "github.com/gorilla/websocket" ) func main() { // Define the URL of the WebSocket server url := "wss://ws.optiondata.io?symbols=AAPL,SPX&token=YOUR_API_KEY&premium=[300000,null]" // Connect to the WebSocket server c, _, err := websocket.DefaultDialer.Dial(url, nil) if err != nil { log.Fatalf("Failed to connect to WebSocket server: %v", err) } defer c.Close() // Handle interrupt signals to terminate gracefully interrupt := make(chan os.Signal, 1) signal.Notify(interrupt, os.Interrupt) fmt.Println("WebSocket connection opened") done := make(chan struct{}) // Goroutine for reading messages go func() { defer close(done) for { _, message, err := c.ReadMessage() if err != nil { log.Println("Error reading message:", err) return } fmt.Printf("Received message: %s\n", message) // Ideally, you would parse and handle the JSON message here } }() // Main loop for handling program exit for { select { case <-done: return case <-interrupt: log.Println("Interrupt received, closing WebSocket connection...") // To cleanly close the connection, send a close message and wait for the server to close the connection err := c.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, "")) if err != nil { log.Println("Error during closing WebSocket connection:", err) return } select { case <-done: } return } } } ``` -------------------------------- ### SQL expression to prevent NUMERIC_OVERFLOW Source: https://www.optiondata.io/docs/historical-option-trades-api/?lang=zh Example expression to avoid NUMERIC_OVERFLOW when aggregating fixed-precision operands. Cast the price to Float64 before multiplying by size and 100 to stay within supported numeric precision. ```SQL SUM(toFloat64(price) * size * 100) ``` -------------------------------- ### Prompt for AI assistant to use OptionData Realtime Option Trades API docs Source: https://www.optiondata.io/docs/realtime-option-trades-api/?lang=zh Use this prompt to instruct an AI assistant to consult OptionData's public documentation before answering questions about the Realtime Option Trades API. It lists the authoritative files and endpoints, and requires the assistant to avoid inventing details. ```text You are helping me use OptionData (https://www.optiondata.io/), an OPRA-licensed U.S. equity options data API. Before answering, fetch these public files (no login required) and treat them as the source of truth: - https://www.optiondata.io/llms.txt — short product map (same content as https://www.optiondata.io/llm.txt) - https://www.optiondata.io/llms-full.txt — full API reference - https://www.optiondata.io/openapi.json — HTTP OpenAPI Do not invent endpoints, fields, tables, or limits. Prefer `Authorization: Bearer apikey_…` for HTTP APIs. Realtime uses `wss://ws.optiondata.io` with a `token` query parameter. Products: - Realtime trades WebSocket: wss://ws.optiondata.io - Historical SQL: POST https://www.optiondata.io/api/historical/sql - Option chain: POST https://www.optiondata.io/api/option-chain - Market structure: GET https://www.optiondata.io/api/v1/market-structure/{symbol} I am asking about: Realtime Option Trades API - Markdown: https://www.optiondata.io/md/realtime-option-trades-api/ - HTML docs: https://www.optiondata.io/docs/realtime-option-trades-api/ My question: ``` -------------------------------- ### GET /historical-option-trades Source: https://www.optiondata.io/docs/historical-option-trades-api/?lang=zh Retrieves historical option trades data. The response includes trade details such as date, time, symbol, option type, strike, expiration, size, price, and Greeks. Errors are returned with status codes and error messages. ```APIDOC ## [GET] /historical-option-trades ### Description Retrieves historical option trades data. The response includes trade details such as date, time, symbol, option type, strike, expiration, size, price, and Greeks. ### Method GET ### Endpoint /historical-option-trades ### Response #### Success Response (200 OK) - **status** (string) - Always "SUCCESS" - **data** (array) - Array of trade objects - **date** (string) - Trade date (YYYY-MM-DD) - **time** (string) - Trade timestamp (YYYY-MM-DD HH:MM:SS.mmm) - **symbol** (string) - Underlying symbol - **put_call** (string) - Option type: "CALL" or "PUT" - **strike** (number) - Strike price - **expiration_date** (string) - Expiration date (YYYY-MM-DD) - **size** (integer) - Trade size - **price** (number) - Trade price - **bid** (number) - Bid price - **ask** (number) - Ask price - **underlying_price** (number) - Underlying asset price - **iv** (number) - Implied volatility - **delta** (number) - Delta - **gamma** (number) - Gamma - **oi** (integer) - Open interest - **dei** (number) - Delta exposure indicator - **meta** (object) - Metadata - **entitlement** (string) - Entitlement status - **row_limit** (integer) - Maximum number of rows returned - **capped** (boolean) - Whether the response was capped - **minimum_data_delay_minutes** (integer) - Minimum data delay in minutes #### Response Example { "status": "SUCCESS", "data": [ { "date": "2025-01-17", "time": "2025-01-17 09:30:15.123", "symbol": "TSLA", "put_call": "CALL", "strike": 420.000, "expiration_date": "2025-01-24", "size": 10, "price": 4.2500, "bid": 4.2000, "ask": 4.3000, "underlying_price": 418.5200, "iv": 0.4523, "delta": 0.5234, "gamma": 0.012345, "oi": 15234, "dei": 0.0012 } ], "meta": { "entitlement": "active", "row_limit": 10000, "capped": false, "minimum_data_delay_minutes": 15 } } ### Errors #### Invalid API Key - **status** (string) - "ERROR" - **errorMsg** (string) - "API Key is required" #### Invalid SQL - **status** (string) - "ERROR" - **errorMsg** (string) - "Invalid SQL query: Only SELECT queries are allowed" #### Invalid query fields or expressions (422 Unprocessable Content) - **status** (string) - "ERROR" - **errorCode** (string) - "INVALID_QUERY" - **reason** (string) - Possible values: UNKNOWN_IDENTIFIER, UNKNOWN_FUNCTION, TYPE_MISMATCH, NUMERIC_OVERFLOW, SYNTAX_ERROR, INVALID_AGGREGATION, INVALID_ARGUMENTS, INVALID_EXPRESSION - **errorMsg** (string) - Error message Additional error codes: - QUERY_TOO_BROAD (HTTP 422) - Valid query exceeds server read limits - QUERY_TIMEOUT (HTTP 504) - Query timeout - INTERNAL_ERROR (HTTP 500) - Unexpected service or infrastructure failure Unexpected HTTP 500 responses include an X-Request-Id response header. Include that reference when contacting support. ``` -------------------------------- ### WebSocket Connection to wss://ws.optiondata.io Source: https://www.optiondata.io/docs/realtime-option-trades-api/?lang=zh Establishes a WebSocket connection to the realtime option trades API. The connection URL includes query parameters for symbols, authentication token, and optional filters. The sample code shows how to connect, handle messages, and manage connection events. ```APIDOC ## WebSocket Connection ### Description Connect to the realtime option trades WebSocket endpoint to receive streaming trade data. The connection URL supports query parameters for filtering and authentication. ### Endpoint wss://ws.optiondata.io?symbols=AAPL,SPX&token=YOUR_API_KEY&premium=[300000,null] ### Parameters #### Query Parameters - **symbols** (string) - Required - Comma-separated list of option symbols to subscribe to. - **token** (string) - Required - API key for authentication. - **premium** (array) - Optional - Filter for premium range. Format: [min, max]. Example: [300000, null] means minimum premium 300000, no maximum. - **option_activity_type** (string) - Optional - OPRA trade condition code. Values: AUTO, SLAN, MLET, MLAT, ISOI, MESL, TLET, SLFT, MLFT, CBMO. AGGREGATED MODE only. - **trade_count** (array) - Optional - Number of trades involved. Use [1,1] for block trades, [2,null] for aggregated trades. In RAW mode, always 1. - **is_opening_only** (boolean) - Optional - Only opening trades (2 * size >= OI + daily volume). AGGREGATED MODE only. - **size** (array) - Optional - Filter for total order size. Format: [min, max]. Default [0, null]. - **dex** (array) - Optional - Filter for Delta Exposure (DEX). Format: [min, max]. - **dei** (array) - Optional - Filter for Delta Impact (DEI). Format: [min, max]. - **test_mode** (boolean) - Optional - Enable test snapshot mode: server sends pre-loaded sample data and then closes the connection. No authentication required. ### Request Example No request body; connection is established via WebSocket URL. ### Response #### Success Response (Connection Open) - WebSocket connection opened. #### Message Format - Data received as JSON string. #### Response Example { "example": "parsed data" } ### Sample Code (TypeScript) ```typescript import WebSocket from 'ws'; const url = "wss://ws.optiondata.io?symbols=AAPL,SPX&token=YOUR_API_KEY&premium=[300000,null]"; // Create a new WebSocket instance const ws = new WebSocket(url); // Event handler for connection open ws.on('open', function open() { console.log('WebSocket connection opened'); }); // Event handler for incoming messages ws.on('message', function incoming(data) { console.log('Received message:', data); // You can parse and handle the data here try { const receivedData = JSON.parse(data.toString()); console.log('Parsed data:', receivedData); // Further processing of receivedData } catch (error) { console.error('Error parsing received data:', error); } }); // Event handler for connection close ws.on('close', function close() { console.log('WebSocket connection closed'); }); // Event handler for errors ws.on('error', function error(err) { console.error('WebSocket error:', err); }); ``` ``` -------------------------------- ### Connect to WebSocket for real-time option trades Source: https://www.optiondata.io/docs/realtime-option-trades-api/?lang=zh Connects to the real-time option trades WebSocket endpoint using the 'ws' library. The URL includes the symbols, API token, and a premium filter. Handles open, message, close, and error events, parsing incoming JSON data. ```TypeScript import WebSocket from 'ws'; const url = "wss://ws.optiondata.io?symbols=AAPL,SPX&token=YOUR_API_KEY&premium=[300000,null]"; // Create a new WebSocket instance const ws = new WebSocket(url); // Event handler for connection open ws.on('open', function open() { console.log('WebSocket connection opened'); }); // Event handler for incoming messages ws.on('message', function incoming(data) { console.log('Received message:', data); // You can parse and handle the data here try { const receivedData = JSON.parse(data.toString()); console.log('Parsed data:', receivedData); // Further processing of receivedData } catch (error) { console.error('Error parsing received data:', error); } }); // Event handler for connection close ws.on('close', function close() { console.log('WebSocket connection closed'); }); // Event handler for errors ws.on('error', function error(err) { console.error('WebSocket error:', err); }); ``` -------------------------------- ### LLM Prompt Template for OptionData Source: https://www.optiondata.io/docs/basic-concepts A prompt template designed for ChatGPT, Claude, or other AI assistants to ensure they use official OptionData documentation as the source of truth. ```text You are helping me use OptionData (https://www.optiondata.io/), an OPRA-licensed U.S. equity options data API. Before answering, fetch these public files (no login required) and treat them as the source of truth: - https://www.optiondata.io/llms.txt — short product map (same content as https://www.optiondata.io/llm.txt) - https://www.optiondata.io/llms-full.txt — full API reference - https://www.optiondata.io/openapi.json — HTTP OpenAPI Do not invent endpoints, fields, tables, or limits. Prefer `Authorization: Bearer apikey_…` for HTTP APIs. Realtime uses `wss://ws.optiondata.io` with a `token` query parameter. Products: - Realtime trades WebSocket: wss://ws.optiondata.io - Historical SQL: POST https://www.optiondata.io/api/historical/sql - Option chain: POST https://www.optiondata.io/api/option-chain - Market structure: GET https://www.optiondata.io/api/v1/market-structure/{symbol} I am asking about: Options Data Basic Concepts - Markdown: https://www.optiondata.io/md/basic-concepts/ - HTML docs: https://www.optiondata.io/docs/basic-concepts/ My question: ``` -------------------------------- ### Request latest market-structure snapshot with curl Source: https://www.optiondata.io/docs/market-structure-quickstart Fetches the latest market-structure snapshot for the SPY option root. Requires the OPTIONDATA_API_KEY environment variable to be set. Use the exact option root; for index products, roots such as SPX and SPXW are distinct. ```shell curl "https://www.optiondata.io/api/v1/market-structure/SPY" \ -H "Authorization: Bearer $OPTIONDATA_API_KEY" ``` -------------------------------- ### Prompt for AI assistants about the Historical Option Trades API Source: https://www.optiondata.io/docs/historical-option-trades-api/?lang=zh Use this prompt to ask an AI assistant about the Historical Option Trades API. It instructs the model to fetch the public documentation files first and to rely only on those sources, avoiding invented endpoints or fields. Replace the trailing 'My question:' with your specific question. ```text You are helping me use OptionData (https://www.optiondata.io/), an OPRA-licensed U.S. equity options data API. Before answering, fetch these public files (no login required) and treat them as the source of truth: - https://www.optiondata.io/llms.txt — short product map (same content as https://www.optiondata.io/llm.txt) - https://www.optiondata.io/llms-full.txt — full API reference - https://www.optiondata.io/openapi.json — HTTP OpenAPI Do not invent endpoints, fields, tables, or limits. Prefer `Authorization: Bearer apikey_…` for HTTP APIs. Realtime uses `wss://ws.optiondata.io` with a `token` query parameter. Products: - Realtime trades WebSocket: wss://ws.optiondata.io - Historical SQL: POST https://www.optiondata.io/api/historical/sql - Option chain: POST https://www.optiondata.io/api/option-chain - Market structure: GET https://www.optiondata.io/api/v1/market-structure/{symbol} I am asking about: Historical Option Trades API (SQL) - Markdown: https://www.optiondata.io/md/historical-option-trades-api/ - HTML docs: https://www.optiondata.io/docs/historical-option-trades-api/ My question: ``` -------------------------------- ### Python WebSocket Client for Option Trades Source: https://www.optiondata.io/docs/realtime-option-trades-api A Python implementation using the websockets library to connect to the API, filter incoming trades based on volume and price, and queue the data. ```python import asyncio import websockets import json import datetime from asyncio import Queue # Set your WebSocket URL here url = "wss://ws.optiondata.io?token=YOUR_API_KEY" # If this runs in a managed notebook with an HTTP proxy, allow the WebSocket # host through the proxy (for example: NO_PROXY=ws.optiondata.io,.optiondata.io). # Create a global queue for demonstration data_queue = Queue() async def connect(): """Connect to WebSocket and process messages.""" while True: try: async with websockets.connect(url, ping_interval=10, ping_timeout=15) as websocket: print(f'[{datetime.datetime.utcnow()}] WebSocket connection opened') try: while True: message = await websocket.recv() print(f"[{datetime.datetime.utcnow()}] Message received: {message[:200]}{'...' if len(message) > 200 else ''}") try: received_data = json.loads(message) option_symbol = received_data.get('option_symbol') if received_data.get('daily_volume', 0) > 1000 and ( (received_data.get('price', 0) > 0.02 and option_symbol != "SPY") or option_symbol == "SPY" ): if option_symbol: await data_queue.put(received_data) # Push to queue print(f"[{datetime.datetime.utcnow()}] Queued data for option_symbol: {option_symbol}") except json.JSONDecodeError as e: print(f"[{datetime.datetime.utcnow()}] Error parsing received data: {e}") except websockets.exceptions.ConnectionClosed as e: print(f"[{datetime.datetime.utcnow()}] WebSocket connection closed: {e}, reconnecting immediately.") except websockets.exceptions.WebSocketException as e: print(f"[{datetime.datetime.utcnow()}] WebSocket error: {e}, reconnecting immediately.") except Exception as e: print(f"[{datetime.datetime.utcnow()}] Unexpected error: {e}, reconnecting immediately.") print(f"[{datetime.datetime.utcnow()}] Waiting 2 seconds before reconnecting...") await asyncio.sleep(2) # Backoff before reconnecting to avoid hammering the server if __name__ == "__main__": try: asyncio.run(connect()) except KeyboardInterrupt: print("Shutting down...") ```