@fullstackcraftllc/floe 0.0.3 → 0.0.4
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 +22 -0
- package/dist/client/FloeClient.d.ts +5 -5
- package/dist/client/FloeClient.js +49 -5
- package/dist/client/brokers/TastyTradeClient.d.ts +384 -0
- package/dist/client/brokers/TastyTradeClient.js +1081 -0
- package/dist/impliedpdf/index.d.ts +148 -0
- package/dist/impliedpdf/index.js +277 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +8 -1
- package/dist/volatility/index.d.ts +1 -1
- package/dist/volatility/index.js +1 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -30,6 +30,28 @@ The same library that is used in Full Stack Craft's various fintech products inc
|
|
|
30
30
|
- 💪 **Type-Safe** - Full TypeScript support
|
|
31
31
|
- ⚡ **Zero Dependencies** - Lightweight and fast
|
|
32
32
|
|
|
33
|
+
## Broker Support Roadmap
|
|
34
|
+
|
|
35
|
+
Due to the overwhelming variety of how broker APIs structure their data (and how they make it available), there is a wide variety of how much support we can provide out-of-the-box for different brokers, summarized in this table:
|
|
36
|
+
|
|
37
|
+
| Broker | Black-Scholes | Greeks | Open Interest Based Exposures | Options-Book Based Exposures | Implied PDF Calculations |
|
|
38
|
+
|-----------------------|--------------|--------|-------------------------------|------------------------------|-------------------------|
|
|
39
|
+
| Tradier (via WebSocket) | ✅ | ✅ | ✅ | ✅ | Coming soon |
|
|
40
|
+
| Schwab (via WebSocket) | Coming soon | Coming soon | Coming soon | Coming soon | Coming soon |
|
|
41
|
+
| Tastytrade (via WebSocket - DXLink Streamer) | Coming soon | Coming soon | Coming soon | Coming soon | Coming soon |
|
|
42
|
+
| TradeStation (via HTTP Streaming) | Coming soon | Coming soon | Coming soon | Coming soon | Coming soon |
|
|
43
|
+
|
|
44
|
+
Ideally all aspects of `floe` will be available for all brokers, but this will take time to determine as we work through the various data structures and formats that each broker provides.
|
|
45
|
+
|
|
46
|
+
## Unsupported Brokers
|
|
47
|
+
|
|
48
|
+
The following brokers have no public API:
|
|
49
|
+
|
|
50
|
+
- Fidelity
|
|
51
|
+
- Robinhood
|
|
52
|
+
|
|
53
|
+
If your broker is not listed above, you can still use `floe` by normalizing your broker's data structures to match the expected input types. With options, you can get quite far with `floe` just by having the market price for the underlying and each option. (From those alone you can back out the IV, greeks, and exposures.)
|
|
54
|
+
|
|
33
55
|
## Installation
|
|
34
56
|
|
|
35
57
|
```bash
|
|
@@ -5,7 +5,9 @@ import { NormalizedOption, NormalizedTicker } from "../types";
|
|
|
5
5
|
*/
|
|
6
6
|
export declare enum Broker {
|
|
7
7
|
/** Tradier brokerage API */
|
|
8
|
-
TRADIER = "tradier"
|
|
8
|
+
TRADIER = "tradier",
|
|
9
|
+
/** TastyTrade brokerage API (uses DxLink WebSocket) */
|
|
10
|
+
TASTYTRADE = "tastytrade"
|
|
9
11
|
}
|
|
10
12
|
/**
|
|
11
13
|
* Event types emitted by the FloeClient.
|
|
@@ -69,12 +71,10 @@ export declare class FloeClient {
|
|
|
69
71
|
private currentSubscribedTickers;
|
|
70
72
|
/** List of option symbols (OCC format) currently subscribed to */
|
|
71
73
|
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
74
|
/** Tradier broker client instance */
|
|
77
75
|
private tradierClient;
|
|
76
|
+
/** TastyTrade broker client instance */
|
|
77
|
+
private tastyTradeClient;
|
|
78
78
|
/** Event listeners registry for the EventEmitter pattern */
|
|
79
79
|
private eventListeners;
|
|
80
80
|
/** Callback for ticker data changes (legacy callback pattern) */
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.FloeClient = exports.Broker = void 0;
|
|
4
4
|
const TradierClient_1 = require("./brokers/TradierClient");
|
|
5
|
+
const TastyTradeClient_1 = require("./brokers/TastyTradeClient");
|
|
5
6
|
/**
|
|
6
7
|
* Supported broker integrations for the FloeClient.
|
|
7
8
|
* @enum {string}
|
|
@@ -10,7 +11,8 @@ var Broker;
|
|
|
10
11
|
(function (Broker) {
|
|
11
12
|
/** Tradier brokerage API */
|
|
12
13
|
Broker["TRADIER"] = "tradier";
|
|
13
|
-
|
|
14
|
+
/** TastyTrade brokerage API (uses DxLink WebSocket) */
|
|
15
|
+
Broker["TASTYTRADE"] = "tastytrade";
|
|
14
16
|
})(Broker || (exports.Broker = Broker = {}));
|
|
15
17
|
/**
|
|
16
18
|
* FloeClient provides a unified, broker-agnostic interface for subscribing to
|
|
@@ -61,12 +63,10 @@ class FloeClient {
|
|
|
61
63
|
this.currentSubscribedTickers = [];
|
|
62
64
|
/** List of option symbols (OCC format) currently subscribed to */
|
|
63
65
|
this.currentSubscribedOptions = [];
|
|
64
|
-
/** Cache of the latest normalized ticker data */
|
|
65
|
-
this.normalizedTickers = [];
|
|
66
|
-
/** Cache of the latest normalized option data */
|
|
67
|
-
this.normalizedOptions = [];
|
|
68
66
|
/** Tradier broker client instance */
|
|
69
67
|
this.tradierClient = null;
|
|
68
|
+
/** TastyTrade broker client instance */
|
|
69
|
+
this.tastyTradeClient = null;
|
|
70
70
|
/** Event listeners registry for the EventEmitter pattern */
|
|
71
71
|
this.eventListeners = new Map();
|
|
72
72
|
/** Callback for ticker data changes (legacy callback pattern) */
|
|
@@ -119,6 +119,27 @@ class FloeClient {
|
|
|
119
119
|
// Connect to the streaming API
|
|
120
120
|
await this.tradierClient.connect();
|
|
121
121
|
break;
|
|
122
|
+
case Broker.TASTYTRADE:
|
|
123
|
+
// For TastyTrade, authKey is the session token
|
|
124
|
+
this.tastyTradeClient = new TastyTradeClient_1.TastyTradeClient({
|
|
125
|
+
sessionToken: authKey,
|
|
126
|
+
});
|
|
127
|
+
// Wire up TastyTradeClient events to FloeClient events
|
|
128
|
+
this.tastyTradeClient.on('tickerUpdate', (ticker) => {
|
|
129
|
+
this.emit('tickerUpdate', ticker);
|
|
130
|
+
});
|
|
131
|
+
this.tastyTradeClient.on('optionUpdate', (option) => {
|
|
132
|
+
this.emit('optionUpdate', option);
|
|
133
|
+
});
|
|
134
|
+
this.tastyTradeClient.on('error', (error) => {
|
|
135
|
+
this.emit('error', error);
|
|
136
|
+
});
|
|
137
|
+
this.tastyTradeClient.on('disconnected', () => {
|
|
138
|
+
this.emit('disconnected', { broker, reason: 'DxLink WebSocket disconnected' });
|
|
139
|
+
});
|
|
140
|
+
// Connect to the streaming API
|
|
141
|
+
await this.tastyTradeClient.connect();
|
|
142
|
+
break;
|
|
122
143
|
default:
|
|
123
144
|
throw new Error(`Unsupported broker: ${broker}`);
|
|
124
145
|
}
|
|
@@ -140,6 +161,10 @@ class FloeClient {
|
|
|
140
161
|
this.tradierClient.disconnect();
|
|
141
162
|
this.tradierClient = null;
|
|
142
163
|
}
|
|
164
|
+
if (this.tastyTradeClient) {
|
|
165
|
+
this.tastyTradeClient.disconnect();
|
|
166
|
+
this.tastyTradeClient = null;
|
|
167
|
+
}
|
|
143
168
|
const broker = this.currentBroker;
|
|
144
169
|
this.currentBroker = null;
|
|
145
170
|
this.currentSubscribedTickers = [];
|
|
@@ -170,6 +195,9 @@ class FloeClient {
|
|
|
170
195
|
case Broker.TRADIER:
|
|
171
196
|
this.tradierClient?.subscribe(tickers);
|
|
172
197
|
break;
|
|
198
|
+
case Broker.TASTYTRADE:
|
|
199
|
+
this.tastyTradeClient?.subscribe(tickers);
|
|
200
|
+
break;
|
|
173
201
|
default:
|
|
174
202
|
throw new Error(`Unsupported broker: ${this.currentBroker}`);
|
|
175
203
|
}
|
|
@@ -204,6 +232,9 @@ class FloeClient {
|
|
|
204
232
|
case Broker.TRADIER:
|
|
205
233
|
this.tradierClient?.subscribe(symbols);
|
|
206
234
|
break;
|
|
235
|
+
case Broker.TASTYTRADE:
|
|
236
|
+
this.tastyTradeClient?.subscribe(symbols);
|
|
237
|
+
break;
|
|
207
238
|
default:
|
|
208
239
|
throw new Error(`Unsupported broker: ${this.currentBroker}`);
|
|
209
240
|
}
|
|
@@ -230,6 +261,9 @@ class FloeClient {
|
|
|
230
261
|
case Broker.TRADIER:
|
|
231
262
|
this.tradierClient?.unsubscribe(tickers);
|
|
232
263
|
break;
|
|
264
|
+
case Broker.TASTYTRADE:
|
|
265
|
+
this.tastyTradeClient?.unsubscribe(tickers);
|
|
266
|
+
break;
|
|
233
267
|
default:
|
|
234
268
|
throw new Error(`Unsupported broker: ${this.currentBroker}`);
|
|
235
269
|
}
|
|
@@ -256,6 +290,9 @@ class FloeClient {
|
|
|
256
290
|
case Broker.TRADIER:
|
|
257
291
|
this.tradierClient?.unsubscribe(symbols);
|
|
258
292
|
break;
|
|
293
|
+
case Broker.TASTYTRADE:
|
|
294
|
+
this.tastyTradeClient?.unsubscribe(symbols);
|
|
295
|
+
break;
|
|
259
296
|
default:
|
|
260
297
|
throw new Error(`Unsupported broker: ${this.currentBroker}`);
|
|
261
298
|
}
|
|
@@ -300,6 +337,9 @@ class FloeClient {
|
|
|
300
337
|
case Broker.TRADIER:
|
|
301
338
|
await this.tradierClient?.fetchOpenInterest(symbolsToFetch);
|
|
302
339
|
break;
|
|
340
|
+
case Broker.TASTYTRADE:
|
|
341
|
+
await this.tastyTradeClient?.fetchOpenInterest(symbolsToFetch);
|
|
342
|
+
break;
|
|
303
343
|
default:
|
|
304
344
|
throw new Error(`Unsupported broker: ${this.currentBroker}`);
|
|
305
345
|
}
|
|
@@ -320,6 +360,8 @@ class FloeClient {
|
|
|
320
360
|
switch (this.currentBroker) {
|
|
321
361
|
case Broker.TRADIER:
|
|
322
362
|
return this.tradierClient?.getOption(occSymbol);
|
|
363
|
+
case Broker.TASTYTRADE:
|
|
364
|
+
return this.tastyTradeClient?.getOption(occSymbol);
|
|
323
365
|
default:
|
|
324
366
|
return undefined;
|
|
325
367
|
}
|
|
@@ -341,6 +383,8 @@ class FloeClient {
|
|
|
341
383
|
switch (this.currentBroker) {
|
|
342
384
|
case Broker.TRADIER:
|
|
343
385
|
return this.tradierClient?.getAllOptions() ?? new Map();
|
|
386
|
+
case Broker.TASTYTRADE:
|
|
387
|
+
return this.tastyTradeClient?.getAllOptions() ?? new Map();
|
|
344
388
|
default:
|
|
345
389
|
return new Map();
|
|
346
390
|
}
|
|
@@ -0,0 +1,384 @@
|
|
|
1
|
+
import { NormalizedOption } from '../../types';
|
|
2
|
+
/**
|
|
3
|
+
* TastyTrade option chain item
|
|
4
|
+
*/
|
|
5
|
+
interface TastyTradeOptionChainItem {
|
|
6
|
+
symbol: string;
|
|
7
|
+
'instrument-type': string;
|
|
8
|
+
underlying: string;
|
|
9
|
+
strike: number;
|
|
10
|
+
'expiration-date': string;
|
|
11
|
+
'expiration-type': string;
|
|
12
|
+
'option-type': 'C' | 'P';
|
|
13
|
+
'root-symbol': string;
|
|
14
|
+
'streamer-symbol': string;
|
|
15
|
+
bid?: number;
|
|
16
|
+
ask?: number;
|
|
17
|
+
'bid-size'?: number;
|
|
18
|
+
'ask-size'?: number;
|
|
19
|
+
last?: number;
|
|
20
|
+
volume?: number;
|
|
21
|
+
'open-interest'?: number;
|
|
22
|
+
delta?: number;
|
|
23
|
+
gamma?: number;
|
|
24
|
+
theta?: number;
|
|
25
|
+
vega?: number;
|
|
26
|
+
'implied-volatility'?: number;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Aggressor side of a trade
|
|
30
|
+
*/
|
|
31
|
+
export type AggressorSide = 'buy' | 'sell' | 'unknown';
|
|
32
|
+
/**
|
|
33
|
+
* Intraday trade information with aggressor classification
|
|
34
|
+
*/
|
|
35
|
+
export interface IntradayTrade {
|
|
36
|
+
/** OCC option symbol */
|
|
37
|
+
occSymbol: string;
|
|
38
|
+
/** Trade price */
|
|
39
|
+
price: number;
|
|
40
|
+
/** Trade size (number of contracts) */
|
|
41
|
+
size: number;
|
|
42
|
+
/** Bid at time of trade */
|
|
43
|
+
bid: number;
|
|
44
|
+
/** Ask at time of trade */
|
|
45
|
+
ask: number;
|
|
46
|
+
/** Aggressor side determined from price vs NBBO */
|
|
47
|
+
aggressorSide: AggressorSide;
|
|
48
|
+
/** Timestamp of the trade */
|
|
49
|
+
timestamp: number;
|
|
50
|
+
/** Estimated OI change */
|
|
51
|
+
estimatedOIChange: number;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Event types emitted by TastyTradeClient
|
|
55
|
+
*/
|
|
56
|
+
type TastyTradeClientEventType = 'tickerUpdate' | 'optionUpdate' | 'optionTrade' | 'connected' | 'disconnected' | 'error';
|
|
57
|
+
/**
|
|
58
|
+
* Event listener callback type
|
|
59
|
+
*/
|
|
60
|
+
type TastyTradeEventListener<T> = (data: T) => void;
|
|
61
|
+
/**
|
|
62
|
+
* TastyTradeClient handles real-time streaming connections to the TastyTrade API
|
|
63
|
+
* via DxLink WebSockets.
|
|
64
|
+
*
|
|
65
|
+
* @remarks
|
|
66
|
+
* This client manages WebSocket connections to TastyTrade's DxLink streaming API,
|
|
67
|
+
* normalizes incoming quote and trade data, and emits events for upstream
|
|
68
|
+
* consumption by the FloeClient.
|
|
69
|
+
*
|
|
70
|
+
* Authentication flow:
|
|
71
|
+
* 1. Login to TastyTrade API to get session token (optional, can pass directly)
|
|
72
|
+
* 2. Use session token to get API quote token from /api-quote-tokens
|
|
73
|
+
* 3. Connect to DxLink WebSocket using the quote token
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* ```typescript
|
|
77
|
+
* const client = new TastyTradeClient({
|
|
78
|
+
* sessionToken: 'your-session-token'
|
|
79
|
+
* });
|
|
80
|
+
*
|
|
81
|
+
* client.on('tickerUpdate', (ticker) => {
|
|
82
|
+
* console.log(`${ticker.symbol}: ${ticker.spot}`);
|
|
83
|
+
* });
|
|
84
|
+
*
|
|
85
|
+
* await client.connect();
|
|
86
|
+
* client.subscribe(['SPY', '.SPXW231215C4500']); // Equity and option
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
89
|
+
export declare class TastyTradeClient {
|
|
90
|
+
/** TastyTrade session token */
|
|
91
|
+
private sessionToken;
|
|
92
|
+
/** DxLink API quote token */
|
|
93
|
+
private quoteToken;
|
|
94
|
+
/** DxLink WebSocket URL */
|
|
95
|
+
private dxLinkUrl;
|
|
96
|
+
/** WebSocket connection */
|
|
97
|
+
private ws;
|
|
98
|
+
/** Connection state */
|
|
99
|
+
private connected;
|
|
100
|
+
/** Authorization state */
|
|
101
|
+
private authorized;
|
|
102
|
+
/** Feed channel ID */
|
|
103
|
+
private feedChannelId;
|
|
104
|
+
/** Feed channel opened */
|
|
105
|
+
private feedChannelOpened;
|
|
106
|
+
/** Currently subscribed symbols */
|
|
107
|
+
private subscribedSymbols;
|
|
108
|
+
/** Map from streamer symbol to OCC symbol */
|
|
109
|
+
private streamerToOccMap;
|
|
110
|
+
/** Map from OCC symbol to streamer symbol */
|
|
111
|
+
private occToStreamerMap;
|
|
112
|
+
/** Cached ticker data */
|
|
113
|
+
private tickerCache;
|
|
114
|
+
/** Cached option data */
|
|
115
|
+
private optionCache;
|
|
116
|
+
/** Base open interest from REST API */
|
|
117
|
+
private baseOpenInterest;
|
|
118
|
+
/** Cumulative estimated OI change from intraday trades */
|
|
119
|
+
private cumulativeOIChange;
|
|
120
|
+
/** History of intraday trades */
|
|
121
|
+
private intradayTrades;
|
|
122
|
+
/** Event listeners */
|
|
123
|
+
private eventListeners;
|
|
124
|
+
/** Reconnection attempt counter */
|
|
125
|
+
private reconnectAttempts;
|
|
126
|
+
/** Maximum reconnection attempts */
|
|
127
|
+
private readonly maxReconnectAttempts;
|
|
128
|
+
/** Reconnection delay in ms */
|
|
129
|
+
private readonly baseReconnectDelay;
|
|
130
|
+
/** Keepalive interval handle */
|
|
131
|
+
private keepaliveInterval;
|
|
132
|
+
/** Keepalive timeout in seconds */
|
|
133
|
+
private readonly keepaliveTimeoutSeconds;
|
|
134
|
+
/** TastyTrade API base URL */
|
|
135
|
+
private readonly apiBaseUrl;
|
|
136
|
+
/** Whether to use sandbox environment */
|
|
137
|
+
private readonly sandbox;
|
|
138
|
+
/**
|
|
139
|
+
* Creates a new TastyTradeClient instance.
|
|
140
|
+
*
|
|
141
|
+
* @param options - Client configuration options
|
|
142
|
+
* @param options.sessionToken - TastyTrade session token (required)
|
|
143
|
+
* @param options.sandbox - Whether to use sandbox environment (default: false)
|
|
144
|
+
*/
|
|
145
|
+
constructor(options: {
|
|
146
|
+
sessionToken: string;
|
|
147
|
+
sandbox?: boolean;
|
|
148
|
+
});
|
|
149
|
+
/**
|
|
150
|
+
* Creates a TastyTradeClient by logging in with username/password.
|
|
151
|
+
*
|
|
152
|
+
* @param username - TastyTrade username
|
|
153
|
+
* @param password - TastyTrade password
|
|
154
|
+
* @param options - Additional options
|
|
155
|
+
* @returns Promise resolving to configured TastyTradeClient
|
|
156
|
+
*
|
|
157
|
+
* @example
|
|
158
|
+
* ```typescript
|
|
159
|
+
* const client = await TastyTradeClient.fromCredentials(
|
|
160
|
+
* 'your-username',
|
|
161
|
+
* 'your-password'
|
|
162
|
+
* );
|
|
163
|
+
* await client.connect();
|
|
164
|
+
* ```
|
|
165
|
+
*/
|
|
166
|
+
static fromCredentials(username: string, password: string, options?: {
|
|
167
|
+
sandbox?: boolean;
|
|
168
|
+
rememberMe?: boolean;
|
|
169
|
+
}): Promise<TastyTradeClient>;
|
|
170
|
+
/**
|
|
171
|
+
* Establishes a streaming connection to TastyTrade via DxLink.
|
|
172
|
+
*
|
|
173
|
+
* @returns Promise that resolves when connected and authorized
|
|
174
|
+
* @throws {Error} If token retrieval or WebSocket connection fails
|
|
175
|
+
*/
|
|
176
|
+
connect(): Promise<void>;
|
|
177
|
+
/**
|
|
178
|
+
* Disconnects from the TastyTrade streaming API.
|
|
179
|
+
*/
|
|
180
|
+
disconnect(): void;
|
|
181
|
+
/**
|
|
182
|
+
* Subscribes to real-time updates for the specified symbols.
|
|
183
|
+
*
|
|
184
|
+
* @param symbols - Array of ticker symbols and/or OCC option symbols
|
|
185
|
+
*
|
|
186
|
+
* @remarks
|
|
187
|
+
* For options, you can pass either:
|
|
188
|
+
* - OCC format symbols (e.g., 'SPY240119C00500000')
|
|
189
|
+
* - TastyTrade streamer symbols (e.g., '.SPXW240119C4500')
|
|
190
|
+
*
|
|
191
|
+
* The client will convert OCC symbols to streamer symbols automatically.
|
|
192
|
+
*/
|
|
193
|
+
subscribe(symbols: string[]): void;
|
|
194
|
+
/**
|
|
195
|
+
* Unsubscribes from real-time updates for the specified symbols.
|
|
196
|
+
*
|
|
197
|
+
* @param symbols - Array of symbols to unsubscribe from
|
|
198
|
+
*/
|
|
199
|
+
unsubscribe(symbols: string[]): void;
|
|
200
|
+
/**
|
|
201
|
+
* Returns whether the client is currently connected.
|
|
202
|
+
*/
|
|
203
|
+
isConnected(): boolean;
|
|
204
|
+
/**
|
|
205
|
+
* Fetches options chain data from TastyTrade REST API.
|
|
206
|
+
*
|
|
207
|
+
* @param symbol - Underlying symbol (e.g., 'SPY')
|
|
208
|
+
* @returns Array of option chain items
|
|
209
|
+
*/
|
|
210
|
+
fetchOptionsChain(symbol: string): Promise<TastyTradeOptionChainItem[]>;
|
|
211
|
+
/**
|
|
212
|
+
* Fetches open interest and other static data for subscribed options.
|
|
213
|
+
*
|
|
214
|
+
* @param occSymbols - Array of OCC option symbols to fetch data for
|
|
215
|
+
*/
|
|
216
|
+
fetchOpenInterest(occSymbols: string[]): Promise<void>;
|
|
217
|
+
/**
|
|
218
|
+
* Returns cached option data for a symbol.
|
|
219
|
+
*/
|
|
220
|
+
getOption(occSymbol: string): NormalizedOption | undefined;
|
|
221
|
+
/**
|
|
222
|
+
* Returns all cached options.
|
|
223
|
+
*/
|
|
224
|
+
getAllOptions(): Map<string, NormalizedOption>;
|
|
225
|
+
/**
|
|
226
|
+
* Registers an event listener.
|
|
227
|
+
*/
|
|
228
|
+
on<T>(event: TastyTradeClientEventType, listener: TastyTradeEventListener<T>): this;
|
|
229
|
+
/**
|
|
230
|
+
* Removes an event listener.
|
|
231
|
+
*/
|
|
232
|
+
off<T>(event: TastyTradeClientEventType, listener: TastyTradeEventListener<T>): this;
|
|
233
|
+
/**
|
|
234
|
+
* Returns intraday trades for an option.
|
|
235
|
+
*/
|
|
236
|
+
getIntradayTrades(occSymbol: string): IntradayTrade[];
|
|
237
|
+
/**
|
|
238
|
+
* Returns flow summary for an option.
|
|
239
|
+
*/
|
|
240
|
+
getFlowSummary(occSymbol: string): {
|
|
241
|
+
buyVolume: number;
|
|
242
|
+
sellVolume: number;
|
|
243
|
+
unknownVolume: number;
|
|
244
|
+
netOIChange: number;
|
|
245
|
+
tradeCount: number;
|
|
246
|
+
};
|
|
247
|
+
/**
|
|
248
|
+
* Resets intraday tracking data.
|
|
249
|
+
*/
|
|
250
|
+
resetIntradayData(occSymbols?: string[]): void;
|
|
251
|
+
/**
|
|
252
|
+
* Gets API quote token from TastyTrade.
|
|
253
|
+
*/
|
|
254
|
+
private getQuoteToken;
|
|
255
|
+
/**
|
|
256
|
+
* Connects to DxLink WebSocket.
|
|
257
|
+
*/
|
|
258
|
+
private connectWebSocket;
|
|
259
|
+
/**
|
|
260
|
+
* Sends SETUP message to DxLink.
|
|
261
|
+
*/
|
|
262
|
+
private sendSetup;
|
|
263
|
+
/**
|
|
264
|
+
* Sends AUTH message to DxLink.
|
|
265
|
+
*/
|
|
266
|
+
private sendAuth;
|
|
267
|
+
/**
|
|
268
|
+
* Opens a FEED channel.
|
|
269
|
+
*/
|
|
270
|
+
private openFeedChannel;
|
|
271
|
+
/**
|
|
272
|
+
* Configures the feed channel with desired event fields.
|
|
273
|
+
*/
|
|
274
|
+
private setupFeed;
|
|
275
|
+
/**
|
|
276
|
+
* Sends feed subscription message.
|
|
277
|
+
*/
|
|
278
|
+
private sendFeedSubscription;
|
|
279
|
+
/**
|
|
280
|
+
* Gets streamer symbol from OCC or ticker symbol.
|
|
281
|
+
*/
|
|
282
|
+
private getStreamerSymbol;
|
|
283
|
+
/**
|
|
284
|
+
* Converts streamer symbol back to OCC format.
|
|
285
|
+
*/
|
|
286
|
+
private streamerSymbolToOCC;
|
|
287
|
+
/**
|
|
288
|
+
* Starts keepalive interval.
|
|
289
|
+
*/
|
|
290
|
+
private startKeepalive;
|
|
291
|
+
/**
|
|
292
|
+
* Handles incoming WebSocket messages.
|
|
293
|
+
*/
|
|
294
|
+
private handleMessage;
|
|
295
|
+
/**
|
|
296
|
+
* Handles AUTH_STATE message.
|
|
297
|
+
*/
|
|
298
|
+
private handleAuthState;
|
|
299
|
+
/**
|
|
300
|
+
* Handles CHANNEL_OPENED message.
|
|
301
|
+
*/
|
|
302
|
+
private handleChannelOpened;
|
|
303
|
+
/**
|
|
304
|
+
* Handles FEED_DATA message.
|
|
305
|
+
*/
|
|
306
|
+
private handleFeedData;
|
|
307
|
+
/**
|
|
308
|
+
* Processes a single event from FEED_DATA.
|
|
309
|
+
*/
|
|
310
|
+
private processEventData;
|
|
311
|
+
/**
|
|
312
|
+
* Handles Quote events.
|
|
313
|
+
*/
|
|
314
|
+
private handleQuoteEvent;
|
|
315
|
+
/**
|
|
316
|
+
* Handles Trade events.
|
|
317
|
+
*/
|
|
318
|
+
private handleTradeEvent;
|
|
319
|
+
/**
|
|
320
|
+
* Handles Greeks events.
|
|
321
|
+
*/
|
|
322
|
+
private handleGreeksEvent;
|
|
323
|
+
/**
|
|
324
|
+
* Handles Summary events (includes open interest).
|
|
325
|
+
*/
|
|
326
|
+
private handleSummaryEvent;
|
|
327
|
+
/**
|
|
328
|
+
* Updates ticker from Quote event.
|
|
329
|
+
*/
|
|
330
|
+
private updateTickerFromQuote;
|
|
331
|
+
/**
|
|
332
|
+
* Updates ticker from Trade event.
|
|
333
|
+
*/
|
|
334
|
+
private updateTickerFromTrade;
|
|
335
|
+
/**
|
|
336
|
+
* Updates option from Quote event.
|
|
337
|
+
*/
|
|
338
|
+
private updateOptionFromQuote;
|
|
339
|
+
/**
|
|
340
|
+
* Updates option from Trade event.
|
|
341
|
+
*/
|
|
342
|
+
private updateOptionFromTrade;
|
|
343
|
+
/**
|
|
344
|
+
* Determines aggressor side from trade price vs NBBO.
|
|
345
|
+
*/
|
|
346
|
+
private determineAggressorSide;
|
|
347
|
+
/**
|
|
348
|
+
* Calculates estimated OI change from trade.
|
|
349
|
+
*/
|
|
350
|
+
private calculateOIChangeFromTrade;
|
|
351
|
+
/**
|
|
352
|
+
* Calculates live open interest.
|
|
353
|
+
*/
|
|
354
|
+
private calculateLiveOpenInterest;
|
|
355
|
+
/**
|
|
356
|
+
* Handles DxLink error messages.
|
|
357
|
+
*/
|
|
358
|
+
private handleError;
|
|
359
|
+
/**
|
|
360
|
+
* Attempts to reconnect with exponential backoff.
|
|
361
|
+
*/
|
|
362
|
+
private attemptReconnect;
|
|
363
|
+
/**
|
|
364
|
+
* Checks if symbol is an OCC option symbol.
|
|
365
|
+
*/
|
|
366
|
+
private isOptionSymbol;
|
|
367
|
+
/**
|
|
368
|
+
* Sends a message to the WebSocket.
|
|
369
|
+
*/
|
|
370
|
+
private sendMessage;
|
|
371
|
+
/**
|
|
372
|
+
* Emits an event to all listeners.
|
|
373
|
+
*/
|
|
374
|
+
private emit;
|
|
375
|
+
/**
|
|
376
|
+
* Converts value to number, handling NaN and null.
|
|
377
|
+
*/
|
|
378
|
+
private toNumber;
|
|
379
|
+
/**
|
|
380
|
+
* Sleep utility.
|
|
381
|
+
*/
|
|
382
|
+
private sleep;
|
|
383
|
+
}
|
|
384
|
+
export {};
|