@imbingox/acex 0.1.0-beta.2 → 0.1.0-beta.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.
@@ -1,12 +1,20 @@
1
+ import BigNumber from "bignumber.js";
2
+ import type { RawOrderUpdate } from "../adapters/types.ts";
1
3
  import type {
2
4
  AccountAwareManager,
3
5
  ClientContext,
4
6
  HealthReporter,
5
7
  ManagerLifecycle,
8
+ PrivateOrderDataConsumer,
9
+ PrivateSubscriptionState,
6
10
  } from "../client/context.ts";
11
+ import { AcexError } from "../errors.ts";
7
12
  import { AsyncEventBus } from "../internal/async-event-bus.ts";
8
13
  import { matchesOrderFilter } from "../internal/filters.ts";
9
14
  import type {
15
+ CancelAllOrdersInput,
16
+ CancelOrderInput,
17
+ CreateOrderInput,
10
18
  Exchange,
11
19
  GetOrderInput,
12
20
  OrderDataStatus,
@@ -32,12 +40,28 @@ function cloneOrderStatus(status: OrderDataStatus): OrderDataStatus {
32
40
  return { ...status };
33
41
  }
34
42
 
43
+ function getOrderLookupKey(input: {
44
+ orderId?: string;
45
+ clientOrderId?: string;
46
+ }): string | undefined {
47
+ if (input.orderId) {
48
+ return `order:${input.orderId}`;
49
+ }
50
+
51
+ if (input.clientOrderId) {
52
+ return `client:${input.clientOrderId}`;
53
+ }
54
+
55
+ return undefined;
56
+ }
57
+
35
58
  export class OrderManagerImpl
36
59
  implements
37
60
  OrderManager,
38
61
  ManagerLifecycle,
39
62
  AccountAwareManager,
40
- HealthReporter<OrderDataStatus>
63
+ HealthReporter<OrderDataStatus>,
64
+ PrivateOrderDataConsumer
41
65
  {
42
66
  readonly events: OrderEventStreams;
43
67
 
@@ -81,24 +105,13 @@ export class OrderManagerImpl
81
105
 
82
106
  const record = this.getOrCreateRecord(input.accountId, account.exchange);
83
107
  record.subscribed = true;
84
- record.status = {
85
- ...this.createStatus(input.accountId, account.exchange, "active"),
86
- ready: true,
87
- runtimeStatus: "healthy",
88
- lastReceivedAt: this.context.now(),
89
- lastReadyAt: this.context.now(),
90
- };
91
108
 
92
- const event: OrderSnapshotReplacedEvent = {
93
- type: "order.snapshot_replaced",
94
- accountId: record.accountId,
95
- exchange: record.exchange,
96
- snapshot: [...record.snapshots.values()],
97
- ts: this.context.now(),
98
- };
99
-
100
- this.orderBus.publish(event);
101
- this.publishStatus(record);
109
+ try {
110
+ await this.context.subscribePrivateOrderFeed(input.accountId);
111
+ } catch (error) {
112
+ record.subscribed = false;
113
+ throw error;
114
+ }
102
115
  }
103
116
 
104
117
  async unsubscribeOrders(input: UnsubscribeOrdersInput): Promise<void> {
@@ -107,16 +120,90 @@ export class OrderManagerImpl
107
120
  return;
108
121
  }
109
122
 
123
+ this.context.unsubscribePrivateOrderFeed(input.accountId);
110
124
  record.subscribed = false;
111
125
  record.status = {
112
126
  ...record.status,
113
127
  activity: "inactive",
114
128
  runtimeStatus: "stopped",
129
+ reason: undefined,
115
130
  inactiveSince: this.context.now(),
116
131
  };
117
132
  this.publishStatus(record);
118
133
  }
119
134
 
