@fullstackcraftllc/floe 0.0.1 → 0.0.3
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 +10 -210
- package/dist/adapters/index.js +64 -16
- package/dist/client/FloeClient.d.ts +411 -0
- package/dist/client/FloeClient.js +550 -0
- package/dist/client/brokers/SchwabClient.d.ts +2 -0
- package/dist/client/brokers/SchwabClient.js +6 -0
- package/dist/client/brokers/TradierClient.d.ts +393 -0
- package/dist/client/brokers/TradierClient.js +869 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +14 -1
- package/dist/types/index.d.ts +35 -0
- package/dist/utils/occ.d.ts +164 -0
- package/dist/utils/occ.js +203 -0
- package/package.json +3 -3
|
@@ -0,0 +1,411 @@
|
|
|
1
|
+
import { NormalizedOption, NormalizedTicker } from "../types";
|
|
2
|
+
/**
|
|
3
|
+
* Supported broker integrations for the FloeClient.
|
|
4
|
+
* @enum {string}
|
|
5
|
+
*/
|
|
6
|
+
export declare enum Broker {
|
|
7
|
+
/** Tradier brokerage API */
|
|
8
|
+
TRADIER = "tradier"
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Event types emitted by the FloeClient.
|
|
12
|
+
* @remarks
|
|
13
|
+
* Used with the {@link FloeClient.on} and {@link FloeClient.off} methods for event-driven updates.
|
|
14
|
+
*/
|
|
15
|
+
type FloeEventType = 'tickerUpdate' | 'optionUpdate' | 'error' | 'connected' | 'disconnected';
|
|
16
|
+
/**
|
|
17
|
+
* Event payload map for type-safe event handling.
|
|
18
|
+
*/
|
|
19
|
+
interface FloeEventMap {
|
|
20
|
+
tickerUpdate: NormalizedTicker;
|
|
21
|
+
optionUpdate: NormalizedOption;
|
|
22
|
+
error: Error;
|
|
23
|
+
connected: {
|
|
24
|
+
broker: Broker;
|
|
25
|
+
};
|
|
26
|
+
disconnected: {
|
|
27
|
+
broker: Broker;
|
|
28
|
+
reason?: string;
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Listener function type for FloeClient events.
|
|
33
|
+
* @template T - The event type from FloeEventType
|
|
34
|
+
*/
|
|
35
|
+
type FloeEventListener<T extends FloeEventType> = (data: FloeEventMap[T]) => void;
|
|
36
|
+
/**
|
|
37
|
+
* FloeClient provides a unified, broker-agnostic interface for subscribing to
|
|
38
|
+
* real-time market data including stock tickers and options.
|
|
39
|
+
*
|
|
40
|
+
* @remarks
|
|
41
|
+
* The client normalizes data from various brokers into a consistent format,
|
|
42
|
+
* allowing consumers to switch brokers without changing their application code.
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* ```typescript
|
|
46
|
+
* const client = new FloeClient();
|
|
47
|
+
*
|
|
48
|
+
* // Connect to a broker
|
|
49
|
+
* client.connect(Broker.TRADIER, 'your-api-key');
|
|
50
|
+
*
|
|
51
|
+
* // Subscribe to updates using the event emitter pattern
|
|
52
|
+
* client.on('tickerUpdate', (ticker) => {
|
|
53
|
+
* console.log(`${ticker.symbol}: ${ticker.price}`);
|
|
54
|
+
* });
|
|
55
|
+
*
|
|
56
|
+
* // Or use the callback pattern
|
|
57
|
+
* client.onTickerDataChange((ticker) => {
|
|
58
|
+
* console.log(`${ticker.symbol}: ${ticker.price}`);
|
|
59
|
+
* });
|
|
60
|
+
*
|
|
61
|
+
* // Subscribe to specific tickers
|
|
62
|
+
* client.subscribeToTickers(['AAPL', 'GOOGL', 'MSFT']);
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
export declare class FloeClient {
|
|
66
|
+
/** Currently connected broker, or null if not connected */
|
|
67
|
+
private currentBroker;
|
|
68
|
+
/** List of ticker symbols currently subscribed to */
|
|
69
|
+
private currentSubscribedTickers;
|
|
70
|
+
/** List of option symbols (OCC format) currently subscribed to */
|
|
71
|
+
private currentSubscribedOptions;
|
|
72
|
+
/** Cache of the latest normalized ticker data */
|
|
73
|
+
private normalizedTickers;
|
|
74
|
+
/** Cache of the latest normalized option data */
|
|
75
|
+
private normalizedOptions;
|
|
76
|
+
/** Tradier broker client instance */
|
|
77
|
+
private tradierClient;
|
|
78
|
+
/** Event listeners registry for the EventEmitter pattern */
|
|
79
|
+
private eventListeners;
|
|
80
|
+
/** Callback for ticker data changes (legacy callback pattern) */
|
|
81
|
+
private tickerDataCallback;
|
|
82
|
+
/** Callback for option data changes (legacy callback pattern) */
|
|
83
|
+
private optionDataCallback;
|
|
84
|
+
/**
|
|
85
|
+
* Creates a new FloeClient instance.
|
|
86
|
+
*
|
|
87
|
+
* @remarks
|
|
88
|
+
* The client is created in a disconnected state. Call {@link connect} to
|
|
89
|
+
* establish a connection to a broker before subscribing to data.
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* ```typescript
|
|
93
|
+
* const client = new FloeClient();
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
constructor();
|
|
97
|
+
/**
|
|
98
|
+
* Establishes a connection to a broker's API.
|
|
99
|
+
*
|
|
100
|
+
* @param broker - The broker to connect to (e.g., Broker.TRADIER)
|
|
101
|
+
* @param authKey - The API authentication key or token for the broker
|
|
102
|
+
*
|
|
103
|
+
* @throws {Error} Throws if the specified broker is not supported
|
|
104
|
+
*
|
|
105
|
+
* @remarks
|
|
106
|
+
* Must be called before subscribing to any market data. Only one broker
|
|
107
|
+
* connection is active at a time; calling connect again will switch brokers.
|
|
108
|
+
*
|
|
109
|
+
* @example
|
|
110
|
+
* ```typescript
|
|
111
|
+
* await client.connect(Broker.TRADIER, 'your-tradier-api-key');
|
|
112
|
+
* ```
|
|
113
|
+
*/
|
|
114
|
+
connect(broker: Broker, authKey: string): Promise<void>;
|
|
115
|
+
/**
|
|
116
|
+
* Disconnects from the current broker.
|
|
117
|
+
*
|
|
118
|
+
* @remarks
|
|
119
|
+
* Closes the WebSocket connection and clears all subscriptions.
|
|
120
|
+
*
|
|
121
|
+
* @example
|
|
122
|
+
* ```typescript
|
|
123
|
+
* client.disconnect();
|
|
124
|
+
* ```
|
|
125
|
+
*/
|
|
126
|
+
disconnect(): void;
|
|
127
|
+
/**
|
|
128
|
+
* Subscribes to real-time updates for the specified stock ticker symbols.
|
|
129
|
+
*
|
|
130
|
+
* @param tickers - Array of ticker symbols to subscribe to (e.g., ['AAPL', 'GOOGL'])
|
|
131
|
+
*
|
|
132
|
+
* @throws {Error} Throws if no broker connection has been established
|
|
133
|
+
*
|
|
134
|
+
* @remarks
|
|
135
|
+
* Ticker updates will be delivered via the 'tickerUpdate' event or through
|
|
136
|
+
* the callback registered with {@link onTickerDataChange}.
|
|
137
|
+
*
|
|
138
|
+
* @example
|
|
139
|
+
* ```typescript
|
|
140
|
+
* client.subscribeToTickers(['AAPL', 'GOOGL', 'MSFT']);
|
|
141
|
+
* ```
|
|
142
|
+
*/
|
|
143
|
+
subscribeToTickers(tickers: Array<string>): void;
|
|
144
|
+
/**
|
|
145
|
+
* Subscribes to real-time updates for the specified option contracts.
|
|
146
|
+
*
|
|
147
|
+
* @param symbols - Array of option symbols in OCC format
|
|
148
|
+
* (e.g., ['AAPL230120C00150000'] for AAPL $150 Call expiring Jan 20, 2023)
|
|
149
|
+
*
|
|
150
|
+
* @throws {Error} Throws if no broker connection has been established
|
|
151
|
+
*
|
|
152
|
+
* @remarks
|
|
153
|
+
* Option symbols must be in the standard OCC (Options Clearing Corporation) format:
|
|
154
|
+
* - Root symbol (up to 6 characters, left-padded)
|
|
155
|
+
* - Expiration date (YYMMDD)
|
|
156
|
+
* - Option type (C for call, P for put)
|
|
157
|
+
* - Strike price (8 digits, price × 1000, left-padded with zeros)
|
|
158
|
+
*
|
|
159
|
+
* Option updates will be delivered via the 'optionUpdate' event or through
|
|
160
|
+
* the callback registered with {@link onOptionDataChange}.
|
|
161
|
+
*
|
|
162
|
+
* @example
|
|
163
|
+
* ```typescript
|
|
164
|
+
* // Subscribe to AAPL $150 Call expiring Jan 20, 2023
|
|
165
|
+
* client.subscribeToOptions(['AAPL230120C00150000']);
|
|
166
|
+
* ```
|
|
167
|
+
*/
|
|
168
|
+
subscribeToOptions(symbols: Array<string>): void;
|
|
169
|
+
/**
|
|
170
|
+
* Unsubscribes from real-time updates for the specified stock ticker symbols.
|
|
171
|
+
*
|
|
172
|
+
* @param tickers - Array of ticker symbols to unsubscribe from
|
|
173
|
+
*
|
|
174
|
+
* @throws {Error} Throws if no broker connection has been established
|
|
175
|
+
*
|
|
176
|
+
* @remarks
|
|
177
|
+
* After unsubscribing, no further updates will be received for these tickers.
|
|
178
|
+
* Has no effect if the specified tickers were not previously subscribed.
|
|
179
|
+
*
|
|
180
|
+
* @example
|
|
181
|
+
* ```typescript
|
|
182
|
+
* client.unsubscribeFromTickers(['AAPL', 'GOOGL']);
|
|
183
|
+
* ```
|
|
184
|
+
*/
|
|
185
|
+
unsubscribeFromTickers(tickers: Array<string>): void;
|
|
186
|
+
/**
|
|
187
|
+
* Unsubscribes from real-time updates for the specified option contracts.
|
|
188
|
+
*
|
|
189
|
+
* @param symbols - Array of option symbols in OCC format to unsubscribe from
|
|
190
|
+
*
|
|
191
|
+
* @throws {Error} Throws if no broker connection has been established
|
|
192
|
+
*
|
|
193
|
+
* @remarks
|
|
194
|
+
* After unsubscribing, no further updates will be received for these options.
|
|
195
|
+
* Has no effect if the specified options were not previously subscribed.
|
|
196
|
+
*
|
|
197
|
+
* @example
|
|
198
|
+
* ```typescript
|
|
199
|
+
* client.unsubscribeFromOptions(['AAPL230120C00150000']);
|
|
200
|
+
* ```
|
|
201
|
+
*/
|
|
202
|
+
unsubscribeFromOptions(symbols: Array<string>): void;
|
|
203
|
+
/**
|
|
204
|
+
* Fetches open interest and initial option data via REST API.
|
|
205
|
+
*
|
|
206
|
+
* @param symbols - Array of option symbols in OCC format to fetch data for.
|
|
207
|
+
* If not provided, fetches data for all currently subscribed options.
|
|
208
|
+
* @returns Promise that resolves when all data has been fetched
|
|
209
|
+
*
|
|
210
|
+
* @throws {Error} Throws if no broker connection has been established
|
|
211
|
+
*
|
|
212
|
+
* @remarks
|
|
213
|
+
* Open interest is not available via streaming and must be fetched via REST API.
|
|
214
|
+
* This method should be called after subscribing to options to populate
|
|
215
|
+
* open interest, volume, and initial bid/ask values.
|
|
216
|
+
*
|
|
217
|
+
* The fetched data is automatically merged into the option cache and
|
|
218
|
+
* emitted via 'optionUpdate' events.
|
|
219
|
+
*
|
|
220
|
+
* @example
|
|
221
|
+
* ```typescript
|
|
222
|
+
* // Subscribe to options
|
|
223
|
+
* client.subscribeToOptions(optionSymbols);
|
|
224
|
+
*
|
|
225
|
+
* // Fetch open interest data
|
|
226
|
+
* await client.fetchOpenInterest();
|
|
227
|
+
*
|
|
228
|
+
* // Options now have open interest populated
|
|
229
|
+
* client.on('optionUpdate', (option) => {
|
|
230
|
+
* console.log(`${option.occSymbol}: OI=${option.openInterest}`);
|
|
231
|
+
* });
|
|
232
|
+
* ```
|
|
233
|
+
*/
|
|
234
|
+
fetchOpenInterest(symbols?: string[]): Promise<void>;
|
|
235
|
+
/**
|
|
236
|
+
* Returns cached option data for a specific symbol.
|
|
237
|
+
*
|
|
238
|
+
* @param occSymbol - OCC option symbol
|
|
239
|
+
* @returns Cached option data, or undefined if not found
|
|
240
|
+
*
|
|
241
|
+
* @example
|
|
242
|
+
* ```typescript
|
|
243
|
+
* const option = client.getOption('QQQ250117C00530000');
|
|
244
|
+
* console.log(`Open Interest: ${option?.openInterest}`);
|
|
245
|
+
* ```
|
|
246
|
+
*/
|
|
247
|
+
getOption(occSymbol: string): NormalizedOption | undefined;
|
|
248
|
+
/**
|
|
249
|
+
* Returns all cached options.
|
|
250
|
+
*
|
|
251
|
+
* @returns Map of OCC symbols to option data
|
|
252
|
+
*
|
|
253
|
+
* @example
|
|
254
|
+
* ```typescript
|
|
255
|
+
* const allOptions = client.getAllOptions();
|
|
256
|
+
* for (const [symbol, option] of allOptions) {
|
|
257
|
+
* console.log(`${symbol}: OI=${option.openInterest}`);
|
|
258
|
+
* }
|
|
259
|
+
* ```
|
|
260
|
+
*/
|
|
261
|
+
getAllOptions(): Map<string, NormalizedOption>;
|
|
262
|
+
/**
|
|
263
|
+
* Registers an event listener for the specified event type.
|
|
264
|
+
*
|
|
265
|
+
* @template T - The event type
|
|
266
|
+
* @param event - The event type to listen for
|
|
267
|
+
* @param listener - The callback function to invoke when the event occurs
|
|
268
|
+
* @returns The FloeClient instance for method chaining
|
|
269
|
+
*
|
|
270
|
+
* @remarks
|
|
271
|
+
* Multiple listeners can be registered for the same event type.
|
|
272
|
+
* Use {@link off} to remove a listener when it's no longer needed.
|
|
273
|
+
*
|
|
274
|
+
* @example
|
|
275
|
+
* ```typescript
|
|
276
|
+
* client
|
|
277
|
+
* .on('tickerUpdate', (ticker) => console.log(ticker))
|
|
278
|
+
* .on('error', (error) => console.error(error));
|
|
279
|
+
* ```
|
|
280
|
+
*/
|
|
281
|
+
on<T extends FloeEventType>(event: T, listener: FloeEventListener<T>): this;
|
|
282
|
+
/**
|
|
283
|
+
* Removes an event listener for the specified event type.
|
|
284
|
+
*
|
|
285
|
+
* @template T - The event type
|
|
286
|
+
* @param event - The event type to stop listening for
|
|
287
|
+
* @param listener - The callback function to remove
|
|
288
|
+
* @returns The FloeClient instance for method chaining
|
|
289
|
+
*
|
|
290
|
+
* @remarks
|
|
291
|
+
* The listener must be the exact same function reference that was passed to {@link on}.
|
|
292
|
+
*
|
|
293
|
+
* @example
|
|
294
|
+
* ```typescript
|
|
295
|
+
* const handler = (ticker) => console.log(ticker);
|
|
296
|
+
* client.on('tickerUpdate', handler);
|
|
297
|
+
* // Later...
|
|
298
|
+
* client.off('tickerUpdate', handler);
|
|
299
|
+
* ```
|
|
300
|
+
*/
|
|
301
|
+
off<T extends FloeEventType>(event: T, listener: FloeEventListener<T>): this;
|
|
302
|
+
/**
|
|
303
|
+
* Registers a one-time event listener that automatically removes itself after firing.
|
|
304
|
+
*
|
|
305
|
+
* @template T - The event type
|
|
306
|
+
* @param event - The event type to listen for
|
|
307
|
+
* @param listener - The callback function to invoke once when the event occurs
|
|
308
|
+
* @returns The FloeClient instance for method chaining
|
|
309
|
+
*
|
|
310
|
+
* @example
|
|
311
|
+
* ```typescript
|
|
312
|
+
* client.once('connected', ({ broker }) => {
|
|
313
|
+
* console.log(`Connected to ${broker}`);
|
|
314
|
+
* });
|
|
315
|
+
* ```
|
|
316
|
+
*/
|
|
317
|
+
once<T extends FloeEventType>(event: T, listener: FloeEventListener<T>): this;
|
|
318
|
+
/**
|
|
319
|
+
* Emits an event to all registered listeners.
|
|
320
|
+
*
|
|
321
|
+
* @template T - The event type
|
|
322
|
+
* @param event - The event type to emit
|
|
323
|
+
* @param data - The event payload
|
|
324
|
+
*
|
|
325
|
+
* @internal
|
|
326
|
+
* @remarks
|
|
327
|
+
* This method is used internally to dispatch events. It also triggers
|
|
328
|
+
* legacy callback handlers for backwards compatibility.
|
|
329
|
+
*/
|
|
330
|
+
private emit;
|
|
331
|
+
/**
|
|
332
|
+
* Registers a callback to be invoked whenever ticker data is updated.
|
|
333
|
+
*
|
|
334
|
+
* @param callback - Function to call with the updated ticker data
|
|
335
|
+
*
|
|
336
|
+
* @deprecated Prefer using {@link on}('tickerUpdate', callback) for new code.
|
|
337
|
+
* The event emitter pattern supports multiple listeners and provides
|
|
338
|
+
* better lifecycle management.
|
|
339
|
+
*
|
|
340
|
+
* @remarks
|
|
341
|
+
* Only one callback can be registered at a time. Calling this method again
|
|
342
|
+
* will replace the previous callback. For multiple listeners, use {@link on}.
|
|
343
|
+
*
|
|
344
|
+
* @example
|
|
345
|
+
* ```typescript
|
|
346
|
+
* client.onTickerDataChange((ticker) => {
|
|
347
|
+
* console.log(`${ticker.symbol} updated: ${ticker.price}`);
|
|
348
|
+
* });
|
|
349
|
+
* ```
|
|
350
|
+
*/
|
|
351
|
+
onTickerDataChange(callback: (data: NormalizedTicker) => void): void;
|
|
352
|
+
/**
|
|
353
|
+
* Registers a callback to be invoked whenever option data is updated.
|
|
354
|
+
*
|
|
355
|
+
* @param callback - Function to call with the updated option data
|
|
356
|
+
*
|
|
357
|
+
* @deprecated Prefer using {@link on}('optionUpdate', callback) for new code.
|
|
358
|
+
* The event emitter pattern supports multiple listeners and provides
|
|
359
|
+
* better lifecycle management.
|
|
360
|
+
*
|
|
361
|
+
* @remarks
|
|
362
|
+
* Only one callback can be registered at a time. Calling this method again
|
|
363
|
+
* will replace the previous callback. For multiple listeners, use {@link on}.
|
|
364
|
+
*
|
|
365
|
+
* @example
|
|
366
|
+
* ```typescript
|
|
367
|
+
* client.onOptionDataChange((option) => {
|
|
368
|
+
* console.log(`${option.symbol} bid: ${option.bid}, ask: ${option.ask}`);
|
|
369
|
+
* });
|
|
370
|
+
* ```
|
|
371
|
+
*/
|
|
372
|
+
onOptionDataChange(callback: (data: NormalizedOption) => void): void;
|
|
373
|
+
/**
|
|
374
|
+
* Returns the list of currently subscribed ticker symbols.
|
|
375
|
+
*
|
|
376
|
+
* @returns Array of ticker symbols currently subscribed to
|
|
377
|
+
*
|
|
378
|
+
* @example
|
|
379
|
+
* ```typescript
|
|
380
|
+
* const tickers = client.getSubscribedTickers();
|
|
381
|
+
* console.log(`Subscribed to: ${tickers.join(', ')}`);
|
|
382
|
+
* ```
|
|
383
|
+
*/
|
|
384
|
+
getSubscribedTickers(): ReadonlyArray<string>;
|
|
385
|
+
/**
|
|
386
|
+
* Returns the list of currently subscribed option symbols.
|
|
387
|
+
*
|
|
388
|
+
* @returns Array of option symbols (OCC format) currently subscribed to
|
|
389
|
+
*
|
|
390
|
+
* @example
|
|
391
|
+
* ```typescript
|
|
392
|
+
* const options = client.getSubscribedOptions();
|
|
393
|
+
* console.log(`Subscribed to ${options.length} options`);
|
|
394
|
+
* ```
|
|
395
|
+
*/
|
|
396
|
+
getSubscribedOptions(): ReadonlyArray<string>;
|
|
397
|
+
/**
|
|
398
|
+
* Returns whether the client is currently connected to a broker.
|
|
399
|
+
*
|
|
400
|
+
* @returns True if connected to a broker, false otherwise
|
|
401
|
+
*
|
|
402
|
+
* @example
|
|
403
|
+
* ```typescript
|
|
404
|
+
* if (client.isConnected()) {
|
|
405
|
+
* client.subscribeToTickers(['AAPL']);
|
|
406
|
+
* }
|
|
407
|
+
* ```
|
|
408
|
+
*/
|
|
409
|
+
isConnected(): boolean;
|
|
410
|
+
}
|
|
411
|
+
export {};
|