| 13 |
13 |
{ id: 'fx', name: 'FX', desc: 'Foreign-exchange pairs.', adjustments: ['none'], example: 'EURUSD' }, |
| 14 |
14 |
] |
| 15 |
15 |
|
|
16 |
+export const ASSET_IDS = ASSET_TYPES.map(a => a.id) |
|
17 |
+export const ADJUSTMENTS_BY_ASSET = Object.fromEntries( |
|
18 |
+ ASSET_TYPES.map(a => [a.id, a.adjustments])) |
|
19 |
+export const EXAMPLE_TICKER = Object.fromEntries( |
|
20 |
+ ASSET_TYPES.map(a => [a.id, a.example])) |
|
21 |
+ |
| 16 |
22 |
export const TIMEFRAMES = ['1min', '5min', '30min', '1hour', '1day'] |
| 17 |
23 |
|
| 18 |
24 |
export const BAR_FIELDS = [ |
| 54 |
60 |
{ code: 503, meaning: 'Unavailable', desc: 'The requested dataset segment has not been ingested yet.' }, |
| 55 |
61 |
] |
| 56 |
62 |
|
|
63 |
+export const CAPABILITIES = [ |
|
64 |
+ { title: 'Any window, to the minute', desc: 'start / end accept full timestamps — pull exactly 4 hours of 1-minute bars, one session, or 20 years of dailies.' }, |
|
65 |
+ { title: 'Whole watchlists in one call', desc: 'Up to 50 tickers per request on /v1/bars/{asset} — per-ticker limits, rows grouped by symbol.' }, |
|
66 |
+ { title: 'Point-in-time snapshots', desc: 'The state of every ticker you follow at 10:35:00 on any given day — one request.' }, |
|
67 |
+ { title: 'Options with the full Greek set', desc: 'Chains, expirations and single-contract life stories — quotes, bid/ask IV, OI, delta gamma vega theta rho.' }, |
|
68 |
+ { title: 'Bulk CSV extraction', desc: 'format=csv streams up to 2,000,000 rows per request — pandas.read_csv straight from the URL.' }, |
|
69 |
+ { title: 'Every adjustment variant', desc: 'Split-only, split+dividend or raw unadjusted equities; ratio / absolute / unadjusted futures rolls.' }, |
|
70 |
+] |
|
71 |
+ |
|
72 |
+// t: input type ('select' | 'text'), opts: fixed list or dynamic key, |
|
73 |
+// def: playground default, ph: placeholder |
| 57 |
74 |
export const ENDPOINTS = [ |
| 58 |
75 |
{ |
| 59 |
76 |
id: 'health', |
| 63 |
80 |
tag: 'Meta', |
| 64 |
81 |
desc: 'Service liveness probe. Returns service name, version and whether the data lake is mounted.', |
| 65 |
82 |
params: [], |
| 66 |
|
− example: '/health', |
| 67 |
83 |
response: `{ |
| 68 |
84 |
"status": "ok", |
| 69 |
85 |
"service": "hfmarketdata-api", |
| 77 |
93 |
path: '/v1/status', |
| 78 |
94 |
title: 'Dataset inventory', |
| 79 |
95 |
tag: 'Meta', |
| 80 |
|
− desc: 'Full inventory of the data lake: every asset type, timeframe and adjustment with the number of instruments available, plus the list of options quarters. Coverage grows continuously as ingestion progresses.', |
|
96 |
+ desc: 'Full inventory of the data lake: every asset type, timeframe and adjustment with the number of instruments available, plus the list of options quarters.', |
| 81 |
97 |
params: [], |
| 82 |
|
− example: '/v1/status', |
| 83 |
98 |
response: `{ |
| 84 |
99 |
"datasets": { |
| 85 |
100 |
"stock": { |
| 86 |
|
− "1day": { "adj_split": 7664, "adj_splitdiv": 7664, "UNADJUSTED": 7665 }, |
| 87 |
|
− "1min": { "adj_split": 7659, "adj_splitdiv": 7659, "UNADJUSTED": 7660 } |
|
101 |
+ "1min": { "adj_split": 7669, "adj_splitdiv": 7669, "UNADJUSTED": 7670 }, |
|
102 |
+ "1day": { "adj_split": 7664, "adj_splitdiv": 7664, "UNADJUSTED": 7665 } |
| 88 |
103 |
}, |
| 89 |
|
− "fx": { "1day": { "none": 79 } }, |
|
104 |
+ "fx": { "1min": { "none": 79 } }, |
| 90 |
105 |
"options": { |
| 91 |
106 |
"quarters": ["2010_q1", "2010_q2", "…", "2026_q2"], |
| 92 |
107 |
"files_latest_quarter": 5972 |
| 102 |
117 |
tag: 'Bars', |
| 103 |
118 |
desc: 'Every instrument available for an asset type / timeframe / adjustment combination. Use it to discover coverage before requesting bars.', |
| 104 |
119 |
params: [ |
| 105 |
|
− { name: 'asset', in: 'path', req: true, desc: 'stock · etf · futures · futures_contracts · crypto · index · fx' }, |
| 106 |
|
− { name: 'timeframe', in: 'query', req: false, desc: '1min · 5min · 30min · 1hour · 1day — default 1day' }, |
| 107 |
|
− { name: 'adjustment', in: 'query', req: false, desc: 'Adjustment variant; a sensible default is applied per asset type' }, |
| 108 |
|
− { name: 'search', in: 'query', req: false, desc: 'Case-insensitive substring filter' }, |
| 109 |
|
− { name: 'limit', in: 'query', req: false, desc: 'Max results — default 10 000' }, |
|
120 |
+ { name: 'asset', in: 'path', req: true, desc: 'Asset class', t: 'select', opts: 'ASSETS', def: 'stock' }, |
|
121 |
+ { name: 'timeframe', in: 'query', req: false, desc: 'Bar resolution — default 1day', t: 'select', opts: TIMEFRAMES, def: '1day' }, |
|
122 |
+ { name: 'adjustment', in: 'query', req: false, desc: 'Adjustment variant; sensible default per asset type', t: 'select', opts: 'ADJ_BY_ASSET', def: '' }, |
|
123 |
+ { name: 'search', in: 'query', req: false, desc: 'Case-insensitive substring filter', t: 'text', def: 'AAP', ph: 'AAP' }, |
|
124 |
+ { name: 'limit', in: 'query', req: false, desc: 'Max results — default 10 000', t: 'text', def: '', ph: '10000' }, |
| 110 |
125 |
], |
| 111 |
|
− example: '/v1/stock/tickers?timeframe=1day&search=AAP', |
| 112 |
126 |
response: `{ |
| 113 |
127 |
"asset": "stock", |
| 114 |
128 |
"timeframe": "1day", |
| 123 |
137 |
path: '/v1/bars/{asset}/{ticker}', |
| 124 |
138 |
title: 'OHLCV bars', |
| 125 |
139 |
tag: 'Bars', |
| 126 |
|
− desc: 'Historical bars for one instrument, 1-minute to daily. Daily futures bars also carry open interest. Switch to format=csv for bulk extraction — up to 2 million rows per request.', |
|
140 |
+ desc: 'Historical bars for one instrument, 1-minute to daily. start and end accept full timestamps, so any precise window works — one trading hour or twenty years. Daily futures bars also carry open interest.', |
| 127 |
141 |
params: [ |
| 128 |
|
− { name: 'asset', in: 'path', req: true, desc: 'stock · etf · futures · futures_contracts · crypto · index · fx' }, |
| 129 |
|
− { name: 'ticker', in: 'path', req: true, desc: 'Instrument symbol — AAPL, SPY, ES, BTCUSD, EURUSD…' }, |
| 130 |
|
− { name: 'timeframe', in: 'query', req: false, desc: '1min · 5min · 30min · 1hour · 1day — default 1day' }, |
| 131 |
|
− { name: 'adjustment', in: 'query', req: false, desc: 'stock/etf: adj_split · adj_splitdiv · UNADJUSTED — futures: contin_UNadj · contin_adj_ratio · contin_adj_absolute' }, |
| 132 |
|
− { name: 'start', in: 'query', req: false, desc: 'ISO lower bound — 2024-01-01 or 2024-01-01 09:30:00' }, |
| 133 |
|
− { name: 'end', in: 'query', req: false, desc: 'ISO upper bound' }, |
| 134 |
|
− { name: 'order', in: 'query', req: false, desc: 'asc (default) · desc' }, |
| 135 |
|
− { name: 'limit', in: 'query', req: false, desc: 'Max rows — default 5 000 · JSON cap 50 000 · CSV cap 2 000 000' }, |
| 136 |
|
− { name: 'format', in: 'query', req: false, desc: 'json (default) · csv' }, |
|
142 |
+ { name: 'asset', in: 'path', req: true, desc: 'Asset class', t: 'select', opts: 'ASSETS', def: 'stock' }, |
|
143 |
+ { name: 'ticker', in: 'path', req: true, desc: 'Instrument symbol — AAPL, SPY, ES, BTCUSD, EURUSD…', t: 'text', def: 'AAPL', ph: 'AAPL' }, |
|
144 |
+ { name: 'timeframe', in: 'query', req: false, desc: 'Bar resolution — default 1day', t: 'select', opts: TIMEFRAMES, def: '1day' }, |
|
145 |
+ { name: 'adjustment', in: 'query', req: false, desc: 'stock/etf: adj_split · adj_splitdiv · UNADJUSTED — futures: contin_UNadj · contin_adj_ratio · contin_adj_absolute', t: 'select', opts: 'ADJ_BY_ASSET', def: '' }, |
|
146 |
+ { name: 'start', in: 'query', req: false, desc: 'ISO lower bound — 2024-01-01 or 2024-06-03 09:30:00', t: 'text', def: '2024-06-03', ph: '2024-06-03 09:30:00' }, |
|
147 |
+ { name: 'end', in: 'query', req: false, desc: 'ISO upper bound', t: 'text', def: '', ph: '2024-06-07' }, |
|
148 |
+ { name: 'order', in: 'query', req: false, desc: 'Sort direction', t: 'select', opts: ['asc', 'desc'], def: 'asc' }, |
|
149 |
+ { name: 'limit', in: 'query', req: false, desc: 'Max rows — default 5 000 · JSON cap 50 000 · CSV cap 2 000 000', t: 'text', def: '5', ph: '5000' }, |
|
150 |
+ { name: 'format', in: 'query', req: false, desc: 'Response format', t: 'select', opts: ['json', 'csv'], def: 'json' }, |
| 137 |
151 |
], |
| 138 |
|
− example: '/v1/bars/stock/AAPL?timeframe=1day&start=2024-06-03&limit=2', |
| 139 |
152 |
response: `{ |
| 140 |
153 |
"count": 2, |
| 141 |
154 |
"data": [ |
| 155 |
168 |
tag: 'Bars', |
| 156 |
169 |
desc: 'Bars for several instruments in ONE call. Combine tickers with start/end to slice any precise window — e.g. 4 hours of 1-minute bars across a whole watchlist. The row limit applies per ticker, and rows come back grouped by ticker.', |
| 157 |
170 |
params: [ |
| 158 |
|
− { name: 'asset', in: 'path', req: true, desc: 'stock · etf · futures · futures_contracts · crypto · index · fx' }, |
| 159 |
|
− { name: 'tickers', in: 'query', req: true, desc: 'Comma-separated list — AAPL,MSFT,TSLA (max 50)' }, |
| 160 |
|
− { name: 'timeframe', in: 'query', req: false, desc: '1min · 5min · 30min · 1hour · 1day — default 1day' }, |
| 161 |
|
− { name: 'adjustment', in: 'query', req: false, desc: 'Same variants as single-ticker bars' }, |
| 162 |
|
− { name: 'start', in: 'query', req: false, desc: 'ISO lower bound — precise to the minute' }, |
| 163 |
|
− { name: 'end', in: 'query', req: false, desc: 'ISO upper bound' }, |
| 164 |
|
− { name: 'order', in: 'query', req: false, desc: 'asc (default) · desc' }, |
| 165 |
|
− { name: 'limit', in: 'query', req: false, desc: 'Max rows PER TICKER — default 5 000' }, |
| 166 |
|
− { name: 'format', in: 'query', req: false, desc: 'json (default) · csv' }, |
|
171 |
+ { name: 'asset', in: 'path', req: true, desc: 'Asset class', t: 'select', opts: 'ASSETS', def: 'stock' }, |
|
172 |
+ { name: 'tickers', in: 'query', req: true, desc: 'Comma-separated list — max 50', t: 'text', def: 'AAPL,MSFT,NVDA', ph: 'AAPL,MSFT,NVDA' }, |
|
173 |
+ { name: 'timeframe', in: 'query', req: false, desc: 'Bar resolution — default 1day', t: 'select', opts: TIMEFRAMES, def: '1min' }, |
|
174 |
+ { name: 'adjustment', in: 'query', req: false, desc: 'Same variants as single-ticker bars', t: 'select', opts: 'ADJ_BY_ASSET', def: '' }, |
|
175 |
+ { name: 'start', in: 'query', req: false, desc: 'ISO lower bound — precise to the minute', t: 'text', def: '2024-06-03 09:30:00', ph: '2024-06-03 09:30:00' }, |
|
176 |
+ { name: 'end', in: 'query', req: false, desc: 'ISO upper bound', t: 'text', def: '2024-06-03 13:30:00', ph: '2024-06-03 13:30:00' }, |
|
177 |
+ { name: 'order', in: 'query', req: false, desc: 'Sort direction', t: 'select', opts: ['asc', 'desc'], def: 'asc' }, |
|
178 |
+ { name: 'limit', in: 'query', req: false, desc: 'Max rows PER TICKER — default 5 000', t: 'text', def: '3', ph: '5000' }, |
|
179 |
+ { name: 'format', in: 'query', req: false, desc: 'Response format', t: 'select', opts: ['json', 'csv'], def: 'json' }, |
| 167 |
180 |
], |
| 168 |
|
− example: '/v1/bars/stock?tickers=AAPL,MSFT,NVDA&timeframe=1min&start=2024-06-03%2009:30:00&end=2024-06-03%2013:30:00', |
| 169 |
181 |
response: `{ |
| 170 |
182 |
"count": 720, |
| 171 |
183 |
"data": [ |
| 184 |
196 |
tag: 'Bars', |
| 185 |
197 |
desc: 'The state of a whole watchlist at one precise moment: for each requested instrument, the last bar at or before the given timestamp. Perfect for reconstructing a cross-section of the market at 10:35:00 on any given day.', |
| 186 |
198 |
params: [ |
| 187 |
|
− { name: 'asset', in: 'path', req: true, desc: 'stock · etf · futures · futures_contracts · crypto · index · fx' }, |
| 188 |
|
− { name: 'tickers', in: 'query', req: true, desc: 'Comma-separated list — AAPL,MSFT,TSLA (max 50)' }, |
| 189 |
|
− { name: 'at', in: 'query', req: true, desc: 'The precise moment — 2024-06-03 10:35:00' }, |
| 190 |
|
− { name: 'timeframe', in: 'query', req: false, desc: '1min (default) · 5min · 30min · 1hour · 1day' }, |
| 191 |
|
− { name: 'adjustment', in: 'query', req: false, desc: 'Same variants as bars' }, |
| 192 |
|
− { name: 'format', in: 'query', req: false, desc: 'json (default) · csv' }, |
|
199 |
+ { name: 'asset', in: 'path', req: true, desc: 'Asset class', t: 'select', opts: 'ASSETS', def: 'stock' }, |
|
200 |
+ { name: 'tickers', in: 'query', req: true, desc: 'Comma-separated list — max 50', t: 'text', def: 'AAPL,MSFT,NVDA', ph: 'AAPL,MSFT,NVDA' }, |
|
201 |
+ { name: 'at', in: 'query', req: true, desc: 'The precise moment', t: 'text', def: '2024-06-03 10:35:00', ph: '2024-06-03 10:35:00' }, |
|
202 |
+ { name: 'timeframe', in: 'query', req: false, desc: 'Bar resolution — default 1min', t: 'select', opts: TIMEFRAMES, def: '1min' }, |
|
203 |
+ { name: 'adjustment', in: 'query', req: false, desc: 'Same variants as bars', t: 'select', opts: 'ADJ_BY_ASSET', def: '' }, |
|
204 |
+ { name: 'format', in: 'query', req: false, desc: 'Response format', t: 'select', opts: ['json', 'csv'], def: 'json' }, |
| 193 |
205 |
], |
| 194 |
|
− example: '/v1/snapshot/stock?tickers=AAPL,MSFT,NVDA&at=2024-06-03%2010:35:00', |
| 195 |
206 |
response: `{ |
| 196 |
207 |
"count": 3, |
| 197 |
208 |
"data": [ |
| 210 |
221 |
tag: 'Options', |
| 211 |
222 |
desc: 'The quarterly archives available, from 2010_q1 through the current quarter. Each quarter holds one end-of-day chain file per underlying.', |
| 212 |
223 |
params: [], |
| 213 |
|
− example: '/v1/options/quarters', |
| 214 |
224 |
response: `{ |
| 215 |
225 |
"quarters": ["2010_q1", "2010_q2", "2010_q3", "…", "2026_q1", "2026_q2"] |
| 216 |
226 |
}`, |
| 223 |
233 |
tag: 'Options', |
| 224 |
234 |
desc: 'Underlyings with options data in a given quarter — 5,800+ US equities and indices.', |
| 225 |
235 |
params: [ |
| 226 |
|
− { name: 'quarter', in: 'query', req: false, desc: 'e.g. 2024_q4 — default: latest quarter' }, |
| 227 |
|
− { name: 'search', in: 'query', req: false, desc: 'Substring filter' }, |
| 228 |
|
− { name: 'limit', in: 'query', req: false, desc: 'Max results — default 10 000' }, |
|
236 |
+ { name: 'quarter', in: 'query', req: false, desc: 'e.g. 2024_q4 — default: latest quarter', t: 'text', def: '', ph: '2024_q4' }, |
|
237 |
+ { name: 'search', in: 'query', req: false, desc: 'Substring filter', t: 'text', def: 'TSL', ph: 'TSL' }, |
|
238 |
+ { name: 'limit', in: 'query', req: false, desc: 'Max results — default 10 000', t: 'text', def: '', ph: '10000' }, |
| 229 |
239 |
], |
| 230 |
|
− example: '/v1/options/tickers?search=TSL', |
| 231 |
240 |
response: `{ |
| 232 |
241 |
"quarter": "2026_q2", |
| 233 |
242 |
"count": 14, |
| 242 |
251 |
tag: 'Options', |
| 243 |
252 |
desc: 'The complete end-of-day chain for an underlying on one trade date: last price, bid/ask quotes, bid/ask implied volatility, open interest, volume and the full set of Greeks. Snapshots are sampled 30 seconds before the close to avoid rebalancing-order noise.', |
| 244 |
253 |
params: [ |
| 245 |
|
− { name: 'ticker', in: 'path', req: true, desc: 'Underlying symbol — AAPL, SPX…' }, |
| 246 |
|
− { name: 'trade_date', in: 'query', req: false, desc: 'yyyy-mm-dd — default: latest available date' }, |
| 247 |
|
− { name: 'expiry', in: 'query', req: false, desc: 'Restrict to a single expiry date' }, |
| 248 |
|
− { name: 'call_put', in: 'query', req: false, desc: 'c · p' }, |
| 249 |
|
− { name: 'strike_min', in: 'query', req: false, desc: 'Minimum strike' }, |
| 250 |
|
− { name: 'strike_max', in: 'query', req: false, desc: 'Maximum strike' }, |
| 251 |
|
− { name: 'min_volume', in: 'query', req: false, desc: 'Minimum traded volume' }, |
| 252 |
|
− { name: 'limit', in: 'query', req: false, desc: 'Max rows — default 20 000' }, |
| 253 |
|
− { name: 'format', in: 'query', req: false, desc: 'json (default) · csv' }, |
|
254 |
+ { name: 'ticker', in: 'path', req: true, desc: 'Underlying symbol — AAPL, SPX…', t: 'text', def: 'AAPL', ph: 'AAPL' }, |
|
255 |
+ { name: 'trade_date', in: 'query', req: false, desc: 'yyyy-mm-dd — default: latest available date', t: 'text', def: '2024-06-21', ph: '2024-06-21' }, |
|
256 |
+ { name: 'expiry', in: 'query', req: false, desc: 'Restrict to a single expiry date', t: 'text', def: '', ph: '2024-12-20' }, |
|
257 |
+ { name: 'call_put', in: 'query', req: false, desc: 'Side', t: 'select', opts: ['', 'c', 'p'], def: 'c' }, |
|
258 |
+ { name: 'strike_min', in: 'query', req: false, desc: 'Minimum strike', t: 'text', def: '200', ph: '150' }, |
|
259 |
+ { name: 'strike_max', in: 'query', req: false, desc: 'Maximum strike', t: 'text', def: '210', ph: '250' }, |
|
260 |
+ { name: 'min_volume', in: 'query', req: false, desc: 'Minimum traded volume', t: 'text', def: '', ph: '10' }, |
|
261 |
+ { name: 'limit', in: 'query', req: false, desc: 'Max rows — default 20 000', t: 'text', def: '5', ph: '20000' }, |
|
262 |
+ { name: 'format', in: 'query', req: false, desc: 'Response format', t: 'select', opts: ['json', 'csv'], def: 'json' }, |
| 254 |
263 |
], |
| 255 |
|
− example: '/v1/options/chain/AAPL?call_put=c&strike_min=200&strike_max=210&limit=1', |
| 256 |
264 |
response: `{ |
| 257 |
265 |
"count": 1, |
| 258 |
266 |
"data": [ |
| 259 |
|
− { "ticker": "AAPL", "trade_date": "2026-08-07", "strike": 200.0, |
| 260 |
|
− "expiry": "2026-08-21", "call_put": "c", "last_price": 113.25, |
| 261 |
|
− "bid": 111.25, "ask": 115.0, "bid_iv": 0.412, "ask_iv": 0.487, |
| 262 |
|
− "open_interest": 5.0, "volume": 12.0, "delta": 0.998, |
| 263 |
|
− "gamma": 0.0001, "vega": 0.0012, "theta": -0.0034, "rho": 0.0274 } |
|
267 |
+ { "ticker": "AAPL", "trade_date": "2024-06-21", "strike": 200.0, |
|
268 |
+ "expiry": "2024-06-28", "call_put": "c", "last_price": 8.0, |
|
269 |
+ "bid": 7.85, "ask": 8.15, "bid_iv": 0.264, "ask_iv": 0.271, |
|
270 |
+ "open_interest": 5231.0, "volume": 1930.0, "delta": 0.694, |
|
271 |
+ "gamma": 0.041, "vega": 0.104, "theta": -0.213, "rho": 0.026 } |
| 264 |
272 |
] |
| 265 |
273 |
}`, |
| 266 |
274 |
fields: 'options', |
| 273 |
281 |
tag: 'Options', |
| 274 |
282 |
desc: 'Available expiry dates for an underlying, optionally as of one trade date — the natural first call before requesting a filtered chain.', |
| 275 |
283 |
params: [ |
| 276 |
|
− { name: 'ticker', in: 'path', req: true, desc: 'Underlying symbol' }, |
| 277 |
|
− { name: 'trade_date', in: 'query', req: false, desc: 'yyyy-mm-dd' }, |
|
284 |
+ { name: 'ticker', in: 'path', req: true, desc: 'Underlying symbol', t: 'text', def: 'AAPL', ph: 'AAPL' }, |
|
285 |
+ { name: 'trade_date', in: 'query', req: false, desc: 'yyyy-mm-dd', t: 'text', def: '2024-06-21', ph: '2024-06-21' }, |
| 278 |
286 |
], |
| 279 |
|
− example: '/v1/options/expirations/AAPL', |
| 280 |
287 |
response: `{ |
| 281 |
288 |
"ticker": "AAPL", |
| 282 |
|
− "expirations": ["2026-08-21", "2026-08-28", "2026-09-18", "…"] |
|
289 |
+ "expirations": ["2024-06-28", "2024-07-05", "2024-07-19", "…"] |
| 283 |
290 |
}`, |
| 284 |
291 |
}, |
| 285 |
292 |
{ |
| 290 |
297 |
tag: 'Options', |
| 291 |
298 |
desc: 'The daily time series of one specific contract — strike + expiry + side — across its entire life: price, quotes, implied volatility, open interest and Greeks, day by day.', |
| 292 |
299 |
params: [ |
| 293 |
|
− { name: 'ticker', in: 'path', req: true, desc: 'Underlying symbol' }, |
| 294 |
|
− { name: 'strike', in: 'query', req: true, desc: 'Contract strike' }, |
| 295 |
|
− { name: 'expiry', in: 'query', req: true, desc: 'Contract expiry — yyyy-mm-dd' }, |
| 296 |
|
− { name: 'call_put', in: 'query', req: true, desc: 'c · p' }, |
| 297 |
|
− { name: 'limit', in: 'query', req: false, desc: 'Max rows — default 5 000' }, |
| 298 |
|
− { name: 'format', in: 'query', req: false, desc: 'json (default) · csv' }, |
|
300 |
+ { name: 'ticker', in: 'path', req: true, desc: 'Underlying symbol', t: 'text', def: 'AAPL', ph: 'AAPL' }, |
|
301 |
+ { name: 'strike', in: 'query', req: true, desc: 'Contract strike', t: 'text', def: '200', ph: '200' }, |
|
302 |
+ { name: 'expiry', in: 'query', req: true, desc: 'Contract expiry — yyyy-mm-dd', t: 'text', def: '2024-12-20', ph: '2024-12-20' }, |
|
303 |
+ { name: 'call_put', in: 'query', req: true, desc: 'Side', t: 'select', opts: ['c', 'p'], def: 'c' }, |
|
304 |
+ { name: 'limit', in: 'query', req: false, desc: 'Max rows — default 5 000', t: 'text', def: '5', ph: '5000' }, |
|
305 |
+ { name: 'format', in: 'query', req: false, desc: 'Response format', t: 'select', opts: ['json', 'csv'], def: 'json' }, |
| 299 |
306 |
], |
| 300 |
|
− example: '/v1/options/history/AAPL?strike=200&expiry=2026-12-18&call_put=c', |
| 301 |
307 |
response: `{ |
| 302 |
308 |
"count": 214, |
| 303 |
309 |
"data": [ |
| 304 |
|
− { "ticker": "AAPL", "trade_date": "2026-01-02", "strike": 200.0, |
| 305 |
|
− "expiry": "2026-12-18", "call_put": "c", "last_price": 41.3, "…": "…" } |
|
310 |
+ { "ticker": "AAPL", "trade_date": "2024-01-02", "strike": 200.0, |
|
311 |
+ "expiry": "2024-12-20", "call_put": "c", "last_price": 11.2, "…": "…" } |
| 306 |
312 |
] |
| 307 |
313 |
}`, |
| 308 |
314 |
fields: 'options', |
| 309 |
315 |
}, |
| 310 |
316 |
] |
| 311 |
317 |
|
| 312 |
|
−export function curlSnippet(ep) { |
| 313 |
|
− return `curl "${BASE_URL}${ep.example}"` |
|
318 |
+// ---- URL building + code snippets (shared by docs & playground) ------------- |
|
319 |
+ |
|
320 |
+export function buildUrl(ep, values) { |
|
321 |
+ let path = ep.path |
|
322 |
+ const query = [] |
|
323 |
+ for (const p of ep.params) { |
|
324 |
+ const v = (values[p.name] ?? '').toString().trim() |
|
325 |
+ if (p.in === 'path') { |
|
326 |
+ path = path.replace(`{${p.name}}`, encodeURIComponent(v || `{${p.name}}`)) |
|
327 |
+ } else if (v !== '') { |
|
328 |
+ query.push(`${p.name}=${encodeURIComponent(v).replace(/%2C/g, ',')}`) |
|
329 |
+ } |
|
330 |
+ } |
|
331 |
+ return path + (query.length ? '?' + query.join('&') : '') |
|
332 |
+} |
|
333 |
+ |
|
334 |
+export function defaultValues(ep) { |
|
335 |
+ const v = {} |
|
336 |
+ for (const p of ep.params) v[p.name] = p.def ?? '' |
|
337 |
+ return v |
|
338 |
+} |
|
339 |
+ |
|
340 |
+export function paramOptions(p, values) { |
|
341 |
+ if (p.opts === 'ASSETS') return ASSET_IDS |
|
342 |
+ if (p.opts === 'ADJ_BY_ASSET') { |
|
343 |
+ const asset = values.asset || 'stock' |
|
344 |
+ return ['', ...(ADJUSTMENTS_BY_ASSET[asset] || [])] |
|
345 |
+ } |
|
346 |
+ return p.opts || [] |
|
347 |
+} |
|
348 |
+ |
|
349 |
+export function curlSnippet(url) { |
|
350 |
+ return `curl "${BASE_URL}${url}"` |
| 314 |
351 |
} |
| 315 |
352 |
|
| 316 |
|
−export function pythonSnippet(ep) { |
|
353 |
+export function pythonSnippet(url) { |
| 317 |
354 |
return `import requests |
| 318 |
355 |
|
| 319 |
|
−r = requests.get("${BASE_URL}${ep.example}") |
|
356 |
+r = requests.get("${BASE_URL}${url}") |
| 320 |
357 |
r.raise_for_status() |
| 321 |
358 |
data = r.json() |
| 322 |
|
−print(f"{data.get('count', len(data))} rows")` |
|
359 |
+print(f"{data.get('count', '')} rows")` |
| 323 |
360 |
} |
| 324 |
361 |
|
| 325 |
|
−export function jsSnippet(ep) { |
| 326 |
|
− return `const res = await fetch("${BASE_URL}${ep.example}"); |
|
362 |
+export function jsSnippet(url) { |
|
363 |
+ return `const res = await fetch("${BASE_URL}${url}"); |
| 327 |
364 |
const data = await res.json(); |
| 328 |
365 |
console.log(data);` |
| 329 |
366 |
} |