135
+ async createOrder(input: CreateOrderInput): Promise<OrderSnapshot> {
136
+ this.context.assertStarted();
137
+ const account = this.context.getRegisteredAccount(input.accountId);
138
+ this.context.ensurePrivateCredentials(input.accountId);
139
+ this.validateCreateOrderInput(input, account.exchange);
140
+
141
+ try {
142
+ const update = await this.context.createOrder(input);
143
+ return this.applyCommandUpdate(input.accountId, account.exchange, update);
144
+ } catch (error) {
145
+ throw this.wrapCommandError(
146
+ "ORDER_CREATE_FAILED",
147
+ `Failed to create order for ${input.accountId}: ${input.symbol}`,
148
+ error,
149
+ {
150
+ accountId: input.accountId,
151
+ exchange: account.exchange,
152
+ symbol: input.symbol,
153
+ },
154
+ );
155
+ }
156
+ }
157
+
158
+ async cancelOrder(input: CancelOrderInput): Promise<OrderSnapshot> {
159
+ this.context.assertStarted();
160
+ const account = this.context.getRegisteredAccount(input.accountId);
161
+ this.context.ensurePrivateCredentials(input.accountId);
162
+ this.validateCancelOrderInput(input, account.exchange);
163
+
164
+ try {
165
+ const update = await this.context.cancelOrder(input);
166
+ return this.applyCommandUpdate(input.accountId, account.exchange, update);
167
+ } catch (error) {
168
+ throw this.wrapCommandError(
169
+ "ORDER_CANCEL_FAILED",
170
+ `Failed to cancel order for ${input.accountId}: ${input.symbol}`,
171
+ error,
172
+ {
173
+ accountId: input.accountId,
174
+ exchange: account.exchange,
175
+ symbol: input.symbol,
176
+ },
177
+ );
178
+ }
179
+ }
180
+
181
+ async cancelAllOrders(input: CancelAllOrdersInput): Promise<OrderSnapshot[]> {
182
+ this.context.assertStarted();
183
+ const account = this.context.getRegisteredAccount(input.accountId);
184
+ this.context.ensurePrivateCredentials(input.accountId);
185
+
186
+ try {
187
+ const updates = await this.context.cancelAllOrders(input);
188
+ return this.applyCommandUpdates(
189
+ input.accountId,
190
+ account.exchange,
191
+ updates,
192
+ );
193
+ } catch (error) {
194
+ throw this.wrapCommandError(
195
+ "ORDER_CANCEL_ALL_FAILED",
196
+ `Failed to cancel all orders for ${input.accountId}: ${input.symbol}`,
197
+ error,
198
+ {
199
+ accountId: input.accountId,
200
+ exchange: account.exchange,
201
+ symbol: input.symbol,
202
+ },
203
+ );
204
+ }
205
+ }
206
+
120
207
  getOrder(input: GetOrderInput): OrderSnapshot | undefined {
121
208
  const record = this.records.get(input.accountId);
122
209
  if (!record) {
@@ -167,30 +254,7 @@ export class OrderManagerImpl
167
254
 
168
255
  // --- ManagerLifecycle ---
169
256
 
170
- onClientStarted(): void {
171
- const now = this.context.now();
172
-
173
- for (const [accountId, record] of this.records) {
174
- if (!record.subscribed) {
175
- continue;
176
- }
177
-
178
- const account = this.context.getRegisteredAccount(accountId);
179
- const creds = account.credentials;
180
- if (!creds?.apiKey || !creds.secret) {
181
- continue;
182
- }
183
-
184
- record.status = {
185
- ...this.createStatus(accountId, account.exchange, "active"),
186
- ready: true,
187
- runtimeStatus: "healthy",
188
- lastReceivedAt: now,
189
- lastReadyAt: now,
190
- };
191
- this.publishStatus(record);
192
- }
193
- }
257
+ onClientStarted(): void {}
194
258
 
195
259
  onClientStopping(now: number): void {
196
260
  for (const record of this.records.values()) {
@@ -202,6 +266,7 @@ export class OrderManagerImpl
202
266
  ...record.status,
203
267
  activity: "inactive",
204
268
  runtimeStatus: "stopped",
269
+ reason: undefined,
205
270
  inactiveSince: now,
206
271
  };
207
272
  this.publishStatus(record);
@@ -221,6 +286,7 @@ export class OrderManagerImpl
221
286
  ...record.status,
222
287
  activity: "inactive",
223
288
  runtimeStatus: "stopped",
289
+ reason: undefined,
224
290
  inactiveSince: now,
225
291
  };
226
292
  this.publishStatus(record);
@@ -233,10 +299,144 @@ export class OrderManagerImpl
233
299
  return;
234
300
  }
235
301
 
236
- record.status = this.createStatus(accountId, exchange, "active");
237
- record.status.ready = true;
238
- record.status.runtimeStatus = "healthy";
239
- record.status.lastReadyAt = this.context.now();
302
+ this.onPrivateOrderPending(accountId, exchange);
303
+ }
304
+
305
+ // --- PrivateOrderDataConsumer ---
306
+
307
+ onPrivateOrderPending(accountId: string, exchange: Exchange): void {
308
+ const record = this.getOrCreateRecord(accountId, exchange);
309
+ if (!record.subscribed) {
310
+ return;
311
+ }
312
+
313
+ record.status = {
314
+ ...this.createStatus(accountId, exchange, "active"),
315
+ ready: record.snapshots.size > 0,
316
+ runtimeStatus: "bootstrap_pending",
317
+ reason: undefined,
318
+ lastReceivedAt: record.status.lastReceivedAt,
319
+ lastReadyAt: record.status.lastReadyAt,
320
+ inactiveSince: undefined,
321
+ };
322
+ this.publishStatus(record);
323
+ }
324
+
325
+ onPrivateOrderBootstrap(
326
+ accountId: string,
327
+ exchange: Exchange,
328
+ snapshots: RawOrderUpdate[],
329
+ ): void {
330
+ const record = this.getOrCreateRecord(accountId, exchange);
331
+ if (!record.subscribed) {
332
+ return;
333
+ }
334
+
335
+ const nextSnapshots = new Map<string, OrderSnapshot>();
336
+ for (const update of snapshots) {
337
+ const snapshot = this.createSnapshot(
338
+ accountId,
339
+ exchange,
340
+ update,
341
+ this.getExistingSnapshot(record, update),
342
+ );
343
+ this.setSnapshot(nextSnapshots, snapshot);
344
+ }
345
+
346
+ record.snapshots = nextSnapshots;
347
+ const orderedSnapshots = [...record.snapshots.values()];
348
+ const latestTs = orderedSnapshots.reduce(
349
+ (max, snapshot) => Math.max(max, snapshot.updatedAt),
350
+ 0,
351
+ );
352
+ record.status = {
353
+ ...record.status,
354
+ activity: "active",
355
+ ready: true,
356
+ runtimeStatus: "healthy",
357
+ reason: undefined,
358
+ lastReceivedAt: latestTs || record.status.lastReceivedAt,
359
+ lastReadyAt: latestTs || this.context.now(),
360
+ inactiveSince: undefined,
361
+ };
362
+
363
+ const event: OrderSnapshotReplacedEvent = {
364
+ type: "order.snapshot_replaced",
365
+ accountId,
366
+ exchange,
367
+ snapshot: orderedSnapshots,
368
+ ts: this.context.now(),
369
+ };
370
+
371
+ this.orderBus.publish(event);
372
+ this.publishStatus(record);
373
+ }
374
+
375
+ onPrivateOrderUpdate(
376
+ accountId: string,
377
+ exchange: Exchange,
378
+ update: RawOrderUpdate,
379
+ ): void {
380
+ const record = this.getOrCreateRecord(accountId, exchange);
381
+ if (!record.subscribed) {
382
+ return;
383
+ }
384
+
385
+ const previous = this.getExistingSnapshot(record, update);
386
+ const snapshot = this.createSnapshot(accountId, exchange, update, previous);
387
+ this.setSnapshot(record.snapshots, snapshot);
388
+
389
+ const eventType =
390
+ snapshot.status === "filled"
391
+ ? "order.filled"
392
+ : snapshot.status === "rejected"
393
+ ? "order.rejected"
394
+ : snapshot.status === "canceled" || snapshot.status === "expired"
395
+ ? "order.canceled"
396
+ : "order.updated";
397
+
398
+ this.orderBus.publish({
399
+ type: eventType,
400
+ accountId,
401
+ exchange,
402
+ symbol: snapshot.symbol,
403
+ snapshot,
404
+ ts: this.context.now(),
405
+ });
406
+
407
+ record.status = {
408
+ ...record.status,
409
+ activity: "active",
410
+ ready: true,
411
+ runtimeStatus: "healthy",
412
+ reason: undefined,
413
+ lastReceivedAt: snapshot.receivedAt,
414
+ lastReadyAt: snapshot.updatedAt,
415
+ inactiveSince: undefined,
416
+ };
417
+ this.publishStatus(record);
418
+ }
419
+
420
+ onPrivateOrderStreamState(
421
+ accountId: string,
422
+ exchange: Exchange,
423
+ state: PrivateSubscriptionState,
424
+ ): void {
425
+ const record = this.getOrCreateRecord(accountId, exchange);
426
+ if (!record.subscribed) {
427
+ return;
428
+ }
429
+
430
+ record.status = {
431
+ ...record.status,
432
+ activity: "active",
433
+ ready: state.ready,
434
+ runtimeStatus: state.runtimeStatus,
435
+ reason: state.reason,
436
+ lastReceivedAt: state.lastReceivedAt ?? record.status.lastReceivedAt,
437
+ lastReadyAt: state.lastReadyAt ?? record.status.lastReadyAt,
438
+ inactiveSince: undefined,
439
+ };
240
440
  this.publishStatus(record);
241
441
  }
