@0xmonaco/types 1.1.5 → 1.1.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.
- package/README.md +1 -3
- package/dist/analytics/builders.d.ts +135 -0
- package/dist/analytics/builders.js +11 -0
- package/dist/analytics/index.d.ts +153 -0
- package/dist/analytics/index.js +27 -0
- package/dist/analytics/wallets.d.ts +205 -0
- package/dist/analytics/wallets.js +16 -0
- package/dist/applications/requests.d.ts +5 -5
- package/dist/buildercodes/index.d.ts +13 -11
- package/dist/buildercodes/responses.d.ts +1 -0
- package/dist/buildercodes/responses.js +10 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/margin-accounts/index.d.ts +7 -2
- package/dist/market/index.d.ts +19 -20
- package/dist/profile/index.d.ts +10 -17
- package/dist/rfq/responses.d.ts +145 -0
- package/dist/rfq/responses.js +102 -0
- package/dist/sdk/index.d.ts +4 -1
- package/dist/trading/index.d.ts +7 -3
- package/dist/trading/orders.d.ts +11 -0
- package/dist/trading/responses.d.ts +9 -3
- package/dist/validation/margin-accounts.d.ts +2 -2
- package/dist/validation/margin-accounts.js +5 -5
- package/dist/validation/trading.d.ts +15 -0
- package/dist/validation/trading.js +34 -42
- package/dist/websocket/base.d.ts +40 -10
- package/dist/websocket/client.d.ts +32 -4
- package/dist/websocket/depth.d.ts +142 -0
- package/dist/websocket/depth.js +13 -0
- package/dist/websocket/events/market-stats-events.d.ts +19 -0
- package/dist/websocket/events/orderbook-events.d.ts +41 -1
- package/dist/websocket/events/position-events.d.ts +3 -2
- package/dist/websocket/events/rfq-events.d.ts +51 -1
- package/dist/websocket/events/trade-events.d.ts +37 -0
- package/dist/websocket/index.d.ts +1 -0
- package/dist/websocket/index.js +1 -0
- package/dist/websocket/snapshots.d.ts +23 -1
- package/dist/wire/operations.d.ts +1 -1
- package/dist/wire/operations.js +16 -0
- package/dist/wire/schema.d.ts +2485 -308
- package/package.json +2 -2
|
@@ -64,7 +64,7 @@ export declare const TransferCollateralToRiskBucketSchema: z.ZodObject<{
|
|
|
64
64
|
marginMode: z.ZodLiteral<"CROSS">;
|
|
65
65
|
marginAccountId: z.ZodOptional<z.ZodUUID>;
|
|
66
66
|
selectedTradingPairIds: z.ZodOptional<z.ZodNever>;
|
|
67
|
-
strategyKey: z.ZodOptional<z.
|
|
67
|
+
strategyKey: z.ZodOptional<z.ZodString>;
|
|
68
68
|
tradingPairId: z.ZodOptional<z.ZodNever>;
|
|
69
69
|
}, z.core.$strict>]>>;
|
|
70
70
|
}, z.core.$strip>;
|
|
@@ -171,7 +171,7 @@ export declare const SimulateRiskBucketOrderRiskSchema: z.ZodObject<{
|
|
|
171
171
|
marginMode: z.ZodLiteral<"CROSS">;
|
|
172
172
|
marginAccountId: z.ZodOptional<z.ZodUUID>;
|
|
173
173
|
selectedTradingPairIds: z.ZodOptional<z.ZodNever>;
|
|
174
|
-
strategyKey: z.ZodOptional<z.
|
|
174
|
+
strategyKey: z.ZodOptional<z.ZodString>;
|
|
175
175
|
tradingPairId: z.ZodUUID;
|
|
176
176
|
side: z.ZodEnum<{
|
|
177
177
|
BUY: "BUY";
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Margin Account API Validation Schemas
|
|
3
3
|
*/
|
|
4
4
|
import { z } from "zod";
|
|
5
|
-
import { MarketSlippageToleranceBpsSchema, OrderIdempotencyKeySchema, OrderSideSchema, OrderTypeSchema, PositionSideSchema, PositiveDecimalStringSchema, UUIDSchema, } from "./trading";
|
|
5
|
+
import { MarketSlippageToleranceBpsSchema, OrderIdempotencyKeySchema, OrderSideSchema, OrderTypeSchema, PositionSideSchema, PositiveDecimalStringSchema, StrategyKeySchema, UUIDSchema, } from "./trading";
|
|
6
6
|
const CursorPaginationSchema = z.object({
|
|
7
7
|
/**
|
|
8
8
|
* Rejected, not ignored. A non-strict object would let a JS or `any` caller
|
|
@@ -37,7 +37,7 @@ const TransferCollateralRequestSchema = z
|
|
|
37
37
|
asset: z.string().trim().min(1, "Asset cannot be empty"),
|
|
38
38
|
amount: PositiveDecimalStringSchema,
|
|
39
39
|
tradingPairId: UUIDSchema.optional(),
|
|
40
|
-
strategyKey:
|
|
40
|
+
strategyKey: StrategyKeySchema.optional(),
|
|
41
41
|
// A cross risk bucket has no trading pair, so CROSS is the only way to name
|
|
42
42
|
// one on the way out (0XM-2420). The two never combine.
|
|
43
43
|
marginMode: z.enum(["ISOLATED", "CROSS"]).optional(),
|
|
@@ -54,7 +54,7 @@ const ParentMarginAccountCollateralRequestSchema = z.object({
|
|
|
54
54
|
});
|
|
55
55
|
const RiskBucketRequestSchema = z.object({
|
|
56
56
|
tradingPairId: UUIDSchema,
|
|
57
|
-
strategyKey:
|
|
57
|
+
strategyKey: StrategyKeySchema.optional(),
|
|
58
58
|
});
|
|
59
59
|
const IsolatedRiskBucketRequestSchema = RiskBucketRequestSchema.extend({
|
|
60
60
|
marginMode: z.literal("ISOLATED").optional(),
|
|
@@ -78,7 +78,7 @@ const CrossRiskBucketSimulateRequestSchema = z.object({
|
|
|
78
78
|
marginMode: z.literal("CROSS"),
|
|
79
79
|
marginAccountId: UUIDSchema.optional(),
|
|
80
80
|
selectedTradingPairIds: z.never().optional(),
|
|
81
|
-
strategyKey:
|
|
81
|
+
strategyKey: StrategyKeySchema.optional(),
|
|
82
82
|
});
|
|
83
83
|
// A cross transfer-in names no pairs. Cross scope is derived from trading, so
|
|
84
84
|
// funding has nothing to declare; `selectedTradingPairIds` used to REPLACE the
|
|
@@ -89,7 +89,7 @@ const CrossRiskBucketRequestSchema = z.object({
|
|
|
89
89
|
marginMode: z.literal("CROSS"),
|
|
90
90
|
marginAccountId: UUIDSchema.optional(),
|
|
91
91
|
selectedTradingPairIds: z.never().optional(),
|
|
92
|
-
strategyKey:
|
|
92
|
+
strategyKey: StrategyKeySchema.optional(),
|
|
93
93
|
tradingPairId: z.never().optional(),
|
|
94
94
|
});
|
|
95
95
|
export const TransferCollateralSchema = z.object({
|
|
@@ -126,6 +126,21 @@ export declare const ParentTrailingStopLegSchema: z.ZodObject<{
|
|
|
126
126
|
slippageToleranceBps: z.ZodOptional<z.ZodNumber>;
|
|
127
127
|
expiresAt: z.ZodOptional<z.ZodISODateTime>;
|
|
128
128
|
}, z.core.$strip>;
|
|
129
|
+
/**
|
|
130
|
+
* An order's `strategyKey` names one of the caller's margin accounts by its
|
|
131
|
+
* sub-account key (`default` is the default margin account), as
|
|
132
|
+
* `marginAccountId` names it by id; a copy trading account's `copy:` key names
|
|
133
|
+
* it too, for the reduce-only close a copy account admits. The server refuses
|
|
134
|
+
* a key outside the sub-account key alphabet and a key naming none of the
|
|
135
|
+
* caller's open sub-accounts.
|
|
136
|
+
*/
|
|
137
|
+
export declare const OrderStrategyKeySchema: z.ZodString;
|
|
138
|
+
/**
|
|
139
|
+
* A risk-bucket transfer's or preview's `strategyKey`: the order rule, and a
|
|
140
|
+
* reserved `copy:` key is refused (a copy account's risk buckets are funded
|
|
141
|
+
* by its follow only).
|
|
142
|
+
*/
|
|
143
|
+
export declare const StrategyKeySchema: z.ZodString;
|
|
129
144
|
/**
|
|
130
145
|
* Place Limit Order validation schema
|
|
131
146
|
*/
|
|
@@ -171,6 +171,26 @@ export const TrailingStopLegSchema = z
|
|
|
171
171
|
export const ParentTrailingStopLegSchema = TrailingStopLegSchema;
|
|
172
172
|
const hasParentTpSl = (options) => options?.takeProfit !== undefined || options?.stopLoss !== undefined || options?.trailingStop !== undefined;
|
|
173
173
|
const legacyPositionSideMatchesOrderSide = (side, positionSide) => positionSide === undefined || (positionSide !== "NONE" && ((side === "BUY" && positionSide === "LONG") || (side === "SELL" && positionSide === "SHORT")));
|
|
174
|
+
/**
|
|
175
|
+
* An order's `strategyKey` names one of the caller's margin accounts by its
|
|
176
|
+
* sub-account key (`default` is the default margin account), as
|
|
177
|
+
* `marginAccountId` names it by id; a copy trading account's `copy:` key names
|
|
178
|
+
* it too, for the reduce-only close a copy account admits. The server refuses
|
|
179
|
+
* a key outside the sub-account key alphabet and a key naming none of the
|
|
180
|
+
* caller's open sub-accounts.
|
|
181
|
+
*/
|
|
182
|
+
export const OrderStrategyKeySchema = z
|
|
183
|
+
.string()
|
|
184
|
+
.trim()
|
|
185
|
+
.min(1, "strategyKey cannot be empty")
|
|
186
|
+
.max(64, "strategyKey must be a sub-account key: letters, digits, _ - . :, up to 64 characters")
|
|
187
|
+
.regex(/^[A-Za-z0-9_.:-]+$/, "strategyKey must be a sub-account key: letters, digits, _ - . :, up to 64 characters");
|
|
188
|
+
/**
|
|
189
|
+
* A risk-bucket transfer's or preview's `strategyKey`: the order rule, and a
|
|
190
|
+
* reserved `copy:` key is refused (a copy account's risk buckets are funded
|
|
191
|
+
* by its follow only).
|
|
192
|
+
*/
|
|
193
|
+
export const StrategyKeySchema = OrderStrategyKeySchema.refine((key) => !key.toLowerCase().startsWith("copy:"), "strategy keys starting with copy: are reserved");
|
|
174
194
|
/**
|
|
175
195
|
* Place Limit Order validation schema
|
|
176
196
|
*/
|
|
@@ -196,7 +216,7 @@ export const PlaceLimitOrderSchema = z
|
|
|
196
216
|
marginMode: MarginModeSchema.optional(),
|
|
197
217
|
riskBucketId: UUIDSchema.optional(),
|
|
198
218
|
riskBucketCollateral: PositiveDecimalStringSchema.optional(),
|
|
199
|
-
strategyKey:
|
|
219
|
+
strategyKey: OrderStrategyKeySchema.optional(),
|
|
200
220
|
positionSide: PositionSideSchema.optional(),
|
|
201
221
|
leverage: PositiveDecimalStringSchema.optional(),
|
|
202
222
|
reduceOnly: z.boolean().optional(),
|
|
@@ -216,7 +236,7 @@ export const PlaceLimitOrderSchema = z
|
|
|
216
236
|
message: "leverage is required for normal MARGIN orders",
|
|
217
237
|
path: ["options", "leverage"],
|
|
218
238
|
})
|
|
219
|
-
.refine((data) => !hasParentTpSl(data.options) || data.options?.tradingMode
|
|
239
|
+
.refine((data) => !hasParentTpSl(data.options) || data.options?.tradingMode !== "SPOT", {
|
|
220
240
|
message: "takeProfit/stopLoss/trailingStop are only supported for MARGIN orders",
|
|
221
241
|
path: ["options"],
|
|
222
242
|
})
|
|
@@ -224,17 +244,13 @@ export const PlaceLimitOrderSchema = z
|
|
|
224
244
|
message: "takeProfit/stopLoss/trailingStop cannot be attached to reduce-only orders",
|
|
225
245
|
path: ["options"],
|
|
226
246
|
})
|
|
227
|
-
.refine((data) => data.options?.riskBucketCollateral === undefined || data.options?.tradingMode
|
|
247
|
+
.refine((data) => data.options?.riskBucketCollateral === undefined || data.options?.tradingMode !== "SPOT", {
|
|
228
248
|
message: "riskBucketCollateral is only supported for MARGIN orders",
|
|
229
249
|
path: ["options", "tradingMode"],
|
|
230
250
|
})
|
|
231
|
-
.refine((data) => data.options?.marginMode === undefined || data.options?.tradingMode
|
|
251
|
+
.refine((data) => data.options?.marginMode === undefined || data.options?.tradingMode !== "SPOT", {
|
|
232
252
|
message: "marginMode is only supported for MARGIN orders",
|
|
233
253
|
path: ["options", "tradingMode"],
|
|
234
|
-
})
|
|
235
|
-
.refine((data) => data.options?.marginMode !== "CROSS" || data.options?.marginAccountId !== undefined, {
|
|
236
|
-
message: "marginAccountId is required for CROSS margin orders",
|
|
237
|
-
path: ["options", "marginAccountId"],
|
|
238
254
|
})
|
|
239
255
|
.refine((data) => data.options?.marginMode !== "CROSS" || data.options?.riskBucketId === undefined, {
|
|
240
256
|
message: "marginMode CROSS cannot be combined with riskBucketId",
|
|
@@ -243,10 +259,6 @@ export const PlaceLimitOrderSchema = z
|
|
|
243
259
|
.refine((data) => data.options?.marginMode !== "CROSS" || data.options?.riskBucketCollateral === undefined, {
|
|
244
260
|
message: "marginMode CROSS cannot be combined with riskBucketCollateral",
|
|
245
261
|
path: ["options", "riskBucketCollateral"],
|
|
246
|
-
})
|
|
247
|
-
.refine((data) => data.options?.marginMode !== "CROSS" || data.options?.strategyKey === undefined, {
|
|
248
|
-
message: "marginMode CROSS cannot be combined with strategyKey",
|
|
249
|
-
path: ["options", "strategyKey"],
|
|
250
262
|
})
|
|
251
263
|
.refine((data) => data.options?.riskBucketCollateral === undefined || data.options?.riskBucketId === undefined, {
|
|
252
264
|
message: "riskBucketCollateral creates a new risk bucket and cannot be combined with riskBucketId",
|
|
@@ -277,7 +289,7 @@ export const PlaceMarketOrderSchema = z
|
|
|
277
289
|
marginMode: MarginModeSchema.optional(),
|
|
278
290
|
riskBucketId: UUIDSchema.optional(),
|
|
279
291
|
riskBucketCollateral: PositiveDecimalStringSchema.optional(),
|
|
280
|
-
strategyKey:
|
|
292
|
+
strategyKey: OrderStrategyKeySchema.optional(),
|
|
281
293
|
positionSide: PositionSideSchema.optional(),
|
|
282
294
|
leverage: PositiveDecimalStringSchema.optional(),
|
|
283
295
|
reduceOnly: z.boolean().optional(),
|
|
@@ -296,7 +308,7 @@ export const PlaceMarketOrderSchema = z
|
|
|
296
308
|
message: "leverage is required for normal MARGIN orders",
|
|
297
309
|
path: ["options", "leverage"],
|
|
298
310
|
})
|
|
299
|
-
.refine((data) => !hasParentTpSl(data.options) || data.options?.tradingMode
|
|
311
|
+
.refine((data) => !hasParentTpSl(data.options) || data.options?.tradingMode !== "SPOT", {
|
|
300
312
|
message: "takeProfit/stopLoss/trailingStop are only supported for MARGIN orders",
|
|
301
313
|
path: ["options"],
|
|
302
314
|
})
|
|
@@ -304,17 +316,13 @@ export const PlaceMarketOrderSchema = z
|
|
|
304
316
|
message: "takeProfit/stopLoss/trailingStop cannot be attached to reduce-only orders",
|
|
305
317
|
path: ["options"],
|
|
306
318
|
})
|
|
307
|
-
.refine((data) => data.options?.riskBucketCollateral === undefined || data.options?.tradingMode
|
|
319
|
+
.refine((data) => data.options?.riskBucketCollateral === undefined || data.options?.tradingMode !== "SPOT", {
|
|
308
320
|
message: "riskBucketCollateral is only supported for MARGIN orders",
|
|
309
321
|
path: ["options", "tradingMode"],
|
|
310
322
|
})
|
|
311
|
-
.refine((data) => data.options?.marginMode === undefined || data.options?.tradingMode
|
|
323
|
+
.refine((data) => data.options?.marginMode === undefined || data.options?.tradingMode !== "SPOT", {
|
|
312
324
|
message: "marginMode is only supported for MARGIN orders",
|
|
313
325
|
path: ["options", "tradingMode"],
|
|
314
|
-
})
|
|
315
|
-
.refine((data) => data.options?.marginMode !== "CROSS" || data.options?.marginAccountId !== undefined, {
|
|
316
|
-
message: "marginAccountId is required for CROSS margin orders",
|
|
317
|
-
path: ["options", "marginAccountId"],
|
|
318
326
|
})
|
|
319
327
|
.refine((data) => data.options?.marginMode !== "CROSS" || data.options?.riskBucketId === undefined, {
|
|
320
328
|
message: "marginMode CROSS cannot be combined with riskBucketId",
|
|
@@ -323,10 +331,6 @@ export const PlaceMarketOrderSchema = z
|
|
|
323
331
|
.refine((data) => data.options?.marginMode !== "CROSS" || data.options?.riskBucketCollateral === undefined, {
|
|
324
332
|
message: "marginMode CROSS cannot be combined with riskBucketCollateral",
|
|
325
333
|
path: ["options", "riskBucketCollateral"],
|
|
326
|
-
})
|
|
327
|
-
.refine((data) => data.options?.marginMode !== "CROSS" || data.options?.strategyKey === undefined, {
|
|
328
|
-
message: "marginMode CROSS cannot be combined with strategyKey",
|
|
329
|
-
path: ["options", "strategyKey"],
|
|
330
334
|
})
|
|
331
335
|
.refine((data) => data.options?.riskBucketCollateral === undefined || data.options?.riskBucketId === undefined, {
|
|
332
336
|
message: "riskBucketCollateral creates a new risk bucket and cannot be combined with riskBucketId",
|
|
@@ -466,7 +470,7 @@ export const CreateTwapOrderSchema = z
|
|
|
466
470
|
riskBucketId: UUIDSchema.optional(),
|
|
467
471
|
marginMode: MarginModeSchema.optional(),
|
|
468
472
|
leverage: PositiveDecimalStringSchema.optional(),
|
|
469
|
-
strategyKey:
|
|
473
|
+
strategyKey: OrderStrategyKeySchema.optional(),
|
|
470
474
|
useMasterBalance: z.boolean().optional(),
|
|
471
475
|
clientTwapId: z.string().min(1).max(36, "clientTwapId cannot exceed 36 characters").optional(),
|
|
472
476
|
triggerPrice: PositiveDecimalStringSchema.optional(),
|
|
@@ -482,21 +486,17 @@ export const CreateTwapOrderSchema = z
|
|
|
482
486
|
message: "startTime is only valid together with endTime",
|
|
483
487
|
path: ["options", "startTime"],
|
|
484
488
|
})
|
|
485
|
-
.refine((data) => data.options.marginMode === undefined || data.options.tradingMode
|
|
489
|
+
.refine((data) => data.options.marginMode === undefined || data.options.tradingMode !== "SPOT", {
|
|
486
490
|
message: "marginMode is only supported for MARGIN orders",
|
|
487
491
|
path: ["options", "tradingMode"],
|
|
488
492
|
})
|
|
489
|
-
.refine((data) => data.options.riskBucketId === undefined || data.options.tradingMode
|
|
493
|
+
.refine((data) => data.options.riskBucketId === undefined || data.options.tradingMode !== "SPOT", {
|
|
490
494
|
message: "riskBucketId is only supported for MARGIN orders",
|
|
491
495
|
path: ["options", "tradingMode"],
|
|
492
496
|
})
|
|
493
497
|
.refine((data) => data.options.marginMode !== "CROSS" || data.options.riskBucketId === undefined, {
|
|
494
498
|
message: "marginMode CROSS cannot be combined with riskBucketId",
|
|
495
499
|
path: ["options", "riskBucketId"],
|
|
496
|
-
})
|
|
497
|
-
.refine((data) => data.options.marginMode !== "CROSS" || data.options.strategyKey === undefined, {
|
|
498
|
-
message: "marginMode CROSS cannot be combined with strategyKey",
|
|
499
|
-
path: ["options", "strategyKey"],
|
|
500
500
|
})
|
|
501
501
|
.refine((data) => data.options.tradingMode !== "MARGIN" || data.options.reduceOnly === true || data.options.leverage !== undefined, {
|
|
502
502
|
message: "leverage is required for normal MARGIN TWAP orders",
|
|
@@ -614,7 +614,7 @@ export const BatchCreateOrderItemSchema = z
|
|
|
614
614
|
marginMode: MarginModeSchema.optional(),
|
|
615
615
|
riskBucketId: UUIDSchema.optional(),
|
|
616
616
|
riskBucketCollateral: PositiveDecimalStringSchema.optional(),
|
|
617
|
-
strategyKey:
|
|
617
|
+
strategyKey: OrderStrategyKeySchema.optional(),
|
|
618
618
|
positionSide: PositionSideSchema.optional(),
|
|
619
619
|
leverage: PositiveDecimalStringSchema.optional(),
|
|
620
620
|
reduceOnly: z.boolean().optional(),
|
|
@@ -641,17 +641,13 @@ export const BatchCreateOrderItemSchema = z
|
|
|
641
641
|
message: "postOnly cannot be combined with IOC/FOK time in force",
|
|
642
642
|
path: ["postOnly"],
|
|
643
643
|
})
|
|
644
|
-
.refine((data) => data.riskBucketCollateral === undefined || data.tradingMode
|
|
644
|
+
.refine((data) => data.riskBucketCollateral === undefined || data.tradingMode !== "SPOT", {
|
|
645
645
|
message: "riskBucketCollateral is only supported for MARGIN orders",
|
|
646
646
|
path: ["tradingMode"],
|
|
647
647
|
})
|
|
648
|
-
.refine((data) => data.marginMode === undefined || data.tradingMode
|
|
648
|
+
.refine((data) => data.marginMode === undefined || data.tradingMode !== "SPOT", {
|
|
649
649
|
message: "marginMode is only supported for MARGIN orders",
|
|
650
650
|
path: ["tradingMode"],
|
|
651
|
-
})
|
|
652
|
-
.refine((data) => data.marginMode !== "CROSS" || data.marginAccountId !== undefined, {
|
|
653
|
-
message: "marginAccountId is required for CROSS margin orders",
|
|
654
|
-
path: ["marginAccountId"],
|
|
655
651
|
})
|
|
656
652
|
.refine((data) => data.marginMode !== "CROSS" || data.riskBucketId === undefined, {
|
|
657
653
|
message: "marginMode CROSS cannot be combined with riskBucketId",
|
|
@@ -660,10 +656,6 @@ export const BatchCreateOrderItemSchema = z
|
|
|
660
656
|
.refine((data) => data.marginMode !== "CROSS" || data.riskBucketCollateral === undefined, {
|
|
661
657
|
message: "marginMode CROSS cannot be combined with riskBucketCollateral",
|
|
662
658
|
path: ["riskBucketCollateral"],
|
|
663
|
-
})
|
|
664
|
-
.refine((data) => data.marginMode !== "CROSS" || data.strategyKey === undefined, {
|
|
665
|
-
message: "marginMode CROSS cannot be combined with strategyKey",
|
|
666
|
-
path: ["strategyKey"],
|
|
667
659
|
})
|
|
668
660
|
.refine((data) => data.riskBucketCollateral === undefined || data.riskBucketId === undefined, {
|
|
669
661
|
message: "riskBucketCollateral creates a new risk bucket and cannot be combined with riskBucketId",
|
package/dist/websocket/base.d.ts
CHANGED
|
@@ -71,23 +71,43 @@ export interface WebSocketStatusInfo {
|
|
|
71
71
|
*/
|
|
72
72
|
export type StatusHandler = (status: WebSocketStatus, info: WebSocketStatusInfo) => void;
|
|
73
73
|
/**
|
|
74
|
-
* Why the
|
|
75
|
-
* {@link MonacoWebSocketConfig.onResync}
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
74
|
+
* Why the application should refetch REST state, delivered by
|
|
75
|
+
* {@link MonacoWebSocketConfig.onResync}. Two cases:
|
|
76
|
+
*
|
|
77
|
+
* - A reconnect (`reason` absent): sent after the socket reopens and sends its
|
|
78
|
+
* authentication/subscription requests, without waiting for server acks or
|
|
79
|
+
* snapshots. Refetch every channel.
|
|
80
|
+
* - A scoped resync (`reason: "resynced"`, 0XM-3553): the connection stayed
|
|
81
|
+
* open, but the server reported that an upstream loss may have cost the
|
|
82
|
+
* listed `channels` frames, or re-sent a snapshot for a channel that has no
|
|
83
|
+
* snapshot handler. Delivered once per burst, no earlier than the server's
|
|
84
|
+
* requested delay, with `code: 1013` and `slowClient: true` so a handler
|
|
85
|
+
* written for reconnects still refetches (everything). Refetch only
|
|
86
|
+
* `channels` to recover precisely. The subscriptions stay active.
|
|
87
|
+
*
|
|
88
|
+
* The application owns channel-specific recovery; the SDK does not refetch
|
|
89
|
+
* REST state itself.
|
|
79
90
|
*/
|
|
80
91
|
export interface WebSocketResyncInfo {
|
|
81
92
|
/** WebSocket close code of the connection that was lost. */
|
|
82
93
|
code: number;
|
|
83
94
|
/**
|
|
84
|
-
* True when the server closed with 1013 (try again later): the
|
|
85
|
-
* behind
|
|
86
|
-
*
|
|
87
|
-
* number
|
|
88
|
-
* only safe repair.
|
|
95
|
+
* True when the server closed with 1013 (try again later): the connection
|
|
96
|
+
* fell behind, or the server lost events upstream, and any of its streams
|
|
97
|
+
* may have a gap. Order, account and engine-sourced public streams carry no
|
|
98
|
+
* wire sequence number, so the 1013 close is their gap signal and a snapshot
|
|
99
|
+
* refetch is the only safe repair. `depth`, `bbo` and a single market's
|
|
100
|
+
* market-data-sourced `trades` rebuild from the snapshot the reconnect
|
|
101
|
+
* brings; `trades:*` has no snapshot, so backfill its history over REST.
|
|
89
102
|
*/
|
|
90
103
|
slowClient: boolean;
|
|
104
|
+
/** `"resynced"` for a scoped resync; absent on a reconnect. */
|
|
105
|
+
reason?: "resynced";
|
|
106
|
+
/**
|
|
107
|
+
* The channels to refetch, exactly as subscribed, on a scoped resync;
|
|
108
|
+
* absent on a reconnect, which covers every channel.
|
|
109
|
+
*/
|
|
110
|
+
channels?: string[];
|
|
91
111
|
}
|
|
92
112
|
/** Handler invoked after a reconnect resumes the live stream. */
|
|
93
113
|
export type ResyncHandler = (info: WebSocketResyncInfo) => void;
|
|
@@ -200,6 +220,16 @@ export type ReauthenticationRequiredHandler = (info: WebSocketReauthenticationIn
|
|
|
200
220
|
export interface MonacoWebSocketConfig {
|
|
201
221
|
/** Enable auto-reconnect on disconnect (default: true) */
|
|
202
222
|
autoReconnect?: boolean;
|
|
223
|
+
/**
|
|
224
|
+
* Offer the server the `resync` capability (default: true when
|
|
225
|
+
* {@link onResync} is set, 0XM-3553; never without it, since the channels
|
|
226
|
+
* would have nowhere to go): on an
|
|
227
|
+
* upstream loss it can attribute, the server keeps the connection open and
|
|
228
|
+
* names the channels to refetch (delivered through {@link onResync} with
|
|
229
|
+
* `reason: "resynced"`), or re-sends their snapshots, instead of closing it
|
|
230
|
+
* with 1013. `false` keeps the close-and-reconnect behaviour.
|
|
231
|
+
*/
|
|
232
|
+
scopedResync?: boolean;
|
|
203
233
|
/**
|
|
204
234
|
* Maximum reconnection attempts per outage (default: unlimited). Retry
|
|
205
235
|
* delay is full-jitter exponential backoff capped at 30s, so unlimited
|
|
@@ -59,8 +59,14 @@ import type { Interval } from "../market";
|
|
|
59
59
|
import type { TradingMode } from "../trading";
|
|
60
60
|
import type { SubscriptionChangeHandler, WebSocketStatus, WebSocketSubscriptionState } from "./base";
|
|
61
61
|
import type { OrderbookQuotationMode } from "./clients/orderbook-client";
|
|
62
|
-
import type {
|
|
62
|
+
import type { Bbo, DepthBook, LocalBookOptions } from "./depth";
|
|
63
|
+
import type { AccountEvent, AccountEventData, ConditionalOrderEvent, ConditionalOrderEventData, CopyEvent, CopyRelationshipEventData, InstrumentEvent, InstrumentEventData, LiquidationEvent, LiquidationEventData, MarketLiquidationEvent, MarketStatsAllEvent, MarketStatsData, MarketStatsEvent, MarketStatsSummary, OHLCVEvent, OHLCVPriceType, OrderbookEvent, OrderEvent, PositionEvent, PositionEventData, PositionValuationEvent, RfqEvent, RfqTradeEvent, TradeEvent, TradeEventData, TradeGap, TwapOrderEvent, TwapOrderEventData, UserBalanceEvent, UserBalanceEventData, UserMovementEvent } from "./events";
|
|
63
64
|
import type { OHLCVSnapshotCandle, OrderSnapshotItem, SnapshotHandler } from "./snapshots";
|
|
65
|
+
/** Options for `ws.trades`. */
|
|
66
|
+
export interface TradesOptions {
|
|
67
|
+
/** Called when a sequenced trade does not link to the last trade delivered (it is still delivered). */
|
|
68
|
+
onGap?: (gap: TradeGap) => void;
|
|
69
|
+
}
|
|
64
70
|
export type MessageHandler<T> = (data: T) => void;
|
|
65
71
|
export interface MonacoWebSocket {
|
|
66
72
|
/** Connect to the WebSocket server */
|
|
@@ -92,10 +98,26 @@ export interface MonacoWebSocket {
|
|
|
92
98
|
/** Subscribe to order events (requires authentication); `onSnapshot` receives every resting order on the pair */
|
|
93
99
|
orders: (tradingPairId: string, tradingMode: TradingMode, handler: MessageHandler<OrderEvent>, onSnapshot?: SnapshotHandler<OrderSnapshotItem>) => () => void;
|
|
94
100
|
/**
|
|
95
|
-
* Subscribe to orderbook events (public); `onSnapshot` receives one event, the current book
|
|
96
|
-
*
|
|
101
|
+
* Subscribe to orderbook events (public); `onSnapshot` receives one event, the current book, in the same shape as a
|
|
102
|
+
* live event. From the matching engine it is the top 20 levels with `sequence` 0; from the market-data service it is
|
|
103
|
+
* grouped over the whole book (at most 20 levels or buckets per side), carries `bookSeq`, and its `sequence` equals
|
|
104
|
+
* `bookSeq`. From the engine, a pair or mode with no book gets `[]`; from the market-data service, an unknown pair
|
|
105
|
+
* gets a `SNAPSHOT_UNAVAILABLE` error (through `onError`) instead, and no snapshot until the pair is listed.
|
|
97
106
|
*/
|
|
98
107
|
orderbook: (tradingPairId: string, tradingMode: TradingMode, magnitude: number, quotationMode: OrderbookQuotationMode, handler: MessageHandler<OrderbookEvent>, onSnapshot?: SnapshotHandler<OrderbookEvent>) => () => void;
|
|
108
|
+
/**
|
|
109
|
+
* Keep a local depth book from the market-data `depth:<tradingPairId>:<SPOT|MARGIN>` channel (public): up to 1000
|
|
110
|
+
* levels per side. The subscribe-time snapshot is the base; live frames that do not link to it are dropped or
|
|
111
|
+
* trigger a rebuild from a fresh snapshot. `onBook` receives the whole book after the snapshot and after every
|
|
112
|
+
* applied frame. Subscribers on the same channel share one book. Returns a function that stops listening.
|
|
113
|
+
*/
|
|
114
|
+
depth: (tradingPairId: string, tradingMode: TradingMode, onBook: MessageHandler<DepthBook>, options?: LocalBookOptions) => () => void;
|
|
115
|
+
/**
|
|
116
|
+
* Keep the top of book from the market-data `bbo:<tradingPairId>:<SPOT|MARGIN>` channel (public), with the same
|
|
117
|
+
* snapshot handoff and link checks as `depth`. `onBbo` receives the current best bid and ask (an empty side is
|
|
118
|
+
* `null`) after the snapshot and after every applied frame.
|
|
119
|
+
*/
|
|
120
|
+
bbo: (tradingPairId: string, tradingMode: TradingMode, onBbo: MessageHandler<Bbo>, options?: LocalBookOptions) => () => void;
|
|
99
121
|
/**
|
|
100
122
|
* Subscribe to OHLCV candlestick events (public); `onSnapshot` receives the series' newest 350 candles, oldest first.
|
|
101
123
|
* The newest snapshot candle can be partial or missing, so upsert live candles by `T`. A `*` price type gets no snapshot.
|
|
@@ -104,8 +126,14 @@ export interface MonacoWebSocket {
|
|
|
104
126
|
/**
|
|
105
127
|
* Subscribe to trade events (public); `onSnapshot` receives the pair's newest 50 trades, newest first.
|
|
106
128
|
* The snapshot can overlap the first live trades or miss one executed just before subscribing, so dedupe on `tradeId`.
|
|
129
|
+
*
|
|
130
|
+
* When the server sources trades from market-data, each trade carries `seq` / `matchIndex` / `prevSeq` /
|
|
131
|
+
* `prevMatchIndex`, and the snapshot's `meta.cursor` names the trade it is current as of. The helper then drops
|
|
132
|
+
* trades at or below the cursor or the last delivered trade, and reports one that does not link to the last
|
|
133
|
+
* delivered trade to `options.onGap` (still delivering it: the server forwards only linking trades, so a mismatch
|
|
134
|
+
* means a frame was lost on this client). Without those fields every trade is delivered as before.
|
|
107
135
|
*/
|
|
108
|
-
trades: (tradingPairId: string, handler: MessageHandler<TradeEvent>, onSnapshot?: SnapshotHandler<TradeEventData
|
|
136
|
+
trades: (tradingPairId: string, handler: MessageHandler<TradeEvent>, onSnapshot?: SnapshotHandler<TradeEventData>, options?: TradesOptions) => () => void;
|
|
109
137
|
/** Subscribe to user movement events (requires authentication) */
|
|
110
138
|
movements: (handler: MessageHandler<UserMovementEvent>) => () => void;
|
|
111
139
|
/** Subscribe to user order events for all trading pairs (requires authentication); `onSnapshot` receives every resting order */
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Market-data depth and BBO types (0XM-3551).
|
|
3
|
+
*
|
|
4
|
+
* The `depth:<tradingPairId>:<SPOT|MARGIN>` and `bbo:<tradingPairId>:<SPOT|MARGIN>`
|
|
5
|
+
* WebSocket channels carry the market-data service's sequenced book: a
|
|
6
|
+
* subscribe-time snapshot, then live frames linked by `bookSeq` /
|
|
7
|
+
* `prevBookSeq`. The SDK's `ws.depth` and `ws.bbo` helpers keep the local
|
|
8
|
+
* state for you; the frame shapes are exported for callers that need them.
|
|
9
|
+
*
|
|
10
|
+
* Sequence numbers are durable-log positions (u64). They are surfaced as
|
|
11
|
+
* decimal strings, since a u64 can exceed `Number.MAX_SAFE_INTEGER`; compare
|
|
12
|
+
* them with `BigInt`.
|
|
13
|
+
*/
|
|
14
|
+
import type { TradingMode } from "../trading";
|
|
15
|
+
/** One price level, with its absolute (not incremental) values. */
|
|
16
|
+
export interface DepthLevel {
|
|
17
|
+
/** Price, a decimal string. */
|
|
18
|
+
price: string;
|
|
19
|
+
/** Resting quantity at this price, a decimal string. */
|
|
20
|
+
quantity: string;
|
|
21
|
+
/** Number of resting orders at this price. */
|
|
22
|
+
orderCount: number;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* The `depth` channel's subscribe-time snapshot: up to 1000 levels per side,
|
|
26
|
+
* best first, exact as of `bookSeq`.
|
|
27
|
+
*/
|
|
28
|
+
export interface DepthSnapshot {
|
|
29
|
+
tradingPairId: string;
|
|
30
|
+
tradingMode: TradingMode | (string & {});
|
|
31
|
+
/** The durable-log sequence the snapshot is exact as of (u64, decimal string). */
|
|
32
|
+
bookSeq: string;
|
|
33
|
+
bids: DepthLevel[];
|
|
34
|
+
asks: DepthLevel[];
|
|
35
|
+
/** Every bid level is in `bids`; when false, levels below the last one are unknown. */
|
|
36
|
+
bidsComplete: boolean;
|
|
37
|
+
/** Every ask level is in `asks`; when false, levels above the last one are unknown. */
|
|
38
|
+
asksComplete: boolean;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* A live `depth` frame: only the levels that changed since `prevBookSeq`,
|
|
42
|
+
* each with its absolute value at `bookSeq`. A quantity of `"0"` (order
|
|
43
|
+
* count 0) removes the level.
|
|
44
|
+
*/
|
|
45
|
+
export interface DepthDelta {
|
|
46
|
+
tradingPairId: string;
|
|
47
|
+
tradingMode: TradingMode | (string & {});
|
|
48
|
+
/** The durable-log sequence of the last change this frame includes. */
|
|
49
|
+
bookSeq: string;
|
|
50
|
+
/** The `bookSeq` this frame continues from. */
|
|
51
|
+
prevBookSeq: string;
|
|
52
|
+
/** The durable-log timestamp of the step at `bookSeq`, in milliseconds. */
|
|
53
|
+
timestampMs: number;
|
|
54
|
+
bids: DepthLevel[];
|
|
55
|
+
asks: DepthLevel[];
|
|
56
|
+
/** Set while the publisher lags the durable log. */
|
|
57
|
+
stale: boolean;
|
|
58
|
+
}
|
|
59
|
+
/** The local book `ws.depth` maintains and hands to its listener. */
|
|
60
|
+
export interface DepthBook {
|
|
61
|
+
tradingPairId: string;
|
|
62
|
+
tradingMode: TradingMode | (string & {});
|
|
63
|
+
/** The sequence the book is current as of (u64, decimal string). */
|
|
64
|
+
bookSeq: string;
|
|
65
|
+
/** Bids, best (highest) first. */
|
|
66
|
+
bids: DepthLevel[];
|
|
67
|
+
/** Asks, best (lowest) first. */
|
|
68
|
+
asks: DepthLevel[];
|
|
69
|
+
/**
|
|
70
|
+
* Every bid level is known. When false, the book holds only levels at or
|
|
71
|
+
* above the snapshot's deepest bid: a level below it that a removal would
|
|
72
|
+
* promote stays unknown until the next snapshot.
|
|
73
|
+
*/
|
|
74
|
+
bidsComplete: boolean;
|
|
75
|
+
/** Every ask level is known (see `bidsComplete`). */
|
|
76
|
+
asksComplete: boolean;
|
|
77
|
+
/** The latest applied frame was published while the service lagged. */
|
|
78
|
+
stale: boolean;
|
|
79
|
+
/** Durable-log time of the latest applied frame; absent right after a snapshot. */
|
|
80
|
+
timestampMs?: number;
|
|
81
|
+
}
|
|
82
|
+
/** The `bbo` channel's subscribe-time snapshot. An empty side is `null`. */
|
|
83
|
+
export interface BboSnapshot {
|
|
84
|
+
tradingPairId: string;
|
|
85
|
+
tradingMode: TradingMode | (string & {});
|
|
86
|
+
bookSeq: string;
|
|
87
|
+
bestBid: string | null;
|
|
88
|
+
/** Quantity resting at `bestBid`. */
|
|
89
|
+
bidQty: string | null;
|
|
90
|
+
bestAsk: string | null;
|
|
91
|
+
/** Quantity resting at `bestAsk`. */
|
|
92
|
+
askQty: string | null;
|
|
93
|
+
}
|
|
94
|
+
/** A live `bbo` frame. */
|
|
95
|
+
export interface BboEvent extends BboSnapshot {
|
|
96
|
+
prevBookSeq: string;
|
|
97
|
+
timestampMs: number;
|
|
98
|
+
stale: boolean;
|
|
99
|
+
}
|
|
100
|
+
/** The top of book `ws.bbo` maintains and hands to its listener. */
|
|
101
|
+
export interface Bbo extends BboSnapshot {
|
|
102
|
+
/** The latest applied frame was published while the service lagged. */
|
|
103
|
+
stale: boolean;
|
|
104
|
+
/** Durable-log time of the latest applied frame; absent right after a snapshot. */
|
|
105
|
+
timestampMs?: number;
|
|
106
|
+
}
|
|
107
|
+
/** Why a local book was discarded and is being rebuilt from a new snapshot. */
|
|
108
|
+
export type LocalBookResyncReason =
|
|
109
|
+
/** A frame did not link to the book (a lost frame), or could not be read. */
|
|
110
|
+
"gap"
|
|
111
|
+
/**
|
|
112
|
+
* The server could not serve a snapshot (`SNAPSHOT_UNAVAILABLE`; it retries
|
|
113
|
+
* and sends one when the book heals), or the one it sent could not be read.
|
|
114
|
+
*/
|
|
115
|
+
| "snapshot_unavailable"
|
|
116
|
+
/**
|
|
117
|
+
* A side whose snapshot was incomplete has thinned below half its snapshot
|
|
118
|
+
* depth: the levels beyond its boundary are unknown, so a fresh snapshot is
|
|
119
|
+
* taken.
|
|
120
|
+
*/
|
|
121
|
+
| "truncated"
|
|
122
|
+
/** The connection dropped; the book is rebuilt from the snapshot the reconnect brings. */
|
|
123
|
+
| "disconnected";
|
|
124
|
+
/** A channel-level error the server sent for a `depth` / `bbo` subscription. */
|
|
125
|
+
export interface LocalBookError {
|
|
126
|
+
/** The server's error code, e.g. `INVALID_SUBSCRIPTION`. */
|
|
127
|
+
code: string;
|
|
128
|
+
message: string;
|
|
129
|
+
}
|
|
130
|
+
/** Options for `ws.depth` and `ws.bbo`. */
|
|
131
|
+
export interface LocalBookOptions {
|
|
132
|
+
/**
|
|
133
|
+
* Called when the local state is discarded to be rebuilt; the listener is
|
|
134
|
+
* called again once the new snapshot arrives.
|
|
135
|
+
*/
|
|
136
|
+
onResync?: (reason: LocalBookResyncReason) => void;
|
|
137
|
+
/**
|
|
138
|
+
* Called when the server rejects the subscription with an error other than
|
|
139
|
+
* `SNAPSHOT_UNAVAILABLE` (which is retried): the book will not arrive.
|
|
140
|
+
*/
|
|
141
|
+
onError?: (error: LocalBookError) => void;
|
|
142
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Market-data depth and BBO types (0XM-3551).
|
|
3
|
+
*
|
|
4
|
+
* The `depth:<tradingPairId>:<SPOT|MARGIN>` and `bbo:<tradingPairId>:<SPOT|MARGIN>`
|
|
5
|
+
* WebSocket channels carry the market-data service's sequenced book: a
|
|
6
|
+
* subscribe-time snapshot, then live frames linked by `bookSeq` /
|
|
7
|
+
* `prevBookSeq`. The SDK's `ws.depth` and `ws.bbo` helpers keep the local
|
|
8
|
+
* state for you; the frame shapes are exported for callers that need them.
|
|
9
|
+
*
|
|
10
|
+
* Sequence numbers are durable-log positions (u64). They are surfaced as
|
|
11
|
+
* decimal strings, since a u64 can exceed `Number.MAX_SAFE_INTEGER`; compare
|
|
12
|
+
* them with `BigInt`.
|
|
13
|
+
*/
|
|
@@ -79,6 +79,11 @@ export interface MarketStatsData {
|
|
|
79
79
|
dailyPriceChange?: string;
|
|
80
80
|
/** 24h percentage price change, two decimals (decimal string) */
|
|
81
81
|
dailyPriceChangePercent?: string;
|
|
82
|
+
/**
|
|
83
|
+
* The 24h volumes split into their order-book and RFQ parts. Omitted while
|
|
84
|
+
* any candle in the window has no recorded split.
|
|
85
|
+
*/
|
|
86
|
+
dailyVolumeBySource?: DailyVolumeBySource;
|
|
82
87
|
/** Current (last settled) funding rate (decimal string). Perp-only; omitted for spot. */
|
|
83
88
|
currentFundingRate?: string;
|
|
84
89
|
/** Estimated next-window funding rate (decimal string). Perp-only; omitted for spot. */
|
|
@@ -185,3 +190,17 @@ export interface MarketStatsAllEvent {
|
|
|
185
190
|
/** One summary row per market */
|
|
186
191
|
markets: MarketStatsSummary[];
|
|
187
192
|
}
|
|
193
|
+
/**
|
|
194
|
+
* A market's 24h volume split by execution source: each total is the
|
|
195
|
+
* order-book part plus the RFQ part (decimal strings, normalized token units).
|
|
196
|
+
*/
|
|
197
|
+
export interface DailyVolumeBySource {
|
|
198
|
+
/** 24h base-token volume filled on the order book */
|
|
199
|
+
orderBookBaseTokenVolume: string;
|
|
200
|
+
/** 24h base-token volume filled by RFQ block trades */
|
|
201
|
+
rfqBaseTokenVolume: string;
|
|
202
|
+
/** 24h quote-token volume filled on the order book; omitted when the 24h quote volume is unavailable */
|
|
203
|
+
orderBookQuoteTokenVolume?: string;
|
|
204
|
+
/** 24h quote-token volume filled by RFQ block trades; omitted when the 24h quote volume is unavailable */
|
|
205
|
+
rfqQuoteTokenVolume?: string;
|
|
206
|
+
}
|
|
@@ -67,6 +67,46 @@ export interface OrderbookEvent {
|
|
|
67
67
|
quoteDecimals: number;
|
|
68
68
|
/** Event timestamp */
|
|
69
69
|
timestamp: string;
|
|
70
|
-
/**
|
|
70
|
+
/**
|
|
71
|
+
* Sequence number for ordering. Under the default engine source it is the
|
|
72
|
+
* matching engine's own frame counter; when the server renders the channel
|
|
73
|
+
* from market-data's book (`WS_ORDERBOOK_SOURCE=market_data`) it equals
|
|
74
|
+
* `bookSeq`. The two are different number spaces: do not compare a value
|
|
75
|
+
* from one source with a value from the other (a reconnect or deploy can
|
|
76
|
+
* switch sources). For exact comparison under the market-data source use
|
|
77
|
+
* `bookSeq`, a u64 decimal string.
|
|
78
|
+
*/
|
|
71
79
|
sequence: number;
|
|
80
|
+
/**
|
|
81
|
+
* Durable-log sequence this book is exact as of, as a decimal string
|
|
82
|
+
* (a u64 can exceed `Number.MAX_SAFE_INTEGER`; compare with `BigInt`).
|
|
83
|
+
*
|
|
84
|
+
* Present on a REST snapshot of more than 100 levels: a point-in-time
|
|
85
|
+
* read and staleness check, not a base for applying depth deltas (the REST
|
|
86
|
+
* snapshot may come from a different market-data replica than the stream;
|
|
87
|
+
* for a live local book use `sdk.ws.depth`, which hands off from the
|
|
88
|
+
* `depth` channel's own snapshot). A side that came back with as many
|
|
89
|
+
* levels as requested may hold more.
|
|
90
|
+
*
|
|
91
|
+
* Also present on every `orderbook` WebSocket frame and snapshot row when
|
|
92
|
+
* the server renders the channel from market-data's book
|
|
93
|
+
* (`WS_ORDERBOOK_SOURCE=market_data`): the same watermark the `depth`
|
|
94
|
+
* channel carries, identical on every server. Each such frame restates the
|
|
95
|
+
* book, so per subscription (one channel string: pair, mode, magnitude and
|
|
96
|
+
* quotation) a frame whose `bookSeq` is not past the last one applied to it
|
|
97
|
+
* can be ignored. The watermark is the book's, shared by every magnitude
|
|
98
|
+
* and quotation of it: a newly subscribed variant starts from its own
|
|
99
|
+
* snapshot even when its `bookSeq` equals another variant's.
|
|
100
|
+
*/
|
|
101
|
+
bookSeq?: string;
|
|
102
|
+
/**
|
|
103
|
+
* On an `orderbook` WebSocket frame rendered from market-data's book
|
|
104
|
+
* (`WS_ORDERBOOK_SOURCE=market_data`): the `bookSeq` of the previous frame
|
|
105
|
+
* this server rendered for the book, `"0"` before the first, as a decimal
|
|
106
|
+
* string. A `prevBookSeq` at or below the `bookSeq` you hold means no
|
|
107
|
+
* rendered state was skipped. Informational only: every frame restates the
|
|
108
|
+
* whole book, so nothing needs to be re-requested when it is higher.
|
|
109
|
+
* Absent under the engine source and on REST snapshots.
|
|
110
|
+
*/
|
|
111
|
+
prevBookSeq?: string;
|
|
72
112
|
}
|