@fullstackcraftllc/floe 0.0.6 → 0.0.7

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.
@@ -221,6 +221,21 @@ export declare class FloeClient {
221
221
  * ```
222
222
  */
223
223
  unsubscribeFromOptions(symbols: Array<string>): void;
224
+ /**
225
+ * Unsubscribes from all currently subscribed tickers and options.
226
+ *
227
+ * @throws {Error} Throws if no broker connection has been established
228
+ *
229
+ * @remarks
230
+ * After calling this method, no further updates will be received for any
231
+ * previously subscribed tickers or options.
232
+ *
233
+ * @example
234
+ * ```typescript
235
+ * client.unsubscribeFromAll();
236
+ * ```
237
+ */
238
+ unsubscribeFromAll(): void;
224
239
  /**
225
240
  * Fetches open interest and initial option data via REST API.
226
241
  *
@@ -394,6 +394,40 @@ class FloeClient {
394
394
  throw new Error(`Unsupported broker: ${this.currentBroker}`);
395
395
  }
396
396
  }
397
+ /**
398
+ * Unsubscribes from all currently subscribed tickers and options.
399
+ *
400
+ * @throws {Error} Throws if no broker connection has been established
401
+ *
402
+ * @remarks
403
+ * After calling this method, no further updates will be received for any
404
+ * previously subscribed tickers or options.
405
+ *
406
+ * @example
407
+ * ```typescript
408
+ * client.unsubscribeFromAll();
409
+ * ```
410
+ */
411
+ unsubscribeFromAll() {
412
+ this.currentSubscribedTickers = [];
413
+ this.currentSubscribedOptions = [];
414
+ switch (this.currentBroker) {
415
+ case Broker.TRADIER:
416
+ this.tradierClient?.unsubscribeFromAll();
417
+ break;
418
+ case Broker.TASTYTRADE:
419
+ this.tastyTradeClient?.unsubscribeFromAll();
420
+ break;
421
+ case Broker.TRADESTATION:
422
+ this.tradeStationClient?.unsubscribeFromAll();
423
+ break;
424
+ case Broker.SCHWAB:
425
+ this.schwabClient?.unsubscribeFromAll();
426
+ break;
427
+ default:
428
+ throw new Error(`Unsupported broker: ${this.currentBroker}`);
429
+ }
430
+ }
397
431
  /**
398
432
  * Fetches open interest and initial option data via REST API.
399
433
  *
@@ -251,6 +251,10 @@ export declare class SchwabClient {
251
251
  * @param symbols - Array of symbols to unsubscribe from
252
252
  */
253
253
  unsubscribe(symbols: string[]): void;
254
+ /**
255
+ * Unsubscribes from all real-time updates.
256
+ */
257
+ unsubscribeFromAll(): void;
254
258
  /**
255
259
  * Returns whether the client is currently connected.
256
260
  */
@@ -276,6 +276,31 @@ class SchwabClient {
276
276
  this.unsubscribeOptionsBook(options);
277
277
  }
278
278
  }
279
+ /**
280
+ * Unsubscribes from all real-time updates.
281
+ */
282
+ unsubscribeFromAll() {
283
+ const allSymbols = Array.from(this.subscribedSymbols);
284
+ const allOptionSymbols = allSymbols.filter(s => this.isOptionSymbol(s)).map(s => this.toSchwabOptionSymbol(s));
285
+ this.subscribedSymbols.clear();
286
+ // unsub from all equities
287
+ if (allSymbols.length > 0) {
288
+ const request = this.makeRequest('LEVELONE_EQUITIES', 'UNSUBS', {
289
+ keys: allSymbols.join(','),
290
+ });
291
+ this.sendMessage({ requests: [request] });
292
+ }
293
+ // unsub from all options (quotes and book)
294
+ if (allOptionSymbols.length > 0) {
295
+ const requestOptions = this.makeRequest('LEVELONE_OPTIONS', 'UNSUBS', {
296
+ keys: allOptionSymbols.join(','),
297
+ });
298
+ const requestBook = this.makeRequest('OPTIONS_BOOK', 'UNSUBS', {
299
+ keys: allOptionSymbols.join(','),
300
+ });
301
+ this.sendMessage({ requests: [requestOptions, requestBook] });
302
+ }
303
+ }
279
304
  /**
280
305
  * Returns whether the client is currently connected.
281
306
  */
@@ -201,6 +201,10 @@ export declare class TastyTradeClient {
201
201
  * @param symbols - Array of symbols to unsubscribe from
202
202
  */
203
203
  unsubscribe(symbols: string[]): void;
204
+ /**
205
+ * Unsubscribes from all real-time updates.
206
+ */
207
+ unsubscribeFromAll(): void;
204
208
  /**
205
209
  * Returns whether the client is currently connected.
206
210
  */
@@ -226,6 +226,17 @@ class TastyTradeClient {
226
226
  }
227
227
  this.sendFeedSubscription(symbols, 'remove');
228
228
  }
229
+ /**
230
+ * Unsubscribes from all real-time updates.
231
+ */
232
+ unsubscribeFromAll() {
233
+ const symbols = Array.from(this.subscribedSymbols);
234
+ this.subscribedSymbols.clear();
235
+ if (!this.connected || !this.feedChannelOpened) {
236
+ return;
237
+ }
238
+ this.sendFeedSubscription(symbols, 'remove');
239
+ }
229
240
  /**
230
241
  * Returns whether the client is currently connected.
231
242
  */
@@ -177,6 +177,10 @@ export declare class TradeStationClient {
177
177
  * restarting with the remaining symbols.
178
178
  */
179
179
  unsubscribe(symbols: string[]): void;
180
+ /**
181
+ * Unsubscribes from all real-time updates.
182
+ */
183
+ unsubscribeFromAll(): void;
180
184
  /**
181
185
  * Returns whether the client is currently connected.
182
186
  */
@@ -217,6 +217,15 @@ class TradeStationClient {
217
217
  this.stopStream('options');
218
218
  }
219
219
  }
220
+ /**
221
+ * Unsubscribes from all real-time updates.
222
+ */
223
+ unsubscribeFromAll() {
224
+ this.subscribedTickers.clear();
225
+ this.subscribedOptions.clear();
226
+ this.stopStream('quotes');
227
+ this.stopStream('options');
228
+ }
220
229
  /**
221
230
  * Returns whether the client is currently connected.
222
231
  */
@@ -182,11 +182,18 @@ export declare class TradierClient {
182
182
  * @param symbols - Array of symbols to unsubscribe from
183
183
  *
184
184
  * @remarks
185
- * Note: Tradier's streaming API doesn't support unsubscription for individual
186
- * symbols. This method removes them from local tracking. To fully unsubscribe,
187
- * you would need to disconnect and reconnect with the new symbol list.
185
+ * Since Tradier's streaming API doesn't support selective unsubscription,
186
+ * this method disconnects and reconnects with the updated symbol list.
188
187
  */
189
- unsubscribe(symbols: string[]): void;
188
+ unsubscribe(symbols: string[]): Promise<void>;
189
+ /**
190
+ * Unsubscribes from all symbols.
191
+ *
192
+ * @remarks
193
+ * Since Tradier's streaming API doesn't support selective unsubscription,
194
+ * this method disconnects and reconnects without any symbols.
195
+ */
196
+ unsubscribeFromAll(): Promise<void>;
190
197
  /**
191
198
  * Returns whether the client is currently connected.
192
199
  */
@@ -251,6 +258,11 @@ export declare class TradierClient {
251
258
  * Attempts to reconnect with exponential backoff.
252
259
  */
253
260
  private attemptReconnect;
261
+ /**
262
+ * Reconnects with the current symbol list.
263
+ * Used for unsubscribe operations since Tradier doesn't support selective unsubscription.
264
+ */
265
+ private reconnectWithSymbols;
254
266
  /**
255
267
  * Handles incoming WebSocket messages.
256
268
  */
@@ -142,14 +142,29 @@ class TradierClient {
142
142
  * @param symbols - Array of symbols to unsubscribe from
143
143
  *
144
144
  * @remarks
145
- * Note: Tradier's streaming API doesn't support unsubscription for individual
146
- * symbols. This method removes them from local tracking. To fully unsubscribe,
147
- * you would need to disconnect and reconnect with the new symbol list.
145
+ * Since Tradier's streaming API doesn't support selective unsubscription,
146
+ * this method disconnects and reconnects with the updated symbol list.
148
147
  */
149
- unsubscribe(symbols) {
148
+ async unsubscribe(symbols) {
150
149
  symbols.forEach(s => this.subscribedSymbols.delete(s));
151
- // Note: Tradier doesn't support selective unsubscribe
152
- // Would need to reconnect with new symbol list for full effect
150
+ // If connected, reconnect with the new symbol list
151
+ if (this.connected) {
152
+ await this.reconnectWithSymbols();
153
+ }
154
+ }
155
+ /**
156
+ * Unsubscribes from all symbols.
157
+ *
158
+ * @remarks
159
+ * Since Tradier's streaming API doesn't support selective unsubscription,
160
+ * this method disconnects and reconnects without any symbols.
161
+ */
162
+ async unsubscribeFromAll() {
163
+ this.subscribedSymbols.clear();
164
+ // If connected, reconnect with empty symbol list
165
+ if (this.connected) {
166
+ await this.reconnectWithSymbols();
167
+ }
153
168
  }
154
169
  /**
155
170
  * Returns whether the client is currently connected.
@@ -431,6 +446,21 @@ class TradierClient {
431
446
  // Reconnect attempt failed, will try again via onclose
432
447
  }
433
448
  }
449
+ /**
450
+ * Reconnects with the current symbol list.
451
+ * Used for unsubscribe operations since Tradier doesn't support selective unsubscription.
452
+ */
453
+ async reconnectWithSymbols() {
454
+ if (this.verbose) {
455
+ console.log(`[Tradier:WS] Reconnecting with ${this.subscribedSymbols.size} symbols`);
456
+ }
457
+ // Disconnect cleanly
458
+ this.disconnect();
459
+ // Wait briefly to ensure clean disconnect
460
+ await this.sleep(100);
461
+ // Reconnect with current symbol list
462
+ await this.connect();
463
+ }
434
464
  /**
435
465
  * Handles incoming WebSocket messages.
436
466
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fullstackcraftllc/floe",
3
- "version": "0.0.6",
3
+ "version": "0.0.7",
4
4
  "description": "Production-ready options analytics toolkit. Normalize broker data structures and calculate Black-Scholes, Greeks, and exposures with a clean, type-safe API. Built for trading platforms and fintech applications.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",