242
442
 
@@ -289,6 +489,86 @@ export class OrderManagerImpl
289
489
  };
290
490
  }
291
491
 
492
+ private getExistingSnapshot(
493
+ record: OrderRecord,
494
+ update: { orderId?: string; clientOrderId?: string },
495
+ ): OrderSnapshot | undefined {
496
+ for (const snapshot of record.snapshots.values()) {
497
+ if (update.orderId && snapshot.orderId === update.orderId) {
498
+ return snapshot;
499
+ }
500
+
501
+ if (
502
+ update.clientOrderId &&
503
+ snapshot.clientOrderId === update.clientOrderId
504
+ ) {
505
+ return snapshot;
506
+ }
507
+ }
508
+
509
+ return undefined;
510
+ }
511
+
512
+ private setSnapshot(
513
+ snapshots: Map<string, OrderSnapshot>,
514
+ snapshot: OrderSnapshot,
515
+ ): void {
516
+ const lookupKey =
517
+ getOrderLookupKey(snapshot) ??
518
+ getOrderLookupKey({
519
+ clientOrderId: snapshot.clientOrderId,
520
+ });
521
+ if (lookupKey) {
522
+ snapshots.set(lookupKey, snapshot);
523
+ }
524
+ }
525
+
526
+ private createSnapshot(
527
+ accountId: string,
528
+ exchange: Exchange,
529
+ input: RawOrderUpdate,
530
+ previous?: OrderSnapshot,
531
+ ): OrderSnapshot {
532
+ const amount = new BigNumber(input.amount);
533
+ const filled = new BigNumber(input.filled);
534
+ const remaining =
535
+ input.remaining === undefined
536
+ ? amount.minus(filled)
537
+ : new BigNumber(input.remaining);
538
+
539
+ return {
540
+ accountId,
541
+ exchange,
542
+ orderId: input.orderId,
543
+ clientOrderId: input.clientOrderId,
544
+ symbol: input.symbol,
545
+ side: input.side,
546
+ type: input.type,
547
+ status: input.status,
548
+ price:
549
+ input.price === undefined
550
+ ? previous?.price
551
+ : new BigNumber(input.price),
552
+ triggerPrice:
553
+ input.triggerPrice === undefined
554
+ ? previous?.triggerPrice
555
+ : new BigNumber(input.triggerPrice),
556
+ amount,
557
+ filled,
558
+ remaining,
559
+ reduceOnly: input.reduceOnly ?? previous?.reduceOnly,
560
+ positionSide: input.positionSide ?? previous?.positionSide,
561
+ avgFillPrice:
562
+ input.avgFillPrice === undefined
563
+ ? previous?.avgFillPrice
564
+ : new BigNumber(input.avgFillPrice),
565
+ exchangeTs: input.exchangeTs,
566
+ receivedAt: input.receivedAt,
567
+ updatedAt: input.receivedAt,
568
+ seq: (previous?.seq ?? 0) + 1,
569
+ };
570
+ }
571
+
292
572
  private publishStatus(record: OrderRecord): void {
293
573
  const event: OrderStatusChangedEvent = {
294
574
  type: "order.status_changed",
@@ -301,4 +581,105 @@ export class OrderManagerImpl
301
581
  this.orderStatusBus.publish(event);
302
582
  this.context.publishHealthEvent(event);
303
583
  }
584
+
585
+ private validateCreateOrderInput(
586
+ input: CreateOrderInput,
587
+ exchange: Exchange,
588
+ ): void {
589
+ if (input.type === "limit" && !input.price) {
590
+ throw this.createError(
591
+ "ORDER_INPUT_INVALID",
592
+ `Limit orders require price: ${input.accountId}`,
593
+ {
594
+ accountId: input.accountId,
595
+ exchange,
596
+ symbol: input.symbol,
597
+ },
598
+ );
599
+ }
600
+ }
601
+
602
+ private validateCancelOrderInput(
603
+ input: CancelOrderInput,
604
+ exchange: Exchange,
605
+ ): void {
606
+ if (input.orderId || input.clientOrderId) {
607
+ return;
608
+ }
609
+
610
+ throw this.createError(
611
+ "ORDER_INPUT_INVALID",
612
+ `cancelOrder requires orderId or clientOrderId: ${input.accountId}`,
613
+ {
614
+ accountId: input.accountId,
615
+ exchange,
616
+ symbol: input.symbol,
617
+ },
618
+ );
619
+ }
620
+
621
+ private applyCommandUpdate(
622
+ accountId: string,
623
+ exchange: Exchange,
624
+ update: RawOrderUpdate,
625
+ ): OrderSnapshot {
626
+ const record = this.getOrCreateRecord(accountId, exchange);
627
+ const previous = this.getExistingSnapshot(record, update);
628
+ const snapshot = this.createSnapshot(accountId, exchange, update, previous);
629
+ this.setSnapshot(record.snapshots, snapshot);
630
+ return snapshot;
631
+ }
632
+
633
+ private applyCommandUpdates(
634
+ accountId: string,
635
+ exchange: Exchange,
636
+ updates: RawOrderUpdate[],
637
+ ): OrderSnapshot[] {
638
+ return updates.map((update) =>
639
+ this.applyCommandUpdate(accountId, exchange, update),
640
+ );
641
+ }
642
+
643
+ private createError(
644
+ code:
645
+ | "ORDER_CANCEL_ALL_FAILED"
646
+ | "ORDER_CANCEL_FAILED"
647
+ | "ORDER_CREATE_FAILED"
648
+ | "ORDER_INPUT_INVALID",
649
+ message: string,
650
+ metadata: {
651
+ accountId: string;
652
+ exchange: Exchange;
653
+ symbol?: string;
654
+ },
655
+ ): AcexError {
656
+ const error = new AcexError(code, message);
657
+ this.context.publishRuntimeError("order", error, metadata);
658
+ return error;
659
+ }
660
+
661
+ private wrapCommandError(
662
+ code:
663
+ | "ORDER_CANCEL_ALL_FAILED"
664
+ | "ORDER_CANCEL_FAILED"
665
+ | "ORDER_CREATE_FAILED",
666
+ message: string,
667
+ error: unknown,
668
+ metadata: {
669
+ accountId: string;
670
+ exchange: Exchange;
671
+ symbol: string;
672
+ },
673
+ ): AcexError {
674
+ if (error instanceof AcexError) {
675
+ return error;
676
+ }
677
+
678
+ this.context.publishRuntimeError(
679
+ "adapter",
680
+ error instanceof Error ? error : new Error(message),
681
+ metadata,
682
+ );
683
+ return new AcexError(code, message);
684
+ }
304
685
  }
