@insightsentry/mcp 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +137 -0
- package/bin/insightsentry-mcp.js +2 -0
- package/dist/api-client.d.ts +6 -0
- package/dist/api-client.d.ts.map +1 -0
- package/dist/api-client.js +92 -0
- package/dist/api-client.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +122 -0
- package/dist/index.js.map +1 -0
- package/dist/resources.d.ts +9 -0
- package/dist/resources.d.ts.map +1 -0
- package/dist/resources.js +2693 -0
- package/dist/resources.js.map +1 -0
- package/dist/tool-definitions.d.ts +10 -0
- package/dist/tool-definitions.d.ts.map +1 -0
- package/dist/tool-definitions.js +309 -0
- package/dist/tool-definitions.js.map +1 -0
- package/package.json +44 -0
|
@@ -0,0 +1,2693 @@
|
|
|
1
|
+
// AUTO-GENERATED by scripts/generate-docs.ts
|
|
2
|
+
// Static resources (rest-api, workflows) are preserved from the previous version.
|
|
3
|
+
// Extracted resources are regenerated from website TSX doc pages.
|
|
4
|
+
// To regenerate: npm run generate:docs
|
|
5
|
+
export const docResources = [
|
|
6
|
+
{
|
|
7
|
+
uri: "insightsentry://docs/rest-api",
|
|
8
|
+
name: "InsightSentry REST API Guide",
|
|
9
|
+
description: "Complete REST API reference: authentication, base URL, all endpoints with parameters and response formats",
|
|
10
|
+
mimeType: "text/markdown",
|
|
11
|
+
content: `# InsightSentry REST API Guide
|
|
12
|
+
|
|
13
|
+
## Base URL
|
|
14
|
+
\`\`\`
|
|
15
|
+
https://api.insightsentry.com
|
|
16
|
+
\`\`\`
|
|
17
|
+
|
|
18
|
+
## Authentication
|
|
19
|
+
All requests require a Bearer token obtained from the InsightSentry dashboard (https://insightsentry.com/dashboard).
|
|
20
|
+
|
|
21
|
+
\`\`\`
|
|
22
|
+
Authorization: Bearer <your-api-key>
|
|
23
|
+
\`\`\`
|
|
24
|
+
|
|
25
|
+
## Symbol Format
|
|
26
|
+
Symbols use the \`EXCHANGE:SYMBOL\` format. Examples:
|
|
27
|
+
- \`NASDAQ:AAPL\` — Apple on NASDAQ
|
|
28
|
+
- \`NYSE:TSLA\` — Tesla on NYSE
|
|
29
|
+
- \`BINANCE:BTCUSDT\` — Bitcoin/USDT on Binance
|
|
30
|
+
- \`CME_MINI:NQ1!\` — E-mini NASDAQ continuous futures
|
|
31
|
+
- \`COMEX:GC1!\` — Gold continuous futures
|
|
32
|
+
- \`OPRA:AAPL260417P325.0\` — Apple put option
|
|
33
|
+
|
|
34
|
+
Use the \`search_symbols\` tool to find symbol codes.
|
|
35
|
+
|
|
36
|
+
## Endpoints Overview
|
|
37
|
+
|
|
38
|
+
### Time Series & Historical Data
|
|
39
|
+
- **GET /v3/symbols/{symbol}/series** — Recent OHLCV data (up to 30k bars) with real-time option
|
|
40
|
+
- Parameters: bar_type (tick/second/minute/hour/day/week/month), bar_interval (1-1440), dp (data points, 1-30000), extended (pre/post market), dadj (dividend adjustment), badj (back-adjustment), settlement, long_poll (wait for real-time), currency (convert to different currency)
|
|
41
|
+
- **GET /v3/symbols/{symbol}/history** — Deep historical data (20+ years)
|
|
42
|
+
- Parameters: bar_type (second/minute/hour, required), bar_interval, start_date (YYYY-MM or YYYY-MM-DD, required), extended, dadj, badj, settlement
|
|
43
|
+
- Note: Returns data for the specified month. Iterate months for longer ranges.
|
|
44
|
+
|
|
45
|
+
### Symbol Information
|
|
46
|
+
- **GET /v3/symbols/{symbol}/info** — Detailed metadata: type, currency, sector, industry, CEO, market cap, P/E, dividends, splits, option chains, all-time high/low, etc.
|
|
47
|
+
- **GET /v3/symbols/{symbol}/session** — Trading session details: holidays, trading hours, timezone, session corrections
|
|
48
|
+
- **GET /v3/symbols/{symbol}/contracts** — Futures contract list with settlement dates
|
|
49
|
+
|
|
50
|
+
### Quotes
|
|
51
|
+
- **GET /v3/symbols/quotes?codes=...** — Real-time quotes for up to 10 symbols (comma-separated)
|
|
52
|
+
- Returns: last_price, change, change_percent, bid/ask, volume, market_cap, status (OPEN/CLOSED/PRE/POST)
|
|
53
|
+
|
|
54
|
+
### Search
|
|
55
|
+
- **GET /v3/symbols/search** — Search for symbols
|
|
56
|
+
- Parameters: query, type (stock/crypto/futures/forex/etf/bond/index/...), country (2-letter ISO), page
|
|
57
|
+
- Tip: Use \`query=NASDAQ:\` to list all NASDAQ symbols. Leave query empty with type filter to browse.
|
|
58
|
+
|
|
59
|
+
### Fundamentals
|
|
60
|
+
- **GET /v3/symbols/{symbol}/fundamentals** — Comprehensive fundamental data (valuation, profitability, balance sheet, income statement, cash flow)
|
|
61
|
+
- **GET /v3/symbols/{symbol}/fundamentals/series?ids=...** — Historical fundamental indicators (max 5 IDs per request). Get available IDs from the fundamentals meta endpoint.
|
|
62
|
+
- **GET /v3/symbols/fundamentals** — Metadata: available fundamental/technical indicator IDs and their names
|
|
63
|
+
|
|
64
|
+
### Options
|
|
65
|
+
- **GET /v3/options/list?code=...** — List available option contracts for a symbol
|
|
66
|
+
- **GET /v3/options/expiration?code=...&expiration=YYYY-MM-DD** — Option chain by expiration date
|
|
67
|
+
- **GET /v3/options/strike?code=...&strike=210** — Option chain by strike price
|
|
68
|
+
- Both support sortBy (type/ask_price/bid_price/delta/gamma/implied_volatility/rho/strike_price/theta/vega) and sort (asc/desc)
|
|
69
|
+
- Response includes Greeks: delta, gamma, theta, vega, rho, implied_volatility, bid_iv, ask_iv
|
|
70
|
+
|
|
71
|
+
### Screeners
|
|
72
|
+
- **GET /v3/screeners/{type}** — Get available fields, exchanges, countries for a screener type (stock/etf/bond/crypto)
|
|
73
|
+
- **POST /v3/screeners/{type}** — Filter instruments with custom criteria
|
|
74
|
+
- Body: { fields: string[] (required, 1-10), exchanges?: string[], countries?: string[], page?: number, sortBy?: string, sortOrder?: "asc"|"desc", ignore_invalid?: boolean }
|
|
75
|
+
- Response: paginated data with requested fields, up to 1000 items per page
|
|
76
|
+
- Note: Crypto screener does not support country filtering
|
|
77
|
+
|
|
78
|
+
### Calendar
|
|
79
|
+
- **GET /v3/calendar/dividends** — Dividend calendar (w: week range, c: country codes)
|
|
80
|
+
- **GET /v3/calendar/earnings** — Earnings calendar
|
|
81
|
+
- **GET /v3/calendar/ipos** — IPO calendar
|
|
82
|
+
- **GET /v3/calendar/events** — Economic events calendar
|
|
83
|
+
|
|
84
|
+
### News
|
|
85
|
+
- **GET /v3/newsfeed** — Financial news feed
|
|
86
|
+
- Parameters: keywords (comma-separated), limit (1-500, default 500), page
|
|
87
|
+
|
|
88
|
+
### Documents (SEC Filings)
|
|
89
|
+
- **GET /v3/documents?code=...** — List filings/transcripts/reports for a symbol
|
|
90
|
+
- **GET /v3/documents/{id}?code=...** — Get document content (JSON for text, PDF binary for filings)
|
|
91
|
+
|
|
92
|
+
## Response Format: OHLCV Time Series
|
|
93
|
+
\`\`\`json
|
|
94
|
+
{
|
|
95
|
+
"code": "NASDAQ:AAPL",
|
|
96
|
+
"bar_end": 1733432399.0,
|
|
97
|
+
"last_update": 1733432399820,
|
|
98
|
+
"bar_type": "1m",
|
|
99
|
+
"series": [
|
|
100
|
+
{ "time": 1733432340.0, "open": 242.89, "high": 243.09, "low": 242.82, "close": 243.08, "volume": 533779.0 }
|
|
101
|
+
]
|
|
102
|
+
}
|
|
103
|
+
\`\`\`
|
|
104
|
+
|
|
105
|
+
## Response Format: Quote Data
|
|
106
|
+
\`\`\`json
|
|
107
|
+
{
|
|
108
|
+
"total_items": 1,
|
|
109
|
+
"data": [{
|
|
110
|
+
"code": "NASDAQ:AAPL",
|
|
111
|
+
"status": "OPEN",
|
|
112
|
+
"last_price": 239.42,
|
|
113
|
+
"change_percent": -0.15,
|
|
114
|
+
"change": -0.36,
|
|
115
|
+
"ask": 239.47,
|
|
116
|
+
"bid": 239.42,
|
|
117
|
+
"volume": 47549429.0,
|
|
118
|
+
"market_cap": 3558428648118.0,
|
|
119
|
+
"currency_code": "USD",
|
|
120
|
+
"delay_seconds": 0
|
|
121
|
+
}]
|
|
122
|
+
}
|
|
123
|
+
\`\`\`
|
|
124
|
+
|
|
125
|
+
## Interactive Documentation & Examples
|
|
126
|
+
- API Playground: https://insightsentry.com/docs
|
|
127
|
+
- OpenAPI Spec: https://insightsentry.com/openapi.json
|
|
128
|
+
`,
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
uri: "insightsentry://docs/workflows",
|
|
132
|
+
name: "InsightSentry Integration Workflows",
|
|
133
|
+
description: "Step-by-step workflows for common use cases: building trading apps, dashboards, screeners, and WebSocket integrations",
|
|
134
|
+
mimeType: "text/markdown",
|
|
135
|
+
content: `# InsightSentry Integration Workflows
|
|
136
|
+
|
|
137
|
+
This guide helps you build applications that integrate with the InsightSentry API. Each workflow includes the recommended tool sequence, code patterns, and best practices.
|
|
138
|
+
|
|
139
|
+
## Workflow 1: Build a Stock Dashboard
|
|
140
|
+
|
|
141
|
+
### What you need
|
|
142
|
+
A dashboard showing real-time quotes, charts, and company info for user-selected symbols.
|
|
143
|
+
|
|
144
|
+
### REST API Setup
|
|
145
|
+
\`\`\`
|
|
146
|
+
1. search_symbols(query="apple") → Get symbol code "NASDAQ:AAPL"
|
|
147
|
+
2. get_quotes(codes="NASDAQ:AAPL") → Current price, change, bid/ask
|
|
148
|
+
3. get_symbol_series(symbol="NASDAQ:AAPL", bar_type="day", dp=365) → 1 year daily chart
|
|
149
|
+
4. get_symbol_info(symbol="NASDAQ:AAPL") → Company details, sector, market cap
|
|
150
|
+
5. get_symbol_fundamentals(symbol="NASDAQ:AAPL") → P/E, revenue, earnings
|
|
151
|
+
\`\`\`
|
|
152
|
+
|
|
153
|
+
### Add Real-Time Updates via WebSocket
|
|
154
|
+
\`\`\`javascript
|
|
155
|
+
// After initial REST load, connect WebSocket for live updates
|
|
156
|
+
const ws = new WebSocket('wss://realtime.insightsentry.com/live');
|
|
157
|
+
|
|
158
|
+
ws.onopen = () => {
|
|
159
|
+
ws.send(JSON.stringify({
|
|
160
|
+
api_key: API_KEY,
|
|
161
|
+
subscriptions: [
|
|
162
|
+
{ code: 'NASDAQ:AAPL', type: 'quote' }, // Live price updates
|
|
163
|
+
{ code: 'NASDAQ:AAPL', type: 'series', bar_type: 'minute', bar_interval: 1 } // Live chart
|
|
164
|
+
]
|
|
165
|
+
}));
|
|
166
|
+
// Keep-alive
|
|
167
|
+
setInterval(() => ws.send('ping'), 25000);
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
ws.onmessage = (event) => {
|
|
171
|
+
const msg = event.data;
|
|
172
|
+
if (msg === 'pong') return;
|
|
173
|
+
const data = JSON.parse(msg);
|
|
174
|
+
if (data.server_time) return; // Heartbeat
|
|
175
|
+
|
|
176
|
+
if (data.data) {
|
|
177
|
+
// Quote update — data.data[0] has last_price, change, bid, ask, etc.
|
|
178
|
+
updateQuoteDisplay(data.data[0]);
|
|
179
|
+
} else if (data.series) {
|
|
180
|
+
// Series update — data.series has new OHLCV bars
|
|
181
|
+
updateChart(data.series);
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
\`\`\`
|
|
185
|
+
|
|
186
|
+
### Python Equivalent
|
|
187
|
+
\`\`\`python
|
|
188
|
+
import asyncio, json, websockets, requests
|
|
189
|
+
|
|
190
|
+
API_KEY = "your-api-key"
|
|
191
|
+
BASE = "https://api.insightsentry.com"
|
|
192
|
+
HEADERS = {"Authorization": f"Bearer {API_KEY}"}
|
|
193
|
+
|
|
194
|
+
# Initial data load via REST
|
|
195
|
+
quote = requests.get(f"{BASE}/v3/symbols/quotes", headers=HEADERS, params={"codes": "NASDAQ:AAPL"}).json()
|
|
196
|
+
series = requests.get(f"{BASE}/v3/symbols/NASDAQ:AAPL/series", headers=HEADERS, params={"bar_type": "day", "dp": 365}).json()
|
|
197
|
+
|
|
198
|
+
# Then stream updates via WebSocket
|
|
199
|
+
async def stream():
|
|
200
|
+
async with websockets.connect("wss://realtime.insightsentry.com/live") as ws:
|
|
201
|
+
await ws.send(json.dumps({
|
|
202
|
+
"api_key": API_KEY,
|
|
203
|
+
"subscriptions": [
|
|
204
|
+
{"code": "NASDAQ:AAPL", "type": "quote"},
|
|
205
|
+
{"code": "NASDAQ:AAPL", "type": "series", "bar_type": "minute", "bar_interval": 1}
|
|
206
|
+
]
|
|
207
|
+
}))
|
|
208
|
+
async for message in ws:
|
|
209
|
+
if message == "pong": continue
|
|
210
|
+
data = json.loads(message)
|
|
211
|
+
if "server_time" in data: continue
|
|
212
|
+
process_update(data)
|
|
213
|
+
|
|
214
|
+
asyncio.run(stream())
|
|
215
|
+
\`\`\`
|
|
216
|
+
|
|
217
|
+
## Workflow 2: Build a Market Screener
|
|
218
|
+
|
|
219
|
+
### Step-by-step
|
|
220
|
+
\`\`\`
|
|
221
|
+
1. get_stock_screener_params() → Discover available fields, exchanges, countries
|
|
222
|
+
2. screen_stocks({ fields: ["close","change_percent","volume","market_cap"], sortBy: "market_cap", sortOrder: "desc", countries: ["US"] })
|
|
223
|
+
3. For each result, optionally: get_quotes(codes="RESULT_CODE_1,RESULT_CODE_2,...") for live prices
|
|
224
|
+
\`\`\`
|
|
225
|
+
|
|
226
|
+
### Implementation Pattern
|
|
227
|
+
\`\`\`python
|
|
228
|
+
# 1. Discover fields
|
|
229
|
+
params = requests.get(f"{BASE}/v3/screeners/stock", headers=HEADERS).json()
|
|
230
|
+
print("Fields:", params["available_fields"][:20])
|
|
231
|
+
print("Exchanges:", params["available_exchanges"])
|
|
232
|
+
|
|
233
|
+
# 2. Run screener
|
|
234
|
+
results = requests.post(f"{BASE}/v3/screeners/stock", headers=HEADERS, json={
|
|
235
|
+
"fields": ["close", "change_percent", "volume", "market_cap"],
|
|
236
|
+
"countries": ["US"],
|
|
237
|
+
"exchanges": ["NASDAQ", "NYSE"],
|
|
238
|
+
"sortBy": "market_cap",
|
|
239
|
+
"sortOrder": "desc",
|
|
240
|
+
"page": 1
|
|
241
|
+
}).json()
|
|
242
|
+
|
|
243
|
+
# 3. Paginate
|
|
244
|
+
while results["hasNext"]:
|
|
245
|
+
next_page = results["current_page"] + 1
|
|
246
|
+
results = requests.post(f"{BASE}/v3/screeners/stock", headers=HEADERS, json={
|
|
247
|
+
"fields": ["close", "change_percent", "volume", "market_cap"],
|
|
248
|
+
"countries": ["US"],
|
|
249
|
+
"sortBy": "market_cap",
|
|
250
|
+
"sortOrder": "desc",
|
|
251
|
+
"page": next_page
|
|
252
|
+
}).json()
|
|
253
|
+
\`\`\`
|
|
254
|
+
|
|
255
|
+
## Workflow 3: Options Trading App
|
|
256
|
+
|
|
257
|
+
### Step-by-step
|
|
258
|
+
\`\`\`
|
|
259
|
+
1. search_symbols(query="AAPL") → "NASDAQ:AAPL"
|
|
260
|
+
2. get_symbol_info(symbol="NASDAQ:AAPL") → Check option_info for available expirations & strikes
|
|
261
|
+
3. list_options(code="NASDAQ:AAPL") → All option contracts
|
|
262
|
+
4. get_options_expiration(code="NASDAQ:AAPL", expiration="2027-06-17", sortBy="strike_price") → Chain with Greeks
|
|
263
|
+
5. get_quotes(codes="OPRA:AAPL270617C200.0") → Real-time option price
|
|
264
|
+
6. get_symbol_series(symbol="OPRA:AAPL270617C200.0", bar_type="day") → Historical option prices
|
|
265
|
+
\`\`\`
|
|
266
|
+
|
|
267
|
+
### Option Code Cheatsheet
|
|
268
|
+
\`OPRA:AAPL260417P325.0\` = Exchange:Symbol + YYMMDD + C/P + Strike
|
|
269
|
+
- OPRA = Options exchange
|
|
270
|
+
- AAPL = Underlying
|
|
271
|
+
- 260417 = Expires April 17, 2026
|
|
272
|
+
- P = Put (C = Call)
|
|
273
|
+
- 325.0 = Strike price
|
|
274
|
+
|
|
275
|
+
## Workflow 4: News & Events Monitoring
|
|
276
|
+
|
|
277
|
+
### REST polling
|
|
278
|
+
\`\`\`
|
|
279
|
+
1. get_newsfeed(keywords="earnings,fed", limit=50) → Latest news
|
|
280
|
+
2. get_earnings(w=1, c="US") → This week's US earnings
|
|
281
|
+
3. get_events(w=1) → Economic events this week
|
|
282
|
+
\`\`\`
|
|
283
|
+
|
|
284
|
+
### Real-time news via WebSocket
|
|
285
|
+
\`\`\`javascript
|
|
286
|
+
const ws = new WebSocket('wss://realtime.insightsentry.com/newsfeed');
|
|
287
|
+
ws.onopen = () => {
|
|
288
|
+
ws.send(JSON.stringify({ api_key: API_KEY }));
|
|
289
|
+
// Server immediately sends 10 most recent news items
|
|
290
|
+
// Then pushes new items as they arrive
|
|
291
|
+
};
|
|
292
|
+
ws.onmessage = (event) => {
|
|
293
|
+
if (event.data === 'pong') return;
|
|
294
|
+
const news = JSON.parse(event.data);
|
|
295
|
+
displayNewsItem(news);
|
|
296
|
+
};
|
|
297
|
+
\`\`\`
|
|
298
|
+
|
|
299
|
+
## Workflow 5: Historical Data Pipeline (Backtesting)
|
|
300
|
+
|
|
301
|
+
### For recent data (up to 30k bars)
|
|
302
|
+
\`\`\`
|
|
303
|
+
get_symbol_series(symbol="NASDAQ:AAPL", bar_type="minute", bar_interval=5, dp=30000)
|
|
304
|
+
\`\`\`
|
|
305
|
+
|
|
306
|
+
### For deep history (20+ years, month by month)
|
|
307
|
+
\`\`\`python
|
|
308
|
+
# Iterate month by month
|
|
309
|
+
for year in range(2020, 2026):
|
|
310
|
+
for month in range(1, 13):
|
|
311
|
+
start_date = f"{year}-{month:02d}"
|
|
312
|
+
data = requests.get(
|
|
313
|
+
f"{BASE}/v3/symbols/NASDAQ:AAPL/history",
|
|
314
|
+
headers=HEADERS,
|
|
315
|
+
params={"bar_type": "minute", "bar_interval": 1, "start_date": start_date}
|
|
316
|
+
).json()
|
|
317
|
+
save_to_database(data)
|
|
318
|
+
time.sleep(1) # Rate limit courtesy
|
|
319
|
+
\`\`\`
|
|
320
|
+
|
|
321
|
+
### For futures (specific contracts)
|
|
322
|
+
\`\`\`python
|
|
323
|
+
# 1. Find contracts
|
|
324
|
+
contracts = requests.get(f"{BASE}/v3/symbols/COMEX:GC1!/contracts", headers=HEADERS).json()
|
|
325
|
+
|
|
326
|
+
# 2. Fetch each contract's history
|
|
327
|
+
for contract in contracts["contracts"]:
|
|
328
|
+
code = contract["code"] # e.g., "COMEX:GCZ2024"
|
|
329
|
+
for month in ["2024-09", "2024-10", "2024-11", "2024-12"]:
|
|
330
|
+
data = requests.get(
|
|
331
|
+
f"{BASE}/v3/symbols/{code}/history",
|
|
332
|
+
headers=HEADERS,
|
|
333
|
+
params={"bar_type": "minute", "bar_interval": 1, "start_date": month}
|
|
334
|
+
).json()
|
|
335
|
+
time.sleep(1)
|
|
336
|
+
\`\`\`
|
|
337
|
+
|
|
338
|
+
## WebSocket Best Practices
|
|
339
|
+
|
|
340
|
+
### Connection Management
|
|
341
|
+
- Always re-send subscription message in \`onOpen\` (handles reconnection)
|
|
342
|
+
- Implement exponential backoff for reconnection (2s, 4s, 8s, max 30s)
|
|
343
|
+
- Send \`"ping"\` every 25 seconds to keep connection alive
|
|
344
|
+
- Set client timeout to at least 12 seconds
|
|
345
|
+
|
|
346
|
+
### Subscription Management
|
|
347
|
+
- Each new subscription message **replaces all** previous subscriptions
|
|
348
|
+
- Include ALL symbols you want in every message
|
|
349
|
+
- Don't send more than 300 messages per 5 minutes
|
|
350
|
+
|
|
351
|
+
### Data Handling
|
|
352
|
+
- Filter out \`"pong"\` string messages
|
|
353
|
+
- Filter out heartbeats: \`{"server_time": ...}\`
|
|
354
|
+
- Quote updates come in \`data\` array, series updates in \`series\` array
|
|
355
|
+
|
|
356
|
+
## Rate Limiting Tips
|
|
357
|
+
- REST API: Respect rate limits based on your plan tier
|
|
358
|
+
- Run requests sequentially for historical data (concurrent may fail)
|
|
359
|
+
- Screener returns up to 1000 items per page — use pagination
|
|
360
|
+
- get_quotes supports up to 10 symbols per call
|
|
361
|
+
- get_fundamentals_series supports up to 5 indicator IDs per call
|
|
362
|
+
`,
|
|
363
|
+
},
|
|
364
|
+
{
|
|
365
|
+
uri: "insightsentry://docs/websocket",
|
|
366
|
+
name: "InsightSentry WebSocket API Guide",
|
|
367
|
+
description: "Complete WebSocket API documentation: connection, authentication, subscriptions, data formats, keepalive, error handling, and code examples",
|
|
368
|
+
mimeType: "text/markdown",
|
|
369
|
+
content: `# InsightSentry WebSocket API Guide
|
|
370
|
+
|
|
371
|
+
Interactive examples: https://insightsentry.com/test/realtime and https://insightsentry.com/test/newsfeed
|
|
372
|
+
|
|
373
|
+
## 1. Getting Started
|
|
374
|
+
|
|
375
|
+
|
|
376
|
+
### Prerequisites
|
|
377
|
+
|
|
378
|
+
Before connecting to our WebSocket API, ensure you have the
|
|
379
|
+
following:
|
|
380
|
+
|
|
381
|
+
|
|
382
|
+
|
|
383
|
+
- WebSocket API Key - Get your unique key from the /v2/websocket-key endpoint Note: This key is different from your REST API keys
|
|
384
|
+
|
|
385
|
+
- WebSocket Client Library - Choose one that supports automatic reconnection and retry logic
|
|
386
|
+
|
|
387
|
+
- Connection Settings - Configure appropriate timeouts and implement ping/pong for stability
|
|
388
|
+
|
|
389
|
+
|
|
390
|
+
|
|
391
|
+
|
|
392
|
+
---
|
|
393
|
+
|
|
394
|
+
|
|
395
|
+
### Connecting to the Server
|
|
396
|
+
|
|
397
|
+
Our WebSocket API provides two specialized endpoints for different
|
|
398
|
+
types of financial data.
|
|
399
|
+
|
|
400
|
+
|
|
401
|
+
|
|
402
|
+
|
|
403
|
+
#### Market Data
|
|
404
|
+
|
|
405
|
+
|
|
406
|
+
Real-time quotes, time series data, and tick data
|
|
407
|
+
|
|
408
|
+
|
|
409
|
+
|
|
410
|
+
|
|
411
|
+
#### News Feed
|
|
412
|
+
|
|
413
|
+
|
|
414
|
+
Latest financial news and market updates
|
|
415
|
+
|
|
416
|
+
|
|
417
|
+
|
|
418
|
+
|
|
419
|
+
|
|
420
|
+
### Authentication
|
|
421
|
+
|
|
422
|
+
Both endpoints require your WebSocket API key, but the
|
|
423
|
+
authentication format varies by endpoint.
|
|
424
|
+
|
|
425
|
+
|
|
426
|
+
|
|
427
|
+
#### Market Data Authentication
|
|
428
|
+
|
|
429
|
+
Combine authentication with your subscription request (covered in
|
|
430
|
+
the next section).
|
|
431
|
+
|
|
432
|
+
|
|
433
|
+
|
|
434
|
+
|
|
435
|
+
|
|
436
|
+
#### News Feed Authentication
|
|
437
|
+
|
|
438
|
+
Send only your API key in this simplified format:
|
|
439
|
+
|
|
440
|
+
|
|
441
|
+
\`\`\`json
|
|
442
|
+
{
|
|
443
|
+
"api_key": ""
|
|
444
|
+
// No subscriptions needed for news feed
|
|
445
|
+
|
|
446
|
+
\`\`\`
|
|
447
|
+
|
|
448
|
+
|
|
449
|
+
|
|
450
|
+
|
|
451
|
+
|
|
452
|
+
#### News Feed Instant Access
|
|
453
|
+
|
|
454
|
+
When you connect to \`/newsfeed\`, the server
|
|
455
|
+
automatically sends the 10 most recent news items. This gives you
|
|
456
|
+
immediate access to current news without additional requests.
|
|
457
|
+
|
|
458
|
+
|
|
459
|
+
|
|
460
|
+
|
|
461
|
+
|
|
462
|
+
|
|
463
|
+
## 2. Subscribing to Data Feeds
|
|
464
|
+
|
|
465
|
+
|
|
466
|
+
### Initial Subscription
|
|
467
|
+
|
|
468
|
+
After connecting to the market data endpoint, send a JSON message to
|
|
469
|
+
authenticate and subscribe to data feeds.
|
|
470
|
+
|
|
471
|
+
This single message handles both authentication and your initial
|
|
472
|
+
symbol subscriptions.
|
|
473
|
+
|
|
474
|
+
**Required Message Format:**
|
|
475
|
+
|
|
476
|
+
|
|
477
|
+
\`\`\`json
|
|
478
|
+
{
|
|
479
|
+
"api_key": "",
|
|
480
|
+
"subscriptions": [
|
|
481
|
+
// Array of subscription objects
|
|
482
|
+
|
|
483
|
+
\`\`\`
|
|
484
|
+
|
|
485
|
+
|
|
486
|
+
#### Subscription Parameters
|
|
487
|
+
|
|
488
|
+
Each subscription object in the array can include these parameters:
|
|
489
|
+
|
|
490
|
+
|
|
491
|
+
|
|
492
|
+
|
|
493
|
+
##### Required Parameters
|
|
494
|
+
|
|
495
|
+
|
|
496
|
+
|
|
497
|
+
- code - Symbol identifier (e.g., "NASDAQ:AAPL", "BINANCE:BTCUSDT")
|
|
498
|
+
|
|
499
|
+
|
|
500
|
+
|
|
501
|
+
|
|
502
|
+
|
|
503
|
+
|
|
504
|
+
|
|
505
|
+
##### Data Type Selection
|
|
506
|
+
|
|
507
|
+
|
|
508
|
+
|
|
509
|
+
- type - Data feed type: "series" (default) or "quote"
|
|
510
|
+
|
|
511
|
+
|
|
512
|
+
|
|
513
|
+
**Tip:** Since "series" is default, you
|
|
514
|
+
can omit this parameter for series data
|
|
515
|
+
|
|
516
|
+
|
|
517
|
+
|
|
518
|
+
|
|
519
|
+
|
|
520
|
+
##### Series Data Parameters (when type="series")
|
|
521
|
+
|
|
522
|
+
|
|
523
|
+
|
|
524
|
+
- bar_type - Time interval: "tick", "second", "minute", "hour", "day", or "week"
|
|
525
|
+
|
|
526
|
+
- bar_interval - Number of units per bar (e.g., 1, 5, 15)
|
|
527
|
+
|
|
528
|
+
- extended - Include extended hours (default: true) - details below
|
|
529
|
+
|
|
530
|
+
- dadj - Apply dividend adjustment (default: false) - details below
|
|
531
|
+
|
|
532
|
+
- badj - Apply back-adjustment for continuous futures contracts (default: false) - details below
|
|
533
|
+
|
|
534
|
+
- max_dp - Number of initial historical data points to receive on connect/reconnect (1-30,000). Default: 1. Mega plan: up to 30,000. Other plans: up to 1,000. Values exceeding your plan's limit are clamped automatically.
|
|
535
|
+
|
|
536
|
+
|
|
537
|
+
|
|
538
|
+
|
|
539
|
+
|
|
540
|
+
|
|
541
|
+
**Example Subscription Message:**
|
|
542
|
+
|
|
543
|
+
|
|
544
|
+
\`\`\`json
|
|
545
|
+
{
|
|
546
|
+
"api_key": "",
|
|
547
|
+
"subscriptions": [
|
|
548
|
+
{"code": "NASDAQ:AAPL", "type": "series", "bar_type": "minute", "bar_interval": 1, "max_dp": 100},
|
|
549
|
+
{"code": "NASDAQ:TSLA", "type": "quote"}
|
|
550
|
+
|
|
551
|
+
\`\`\`
|
|
552
|
+
|
|
553
|
+
|
|
554
|
+
---
|
|
555
|
+
|
|
556
|
+
|
|
557
|
+
### Modifying Subscriptions
|
|
558
|
+
|
|
559
|
+
You can update your subscriptions without disconnecting from the
|
|
560
|
+
WebSocket.
|
|
561
|
+
|
|
562
|
+
Send a new subscription message with your complete desired list. The
|
|
563
|
+
server replaces all previous subscriptions with the new ones.
|
|
564
|
+
|
|
565
|
+
|
|
566
|
+
|
|
567
|
+
#### Complete Replacement
|
|
568
|
+
|
|
569
|
+
Each new subscription message completely replaces your current
|
|
570
|
+
subscriptions. Include all symbols you want to continue receiving
|
|
571
|
+
data for.
|
|
572
|
+
|
|
573
|
+
|
|
574
|
+
|
|
575
|
+
**Example - Updating Subscriptions:**
|
|
576
|
+
|
|
577
|
+
To change from the previous example to track both minute bars and
|
|
578
|
+
quotes for AAPL:
|
|
579
|
+
|
|
580
|
+
|
|
581
|
+
\`\`\`json
|
|
582
|
+
{
|
|
583
|
+
"api_key": "",
|
|
584
|
+
"subscriptions": [
|
|
585
|
+
{"code": "NASDAQ:AAPL", "type": "series", "bar_type": "minute", "bar_interval": 1, "max_dp": 100},
|
|
586
|
+
{"code": "NASDAQ:AAPL", "type": "quote"}
|
|
587
|
+
// NASDAQ:TSLA quote subscription is removed as it's not in the new list
|
|
588
|
+
|
|
589
|
+
\`\`\`
|
|
590
|
+
|
|
591
|
+
|
|
592
|
+
---
|
|
593
|
+
|
|
594
|
+
|
|
595
|
+
### Subscription Rules & Limits
|
|
596
|
+
|
|
597
|
+
Follow these important guidelines when managing your subscriptions:
|
|
598
|
+
|
|
599
|
+
|
|
600
|
+
|
|
601
|
+
|
|
602
|
+
#### Required Authentication
|
|
603
|
+
|
|
604
|
+
Every subscription message must include your valid
|
|
605
|
+
\`api_key\`.
|
|
606
|
+
|
|
607
|
+
|
|
608
|
+
|
|
609
|
+
|
|
610
|
+
|
|
611
|
+
#### Rate Limiting
|
|
612
|
+
|
|
613
|
+
Don't send **300 messages per 5 minutes**. If
|
|
614
|
+
you exceed this limit, your messages will be ignored
|
|
615
|
+
temporarily.
|
|
616
|
+
|
|
617
|
+
**Note:** This only affects new messages you send.
|
|
618
|
+
Your existing data feed continues uninterrupted. Data you
|
|
619
|
+
receive has no rate limit or any restriction.
|
|
620
|
+
|
|
621
|
+
|
|
622
|
+
|
|
623
|
+
|
|
624
|
+
|
|
625
|
+
#### Empty Subscriptions
|
|
626
|
+
|
|
627
|
+
You cannot send an empty \`subscriptions\` array. To
|
|
628
|
+
stop all data, disconnect the WebSocket and reconnect when
|
|
629
|
+
needed.
|
|
630
|
+
|
|
631
|
+
|
|
632
|
+
|
|
633
|
+
|
|
634
|
+
|
|
635
|
+
#### Multiple Symbols
|
|
636
|
+
|
|
637
|
+
Subscribe to multiple symbols in one message by adding multiple
|
|
638
|
+
objects to the \`subscriptions\` array (subject to your
|
|
639
|
+
plan limits).
|
|
640
|
+
|
|
641
|
+
|
|
642
|
+
|
|
643
|
+
|
|
644
|
+
|
|
645
|
+
|
|
646
|
+
|
|
647
|
+
## 3. Response Data Formats
|
|
648
|
+
|
|
649
|
+
The server sends real-time data updates as JSON messages. The format
|
|
650
|
+
|
|
651
|
+
For complete field descriptions, see the corresponding REST API
|
|
652
|
+
documentation: \`/symbols/:symbol/series\` or
|
|
653
|
+
\`/symbols/quotes\`.
|
|
654
|
+
|
|
655
|
+
|
|
656
|
+
### Series Data (type: "series")
|
|
657
|
+
|
|
658
|
+
Series data provides OHLCV (Open, High, Low, Close, Volume) bar
|
|
659
|
+
information and tick data.
|
|
660
|
+
|
|
661
|
+
|
|
662
|
+
|
|
663
|
+
|
|
664
|
+
|
|
665
|
+
|
|
666
|
+
#### Real-time Updates
|
|
667
|
+
|
|
668
|
+
|
|
669
|
+
Regardless of your chosen \`bar_type\` and
|
|
670
|
+
\`bar_interval\`, you receive updates whenever the
|
|
671
|
+
close price or volume changes within the current bar period.
|
|
672
|
+
|
|
673
|
+
**Example:** With
|
|
674
|
+
\`bar_type: "hour"\`, you get real-time
|
|
675
|
+
updates throughout the hour, not just once per hour.
|
|
676
|
+
|
|
677
|
+
|
|
678
|
+
|
|
679
|
+
|
|
680
|
+
|
|
681
|
+
|
|
682
|
+
|
|
683
|
+
|
|
684
|
+
|
|
685
|
+
|
|
686
|
+
|
|
687
|
+
#### Update Frequency by Bar Type
|
|
688
|
+
|
|
689
|
+
Data delivery varies based on your \`bar_type\`
|
|
690
|
+
subscription:
|
|
691
|
+
|
|
692
|
+
|
|
693
|
+
|
|
694
|
+
**Tick Data** (
|
|
695
|
+
\`bar_type: "tick"\`) - Data pushed for
|
|
696
|
+
every individual trade
|
|
697
|
+
|
|
698
|
+
|
|
699
|
+
**Second Intervals** (
|
|
700
|
+
\`bar_type: "second"\`) - Data pushed
|
|
701
|
+
only when close price or volume changes
|
|
702
|
+
|
|
703
|
+
|
|
704
|
+
**Higher Timeframes** (
|
|
705
|
+
\`bar_type: "minute"\` or above) - Data
|
|
706
|
+
pushed when price/volume changes AND when new bar periods
|
|
707
|
+
start
|
|
708
|
+
|
|
709
|
+
|
|
710
|
+
|
|
711
|
+
|
|
712
|
+
|
|
713
|
+
|
|
714
|
+
|
|
715
|
+
\`\`\`json
|
|
716
|
+
{
|
|
717
|
+
"code": "NASDAQ:AAPL",
|
|
718
|
+
"bar_end": 1733432399.0,
|
|
719
|
+
"last_update": 1733432399820,
|
|
720
|
+
"bar_type": "1m",
|
|
721
|
+
"series": [
|
|
722
|
+
{
|
|
723
|
+
"time": 1733432340.0,
|
|
724
|
+
"open": 242.89,
|
|
725
|
+
"high": 243.09,
|
|
726
|
+
"low": 242.82,
|
|
727
|
+
"close": 243.08,
|
|
728
|
+
"volume": 533779.0
|
|
729
|
+
|
|
730
|
+
\`\`\`
|
|
731
|
+
|
|
732
|
+
|
|
733
|
+
---
|
|
734
|
+
|
|
735
|
+
|
|
736
|
+
### Quote Data (type: "quote")
|
|
737
|
+
|
|
738
|
+
Quote data provides real-time market information including current
|
|
739
|
+
prices, trading volume, and bid/ask spreads.
|
|
740
|
+
|
|
741
|
+
This data type is ideal for monitoring current market conditions and
|
|
742
|
+
building trading interfaces.
|
|
743
|
+
|
|
744
|
+
|
|
745
|
+
\`\`\`json
|
|
746
|
+
{
|
|
747
|
+
"last_update": 1757061265540,
|
|
748
|
+
"total_items": 1,
|
|
749
|
+
"data": [
|
|
750
|
+
{
|
|
751
|
+
"code": "NASDAQ:AAPL",
|
|
752
|
+
"status": "PRE",
|
|
753
|
+
"lp_time": 1757061117.0,
|
|
754
|
+
"volume": 47549429.0,
|
|
755
|
+
"last_price": 239.42,
|
|
756
|
+
"change_percent": -0.15,
|
|
757
|
+
"change": -0.36,
|
|
758
|
+
"ask": 239.47,
|
|
759
|
+
"bid": 239.42,
|
|
760
|
+
"ask_size": 2.0,
|
|
761
|
+
"bid_size": 1.0,
|
|
762
|
+
"prev_close_price": 238.47,
|
|
763
|
+
"open_price": 238.45,
|
|
764
|
+
"low_price": 236.74,
|
|
765
|
+
"high_price": 239.8999,
|
|
766
|
+
"market_cap": 3558428648118.0,
|
|
767
|
+
"currency_code": "USD",
|
|
768
|
+
"delay_seconds": 0
|
|
769
|
+
|
|
770
|
+
\`\`\`
|
|
771
|
+
|
|
772
|
+
|
|
773
|
+
|
|
774
|
+
|
|
775
|
+
|
|
776
|
+
|
|
777
|
+
#### Understanding delay_seconds
|
|
778
|
+
|
|
779
|
+
|
|
780
|
+
The \`delay_seconds\` field indicates the data
|
|
781
|
+
delay in seconds:
|
|
782
|
+
|
|
783
|
+
|
|
784
|
+
|
|
785
|
+
- 0 - Real-time with no artificial delay
|
|
786
|
+
|
|
787
|
+
- 900 - Data is delayed by 900 seconds
|
|
788
|
+
|
|
789
|
+
- -1 - End-of-day (EOD)
|
|
790
|
+
|
|
791
|
+
|
|
792
|
+
|
|
793
|
+
|
|
794
|
+
|
|
795
|
+
|
|
796
|
+
|
|
797
|
+
|
|
798
|
+
|
|
799
|
+
|
|
800
|
+
|
|
801
|
+
## 4. Additional Parameters
|
|
802
|
+
|
|
803
|
+
The WebSocket API supports several additional parameters for
|
|
804
|
+
fine-tuning your data feeds and customizing the response format.
|
|
805
|
+
|
|
806
|
+
|
|
807
|
+
### Extended Market Hours (extended)
|
|
808
|
+
|
|
809
|
+
The \`extended\` parameter applies to many US and Global
|
|
810
|
+
stock markets.
|
|
811
|
+
|
|
812
|
+
|
|
813
|
+
|
|
814
|
+
- extended: true (default) - Includes pre-market and after-hours trading data where available. For US equities, this covers 4:00 AM - 9:30 AM ET (pre-market) and 4:00 PM - 8:00 PM ET (after-hours).
|
|
815
|
+
|
|
816
|
+
- extended: false - Only includes regular trading hours data.
|
|
817
|
+
|
|
818
|
+
- Note: Not all markets support extended hours trading. Setting extended: true for markets without extended hours will return only regular session data.
|
|
819
|
+
|
|
820
|
+
|
|
821
|
+
|
|
822
|
+
**Example:**
|
|
823
|
+
|
|
824
|
+
|
|
825
|
+
\`\`\`json
|
|
826
|
+
{
|
|
827
|
+
"api_key": "",
|
|
828
|
+
"subscriptions": [
|
|
829
|
+
{"code": "NASDAQ:AAPL", "bar_type": "minute", "bar_interval": 1, "extended": false}
|
|
830
|
+
|
|
831
|
+
\`\`\`
|
|
832
|
+
|
|
833
|
+
|
|
834
|
+
---
|
|
835
|
+
|
|
836
|
+
|
|
837
|
+
### Dividend Adjustment (dadj)
|
|
838
|
+
|
|
839
|
+
For equities data, you can request dividend-adjusted price series.
|
|
840
|
+
|
|
841
|
+
|
|
842
|
+
|
|
843
|
+
- dadj: true - Applies dividend adjustments to all price values.
|
|
844
|
+
|
|
845
|
+
- dadj: false (default) - Shows unadjusted prices.
|
|
846
|
+
|
|
847
|
+
|
|
848
|
+
|
|
849
|
+
**Example:**
|
|
850
|
+
|
|
851
|
+
|
|
852
|
+
\`\`\`json
|
|
853
|
+
{
|
|
854
|
+
"api_key": "",
|
|
855
|
+
"subscriptions": [
|
|
856
|
+
{"code": "NASDAQ:AAPL", "bar_type": "day", "bar_interval": 1, "dadj": true}
|
|
857
|
+
|
|
858
|
+
\`\`\`
|
|
859
|
+
|
|
860
|
+
|
|
861
|
+
---
|
|
862
|
+
|
|
863
|
+
|
|
864
|
+
### Back-Adjustment (badj)
|
|
865
|
+
|
|
866
|
+
For continuous futures contracts (e.g., ES1!, NQ1!), you can request
|
|
867
|
+
back-adjusted price series to remove price gaps between contract rollovers.
|
|
868
|
+
|
|
869
|
+
|
|
870
|
+
|
|
871
|
+
- badj: true - Applies back-adjustment to smooth price gaps at contract rollovers.
|
|
872
|
+
|
|
873
|
+
- badj: false (default) - Shows unadjusted prices with natural contract rollover gaps.
|
|
874
|
+
|
|
875
|
+
|
|
876
|
+
|
|
877
|
+
**Example:**
|
|
878
|
+
|
|
879
|
+
|
|
880
|
+
\`\`\`json
|
|
881
|
+
{
|
|
882
|
+
"api_key": "",
|
|
883
|
+
"subscriptions": [
|
|
884
|
+
{"code": "CME_MINI:ES1!", "bar_type": "day", "bar_interval": 1, "badj": true}
|
|
885
|
+
|
|
886
|
+
\`\`\`
|
|
887
|
+
|
|
888
|
+
|
|
889
|
+
---
|
|
890
|
+
|
|
891
|
+
|
|
892
|
+
### Settlement Price (settlement)
|
|
893
|
+
|
|
894
|
+
For futures and other applicable instruments, you can control
|
|
895
|
+
whether historical data uses settlement prices for the close value.
|
|
896
|
+
|
|
897
|
+
|
|
898
|
+
|
|
899
|
+
- settlement: true - Uses settlement prices as the close price where applicable.
|
|
900
|
+
|
|
901
|
+
- settlement: false (default) - Uses the regular close price (last traded price).
|
|
902
|
+
|
|
903
|
+
|
|
904
|
+
|
|
905
|
+
**Example:**
|
|
906
|
+
|
|
907
|
+
|
|
908
|
+
\`\`\`json
|
|
909
|
+
{
|
|
910
|
+
"api_key": "",
|
|
911
|
+
"subscriptions": [
|
|
912
|
+
{"code": "CME_MINI:ES1!", "bar_type": "day", "bar_interval": 1, "settlement": false}
|
|
913
|
+
|
|
914
|
+
\`\`\`
|
|
915
|
+
|
|
916
|
+
|
|
917
|
+
### Initial Data Points (max_dp)
|
|
918
|
+
|
|
919
|
+
Control how many historical data points you receive when first
|
|
920
|
+
connecting or reconnecting to a symbol. Accepts a number from 1 to 30,000.
|
|
921
|
+
If not specified, defaults to **1** (only the current bar).
|
|
922
|
+
|
|
923
|
+
When you connect (or reconnect), the first message will contain the
|
|
924
|
+
most recent \`max_dp\` bars in the \`series\` property, followed
|
|
925
|
+
by real-time updates with single bars.
|
|
926
|
+
|
|
927
|
+
|
|
928
|
+
|
|
929
|
+
- Mega Plan (10+ symbol subscriptions): up to 30,000 data points.
|
|
930
|
+
|
|
931
|
+
- Other Plans: up to 1,000 data points.
|
|
932
|
+
|
|
933
|
+
- If you specify a value higher than your plan allows, it will be automatically clamped to your plan's maximum.
|
|
934
|
+
|
|
935
|
+
|
|
936
|
+
|
|
937
|
+
**Example:**
|
|
938
|
+
|
|
939
|
+
|
|
940
|
+
\`\`\`json
|
|
941
|
+
{
|
|
942
|
+
"api_key": "",
|
|
943
|
+
"subscriptions": [
|
|
944
|
+
{"code": "NASDAQ:AAPL", "bar_type": "minute", "bar_interval": 1, "max_dp": 5000}
|
|
945
|
+
|
|
946
|
+
\`\`\`
|
|
947
|
+
|
|
948
|
+
|
|
949
|
+
|
|
950
|
+
|
|
951
|
+
|
|
952
|
+
## 5. Maintaining Connection & Best Practices
|
|
953
|
+
|
|
954
|
+
|
|
955
|
+
### Automatic Re-subscription
|
|
956
|
+
|
|
957
|
+
|
|
958
|
+
|
|
959
|
+
|
|
960
|
+
|
|
961
|
+
|
|
962
|
+
#### Critical Implementation Detail
|
|
963
|
+
|
|
964
|
+
Configure your WebSocket client to automatically send your
|
|
965
|
+
subscription message in the \`onOpen\` event handler.
|
|
966
|
+
This ensures immediate re-subscription after any disconnection
|
|
967
|
+
(network issues, server restarts).
|
|
968
|
+
|
|
969
|
+
|
|
970
|
+
|
|
971
|
+
|
|
972
|
+
|
|
973
|
+
---
|
|
974
|
+
|
|
975
|
+
|
|
976
|
+
### Server Heartbeat (Keep-Alive)
|
|
977
|
+
|
|
978
|
+
Our server automatically sends periodic timestamp messages
|
|
979
|
+
(approximately every 10 seconds) to maintain connection health and
|
|
980
|
+
allow connectivity verification.
|
|
981
|
+
|
|
982
|
+
**Heartbeat Message Format:**
|
|
983
|
+
|
|
984
|
+
|
|
985
|
+
\`\`\`json
|
|
986
|
+
{"server_time": 1741397070281}
|
|
987
|
+
\`\`\`
|
|
988
|
+
|
|
989
|
+
|
|
990
|
+
---
|
|
991
|
+
|
|
992
|
+
|
|
993
|
+
### Preventing Connection Drops
|
|
994
|
+
|
|
995
|
+
Some WebSocket libraries drop connections during inactivity periods.
|
|
996
|
+
Implement a ping-pong mechanism for connection stability.
|
|
997
|
+
|
|
998
|
+
|
|
999
|
+
|
|
1000
|
+
#### Ping-Pong Implementation
|
|
1001
|
+
|
|
1002
|
+
|
|
1003
|
+
|
|
1004
|
+
- Send a 'ping' text message every 20-30 seconds
|
|
1005
|
+
|
|
1006
|
+
- Server responds with 'pong' to confirm connection
|
|
1007
|
+
|
|
1008
|
+
- Filter out 'pong' messages in your data handler
|
|
1009
|
+
|
|
1010
|
+
|
|
1011
|
+
|
|
1012
|
+
|
|
1013
|
+
|
|
1014
|
+
|
|
1015
|
+
|
|
1016
|
+
#### Rate Limiting Warning
|
|
1017
|
+
|
|
1018
|
+
Don't send pings more than once every 15 seconds to avoid
|
|
1019
|
+
triggering rate limits. This WebSocket rate limit is separate from
|
|
1020
|
+
REST API limits.
|
|
1021
|
+
|
|
1022
|
+
|
|
1023
|
+
|
|
1024
|
+
\`\`\`python
|
|
1025
|
+
import asyncio
|
|
1026
|
+
import websockets
|
|
1027
|
+
import json
|
|
1028
|
+
|
|
1029
|
+
async def websocket_client():
|
|
1030
|
+
uri = 'wss://realtime.insightsentry.com/live'
|
|
1031
|
+
|
|
1032
|
+
async with websockets.connect(uri) as websocket:
|
|
1033
|
+
# Start ping task
|
|
1034
|
+
ping_task = asyncio.create_task(send_ping(websocket))
|
|
1035
|
+
|
|
1036
|
+
async for message in websocket:
|
|
1037
|
+
|
|
1038
|
+
print('Received pong from server')
|
|
1039
|
+
continue
|
|
1040
|
+
# Handle other messages here
|
|
1041
|
+
|
|
1042
|
+
except websockets.exceptions.ConnectionClosed:
|
|
1043
|
+
print('WebSocket connection closed')
|
|
1044
|
+
finally:
|
|
1045
|
+
ping_task.cancel()
|
|
1046
|
+
|
|
1047
|
+
async def send_ping(websocket):
|
|
1048
|
+
while True:
|
|
1049
|
+
|
|
1050
|
+
await asyncio.sleep(20)
|
|
1051
|
+
await websocket.send('ping')
|
|
1052
|
+
except asyncio.CancelledError:
|
|
1053
|
+
break
|
|
1054
|
+
|
|
1055
|
+
# Run the client
|
|
1056
|
+
asyncio.run(websocket_client())
|
|
1057
|
+
\`\`\`
|
|
1058
|
+
|
|
1059
|
+
|
|
1060
|
+
---
|
|
1061
|
+
|
|
1062
|
+
|
|
1063
|
+
### Client-Side Timeout
|
|
1064
|
+
|
|
1065
|
+
Configure your WebSocket library with an appropriate timeout value.
|
|
1066
|
+
We recommend a minimum timeout of **12 seconds**. This
|
|
1067
|
+
helps handle periods of low market activity (e.g., weekends,
|
|
1068
|
+
holidays) where price updates might be infrequent, preventing
|
|
1069
|
+
premature disconnection by the client.
|
|
1070
|
+
|
|
1071
|
+
|
|
1072
|
+
|
|
1073
|
+
|
|
1074
|
+
|
|
1075
|
+
## 6. Error Handling
|
|
1076
|
+
|
|
1077
|
+
If you send an invalid request (e.g., incorrect format, invalid
|
|
1078
|
+
symbol) or if a server-side error occurs related to your request,
|
|
1079
|
+
the server will send a JSON-encoded error message:
|
|
1080
|
+
|
|
1081
|
+
|
|
1082
|
+
\`\`\`json
|
|
1083
|
+
{
|
|
1084
|
+
"message": "Invalid Symbol Code"
|
|
1085
|
+
|
|
1086
|
+
\`\`\`
|
|
1087
|
+
|
|
1088
|
+
|
|
1089
|
+
|
|
1090
|
+
- The WebSocket connection typically remains open after an error message is sent.
|
|
1091
|
+
|
|
1092
|
+
- However, processing for the invalid request will stop.
|
|
1093
|
+
|
|
1094
|
+
- Action Required: You should close the connection, correct the subscription request that caused the error, and then establish a new connection.
|
|
1095
|
+
|
|
1096
|
+
- Always validate symbol codes and message formats before sending subscription requests.
|
|
1097
|
+
|
|
1098
|
+
|
|
1099
|
+
|
|
1100
|
+
|
|
1101
|
+
|
|
1102
|
+
|
|
1103
|
+
|
|
1104
|
+
## 7. API Key Rotation
|
|
1105
|
+
|
|
1106
|
+
|
|
1107
|
+
|
|
1108
|
+
|
|
1109
|
+
|
|
1110
|
+
|
|
1111
|
+
#### RapidAPI Users Only
|
|
1112
|
+
|
|
1113
|
+
This section applies only to RapidAPI subscribers. Native API
|
|
1114
|
+
Gateway users have persistent keys until manually refreshed in
|
|
1115
|
+
the portal.
|
|
1116
|
+
|
|
1117
|
+
|
|
1118
|
+
|
|
1119
|
+
|
|
1120
|
+
|
|
1121
|
+
WebSocket API keys can be rotated for enhanced security.
|
|
1122
|
+
Understanding key expiration is crucial for maintaining
|
|
1123
|
+
uninterrupted service.
|
|
1124
|
+
|
|
1125
|
+
|
|
1126
|
+
|
|
1127
|
+
|
|
1128
|
+
|
|
1129
|
+
|
|
1130
|
+
#### Automatic Expiration
|
|
1131
|
+
|
|
1132
|
+
WebSocket API keys expire automatically after
|
|
1133
|
+
**one week** from issuance for security purposes.
|
|
1134
|
+
|
|
1135
|
+
|
|
1136
|
+
|
|
1137
|
+
|
|
1138
|
+
|
|
1139
|
+
### Key Rotation Process
|
|
1140
|
+
|
|
1141
|
+
Follow these steps to rotate your WebSocket API key:
|
|
1142
|
+
|
|
1143
|
+
|
|
1144
|
+
|
|
1145
|
+
- Request a new key from the /v2/websocket-key endpoint
|
|
1146
|
+
|
|
1147
|
+
- Your existing key is immediately invalidated when the new key is issued
|
|
1148
|
+
|
|
1149
|
+
- Update your application to use the new key for all connections
|
|
1150
|
+
|
|
1151
|
+
- The response includes the key and expiration timestamp (Unix epoch seconds)
|
|
1152
|
+
|
|
1153
|
+
|
|
1154
|
+
|
|
1155
|
+
|
|
1156
|
+
### API Key Response Format
|
|
1157
|
+
|
|
1158
|
+
|
|
1159
|
+
\`\`\`json
|
|
1160
|
+
{
|
|
1161
|
+
"api_key": "your-websocket-api-key",
|
|
1162
|
+
"expiration": 1747580931
|
|
1163
|
+
|
|
1164
|
+
\`\`\`
|
|
1165
|
+
|
|
1166
|
+
|
|
1167
|
+
### Key Management Best Practices
|
|
1168
|
+
|
|
1169
|
+
|
|
1170
|
+
|
|
1171
|
+
- Refresh your key regularly - you can refresh it daily if desired, or at least once a week before expiration.
|
|
1172
|
+
|
|
1173
|
+
- Store the WebSocket API key in your database along with its expiration timestamp.
|
|
1174
|
+
|
|
1175
|
+
- Before using a stored key, check if it's expired or close to expiration.
|
|
1176
|
+
|
|
1177
|
+
- If the key is expired or close to expiration, automatically issue a new WebSocket API key and update your database.
|
|
1178
|
+
|
|
1179
|
+
|
|
1180
|
+
|
|
1181
|
+
|
|
1182
|
+
\`\`\`python
|
|
1183
|
+
import time
|
|
1184
|
+
import requests
|
|
1185
|
+
from typing import Optional, Dict, Any
|
|
1186
|
+
from dataclasses import dataclass
|
|
1187
|
+
|
|
1188
|
+
BASE_URL = 'https://insightsentry.p.rapidapi.com'
|
|
1189
|
+
|
|
1190
|
+
@dataclass
|
|
1191
|
+
class WebSocketKey:
|
|
1192
|
+
key: str
|
|
1193
|
+
expires_at: int
|
|
1194
|
+
|
|
1195
|
+
async def get_valid_websocket_key() -> str:
|
|
1196
|
+
stored_key = await database.get_websocket_key()
|
|
1197
|
+
|
|
1198
|
+
now = int(time.time())
|
|
1199
|
+
buffer_time = 24 * 60 * 60 # 24 hours
|
|
1200
|
+
|
|
1201
|
+
|
|
1202
|
+
response = requests.get(
|
|
1203
|
+
f'{BASE_URL}/v2/websocket-key',
|
|
1204
|
+
headers={
|
|
1205
|
+
'x-rapidapi-key': 'YOUR_RAPID_API_KEY'
|
|
1206
|
+
|
|
1207
|
+
response.raise_for_status()
|
|
1208
|
+
data = response.json()
|
|
1209
|
+
|
|
1210
|
+
await database.save_websocket_key(WebSocketKey(
|
|
1211
|
+
key=data['api_key'],
|
|
1212
|
+
expires_at=data['expiration']
|
|
1213
|
+
))
|
|
1214
|
+
|
|
1215
|
+
\`\`\`
|
|
1216
|
+
|
|
1217
|
+
|
|
1218
|
+
|
|
1219
|
+
|
|
1220
|
+
|
|
1221
|
+
## 8. Code Examples
|
|
1222
|
+
|
|
1223
|
+
The following examples demonstrate how to connect to our WebSocket
|
|
1224
|
+
API and handle real-time data feeds using popular programming
|
|
1225
|
+
languages.
|
|
1226
|
+
|
|
1227
|
+
|
|
1228
|
+
|
|
1229
|
+
|
|
1230
|
+
|
|
1231
|
+
|
|
1232
|
+
#### Before You Start
|
|
1233
|
+
|
|
1234
|
+
Replace \`\` or
|
|
1235
|
+
\`\` placeholders with your actual
|
|
1236
|
+
WebSocket API key in all examples.
|
|
1237
|
+
|
|
1238
|
+
|
|
1239
|
+
|
|
1240
|
+
|
|
1241
|
+
|
|
1242
|
+
|
|
1243
|
+
|
|
1244
|
+
|
|
1245
|
+
|
|
1246
|
+
|
|
1247
|
+
## FAQ
|
|
1248
|
+
|
|
1249
|
+
|
|
1250
|
+
|
|
1251
|
+
### Q: WebSocket is disconnected frequently
|
|
1252
|
+
|
|
1253
|
+
There could be several causes. First, check if your main thread is
|
|
1254
|
+
blocked due to heavy data processing. If the main thread is
|
|
1255
|
+
blocked, the WebSocket library's internal ping mechanism may
|
|
1256
|
+
fail to respond, which can lead to disconnection. This is one of
|
|
1257
|
+
the most common causes. You can easily identify this by comparing
|
|
1258
|
+
your machine's current time with the \`server_time\`
|
|
1259
|
+
field in the messages sent from our servers. If
|
|
1260
|
+
\`Time.inMilliseconds - server_time\` results in a
|
|
1261
|
+
negative value, it indicates that your main thread is being
|
|
1262
|
+
blocked.
|
|
1263
|
+
|
|
1264
|
+
|
|
1265
|
+
|
|
1266
|
+
|
|
1267
|
+
### Q: There are missing messages when using 'second' as
|
|
1268
|
+
bar_type and 1 as bar_interval
|
|
1269
|
+
|
|
1270
|
+
For the 1-second time frame, a bar message is sent only when there
|
|
1271
|
+
is a change in the close price or volume. This means you may not
|
|
1272
|
+
receive a message every second. To handle missing bars, you can
|
|
1273
|
+
normalize your data by filling in with the previous bar's
|
|
1274
|
+
values when no update is received.`,
|
|
1275
|
+
},
|
|
1276
|
+
{
|
|
1277
|
+
uri: "insightsentry://docs/screener",
|
|
1278
|
+
name: "InsightSentry Screener API Guide",
|
|
1279
|
+
description: "Screener API: discover available fields, filter stocks/ETFs/bonds/crypto with custom criteria",
|
|
1280
|
+
mimeType: "text/markdown",
|
|
1281
|
+
content: `# InsightSentry Screener API Guide
|
|
1282
|
+
|
|
1283
|
+
Full documentation: https://insightsentry.com/docs
|
|
1284
|
+
|
|
1285
|
+
## 1. Overview
|
|
1286
|
+
|
|
1287
|
+
The Screener API allows you to filter and retrieve financial
|
|
1288
|
+
instruments across multiple asset classes including stocks, ETFs,
|
|
1289
|
+
bonds, and cryptocurrencies. You can query data with custom field
|
|
1290
|
+
selections, apply filters by exchange or country, and sort results.
|
|
1291
|
+
|
|
1292
|
+
|
|
1293
|
+
### Supported Asset Types
|
|
1294
|
+
|
|
1295
|
+
|
|
1296
|
+
|
|
1297
|
+
stock
|
|
1298
|
+
|
|
1299
|
+
Equities
|
|
1300
|
+
|
|
1301
|
+
|
|
1302
|
+
|
|
1303
|
+
etf
|
|
1304
|
+
|
|
1305
|
+
Exchange-Traded Funds
|
|
1306
|
+
|
|
1307
|
+
|
|
1308
|
+
|
|
1309
|
+
bond
|
|
1310
|
+
|
|
1311
|
+
Fixed Income
|
|
1312
|
+
|
|
1313
|
+
|
|
1314
|
+
|
|
1315
|
+
crypto
|
|
1316
|
+
|
|
1317
|
+
Cryptocurrencies
|
|
1318
|
+
|
|
1319
|
+
|
|
1320
|
+
|
|
1321
|
+
|
|
1322
|
+
|
|
1323
|
+
### Base URL
|
|
1324
|
+
|
|
1325
|
+
|
|
1326
|
+
\`\`\`bash
|
|
1327
|
+
https://api.insightsentry.com/v3/screeners/{type}
|
|
1328
|
+
\`\`\`
|
|
1329
|
+
|
|
1330
|
+
|
|
1331
|
+
|
|
1332
|
+
|
|
1333
|
+
|
|
1334
|
+
## 2. Available Options
|
|
1335
|
+
|
|
1336
|
+
Before querying the screener, you can discover available fields,
|
|
1337
|
+
exchanges, and countries for each asset type using a GET request.
|
|
1338
|
+
|
|
1339
|
+
|
|
1340
|
+
### Endpoint
|
|
1341
|
+
|
|
1342
|
+
|
|
1343
|
+
\`\`\`bash
|
|
1344
|
+
GET https://api.insightsentry.com/v3/screeners/{type}
|
|
1345
|
+
\`\`\`
|
|
1346
|
+
|
|
1347
|
+
|
|
1348
|
+
### Example Request
|
|
1349
|
+
|
|
1350
|
+
|
|
1351
|
+
\`\`\`bash
|
|
1352
|
+
GET https://api.insightsentry.com/v3/screeners/stock
|
|
1353
|
+
\`\`\`
|
|
1354
|
+
|
|
1355
|
+
|
|
1356
|
+
### Response
|
|
1357
|
+
|
|
1358
|
+
|
|
1359
|
+
\`\`\`json
|
|
1360
|
+
{
|
|
1361
|
+
"available_fields": [
|
|
1362
|
+
"close",
|
|
1363
|
+
"change",
|
|
1364
|
+
"high",
|
|
1365
|
+
"low",
|
|
1366
|
+
"open",
|
|
1367
|
+
"volume",
|
|
1368
|
+
"market_cap",
|
|
1369
|
+
"..."
|
|
1370
|
+
],
|
|
1371
|
+
"available_exchanges": [
|
|
1372
|
+
"NASDAQ",
|
|
1373
|
+
"NYSE",
|
|
1374
|
+
"AMEX",
|
|
1375
|
+
"..."
|
|
1376
|
+
],
|
|
1377
|
+
"available_countries": [
|
|
1378
|
+
"US",
|
|
1379
|
+
"CA",
|
|
1380
|
+
"GB",
|
|
1381
|
+
"..."
|
|
1382
|
+
],
|
|
1383
|
+
"sortOrder": ["asc", "desc"]
|
|
1384
|
+
|
|
1385
|
+
\`\`\`
|
|
1386
|
+
|
|
1387
|
+
|
|
1388
|
+
|
|
1389
|
+
|
|
1390
|
+
|
|
1391
|
+
|
|
1392
|
+
#### Asset Type Differences
|
|
1393
|
+
|
|
1394
|
+
|
|
1395
|
+
**Crypto**: Does not support country filtering
|
|
1396
|
+
|
|
1397
|
+
**Bond**: Has different country codes specific
|
|
1398
|
+
to bond markets
|
|
1399
|
+
|
|
1400
|
+
Each asset type has its own set of available fields tailored
|
|
1401
|
+
to that market
|
|
1402
|
+
|
|
1403
|
+
|
|
1404
|
+
|
|
1405
|
+
|
|
1406
|
+
|
|
1407
|
+
|
|
1408
|
+
|
|
1409
|
+
|
|
1410
|
+
|
|
1411
|
+
## 3. Query Screener
|
|
1412
|
+
|
|
1413
|
+
Use a POST request to query the screener with your desired fields,
|
|
1414
|
+
filters, and sorting options.
|
|
1415
|
+
|
|
1416
|
+
|
|
1417
|
+
### Endpoint
|
|
1418
|
+
|
|
1419
|
+
|
|
1420
|
+
\`\`\`bash
|
|
1421
|
+
POST https://api.insightsentry.com/v3/screeners/{type}
|
|
1422
|
+
\`\`\`
|
|
1423
|
+
|
|
1424
|
+
|
|
1425
|
+
### Request Body
|
|
1426
|
+
|
|
1427
|
+
|
|
1428
|
+
|
|
1429
|
+
| Parameter | Type | Required | Description |
|
|
1430
|
+
| -------------- | -------- | -------- | -------------------------------------------------------------------------------------------------------------- |
|
|
1431
|
+
| fields | string[] | Yes | Array of fields to retrieve (1-10 fields) |
|
|
1432
|
+
| page | number | No | Page number for pagination (default: 1) |
|
|
1433
|
+
| sortBy | string | No | Field to sort by, must be one of the requested fields or
|
|
1434
|
+
"name" (default: "name") |
|
|
1435
|
+
| sortOrder | string | No | "asc" or "desc" (default:
|
|
1436
|
+
"asc") |
|
|
1437
|
+
| exchanges | string[] | No | Filter by specific exchanges |
|
|
1438
|
+
| countries | string[] | No | Filter by country codes (not available for crypto) |
|
|
1439
|
+
| ignore_invalid | boolean | No | If true, invalid fields/exchanges/countries are filtered out
|
|
1440
|
+
instead of returning an error |
|
|
1441
|
+
|
|
1442
|
+
|
|
1443
|
+
|
|
1444
|
+
|
|
1445
|
+
### Example Request
|
|
1446
|
+
|
|
1447
|
+
|
|
1448
|
+
\`\`\`json
|
|
1449
|
+
POST https://api.insightsentry.com/v3/screeners/stock
|
|
1450
|
+
|
|
1451
|
+
{
|
|
1452
|
+
"fields": ["close", "change_percent", "volume", "market_cap"],
|
|
1453
|
+
"page": 1,
|
|
1454
|
+
"sortBy": "market_cap",
|
|
1455
|
+
"sortOrder": "desc",
|
|
1456
|
+
"exchanges": ["NASDAQ", "NYSE"],
|
|
1457
|
+
"countries": ["US"]
|
|
1458
|
+
|
|
1459
|
+
\`\`\`
|
|
1460
|
+
|
|
1461
|
+
|
|
1462
|
+
|
|
1463
|
+
|
|
1464
|
+
|
|
1465
|
+
|
|
1466
|
+
#### Field Validation
|
|
1467
|
+
|
|
1468
|
+
|
|
1469
|
+
|
|
1470
|
+
- At least one field is required
|
|
1471
|
+
|
|
1472
|
+
- Maximum of 10 fields per request
|
|
1473
|
+
|
|
1474
|
+
- Up to 1000 items are returned per request
|
|
1475
|
+
|
|
1476
|
+
- Field names are case-insensitive and will be normalized to lowercase
|
|
1477
|
+
|
|
1478
|
+
- The sortBy field must be one of the requested fields or "name"
|
|
1479
|
+
|
|
1480
|
+
|
|
1481
|
+
|
|
1482
|
+
|
|
1483
|
+
|
|
1484
|
+
|
|
1485
|
+
|
|
1486
|
+
|
|
1487
|
+
|
|
1488
|
+
|
|
1489
|
+
## 4. Response Format
|
|
1490
|
+
|
|
1491
|
+
The screener returns paginated results with metadata about the
|
|
1492
|
+
current page and total available data.
|
|
1493
|
+
|
|
1494
|
+
|
|
1495
|
+
### Response Structure
|
|
1496
|
+
|
|
1497
|
+
|
|
1498
|
+
\`\`\`json
|
|
1499
|
+
{
|
|
1500
|
+
"hasNext": true,
|
|
1501
|
+
"current_page": 1,
|
|
1502
|
+
"total_page": 15,
|
|
1503
|
+
"current_items": 1000,
|
|
1504
|
+
"data": [
|
|
1505
|
+
{
|
|
1506
|
+
"symbol_code": "NASDAQ:AAPL",
|
|
1507
|
+
"name": "Apple Inc.",
|
|
1508
|
+
"close": 195.89,
|
|
1509
|
+
"change_percent": 1.25,
|
|
1510
|
+
"volume": 52436789,
|
|
1511
|
+
"market_cap": 3050000000000,
|
|
1512
|
+
"country": "US",
|
|
1513
|
+
"currency": "USD",
|
|
1514
|
+
"delay_seconds": 0,
|
|
1515
|
+
"fundamental_currency": "USD"
|
|
1516
|
+
|
|
1517
|
+
\`\`\`
|
|
1518
|
+
|
|
1519
|
+
|
|
1520
|
+
### Response Fields
|
|
1521
|
+
|
|
1522
|
+
|
|
1523
|
+
|
|
1524
|
+
#### Pagination Metadata:
|
|
1525
|
+
|
|
1526
|
+
|
|
1527
|
+
|
|
1528
|
+
- hasNext: Boolean indicating if more pages are available
|
|
1529
|
+
|
|
1530
|
+
- current_page: Current page number
|
|
1531
|
+
|
|
1532
|
+
- total_page: Total number of pages
|
|
1533
|
+
|
|
1534
|
+
- current_items: Number of items in current response
|
|
1535
|
+
|
|
1536
|
+
|
|
1537
|
+
|
|
1538
|
+
|
|
1539
|
+
|
|
1540
|
+
|
|
1541
|
+
|
|
1542
|
+
#### Common Fields in Data:
|
|
1543
|
+
|
|
1544
|
+
|
|
1545
|
+
|
|
1546
|
+
- symbol_code: Unique identifier (EXCHANGE:SYMBOL format)
|
|
1547
|
+
|
|
1548
|
+
- name: Description/name of the instrument
|
|
1549
|
+
|
|
1550
|
+
- country: Country code (not for crypto)
|
|
1551
|
+
|
|
1552
|
+
- currency: Trading currency
|
|
1553
|
+
|
|
1554
|
+
- delay_seconds: Data delay in seconds (0 = real-time)
|
|
1555
|
+
|
|
1556
|
+
- fundamental_currency: Currency for fundamental data
|
|
1557
|
+
|
|
1558
|
+
|
|
1559
|
+
|
|
1560
|
+
|
|
1561
|
+
|
|
1562
|
+
|
|
1563
|
+
|
|
1564
|
+
|
|
1565
|
+
|
|
1566
|
+
|
|
1567
|
+
## 5. Examples
|
|
1568
|
+
|
|
1569
|
+
|
|
1570
|
+
### Stock Screener
|
|
1571
|
+
|
|
1572
|
+
Find US stocks by market cap with price data:
|
|
1573
|
+
|
|
1574
|
+
|
|
1575
|
+
\`\`\`json
|
|
1576
|
+
POST https://api.insightsentry.com/v3/screeners/stock
|
|
1577
|
+
|
|
1578
|
+
{
|
|
1579
|
+
"fields": ["close", "change", "volume", "market_cap"],
|
|
1580
|
+
"page": 1,
|
|
1581
|
+
"sortBy": "market_cap",
|
|
1582
|
+
"sortOrder": "desc",
|
|
1583
|
+
"countries": ["US"]
|
|
1584
|
+
|
|
1585
|
+
\`\`\`
|
|
1586
|
+
|
|
1587
|
+
|
|
1588
|
+
### ETF Screener
|
|
1589
|
+
|
|
1590
|
+
Query ETFs from specific exchanges:
|
|
1591
|
+
|
|
1592
|
+
|
|
1593
|
+
\`\`\`json
|
|
1594
|
+
POST https://api.insightsentry.com/v3/screeners/etf
|
|
1595
|
+
|
|
1596
|
+
{
|
|
1597
|
+
"fields": ["close", "volume", "change"],
|
|
1598
|
+
"exchanges": ["NYSE", "NASDAQ"],
|
|
1599
|
+
"sortBy": "volume",
|
|
1600
|
+
"sortOrder": "desc"
|
|
1601
|
+
|
|
1602
|
+
\`\`\`
|
|
1603
|
+
|
|
1604
|
+
|
|
1605
|
+
### Crypto Screener
|
|
1606
|
+
|
|
1607
|
+
Screen cryptocurrencies by volume:
|
|
1608
|
+
|
|
1609
|
+
|
|
1610
|
+
\`\`\`json
|
|
1611
|
+
POST https://api.insightsentry.com/v3/screeners/crypto
|
|
1612
|
+
|
|
1613
|
+
{
|
|
1614
|
+
"fields": ["close", "volume", "change"],
|
|
1615
|
+
"sortBy": "volume",
|
|
1616
|
+
"sortOrder": "desc"
|
|
1617
|
+
|
|
1618
|
+
\`\`\`
|
|
1619
|
+
|
|
1620
|
+
|
|
1621
|
+
### Bond Screener
|
|
1622
|
+
|
|
1623
|
+
Query bonds from specific countries:
|
|
1624
|
+
|
|
1625
|
+
|
|
1626
|
+
\`\`\`json
|
|
1627
|
+
POST https://api.insightsentry.com/v3/screeners/bond
|
|
1628
|
+
|
|
1629
|
+
{
|
|
1630
|
+
"fields": ["close", "yield"],
|
|
1631
|
+
"countries": ["US", "GB"],
|
|
1632
|
+
"sortBy": "yield",
|
|
1633
|
+
"sortOrder": "desc"
|
|
1634
|
+
|
|
1635
|
+
\`\`\`
|
|
1636
|
+
|
|
1637
|
+
|
|
1638
|
+
### With ignore_invalid Flag
|
|
1639
|
+
|
|
1640
|
+
Use \`ignore_invalid\` when you want to attempt queries
|
|
1641
|
+
with fields that might not exist:
|
|
1642
|
+
|
|
1643
|
+
|
|
1644
|
+
\`\`\`json
|
|
1645
|
+
POST https://api.insightsentry.com/v3/screeners/stock
|
|
1646
|
+
|
|
1647
|
+
{
|
|
1648
|
+
"fields": ["close", "volume", "some_unknown_field"],
|
|
1649
|
+
"ignore_invalid": true
|
|
1650
|
+
|
|
1651
|
+
\`\`\`
|
|
1652
|
+
|
|
1653
|
+
With \`ignore_invalid: true\`, the API will filter out
|
|
1654
|
+
"some_unknown_field" and return results with only the
|
|
1655
|
+
valid fields.`,
|
|
1656
|
+
},
|
|
1657
|
+
{
|
|
1658
|
+
uri: "insightsentry://docs/options",
|
|
1659
|
+
name: "InsightSentry Options API Guide",
|
|
1660
|
+
description: "Options API: list options, option chains, Greeks, option code format, historical data",
|
|
1661
|
+
mimeType: "text/markdown",
|
|
1662
|
+
content: `# InsightSentry Options API Guide
|
|
1663
|
+
|
|
1664
|
+
Full documentation: https://insightsentry.com/docs
|
|
1665
|
+
|
|
1666
|
+
## 1. Symbol Search
|
|
1667
|
+
|
|
1668
|
+
|
|
1669
|
+
### Finding Symbols
|
|
1670
|
+
|
|
1671
|
+
Before working with options data, you need to identify the correct
|
|
1672
|
+
symbol codes for the underlying assets.
|
|
1673
|
+
|
|
1674
|
+
The symbol search endpoint helps you discover available symbols and
|
|
1675
|
+
their exact format required for options queries.
|
|
1676
|
+
|
|
1677
|
+
|
|
1678
|
+
### Search Endpoint
|
|
1679
|
+
|
|
1680
|
+
Use the \`/v3/symbols/search\` endpoint to find symbols:
|
|
1681
|
+
|
|
1682
|
+
|
|
1683
|
+
\`\`\`bash
|
|
1684
|
+
GET https://api.insightsentry.com/v3/symbols/search?query=apple
|
|
1685
|
+
\`\`\`
|
|
1686
|
+
|
|
1687
|
+
|
|
1688
|
+
|
|
1689
|
+
|
|
1690
|
+
|
|
1691
|
+
## 2. Get Available Options
|
|
1692
|
+
|
|
1693
|
+
|
|
1694
|
+
### Options List Endpoint
|
|
1695
|
+
|
|
1696
|
+
Once you have the underlying symbol, retrieve all available option
|
|
1697
|
+
contracts using the \`/v3/options/list\` endpoint.
|
|
1698
|
+
|
|
1699
|
+
This endpoint returns all available options for the specified
|
|
1700
|
+
underlying symbol, including different expirations and strike
|
|
1701
|
+
prices, excluding expired options.
|
|
1702
|
+
|
|
1703
|
+
|
|
1704
|
+
### Example
|
|
1705
|
+
|
|
1706
|
+
|
|
1707
|
+
\`\`\`bash
|
|
1708
|
+
GET https://api.insightsentry.com/v3/options/list?code=NASDAQ:AAPL
|
|
1709
|
+
\`\`\`
|
|
1710
|
+
|
|
1711
|
+
Response includes all available option contracts:
|
|
1712
|
+
|
|
1713
|
+
|
|
1714
|
+
\`\`\`json
|
|
1715
|
+
{
|
|
1716
|
+
"last_update": 1756912027000,
|
|
1717
|
+
"codes": [
|
|
1718
|
+
"OPRA:AAPL260417P325.0",
|
|
1719
|
+
"OPRA:AAPL260618C5.0"
|
|
1720
|
+
|
|
1721
|
+
\`\`\`
|
|
1722
|
+
|
|
1723
|
+
|
|
1724
|
+
|
|
1725
|
+
|
|
1726
|
+
|
|
1727
|
+
|
|
1728
|
+
#### Futures Options
|
|
1729
|
+
|
|
1730
|
+
For futures options, you must use specific contract codes
|
|
1731
|
+
rather than continuous contracts:
|
|
1732
|
+
|
|
1733
|
+
|
|
1734
|
+
|
|
1735
|
+
- Use: CME_MINI:NQU2025 (specific contract)
|
|
1736
|
+
|
|
1737
|
+
- Not: CME_MINI:NQ1! (continuous contract)
|
|
1738
|
+
|
|
1739
|
+
- Each futures contract has its own set of options
|
|
1740
|
+
|
|
1741
|
+
- Options expire before the underlying futures contract
|
|
1742
|
+
|
|
1743
|
+
|
|
1744
|
+
|
|
1745
|
+
|
|
1746
|
+
|
|
1747
|
+
|
|
1748
|
+
|
|
1749
|
+
|
|
1750
|
+
|
|
1751
|
+
|
|
1752
|
+
## 3. Get Option Chain Info
|
|
1753
|
+
|
|
1754
|
+
|
|
1755
|
+
### Symbol Metadata
|
|
1756
|
+
|
|
1757
|
+
Before making requests to the expiration or strike filter endpoints,
|
|
1758
|
+
you need to discover what option data is available for a symbol.
|
|
1759
|
+
|
|
1760
|
+
The \`/v3/symbols/:symbol/info\` endpoint provides
|
|
1761
|
+
comprehensive metadata about a symbol, including the
|
|
1762
|
+
\`option_info\` field which contains available expiration
|
|
1763
|
+
dates and strike prices for all option series.
|
|
1764
|
+
|
|
1765
|
+
|
|
1766
|
+
### Endpoint
|
|
1767
|
+
|
|
1768
|
+
Get symbol information including option chain metadata:
|
|
1769
|
+
|
|
1770
|
+
|
|
1771
|
+
\`\`\`bash
|
|
1772
|
+
GET https://api.insightsentry.com/v3/symbols/CME_MINI:NQZ2025/info
|
|
1773
|
+
\`\`\`
|
|
1774
|
+
|
|
1775
|
+
|
|
1776
|
+
### Response Structure
|
|
1777
|
+
|
|
1778
|
+
The response includes basic symbol information and option chain data:
|
|
1779
|
+
|
|
1780
|
+
|
|
1781
|
+
\`\`\`json
|
|
1782
|
+
{
|
|
1783
|
+
"code": "CME_MINI:NQZ2025",
|
|
1784
|
+
"type": "FUTURES",
|
|
1785
|
+
"description": "E-mini Nasdaq-100 Futures (Dec 2025)",
|
|
1786
|
+
"currency_code": "USD",
|
|
1787
|
+
"expiration": 20251219,
|
|
1788
|
+
"option_info": [
|
|
1789
|
+
{
|
|
1790
|
+
"name": "E-mini Nasdaq-100 Options",
|
|
1791
|
+
"type": "AMERICAN",
|
|
1792
|
+
"series": [
|
|
1793
|
+
{
|
|
1794
|
+
"expiration_date": 20251219,
|
|
1795
|
+
"underlying": "CME_MINI:NQZ2025",
|
|
1796
|
+
"strikes": [2500.0, 3000.0, 3500.0, "...", 35500.0]
|
|
1797
|
+
|
|
1798
|
+
},
|
|
1799
|
+
{
|
|
1800
|
+
"name": "E-mini Nasdaq-100 Monday Weekly Options - Week 2",
|
|
1801
|
+
"type": "EUROPEAN",
|
|
1802
|
+
"series": [
|
|
1803
|
+
{
|
|
1804
|
+
"expiration_date": 20251013,
|
|
1805
|
+
"underlying": "CME_MINI:NQZ2025",
|
|
1806
|
+
"strikes": [17500.0, 18000.0, "...", 29000.0]
|
|
1807
|
+
|
|
1808
|
+
\`\`\`
|
|
1809
|
+
|
|
1810
|
+
|
|
1811
|
+
|
|
1812
|
+
#### Option Info Structure:
|
|
1813
|
+
|
|
1814
|
+
|
|
1815
|
+
|
|
1816
|
+
- name: Option series name (e.g., "E-mini Nasdaq-100 Options")
|
|
1817
|
+
|
|
1818
|
+
- type: Exercise style ("AMERICAN" or "EUROPEAN")
|
|
1819
|
+
|
|
1820
|
+
- series: Array of option series containing: expiration_date: YYYYMMDD format (e.g., 20251219)
|
|
1821
|
+
|
|
1822
|
+
- underlying: The underlying contract code
|
|
1823
|
+
|
|
1824
|
+
- strikes: Array of available strike prices
|
|
1825
|
+
|
|
1826
|
+
|
|
1827
|
+
|
|
1828
|
+
|
|
1829
|
+
|
|
1830
|
+
|
|
1831
|
+
|
|
1832
|
+
|
|
1833
|
+
|
|
1834
|
+
|
|
1835
|
+
|
|
1836
|
+
|
|
1837
|
+
|
|
1838
|
+
#### Using Option Info Data
|
|
1839
|
+
|
|
1840
|
+
|
|
1841
|
+
Extract expiration dates from
|
|
1842
|
+
\`option_info.series[].expiration_date\`
|
|
1843
|
+
and use with the
|
|
1844
|
+
\`/options/expiration\`
|
|
1845
|
+
endpoint.
|
|
1846
|
+
|
|
1847
|
+
Extract strike prices from
|
|
1848
|
+
\`option_info.series[].strikes\`
|
|
1849
|
+
and use with the
|
|
1850
|
+
\`/options/strike\`
|
|
1851
|
+
endpoint.
|
|
1852
|
+
|
|
1853
|
+
Some symbols have multiple option series (weekly, monthly,
|
|
1854
|
+
EOM) - each with different expiration dates and strike
|
|
1855
|
+
ranges.
|
|
1856
|
+
|
|
1857
|
+
|
|
1858
|
+
|
|
1859
|
+
|
|
1860
|
+
|
|
1861
|
+
|
|
1862
|
+
|
|
1863
|
+
|
|
1864
|
+
|
|
1865
|
+
|
|
1866
|
+
|
|
1867
|
+
#### Important Notes
|
|
1868
|
+
|
|
1869
|
+
|
|
1870
|
+
|
|
1871
|
+
- Not all symbols have options data (check if option_info field exists)
|
|
1872
|
+
|
|
1873
|
+
- For futures options, you must use the specific futures contract code (e.g., CME_MINI:NQZ2025), not continuous contracts (e.g., CME_MINI:NQ1!)
|
|
1874
|
+
|
|
1875
|
+
- The strikes array can contain hundreds of values - the example shows truncated data
|
|
1876
|
+
|
|
1877
|
+
- Equity options typically have more standardized expiration dates and strikes
|
|
1878
|
+
|
|
1879
|
+
|
|
1880
|
+
|
|
1881
|
+
|
|
1882
|
+
|
|
1883
|
+
|
|
1884
|
+
|
|
1885
|
+
|
|
1886
|
+
### Practical Workflow
|
|
1887
|
+
|
|
1888
|
+
Here's how to use the symbol info endpoint to discover and filter
|
|
1889
|
+
option data:
|
|
1890
|
+
|
|
1891
|
+
|
|
1892
|
+
|
|
1893
|
+
#### Example 1: Filter by Expiration Date
|
|
1894
|
+
|
|
1895
|
+
|
|
1896
|
+
1. Get symbol info:
|
|
1897
|
+
|
|
1898
|
+
GET /v3/symbols/CME_MINI:NQZ2025/info
|
|
1899
|
+
|
|
1900
|
+
2. Extract an expiration date from response (e.g., 20251013)
|
|
1901
|
+
|
|
1902
|
+
3. Use with expiration endpoint:
|
|
1903
|
+
|
|
1904
|
+
GET
|
|
1905
|
+
/v3/options/expiration?code=CME_MINI:NQZ2025&expiration=2025-10-13
|
|
1906
|
+
|
|
1907
|
+
|
|
1908
|
+
|
|
1909
|
+
|
|
1910
|
+
|
|
1911
|
+
|
|
1912
|
+
#### Example 2: Filter by Strike
|
|
1913
|
+
|
|
1914
|
+
|
|
1915
|
+
1. Get symbol info:
|
|
1916
|
+
|
|
1917
|
+
GET /v3/symbols/CME_MINI:NQZ2025/info
|
|
1918
|
+
|
|
1919
|
+
2. Extract a strike price from response (e.g., 25000.0)
|
|
1920
|
+
|
|
1921
|
+
3. Use with strike endpoint:
|
|
1922
|
+
|
|
1923
|
+
GET /v3/options/strike?code=CME_MINI:NQZ2025&strike=25000
|
|
1924
|
+
|
|
1925
|
+
|
|
1926
|
+
|
|
1927
|
+
|
|
1928
|
+
|
|
1929
|
+
|
|
1930
|
+
|
|
1931
|
+
## 4. Understanding Option Codes
|
|
1932
|
+
|
|
1933
|
+
|
|
1934
|
+
### Option Code Structure
|
|
1935
|
+
|
|
1936
|
+
Option codes contain embedded information about the option type,
|
|
1937
|
+
expiration date, and strike price.
|
|
1938
|
+
|
|
1939
|
+
Understanding this structure helps you interpret and construct
|
|
1940
|
+
option codes programmatically.
|
|
1941
|
+
|
|
1942
|
+
|
|
1943
|
+
### Code Format Breakdown
|
|
1944
|
+
|
|
1945
|
+
|
|
1946
|
+
|
|
1947
|
+
| Exchange | Symbol | Expiration | Type | Strike |
|
|
1948
|
+
| --------- | ------ | ---------- | ---- | ------ |
|
|
1949
|
+
| OPRA: | AAPL | 260417 | P | 325.0 |
|
|
1950
|
+
| CME_MINI: | NQ | 250919 | P | 24450 |
|
|
1951
|
+
|
|
1952
|
+
|
|
1953
|
+
|
|
1954
|
+
|
|
1955
|
+
### Format Examples
|
|
1956
|
+
|
|
1957
|
+
|
|
1958
|
+
|
|
1959
|
+
|
|
1960
|
+
#### Equity Option (AAPL Put):
|
|
1961
|
+
|
|
1962
|
+
OPRA:AAPL260417P325.0
|
|
1963
|
+
|
|
1964
|
+
|
|
1965
|
+
|
|
1966
|
+
- OPRA: Options exchange
|
|
1967
|
+
|
|
1968
|
+
- AAPL: Apple Inc. stock
|
|
1969
|
+
|
|
1970
|
+
- 260417: Expires April 17, 2026 (YYMMDD)
|
|
1971
|
+
|
|
1972
|
+
- P: Put option
|
|
1973
|
+
|
|
1974
|
+
- 325.0: Strike price $325.00
|
|
1975
|
+
|
|
1976
|
+
|
|
1977
|
+
|
|
1978
|
+
|
|
1979
|
+
|
|
1980
|
+
|
|
1981
|
+
|
|
1982
|
+
#### Futures Option (NASDAQ Mini Put):
|
|
1983
|
+
|
|
1984
|
+
CME_MINI:NQ250919P24450
|
|
1985
|
+
|
|
1986
|
+
|
|
1987
|
+
|
|
1988
|
+
- CME_MINI: CME futures exchange
|
|
1989
|
+
|
|
1990
|
+
- NQ: NASDAQ 100 E-mini futures
|
|
1991
|
+
|
|
1992
|
+
- 250919: Expires September 19, 2025 (YYMMDD)
|
|
1993
|
+
|
|
1994
|
+
- P: Put option
|
|
1995
|
+
|
|
1996
|
+
- 24450: Strike price 24,450 index points
|
|
1997
|
+
|
|
1998
|
+
|
|
1999
|
+
|
|
2000
|
+
|
|
2001
|
+
|
|
2002
|
+
|
|
2003
|
+
|
|
2004
|
+
|
|
2005
|
+
|
|
2006
|
+
|
|
2007
|
+
|
|
2008
|
+
#### Option Type Codes
|
|
2009
|
+
|
|
2010
|
+
|
|
2011
|
+
**C** = Call option (right to buy)
|
|
2012
|
+
|
|
2013
|
+
**P** = Put option (right to sell)
|
|
2014
|
+
|
|
2015
|
+
|
|
2016
|
+
|
|
2017
|
+
|
|
2018
|
+
|
|
2019
|
+
|
|
2020
|
+
|
|
2021
|
+
|
|
2022
|
+
|
|
2023
|
+
## 5. Option Chains
|
|
2024
|
+
|
|
2025
|
+
|
|
2026
|
+
### Filtering Option Data
|
|
2027
|
+
|
|
2028
|
+
Option chains allow you to filter available options by specific
|
|
2029
|
+
criteria such as expiration date or strike price.
|
|
2030
|
+
|
|
2031
|
+
These endpoints are useful when you need to focus on options with
|
|
2032
|
+
specific characteristics rather than retrieving all available
|
|
2033
|
+
contracts.
|
|
2034
|
+
|
|
2035
|
+
|
|
2036
|
+
### Filter by Expiration Date
|
|
2037
|
+
|
|
2038
|
+
Use the \`/v3/options/expiration\` endpoint to get options
|
|
2039
|
+
expiring on a specific date:
|
|
2040
|
+
|
|
2041
|
+
|
|
2042
|
+
\`\`\`bash
|
|
2043
|
+
GET https://api.insightsentry.com/v3/options/expiration?code=NASDAQ:AAPL&expiration=2027-06-17
|
|
2044
|
+
\`\`\`
|
|
2045
|
+
|
|
2046
|
+
|
|
2047
|
+
#### Sorting Options
|
|
2048
|
+
|
|
2049
|
+
You can sort the results using \`sortBy\` and
|
|
2050
|
+
\`sort\` parameters:
|
|
2051
|
+
|
|
2052
|
+
|
|
2053
|
+
\`\`\`bash
|
|
2054
|
+
GET https://api.insightsentry.com/v3/options/expiration?code=NASDAQ:AAPL&expiration=2027-06-17&sortBy=strike_price&sort=asc
|
|
2055
|
+
\`\`\`
|
|
2056
|
+
|
|
2057
|
+
|
|
2058
|
+
|
|
2059
|
+
##### Available Sort Fields (sortBy):
|
|
2060
|
+
|
|
2061
|
+
|
|
2062
|
+
type
|
|
2063
|
+
ask_price
|
|
2064
|
+
bid_price
|
|
2065
|
+
delta
|
|
2066
|
+
gamma
|
|
2067
|
+
expiration
|
|
2068
|
+
implied_volatility
|
|
2069
|
+
rho
|
|
2070
|
+
strike_price
|
|
2071
|
+
theoretical_price
|
|
2072
|
+
theta
|
|
2073
|
+
vega
|
|
2074
|
+
|
|
2075
|
+
**sort:** Use \`asc\` (ascending) or
|
|
2076
|
+
\`desc\` (descending). Default is \`asc\`.
|
|
2077
|
+
|
|
2078
|
+
|
|
2079
|
+
|
|
2080
|
+
Returns option chain data for the specified expiration date:
|
|
2081
|
+
|
|
2082
|
+
|
|
2083
|
+
\`\`\`json
|
|
2084
|
+
{
|
|
2085
|
+
"underlying_code": "NASDAQ:AAPL",
|
|
2086
|
+
"last_update": 1756912027000,
|
|
2087
|
+
"data": [
|
|
2088
|
+
{
|
|
2089
|
+
"code": "OPRA:AAPL270617C150.0",
|
|
2090
|
+
"ask_price": 12.5,
|
|
2091
|
+
"bid_price": 12.0,
|
|
2092
|
+
"delta": 0.65,
|
|
2093
|
+
"gamma": 0.02,
|
|
2094
|
+
"implied_volatility": 0.25,
|
|
2095
|
+
"type": "CALL",
|
|
2096
|
+
"rho": 0.08,
|
|
2097
|
+
"strike_price": 150,
|
|
2098
|
+
"theoretical_price": 12.25,
|
|
2099
|
+
"theta": -0.05,
|
|
2100
|
+
"vega": 0.15,
|
|
2101
|
+
"bid_iv": 0.24,
|
|
2102
|
+
"ask_iv": 0.26,
|
|
2103
|
+
"expiration": 20270617
|
|
2104
|
+
},
|
|
2105
|
+
{
|
|
2106
|
+
"code": "OPRA:AAPL270617P150.0",
|
|
2107
|
+
"ask_price": 8.2,
|
|
2108
|
+
"bid_price": 7.8,
|
|
2109
|
+
"delta": -0.35,
|
|
2110
|
+
"gamma": 0.02,
|
|
2111
|
+
"implied_volatility": 0.23,
|
|
2112
|
+
"type": "PUT",
|
|
2113
|
+
"rho": -0.06,
|
|
2114
|
+
"strike_price": 150,
|
|
2115
|
+
"theoretical_price": 8.0,
|
|
2116
|
+
"theta": -0.04,
|
|
2117
|
+
"vega": 0.15,
|
|
2118
|
+
"bid_iv": 0.22,
|
|
2119
|
+
"ask_iv": 0.24,
|
|
2120
|
+
"expiration": 20270617
|
|
2121
|
+
|
|
2122
|
+
\`\`\`
|
|
2123
|
+
|
|
2124
|
+
|
|
2125
|
+
### Filter by Strike Price
|
|
2126
|
+
|
|
2127
|
+
Use the \`/v3/options/strike\` endpoint to get options at a
|
|
2128
|
+
specific strike price:
|
|
2129
|
+
|
|
2130
|
+
|
|
2131
|
+
\`\`\`bash
|
|
2132
|
+
GET https://api.insightsentry.com/v3/options/strike?code=NASDAQ:AAPL&strike=210
|
|
2133
|
+
\`\`\`
|
|
2134
|
+
|
|
2135
|
+
You can also sort by any of the available fields (same as expiration
|
|
2136
|
+
endpoint):
|
|
2137
|
+
|
|
2138
|
+
|
|
2139
|
+
\`\`\`bash
|
|
2140
|
+
GET https://api.insightsentry.com/v3/options/strike?code=NASDAQ:AAPL&strike=210&sortBy=expiration&sort=asc
|
|
2141
|
+
\`\`\`
|
|
2142
|
+
|
|
2143
|
+
Returns option chain data for the specified strike price:
|
|
2144
|
+
|
|
2145
|
+
|
|
2146
|
+
\`\`\`json
|
|
2147
|
+
{
|
|
2148
|
+
"underlying_code": "NASDAQ:AAPL",
|
|
2149
|
+
"last_update": 1756912027000,
|
|
2150
|
+
"data": [
|
|
2151
|
+
{
|
|
2152
|
+
"code": "OPRA:AAPL270617C210.0",
|
|
2153
|
+
"ask_price": 8.5,
|
|
2154
|
+
"bid_price": 8.0,
|
|
2155
|
+
"delta": 0.45,
|
|
2156
|
+
"gamma": 0.018,
|
|
2157
|
+
"implied_volatility": 0.28,
|
|
2158
|
+
"type": "CALL",
|
|
2159
|
+
"rho": 0.06,
|
|
2160
|
+
"strike_price": 210,
|
|
2161
|
+
"theoretical_price": 8.25,
|
|
2162
|
+
"theta": -0.08,
|
|
2163
|
+
"vega": 0.18,
|
|
2164
|
+
"bid_iv": 0.27,
|
|
2165
|
+
"ask_iv": 0.29,
|
|
2166
|
+
"expiration": 20270617
|
|
2167
|
+
},
|
|
2168
|
+
{
|
|
2169
|
+
"code": "OPRA:AAPL280115C210.0",
|
|
2170
|
+
"ask_price": 15.2,
|
|
2171
|
+
"bid_price": 14.8,
|
|
2172
|
+
"delta": 0.52,
|
|
2173
|
+
"gamma": 0.015,
|
|
2174
|
+
"implied_volatility": 0.26,
|
|
2175
|
+
"type": "CALL",
|
|
2176
|
+
"rho": 0.09,
|
|
2177
|
+
"strike_price": 210,
|
|
2178
|
+
"theoretical_price": 15.0,
|
|
2179
|
+
"theta": -0.06,
|
|
2180
|
+
"vega": 0.22,
|
|
2181
|
+
"bid_iv": 0.25,
|
|
2182
|
+
"ask_iv": 0.27,
|
|
2183
|
+
"expiration": 20280115
|
|
2184
|
+
|
|
2185
|
+
\`\`\`
|
|
2186
|
+
|
|
2187
|
+
|
|
2188
|
+
|
|
2189
|
+
|
|
2190
|
+
|
|
2191
|
+
|
|
2192
|
+
#### Option Chain Data Fields
|
|
2193
|
+
|
|
2194
|
+
|
|
2195
|
+
|
|
2196
|
+
|
|
2197
|
+
Pricing:
|
|
2198
|
+
|
|
2199
|
+
|
|
2200
|
+
|
|
2201
|
+
- ask_price , bid_price
|
|
2202
|
+
|
|
2203
|
+
- theoretical_price - Fair value estimate
|
|
2204
|
+
|
|
2205
|
+
- bid_iv , ask_iv - Implied volatility at bid/ask
|
|
2206
|
+
|
|
2207
|
+
|
|
2208
|
+
|
|
2209
|
+
|
|
2210
|
+
|
|
2211
|
+
Greeks:
|
|
2212
|
+
|
|
2213
|
+
|
|
2214
|
+
|
|
2215
|
+
- delta - Price sensitivity to underlying
|
|
2216
|
+
|
|
2217
|
+
- gamma - Delta change rate
|
|
2218
|
+
|
|
2219
|
+
- theta - Time decay
|
|
2220
|
+
|
|
2221
|
+
- vega
|
|
2222
|
+
|
|
2223
|
+
- rho
|
|
2224
|
+
|
|
2225
|
+
|
|
2226
|
+
|
|
2227
|
+
|
|
2228
|
+
|
|
2229
|
+
|
|
2230
|
+
\`expiration\`
|
|
2231
|
+
: Date in YYYYMMDD format (e.g., 20270617)
|
|
2232
|
+
|
|
2233
|
+
\`type\`
|
|
2234
|
+
: "CALL" or "PUT"
|
|
2235
|
+
|
|
2236
|
+
|
|
2237
|
+
|
|
2238
|
+
|
|
2239
|
+
|
|
2240
|
+
|
|
2241
|
+
|
|
2242
|
+
|
|
2243
|
+
|
|
2244
|
+
#### When to Use Each Endpoint
|
|
2245
|
+
|
|
2246
|
+
|
|
2247
|
+
|
|
2248
|
+
|
|
2249
|
+
##### Expiration Filter
|
|
2250
|
+
|
|
2251
|
+
Perfect for analyzing options expiring on earnings
|
|
2252
|
+
announcements or other specific events. Sort by strike_price
|
|
2253
|
+
to see the full options chain for a specific expiration.
|
|
2254
|
+
|
|
2255
|
+
|
|
2256
|
+
|
|
2257
|
+
|
|
2258
|
+
##### Strike Filter
|
|
2259
|
+
|
|
2260
|
+
Ideal for comparing options at the same strike across
|
|
2261
|
+
different expiration dates. Sort by expiration to see time
|
|
2262
|
+
decay effects.
|
|
2263
|
+
|
|
2264
|
+
|
|
2265
|
+
|
|
2266
|
+
|
|
2267
|
+
|
|
2268
|
+
|
|
2269
|
+
|
|
2270
|
+
|
|
2271
|
+
## 6. Real-time Quotes
|
|
2272
|
+
|
|
2273
|
+
|
|
2274
|
+
### Getting Real-time Option Prices
|
|
2275
|
+
|
|
2276
|
+
Once you have option codes, retrieve real-time pricing and volume
|
|
2277
|
+
data using the \`/v3/symbols/quotes\` endpoint.
|
|
2278
|
+
|
|
2279
|
+
This endpoint provides current bid/ask prices, last trade
|
|
2280
|
+
information, and trading volume for option contracts.
|
|
2281
|
+
|
|
2282
|
+
|
|
2283
|
+
### Multiple Option Quotes
|
|
2284
|
+
|
|
2285
|
+
Request quotes for multiple options (up to 10) by separating codes
|
|
2286
|
+
with commas:
|
|
2287
|
+
|
|
2288
|
+
|
|
2289
|
+
\`\`\`bash
|
|
2290
|
+
GET https://api.insightsentry.com/v3/symbols/quotes?codes=OPRA:AAPL271217P370.0,OPRA:AAPL251219C145.0,OPRA:AAPL261218P50.0
|
|
2291
|
+
\`\`\`
|
|
2292
|
+
|
|
2293
|
+
Response includes real-time data for each option:
|
|
2294
|
+
|
|
2295
|
+
|
|
2296
|
+
\`\`\`json
|
|
2297
|
+
{
|
|
2298
|
+
"last_update": 1756978199901,
|
|
2299
|
+
"_ct": 1756978199796,
|
|
2300
|
+
"total_items": 3,
|
|
2301
|
+
"data": [
|
|
2302
|
+
{
|
|
2303
|
+
"code": "OPRA:AAPL271217P370.0",
|
|
2304
|
+
"status": "CLOSED",
|
|
2305
|
+
"lp_time": 1750065411.0,
|
|
2306
|
+
"volume": 0.0,
|
|
2307
|
+
"last_price": 166.14,
|
|
2308
|
+
"ask": 133.55,
|
|
2309
|
+
"bid": 129.75,
|
|
2310
|
+
"ask_size": 107.0,
|
|
2311
|
+
"bid_size": 107.0,
|
|
2312
|
+
"open_price": 166.14,
|
|
2313
|
+
"low_price": 166.14,
|
|
2314
|
+
"high_price": 166.14,
|
|
2315
|
+
"delay_seconds": 0
|
|
2316
|
+
},
|
|
2317
|
+
{
|
|
2318
|
+
"code": "OPRA:AAPL251219C145.0",
|
|
2319
|
+
"status": "CLOSED",
|
|
2320
|
+
"lp_time": 1756918904.0,
|
|
2321
|
+
"volume": 6.0,
|
|
2322
|
+
"last_price": 94.2,
|
|
2323
|
+
"change_percent": 10.02,
|
|
2324
|
+
"change": 8.6,
|
|
2325
|
+
"ask": 96.15,
|
|
2326
|
+
"bid": 94.4,
|
|
2327
|
+
"ask_size": 195.0,
|
|
2328
|
+
"bid_size": 258.0,
|
|
2329
|
+
"prev_close_price": 85.62,
|
|
2330
|
+
"open_price": 93.1,
|
|
2331
|
+
"low_price": 93.1,
|
|
2332
|
+
"high_price": 94.28,
|
|
2333
|
+
"delay_seconds": 0
|
|
2334
|
+
},
|
|
2335
|
+
{
|
|
2336
|
+
"code": "OPRA:AAPL261218P50.0",
|
|
2337
|
+
"status": "CLOSED",
|
|
2338
|
+
"lp_time": 1756910857.0,
|
|
2339
|
+
"volume": 1.0,
|
|
2340
|
+
"last_price": 0.09,
|
|
2341
|
+
"change_percent": -18.18,
|
|
2342
|
+
"change": -0.02,
|
|
2343
|
+
"ask": 0.12,
|
|
2344
|
+
"bid": 0.07,
|
|
2345
|
+
"ask_size": 111.0,
|
|
2346
|
+
"bid_size": 98.0,
|
|
2347
|
+
"prev_close_price": 0.11,
|
|
2348
|
+
"open_price": 0.09,
|
|
2349
|
+
"low_price": 0.09,
|
|
2350
|
+
"high_price": 0.09,
|
|
2351
|
+
"delay_seconds": 0
|
|
2352
|
+
|
|
2353
|
+
\`\`\`
|
|
2354
|
+
|
|
2355
|
+
|
|
2356
|
+
### Request Limits
|
|
2357
|
+
|
|
2358
|
+
|
|
2359
|
+
|
|
2360
|
+
#### Multiple Symbol Guidelines:
|
|
2361
|
+
|
|
2362
|
+
|
|
2363
|
+
|
|
2364
|
+
- Maximum 10 symbols per request
|
|
2365
|
+
|
|
2366
|
+
- Separate codes with commas (no spaces)
|
|
2367
|
+
|
|
2368
|
+
- All codes must be valid symbols (options, stocks, futures, etc.)
|
|
2369
|
+
|
|
2370
|
+
- Mixed asset types are supported
|
|
2371
|
+
|
|
2372
|
+
|
|
2373
|
+
|
|
2374
|
+
|
|
2375
|
+
|
|
2376
|
+
|
|
2377
|
+
|
|
2378
|
+
|
|
2379
|
+
## 7. Historical Option Data
|
|
2380
|
+
|
|
2381
|
+
|
|
2382
|
+
### Historical OHLCV Data
|
|
2383
|
+
|
|
2384
|
+
Retrieve historical price (up to 30k data points) and volume data
|
|
2385
|
+
for option contracts using the
|
|
2386
|
+
\`/v3/symbols/:symbol/series\` endpoint.
|
|
2387
|
+
|
|
2388
|
+
This endpoint provides OHLCV (Open, High, Low, Close, Volume) data
|
|
2389
|
+
for analyzing option price movements over time.
|
|
2390
|
+
|
|
2391
|
+
|
|
2392
|
+
|
|
2393
|
+
|
|
2394
|
+
|
|
2395
|
+
|
|
2396
|
+
#### Important Limitations
|
|
2397
|
+
|
|
2398
|
+
Historical options data has the following restrictions:
|
|
2399
|
+
|
|
2400
|
+
|
|
2401
|
+
|
|
2402
|
+
- Expired options are NOT supported
|
|
2403
|
+
|
|
2404
|
+
- Futures options are NOT supported
|
|
2405
|
+
|
|
2406
|
+
- Only equity options are currently available
|
|
2407
|
+
|
|
2408
|
+
- Options must still be active and trading
|
|
2409
|
+
|
|
2410
|
+
|
|
2411
|
+
|
|
2412
|
+
|
|
2413
|
+
|
|
2414
|
+
|
|
2415
|
+
|
|
2416
|
+
|
|
2417
|
+
### Historical Data Request
|
|
2418
|
+
|
|
2419
|
+
Get daily historical data for an option contract:
|
|
2420
|
+
|
|
2421
|
+
|
|
2422
|
+
\`\`\`bash
|
|
2423
|
+
GET https://api.insightsentry.com/v3/symbols/OPRA:AAPL271217P205.0/series?bar_type=day&bar_interval=1&dp=20000
|
|
2424
|
+
\`\`\`
|
|
2425
|
+
|
|
2426
|
+
You can also request different time intervals:
|
|
2427
|
+
|
|
2428
|
+
|
|
2429
|
+
\`\`\`bash
|
|
2430
|
+
# Hourly data
|
|
2431
|
+
GET https://api.insightsentry.com/v3/symbols/OPRA:AAPL271217P205.0/series?bar_type=hour&bar_interval=1&dp=20000
|
|
2432
|
+
|
|
2433
|
+
# 5-minute data
|
|
2434
|
+
GET https://api.insightsentry.com/v3/symbols/OPRA:AAPL271217P205.0/series?bar_type=minute&bar_interval=5&dp=20000
|
|
2435
|
+
\`\`\`
|
|
2436
|
+
|
|
2437
|
+
Response provides OHLCV data with timestamps:
|
|
2438
|
+
|
|
2439
|
+
|
|
2440
|
+
\`\`\`json
|
|
2441
|
+
{
|
|
2442
|
+
"code": "OPRA:AAPL271217P205.0",
|
|
2443
|
+
"bar_end": 1733432340.0,
|
|
2444
|
+
"last_update": 1733432400000,
|
|
2445
|
+
"_ct": 1733432401234,
|
|
2446
|
+
"bar_type": "1D",
|
|
2447
|
+
"series": [
|
|
2448
|
+
{
|
|
2449
|
+
"time": 1704153600.0,
|
|
2450
|
+
"open": 82.50,
|
|
2451
|
+
"high": 84.75,
|
|
2452
|
+
"low": 81.25,
|
|
2453
|
+
"close": 83.80,
|
|
2454
|
+
"volume": 1450
|
|
2455
|
+
},
|
|
2456
|
+
{
|
|
2457
|
+
"time": 1704240000.0,
|
|
2458
|
+
"open": 84.00,
|
|
2459
|
+
"high": 86.25,
|
|
2460
|
+
"low": 83.50,
|
|
2461
|
+
"close": 85.90,
|
|
2462
|
+
"volume": 2100
|
|
2463
|
+
},
|
|
2464
|
+
{
|
|
2465
|
+
"time": 1704326400.0,
|
|
2466
|
+
"open": 85.75,
|
|
2467
|
+
"high": 87.20,
|
|
2468
|
+
"low": 84.90,
|
|
2469
|
+
"close": 86.45,
|
|
2470
|
+
"volume": 1890
|
|
2471
|
+
|
|
2472
|
+
\`\`\`
|
|
2473
|
+
|
|
2474
|
+
|
|
2475
|
+
### Request Parameters
|
|
2476
|
+
|
|
2477
|
+
|
|
2478
|
+
|
|
2479
|
+
#### Available Parameters:
|
|
2480
|
+
|
|
2481
|
+
|
|
2482
|
+
|
|
2483
|
+
- code (required): Option code from /v3/options/list endpoint
|
|
2484
|
+
|
|
2485
|
+
- bar_type (optional): tick, second, minute, hour, day, week, month (default: day)
|
|
2486
|
+
|
|
2487
|
+
- bar_interval (optional): Number of bars (default: 1)
|
|
2488
|
+
|
|
2489
|
+
- extended (optional): Include extended hours data (default: true)
|
|
2490
|
+
|
|
2491
|
+
- dadj (optional): Dividend adjustment for equities (default: false)
|
|
2492
|
+
|
|
2493
|
+
- badj (optional): Back-adjustment for continuous futures (default: true)
|
|
2494
|
+
|
|
2495
|
+
|
|
2496
|
+
|
|
2497
|
+
|
|
2498
|
+
|
|
2499
|
+
|
|
2500
|
+
|
|
2501
|
+
## Try the API Playground
|
|
2502
|
+
|
|
2503
|
+
|
|
2504
|
+
### Interactive REST API Demo
|
|
2505
|
+
|
|
2506
|
+
You can experiment with all our endpoints using the interactive
|
|
2507
|
+
|
|
2508
|
+
API playground
|
|
2509
|
+
|
|
2510
|
+
.
|
|
2511
|
+
|
|
2512
|
+
|
|
2513
|
+
|
|
2514
|
+
|
|
2515
|
+
|
|
2516
|
+
|
|
2517
|
+
#### How to Use
|
|
2518
|
+
|
|
2519
|
+
|
|
2520
|
+
|
|
2521
|
+
- Choose an endpoint and fill in parameters
|
|
2522
|
+
|
|
2523
|
+
- Submit requests and view responses
|
|
2524
|
+
|
|
2525
|
+
- Copy cURL and convert it to your code using AI or other tools`,
|
|
2526
|
+
},
|
|
2527
|
+
{
|
|
2528
|
+
uri: "insightsentry://docs/futures-history",
|
|
2529
|
+
name: "InsightSentry Futures History Guide",
|
|
2530
|
+
description: "How to fetch extensive historical data for futures contracts, including contract month logic",
|
|
2531
|
+
mimeType: "text/markdown",
|
|
2532
|
+
content: `# Futures Historical Data Guide
|
|
2533
|
+
|
|
2534
|
+
Full documentation: https://insightsentry.com/docs
|
|
2535
|
+
|
|
2536
|
+
## 1. Overview
|
|
2537
|
+
|
|
2538
|
+
This guide demonstrates how to fetch historical data for Futures contracts.
|
|
2539
|
+
The example below uses NASDAQ Futures (NQ) to illustrate how to handle contract month logic, date ranges, and pagination.
|
|
2540
|
+
|
|
2541
|
+
Note that continuous futures do not support more than 1 year of historical data. Therefore, for extensive Futures history, you must use specific contracts. This guide explains how to fetch data for each individual contract.
|
|
2542
|
+
|
|
2543
|
+
|
|
2544
|
+
|
|
2545
|
+
|
|
2546
|
+
|
|
2547
|
+
|
|
2548
|
+
#### Important Caution
|
|
2549
|
+
|
|
2550
|
+
Currently, concurrent requests are not encouraged and may fail.
|
|
2551
|
+
Please run requests sequentially as demonstrated in this script.
|
|
2552
|
+
This code is for demonstration purposes and provides a basic implementation.
|
|
2553
|
+
|
|
2554
|
+
|
|
2555
|
+
|
|
2556
|
+
|
|
2557
|
+
|
|
2558
|
+
|
|
2559
|
+
|
|
2560
|
+
|
|
2561
|
+
|
|
2562
|
+
|
|
2563
|
+
## 2. Implementation
|
|
2564
|
+
|
|
2565
|
+
|
|
2566
|
+
|
|
2567
|
+
The following Python script demonstrates how to iterate through contract months and fetch minute-level data.
|
|
2568
|
+
While this example targets NASDAQ Futures, the same logic applies to other futures contracts with appropriate adjustments to contract months and symbols.
|
|
2569
|
+
|
|
2570
|
+
The script will create a \`data\` directory and save JSON files organized by symbol and date.
|
|
2571
|
+
You can also store the data in SQL database or in different format.
|
|
2572
|
+
|
|
2573
|
+
|
|
2574
|
+
|
|
2575
|
+
\`import os
|
|
2576
|
+
import json
|
|
2577
|
+
import time
|
|
2578
|
+
import requests
|
|
2579
|
+
from datetime import datetime
|
|
2580
|
+
|
|
2581
|
+
BASE_URL = 'https://api.insightsentry.com'
|
|
2582
|
+
START_YEAR = 2025
|
|
2583
|
+
BASE_SYMBOL_PREFIX = 'CME_MINI:NQ'
|
|
2584
|
+
BASE_CONTRACTS = ['H', 'M', 'U', 'Z']
|
|
2585
|
+
API_KEY = 'YOUR_KEY'
|
|
2586
|
+
|
|
2587
|
+
def get_contract_months(contract, year):
|
|
2588
|
+
|
|
2589
|
+
datetime(year - 1, 12, 1),
|
|
2590
|
+
datetime(year, 1, 1),
|
|
2591
|
+
datetime(year, 2, 1),
|
|
2592
|
+
datetime(year, 3, 1),
|
|
2593
|
+
|
|
2594
|
+
elif contract == 'M':
|
|
2595
|
+
|
|
2596
|
+
datetime(year, 3, 1),
|
|
2597
|
+
datetime(year, 4, 1),
|
|
2598
|
+
datetime(year, 5, 1),
|
|
2599
|
+
datetime(year, 6, 1),
|
|
2600
|
+
|
|
2601
|
+
elif contract == 'U':
|
|
2602
|
+
|
|
2603
|
+
datetime(year, 6, 1),
|
|
2604
|
+
datetime(year, 7, 1),
|
|
2605
|
+
datetime(year, 8, 1),
|
|
2606
|
+
datetime(year, 9, 1),
|
|
2607
|
+
|
|
2608
|
+
elif contract == 'Z':
|
|
2609
|
+
|
|
2610
|
+
datetime(year, 9, 1),
|
|
2611
|
+
datetime(year, 10, 1),
|
|
2612
|
+
datetime(year, 11, 1),
|
|
2613
|
+
datetime(year, 12, 1),
|
|
2614
|
+
|
|
2615
|
+
def fetch_and_save(symbol_code, start_date):
|
|
2616
|
+
base_dir = f'./data/{BASE_SYMBOL_PREFIX}'
|
|
2617
|
+
date_str = start_date.strftime('%Y-%m-%d')
|
|
2618
|
+
file_path = f'{base_dir}/{symbol_code}/{date_str}.json'
|
|
2619
|
+
|
|
2620
|
+
print(f'Already exists: {date_str}')
|
|
2621
|
+
|
|
2622
|
+
os.makedirs(os.path.dirname(file_path), exist_ok=True)
|
|
2623
|
+
|
|
2624
|
+
data = get_ohlcv(symbol_code, start_date)
|
|
2625
|
+
|
|
2626
|
+
series_len = len(data.get('series', []))
|
|
2627
|
+
print(f"Symbol: {symbol_code} | Date: {start_date} | Bars: {series_len} bars")
|
|
2628
|
+
with open(file_path, 'w') as f:
|
|
2629
|
+
json.dump(data, f)
|
|
2630
|
+
|
|
2631
|
+
def get_ohlcv(symbol_code, start_date):
|
|
2632
|
+
# timeformat is YYYY-MM for minute and hour
|
|
2633
|
+
formatted_start_date_str = start_date.strftime('%Y-%m')
|
|
2634
|
+
|
|
2635
|
+
retry_counter = 0
|
|
2636
|
+
while retry_counter < 5:
|
|
2637
|
+
result = _fetch(symbol_code, formatted_start_date_str)
|
|
2638
|
+
|
|
2639
|
+
print(f'Failed to fetch data for {symbol_code} | Date: {start_date} | Retrying... ({retry_counter}) ')
|
|
2640
|
+
retry_counter += 1
|
|
2641
|
+
time.sleep(retry_counter * 0.5)
|
|
2642
|
+
|
|
2643
|
+
def _fetch(symbol_code, formatted_start_date_str):
|
|
2644
|
+
|
|
2645
|
+
url = f'{BASE_URL}/v3/symbols/{symbol_code}/history'
|
|
2646
|
+
params = {
|
|
2647
|
+
'bar_interval': '1',
|
|
2648
|
+
'bar_type': 'minute',
|
|
2649
|
+
'start_date': formatted_start_date_str,
|
|
2650
|
+
|
|
2651
|
+
headers = {
|
|
2652
|
+
'Authorization': f'Bearer {API_KEY}',
|
|
2653
|
+
'Content-Type': 'application/json'
|
|
2654
|
+
|
|
2655
|
+
response = requests.get(url, params=params, headers=headers, timeout=120)
|
|
2656
|
+
|
|
2657
|
+
print(response.text)
|
|
2658
|
+
response.raise_for_status()
|
|
2659
|
+
|
|
2660
|
+
data = response.json()
|
|
2661
|
+
|
|
2662
|
+
print(data)
|
|
2663
|
+
raise Exception(data.get('message') or data.get('error'))
|
|
2664
|
+
|
|
2665
|
+
print(response.text)
|
|
2666
|
+
|
|
2667
|
+
except requests.exceptions.RequestException as e:
|
|
2668
|
+
|
|
2669
|
+
raise e
|
|
2670
|
+
print(e)
|
|
2671
|
+
|
|
2672
|
+
except Exception as e:
|
|
2673
|
+
print(e)
|
|
2674
|
+
|
|
2675
|
+
def main():
|
|
2676
|
+
current_year = datetime.now().year
|
|
2677
|
+
|
|
2678
|
+
for year in range(START_YEAR, current_year + 1):
|
|
2679
|
+
for contract in BASE_CONTRACTS:
|
|
2680
|
+
symbol_code = f'{BASE_SYMBOL_PREFIX}{contract}{year}'
|
|
2681
|
+
months = get_contract_months(contract, year)
|
|
2682
|
+
|
|
2683
|
+
for start_date in months:
|
|
2684
|
+
|
|
2685
|
+
continue
|
|
2686
|
+
|
|
2687
|
+
print(f"Fetching data for {symbol_code} for {start_date.strftime('%Y-%m-%d')}")
|
|
2688
|
+
fetch_and_save(symbol_code, start_date)
|
|
2689
|
+
|
|
2690
|
+
main()\``,
|
|
2691
|
+
}
|
|
2692
|
+
];
|
|
2693
|
+
//# sourceMappingURL=resources.js.map
|