@@ -1,6 +1,7 @@
1
1
  import type BigNumber from "bignumber.js";
2
2
  import type {
3
3
  Exchange,
4
+ PrivateRuntimeReason,
4
5
  PrivateRuntimeStatus,
5
6
  SubscriptionActivity,
6
7
  } from "./shared.ts";
@@ -14,12 +15,7 @@ export interface AccountDataStatus {
14
15
  lastReceivedAt?: number;
15
16
  lastReadyAt?: number;
16
17
  inactiveSince?: number;
17
- reason?:
18
- | "credentials_missing"
19
- | "auth_failed"
20
- | "ws_disconnected"
21
- | "heartbeat_timeout"
22
- | "reconciling";
18
+ reason?: PrivateRuntimeReason;
23
19
  }
24
20
 
25
21
  export interface AccountStatusChangedEvent {
@@ -42,6 +42,16 @@ export interface MarketDataStatus {
42
42
  reason?: "ws_disconnected" | "heartbeat_timeout" | "reconciling";
43
43
  }
44
44
 
45
+ export interface MarketDataStreamStatus {
46
+ activity: SubscriptionActivity;
47
+ ready: boolean;
48
+ freshness?: MarketFreshness;
49
+ lastReceivedAt?: number;
50
+ lastReadyAt?: number;
51
+ inactiveSince?: number;
52
+ reason?: MarketDataStatus["reason"];
53
+ }
54
+
45
55
  export interface MarketKeyInput {
46
56
  exchange: Exchange;
47
57
  symbol: string;
@@ -67,6 +77,7 @@ export interface L1Book {
67
77
  receivedAt: number;
68
78
  updatedAt: number;
69
79
  version: number;
80
+ status: MarketDataStreamStatus;
70
81
  }
71
82
 
72
83
  export interface FundingRateSnapshot {
@@ -80,6 +91,7 @@ export interface FundingRateSnapshot {
80
91
  receivedAt: number;
81
92
  updatedAt: number;
82
93
  version: number;
94
+ status: MarketDataStreamStatus;
83
95
  }
84
96
 
85
97
  export interface MarketStatusChangedEvent {
@@ -2,6 +2,7 @@ import type BigNumber from "bignumber.js";
2
2
  import type { PositionSide } from "./account.ts";
3
3
  import type {
4
4
  Exchange,
5
+ PrivateRuntimeReason,
5
6
  PrivateRuntimeStatus,
6
7
  SubscriptionActivity,
7
8
  } from "./shared.ts";
@@ -15,12 +16,7 @@ export interface OrderDataStatus {
15
16
  lastReceivedAt?: number;
16
17
  lastReadyAt?: number;
17
18
  inactiveSince?: number;
18
- reason?:
19
- | "credentials_missing"
20
- | "auth_failed"
21
- | "ws_disconnected"
22
- | "heartbeat_timeout"
23
- | "reconciling";
19
+ reason?: PrivateRuntimeReason;
24
20
  }
25
21
 
26
22
  export interface OrderStatusChangedEvent {
@@ -41,6 +37,8 @@ export type OrderStatus =
41
37
  | "rejected"
42
38
  | "expired";
43
39
 
40
+ export type CreateOrderType = "limit" | "market";
41
+
44
42
  export interface SubscribeOrdersInput {
45
43
  accountId: string;
46
44
  }
@@ -55,6 +53,39 @@ export interface GetOrderInput {
55
53
  clientOrderId?: string;
56
54
  }
57
55
 
56
+ interface CreateOrderInputBase {
57
+ accountId: string;
58
+ symbol: string;
59
+ side: OrderSide;
60
+ amount: string;
61
+ clientOrderId?: string;
62
+ reduceOnly?: boolean;
63
+ positionSide?: PositionSide;
64
+ }
65
+
66
+ export interface CreateLimitOrderInput extends CreateOrderInputBase {
67
+ type: "limit";
68
+ price: string;
69
+ }
70
+
71
+ export interface CreateMarketOrderInput extends CreateOrderInputBase {
72
+ type: "market";
73
+ }
74
+
75
+ export type CreateOrderInput = CreateLimitOrderInput | CreateMarketOrderInput;
76
+
77
+ export interface CancelOrderInput {
78
+ accountId: string;
79
+ symbol: string;
80
+ orderId?: string;
81
+ clientOrderId?: string;
82
+ }
83
+
84
+ export interface CancelAllOrdersInput {
85
+ accountId: string;
86
+ symbol: string;
87
+ }
88
+
58
89
  export interface OrderEventFilter {
59
90
  accountId?: string;
60
91
  exchange?: Exchange;
@@ -136,6 +167,9 @@ export interface OrderManager {
136
167
 
137
168
  subscribeOrders(input: SubscribeOrdersInput): Promise<void>;
138
169
  unsubscribeOrders(input: UnsubscribeOrdersInput): Promise<void>;
170
+ createOrder(input: CreateOrderInput): Promise<OrderSnapshot>;
171
+ cancelOrder(input: CancelOrderInput): Promise<OrderSnapshot>;
172
+ cancelAllOrders(input: CancelAllOrdersInput): Promise<OrderSnapshot[]>;
139
173
 
140
174
  getOrder(input: GetOrderInput): OrderSnapshot | undefined;
141
175
  getOpenOrders(accountId: string, symbol?: string): OrderSnapshot[];