@lightconexyz/lightcone-sdk 0.1.0
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 +232 -0
- package/dist/api/client.d.ts +225 -0
- package/dist/api/client.d.ts.map +1 -0
- package/dist/api/client.js +452 -0
- package/dist/api/client.js.map +1 -0
- package/dist/api/error.d.ts +58 -0
- package/dist/api/error.d.ts.map +1 -0
- package/dist/api/error.js +98 -0
- package/dist/api/error.js.map +1 -0
- package/dist/api/index.d.ts +23 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/index.js +51 -0
- package/dist/api/index.js.map +1 -0
- package/dist/api/types/admin.d.ts +49 -0
- package/dist/api/types/admin.d.ts.map +1 -0
- package/dist/api/types/admin.js +13 -0
- package/dist/api/types/admin.js.map +1 -0
- package/dist/api/types/index.d.ts +14 -0
- package/dist/api/types/index.d.ts.map +1 -0
- package/dist/api/types/index.js +13 -0
- package/dist/api/types/index.js.map +1 -0
- package/dist/api/types/market.d.ts +186 -0
- package/dist/api/types/market.d.ts.map +1 -0
- package/dist/api/types/market.js +6 -0
- package/dist/api/types/market.js.map +1 -0
- package/dist/api/types/order.d.ts +190 -0
- package/dist/api/types/order.d.ts.map +1 -0
- package/dist/api/types/order.js +6 -0
- package/dist/api/types/order.js.map +1 -0
- package/dist/api/types/orderbook.d.ts +36 -0
- package/dist/api/types/orderbook.d.ts.map +1 -0
- package/dist/api/types/orderbook.js +6 -0
- package/dist/api/types/orderbook.js.map +1 -0
- package/dist/api/types/position.d.ts +60 -0
- package/dist/api/types/position.d.ts.map +1 -0
- package/dist/api/types/position.js +6 -0
- package/dist/api/types/position.js.map +1 -0
- package/dist/api/types/price_history.d.ts +68 -0
- package/dist/api/types/price_history.d.ts.map +1 -0
- package/dist/api/types/price_history.js +13 -0
- package/dist/api/types/price_history.js.map +1 -0
- package/dist/api/types/trade.d.ts +67 -0
- package/dist/api/types/trade.d.ts.map +1 -0
- package/dist/api/types/trade.js +13 -0
- package/dist/api/types/trade.js.map +1 -0
- package/dist/api/validation.d.ts +24 -0
- package/dist/api/validation.d.ts.map +1 -0
- package/dist/api/validation.js +53 -0
- package/dist/api/validation.js.map +1 -0
- package/dist/auth.d.ts +80 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +149 -0
- package/dist/auth.js.map +1 -0
- package/dist/index.d.ts +55 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +107 -0
- package/dist/index.js.map +1 -0
- package/dist/network.d.ts +5 -0
- package/dist/network.d.ts.map +1 -0
- package/dist/network.js +8 -0
- package/dist/network.js.map +1 -0
- package/dist/program/accounts.d.ts +98 -0
- package/dist/program/accounts.d.ts.map +1 -0
- package/dist/program/accounts.js +319 -0
- package/dist/program/accounts.js.map +1 -0
- package/dist/program/builder.d.ts +94 -0
- package/dist/program/builder.d.ts.map +1 -0
- package/dist/program/builder.js +175 -0
- package/dist/program/builder.js.map +1 -0
- package/dist/program/client.d.ts +56 -0
- package/dist/program/client.d.ts.map +1 -0
- package/dist/program/client.js +288 -0
- package/dist/program/client.js.map +1 -0
- package/dist/program/constants.d.ts +108 -0
- package/dist/program/constants.d.ts.map +1 -0
- package/dist/program/constants.js +112 -0
- package/dist/program/constants.js.map +1 -0
- package/dist/program/index.d.ts +14 -0
- package/dist/program/index.d.ts.map +1 -0
- package/dist/program/index.js +149 -0
- package/dist/program/index.js.map +1 -0
- package/dist/program/instructions.d.ts +248 -0
- package/dist/program/instructions.d.ts.map +1 -0
- package/dist/program/instructions.js +692 -0
- package/dist/program/instructions.js.map +1 -0
- package/dist/program/orders.d.ts +151 -0
- package/dist/program/orders.d.ts.map +1 -0
- package/dist/program/orders.js +417 -0
- package/dist/program/orders.js.map +1 -0
- package/dist/program/pda.d.ts +73 -0
- package/dist/program/pda.d.ts.map +1 -0
- package/dist/program/pda.js +131 -0
- package/dist/program/pda.js.map +1 -0
- package/dist/program/types.d.ts +380 -0
- package/dist/program/types.d.ts.map +1 -0
- package/dist/program/types.js +27 -0
- package/dist/program/types.js.map +1 -0
- package/dist/program/utils.d.ts +91 -0
- package/dist/program/utils.d.ts.map +1 -0
- package/dist/program/utils.js +219 -0
- package/dist/program/utils.js.map +1 -0
- package/dist/shared/index.d.ts +8 -0
- package/dist/shared/index.d.ts.map +1 -0
- package/dist/shared/index.js +18 -0
- package/dist/shared/index.js.map +1 -0
- package/dist/shared/price.d.ts +41 -0
- package/dist/shared/price.d.ts.map +1 -0
- package/dist/shared/price.js +57 -0
- package/dist/shared/price.js.map +1 -0
- package/dist/shared/scaling.d.ts +45 -0
- package/dist/shared/scaling.d.ts.map +1 -0
- package/dist/shared/scaling.js +84 -0
- package/dist/shared/scaling.js.map +1 -0
- package/dist/shared/types.d.ts +19 -0
- package/dist/shared/types.d.ts.map +1 -0
- package/dist/shared/types.js +23 -0
- package/dist/shared/types.js.map +1 -0
- package/dist/websocket/client.d.ts +238 -0
- package/dist/websocket/client.d.ts.map +1 -0
- package/dist/websocket/client.js +580 -0
- package/dist/websocket/client.js.map +1 -0
- package/dist/websocket/error.d.ts +47 -0
- package/dist/websocket/error.d.ts.map +1 -0
- package/dist/websocket/error.js +83 -0
- package/dist/websocket/error.js.map +1 -0
- package/dist/websocket/handlers.d.ts +97 -0
- package/dist/websocket/handlers.d.ts.map +1 -0
- package/dist/websocket/handlers.js +277 -0
- package/dist/websocket/handlers.js.map +1 -0
- package/dist/websocket/index.d.ts +38 -0
- package/dist/websocket/index.d.ts.map +1 -0
- package/dist/websocket/index.js +75 -0
- package/dist/websocket/index.js.map +1 -0
- package/dist/websocket/state/index.d.ts +7 -0
- package/dist/websocket/state/index.d.ts.map +1 -0
- package/dist/websocket/state/index.js +14 -0
- package/dist/websocket/state/index.js.map +1 -0
- package/dist/websocket/state/orderbook.d.ts +107 -0
- package/dist/websocket/state/orderbook.d.ts.map +1 -0
- package/dist/websocket/state/orderbook.js +293 -0
- package/dist/websocket/state/orderbook.js.map +1 -0
- package/dist/websocket/state/price.d.ts +108 -0
- package/dist/websocket/state/price.d.ts.map +1 -0
- package/dist/websocket/state/price.js +243 -0
- package/dist/websocket/state/price.js.map +1 -0
- package/dist/websocket/state/user.d.ts +83 -0
- package/dist/websocket/state/user.d.ts.map +1 -0
- package/dist/websocket/state/user.js +228 -0
- package/dist/websocket/state/user.js.map +1 -0
- package/dist/websocket/subscriptions.d.ts +143 -0
- package/dist/websocket/subscriptions.d.ts.map +1 -0
- package/dist/websocket/subscriptions.js +244 -0
- package/dist/websocket/subscriptions.js.map +1 -0
- package/dist/websocket/types.d.ts +417 -0
- package/dist/websocket/types.d.ts.map +1 -0
- package/dist/websocket/types.js +195 -0
- package/dist/websocket/types.js.map +1 -0
- package/package.json +75 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* WebSocket client module for Lightcone.
|
|
4
|
+
*
|
|
5
|
+
* This module provides real-time data streaming functionality for
|
|
6
|
+
* live orderbook updates, trade notifications, and market events.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* import { websocket } from "@lightcone/sdk";
|
|
11
|
+
*
|
|
12
|
+
* const client = await websocket.LightconeWebSocketClient.connectDefault();
|
|
13
|
+
*
|
|
14
|
+
* client.on((event) => {
|
|
15
|
+
* if (event.type === "BookUpdate") {
|
|
16
|
+
* const book = client.getOrderbook(event.orderbookId);
|
|
17
|
+
* console.log("Best bid:", book?.bestBid());
|
|
18
|
+
* }
|
|
19
|
+
* });
|
|
20
|
+
*
|
|
21
|
+
* await client.subscribeBookUpdates(["market1:ob1"]);
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* @module websocket
|
|
25
|
+
*/
|
|
26
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
27
|
+
exports.DEFAULT_API_URL = exports.signMessage = exports.generateSigninMessageWithTimestamp = exports.generateSigninMessage = exports.authenticate = exports.MessageHandler = exports.subscriptionType = exports.subscriptionToParams = exports.SubscriptionManager = exports.PriceHistoryKey = exports.PriceHistory = exports.UserState = exports.LocalOrderbook = exports.parsePriceLevelSide = exports.sideToNumber = exports.parseSide = exports.parseWsMessage = exports.parseMessageType = exports.parseErrorCode = exports.parseMarketEventType = exports.toCandle = exports.marketParams = exports.priceHistoryParams = exports.userParams = exports.tradesParams = exports.bookUpdateParams = exports.createPingRequest = exports.createUnsubscribeRequest = exports.createSubscribeRequest = exports.WebSocketError = exports.DEFAULT_WS_URL = exports.LightconeWebSocketClient = void 0;
|
|
28
|
+
// Client
|
|
29
|
+
var client_1 = require("./client");
|
|
30
|
+
Object.defineProperty(exports, "LightconeWebSocketClient", { enumerable: true, get: function () { return client_1.LightconeWebSocketClient; } });
|
|
31
|
+
Object.defineProperty(exports, "DEFAULT_WS_URL", { enumerable: true, get: function () { return client_1.DEFAULT_WS_URL; } });
|
|
32
|
+
// Error types
|
|
33
|
+
var error_1 = require("./error");
|
|
34
|
+
Object.defineProperty(exports, "WebSocketError", { enumerable: true, get: function () { return error_1.WebSocketError; } });
|
|
35
|
+
var types_1 = require("./types");
|
|
36
|
+
Object.defineProperty(exports, "createSubscribeRequest", { enumerable: true, get: function () { return types_1.createSubscribeRequest; } });
|
|
37
|
+
Object.defineProperty(exports, "createUnsubscribeRequest", { enumerable: true, get: function () { return types_1.createUnsubscribeRequest; } });
|
|
38
|
+
Object.defineProperty(exports, "createPingRequest", { enumerable: true, get: function () { return types_1.createPingRequest; } });
|
|
39
|
+
Object.defineProperty(exports, "bookUpdateParams", { enumerable: true, get: function () { return types_1.bookUpdateParams; } });
|
|
40
|
+
Object.defineProperty(exports, "tradesParams", { enumerable: true, get: function () { return types_1.tradesParams; } });
|
|
41
|
+
Object.defineProperty(exports, "userParams", { enumerable: true, get: function () { return types_1.userParams; } });
|
|
42
|
+
Object.defineProperty(exports, "priceHistoryParams", { enumerable: true, get: function () { return types_1.priceHistoryParams; } });
|
|
43
|
+
Object.defineProperty(exports, "marketParams", { enumerable: true, get: function () { return types_1.marketParams; } });
|
|
44
|
+
Object.defineProperty(exports, "toCandle", { enumerable: true, get: function () { return types_1.toCandle; } });
|
|
45
|
+
Object.defineProperty(exports, "parseMarketEventType", { enumerable: true, get: function () { return types_1.parseMarketEventType; } });
|
|
46
|
+
Object.defineProperty(exports, "parseErrorCode", { enumerable: true, get: function () { return types_1.parseErrorCode; } });
|
|
47
|
+
Object.defineProperty(exports, "parseMessageType", { enumerable: true, get: function () { return types_1.parseMessageType; } });
|
|
48
|
+
Object.defineProperty(exports, "parseWsMessage", { enumerable: true, get: function () { return types_1.parseWsMessage; } });
|
|
49
|
+
Object.defineProperty(exports, "parseSide", { enumerable: true, get: function () { return types_1.parseSide; } });
|
|
50
|
+
Object.defineProperty(exports, "sideToNumber", { enumerable: true, get: function () { return types_1.sideToNumber; } });
|
|
51
|
+
Object.defineProperty(exports, "parsePriceLevelSide", { enumerable: true, get: function () { return types_1.parsePriceLevelSide; } });
|
|
52
|
+
// State management
|
|
53
|
+
var state_1 = require("./state");
|
|
54
|
+
Object.defineProperty(exports, "LocalOrderbook", { enumerable: true, get: function () { return state_1.LocalOrderbook; } });
|
|
55
|
+
Object.defineProperty(exports, "UserState", { enumerable: true, get: function () { return state_1.UserState; } });
|
|
56
|
+
Object.defineProperty(exports, "PriceHistory", { enumerable: true, get: function () { return state_1.PriceHistory; } });
|
|
57
|
+
Object.defineProperty(exports, "PriceHistoryKey", { enumerable: true, get: function () { return state_1.PriceHistoryKey; } });
|
|
58
|
+
// Subscription management
|
|
59
|
+
var subscriptions_1 = require("./subscriptions");
|
|
60
|
+
Object.defineProperty(exports, "SubscriptionManager", { enumerable: true, get: function () { return subscriptions_1.SubscriptionManager; } });
|
|
61
|
+
Object.defineProperty(exports, "subscriptionToParams", { enumerable: true, get: function () { return subscriptions_1.subscriptionToParams; } });
|
|
62
|
+
Object.defineProperty(exports, "subscriptionType", { enumerable: true, get: function () { return subscriptions_1.subscriptionType; } });
|
|
63
|
+
// Message handlers
|
|
64
|
+
var handlers_1 = require("./handlers");
|
|
65
|
+
Object.defineProperty(exports, "MessageHandler", { enumerable: true, get: function () { return handlers_1.MessageHandler; } });
|
|
66
|
+
// Authentication
|
|
67
|
+
var auth_1 = require("../auth");
|
|
68
|
+
Object.defineProperty(exports, "authenticate", { enumerable: true, get: function () { return auth_1.authenticate; } });
|
|
69
|
+
Object.defineProperty(exports, "generateSigninMessage", { enumerable: true, get: function () { return auth_1.generateSigninMessage; } });
|
|
70
|
+
Object.defineProperty(exports, "generateSigninMessageWithTimestamp", { enumerable: true, get: function () { return auth_1.generateSigninMessageWithTimestamp; } });
|
|
71
|
+
Object.defineProperty(exports, "signMessage", { enumerable: true, get: function () { return auth_1.signMessage; } });
|
|
72
|
+
// Network constants
|
|
73
|
+
var network_1 = require("../network");
|
|
74
|
+
Object.defineProperty(exports, "DEFAULT_API_URL", { enumerable: true, get: function () { return network_1.DEFAULT_API_URL; } });
|
|
75
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/websocket/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;;;AAEH,SAAS;AACT,mCAGkB;AAFhB,kHAAA,wBAAwB,OAAA;AACxB,wGAAA,cAAc,OAAA;AAQhB,cAAc;AACd,iCAAyC;AAAhC,uGAAA,cAAc,OAAA;AAqCvB,iCAiBiB;AAhBf,+GAAA,sBAAsB,OAAA;AACtB,iHAAA,wBAAwB,OAAA;AACxB,0GAAA,iBAAiB,OAAA;AACjB,yGAAA,gBAAgB,OAAA;AAChB,qGAAA,YAAY,OAAA;AACZ,mGAAA,UAAU,OAAA;AACV,2GAAA,kBAAkB,OAAA;AAClB,qGAAA,YAAY,OAAA;AACZ,iGAAA,QAAQ,OAAA;AACR,6GAAA,oBAAoB,OAAA;AACpB,uGAAA,cAAc,OAAA;AACd,yGAAA,gBAAgB,OAAA;AAChB,uGAAA,cAAc,OAAA;AACd,kGAAA,SAAS,OAAA;AACT,qGAAA,YAAY,OAAA;AACZ,4GAAA,mBAAmB,OAAA;AAGrB,mBAAmB;AACnB,iCAAmF;AAA1E,uGAAA,cAAc,OAAA;AAAE,kGAAA,SAAS,OAAA;AAAE,qGAAA,YAAY,OAAA;AAAE,wGAAA,eAAe,OAAA;AAEjE,0BAA0B;AAC1B,iDAA8F;AAArF,oHAAA,mBAAmB,OAAA;AAAE,qHAAA,oBAAoB,OAAA;AAAE,iHAAA,gBAAgB,OAAA;AAGpE,mBAAmB;AACnB,uCAA4C;AAAnC,0GAAA,cAAc,OAAA;AAEvB,iBAAiB;AACjB,gCAKiB;AAJf,oGAAA,YAAY,OAAA;AACZ,6GAAA,qBAAqB,OAAA;AACrB,0HAAA,kCAAkC,OAAA;AAClC,mGAAA,WAAW,OAAA;AAIb,oBAAoB;AACpB,sCAA6C;AAApC,0GAAA,eAAe,OAAA","sourcesContent":["/**\n * WebSocket client module for Lightcone.\n *\n * This module provides real-time data streaming functionality for\n * live orderbook updates, trade notifications, and market events.\n *\n * @example\n * ```typescript\n * import { websocket } from \"@lightcone/sdk\";\n *\n * const client = await websocket.LightconeWebSocketClient.connectDefault();\n *\n * client.on((event) => {\n * if (event.type === \"BookUpdate\") {\n * const book = client.getOrderbook(event.orderbookId);\n * console.log(\"Best bid:\", book?.bestBid());\n * }\n * });\n *\n * await client.subscribeBookUpdates([\"market1:ob1\"]);\n * ```\n *\n * @module websocket\n */\n\n// Client\nexport {\n LightconeWebSocketClient,\n DEFAULT_WS_URL,\n} from \"./client\";\nexport type {\n WebSocketConfig,\n ConnectionState,\n EventCallback,\n} from \"./client\";\n\n// Error types\nexport { WebSocketError } from \"./error\";\nexport type { WebSocketErrorVariant } from \"./error\";\n\n// Types\nexport type {\n WsRequest,\n SubscribeParams,\n BookUpdateParams,\n TradesParams,\n UserParams,\n PriceHistoryParams,\n MarketParams,\n WsServerMessage,\n AuthData,\n WsMessage,\n BookUpdateData,\n PriceLevel,\n TradeData,\n UserEventData,\n Order,\n OrderUpdate,\n Balance,\n OutcomeBalance,\n BalanceEntry,\n PriceHistoryData,\n Candle,\n MarketEventData,\n MarketEventType,\n ErrorData,\n ErrorCode,\n PongData,\n WsEvent,\n MessageType,\n Side,\n PriceLevelSide,\n} from \"./types\";\n\nexport {\n createSubscribeRequest,\n createUnsubscribeRequest,\n createPingRequest,\n bookUpdateParams,\n tradesParams,\n userParams,\n priceHistoryParams,\n marketParams,\n toCandle,\n parseMarketEventType,\n parseErrorCode,\n parseMessageType,\n parseWsMessage,\n parseSide,\n sideToNumber,\n parsePriceLevelSide,\n} from \"./types\";\n\n// State management\nexport { LocalOrderbook, UserState, PriceHistory, PriceHistoryKey } from \"./state\";\n\n// Subscription management\nexport { SubscriptionManager, subscriptionToParams, subscriptionType } from \"./subscriptions\";\nexport type { Subscription } from \"./subscriptions\";\n\n// Message handlers\nexport { MessageHandler } from \"./handlers\";\n\n// Authentication\nexport {\n authenticate,\n generateSigninMessage,\n generateSigninMessageWithTimestamp,\n signMessage,\n} from \"../auth\";\nexport type { AuthCredentials } from \"../auth\";\n\n// Network constants\nexport { DEFAULT_API_URL } from \"../network\";\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/websocket/state/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACnC,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* State management exports for the WebSocket client.
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.PriceHistoryKey = exports.PriceHistory = exports.UserState = exports.LocalOrderbook = void 0;
|
|
7
|
+
var orderbook_1 = require("./orderbook");
|
|
8
|
+
Object.defineProperty(exports, "LocalOrderbook", { enumerable: true, get: function () { return orderbook_1.LocalOrderbook; } });
|
|
9
|
+
var user_1 = require("./user");
|
|
10
|
+
Object.defineProperty(exports, "UserState", { enumerable: true, get: function () { return user_1.UserState; } });
|
|
11
|
+
var price_1 = require("./price");
|
|
12
|
+
Object.defineProperty(exports, "PriceHistory", { enumerable: true, get: function () { return price_1.PriceHistory; } });
|
|
13
|
+
Object.defineProperty(exports, "PriceHistoryKey", { enumerable: true, get: function () { return price_1.PriceHistoryKey; } });
|
|
14
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/websocket/state/index.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAEH,yCAA6C;AAApC,2GAAA,cAAc,OAAA;AACvB,+BAAmC;AAA1B,iGAAA,SAAS,OAAA;AAClB,iCAAwD;AAA/C,qGAAA,YAAY,OAAA;AAAE,wGAAA,eAAe,OAAA","sourcesContent":["/**\n * State management exports for the WebSocket client.\n */\n\nexport { LocalOrderbook } from \"./orderbook\";\nexport { UserState } from \"./user\";\nexport { PriceHistory, PriceHistoryKey } from \"./price\";\n"]}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local orderbook state management.
|
|
3
|
+
*
|
|
4
|
+
* Maintains a local copy of the orderbook state, applying deltas from
|
|
5
|
+
* WebSocket updates.
|
|
6
|
+
*
|
|
7
|
+
* Note: Internally uses string keys/values to match the string-based API.
|
|
8
|
+
* For numeric comparisons, parse the strings as needed.
|
|
9
|
+
*/
|
|
10
|
+
import type { BookUpdateData, PriceLevel } from "../types";
|
|
11
|
+
/**
|
|
12
|
+
* Local orderbook state.
|
|
13
|
+
*/
|
|
14
|
+
export declare class LocalOrderbook {
|
|
15
|
+
/** Maximum number of price levels to maintain per side */
|
|
16
|
+
private static readonly MAX_LEVELS;
|
|
17
|
+
/** Orderbook identifier */
|
|
18
|
+
readonly orderbookId: string;
|
|
19
|
+
/** Bid levels (price string -> size string) */
|
|
20
|
+
private bids;
|
|
21
|
+
/** Ask levels (price string -> size string) */
|
|
22
|
+
private asks;
|
|
23
|
+
/** Expected next sequence number */
|
|
24
|
+
private expectedSeq;
|
|
25
|
+
/** Whether initial snapshot has been received */
|
|
26
|
+
private _hasSnapshot;
|
|
27
|
+
/** Last update timestamp */
|
|
28
|
+
private _lastTimestamp?;
|
|
29
|
+
constructor(orderbookId: string);
|
|
30
|
+
/**
|
|
31
|
+
* Apply a snapshot (full orderbook state).
|
|
32
|
+
*/
|
|
33
|
+
applySnapshot(update: BookUpdateData): void;
|
|
34
|
+
/**
|
|
35
|
+
* Apply a delta update.
|
|
36
|
+
*
|
|
37
|
+
* @throws {WebSocketError} If a sequence gap is detected
|
|
38
|
+
*/
|
|
39
|
+
applyDelta(update: BookUpdateData): void;
|
|
40
|
+
/**
|
|
41
|
+
* Apply an update (snapshot or delta).
|
|
42
|
+
*
|
|
43
|
+
* @throws {WebSocketError} If a sequence gap is detected
|
|
44
|
+
*/
|
|
45
|
+
applyUpdate(update: BookUpdateData): void;
|
|
46
|
+
/**
|
|
47
|
+
* Get all bid levels sorted by price (descending).
|
|
48
|
+
*/
|
|
49
|
+
getBids(): PriceLevel[];
|
|
50
|
+
/**
|
|
51
|
+
* Get all ask levels sorted by price (ascending).
|
|
52
|
+
*/
|
|
53
|
+
getAsks(): PriceLevel[];
|
|
54
|
+
/**
|
|
55
|
+
* Get top N bid levels.
|
|
56
|
+
*/
|
|
57
|
+
getTopBids(n: number): PriceLevel[];
|
|
58
|
+
/**
|
|
59
|
+
* Get top N ask levels.
|
|
60
|
+
*/
|
|
61
|
+
getTopAsks(n: number): PriceLevel[];
|
|
62
|
+
/**
|
|
63
|
+
* Get the best bid (highest bid price) as [price, size].
|
|
64
|
+
*/
|
|
65
|
+
bestBid(): [string, string] | undefined;
|
|
66
|
+
/**
|
|
67
|
+
* Get the best ask (lowest ask price) as [price, size].
|
|
68
|
+
*/
|
|
69
|
+
bestAsk(): [string, string] | undefined;
|
|
70
|
+
/**
|
|
71
|
+
* Get the spread as a string (best_ask - best_bid).
|
|
72
|
+
*/
|
|
73
|
+
spread(): string | undefined;
|
|
74
|
+
/**
|
|
75
|
+
* Get the midpoint price as a string.
|
|
76
|
+
*/
|
|
77
|
+
midpoint(): string | undefined;
|
|
78
|
+
/**
|
|
79
|
+
* Get size at a specific bid price.
|
|
80
|
+
*/
|
|
81
|
+
bidSizeAt(price: string): string | undefined;
|
|
82
|
+
/**
|
|
83
|
+
* Get size at a specific ask price.
|
|
84
|
+
*/
|
|
85
|
+
askSizeAt(price: string): string | undefined;
|
|
86
|
+
/**
|
|
87
|
+
* Get total bid depth (sum of all bid sizes).
|
|
88
|
+
*/
|
|
89
|
+
totalBidDepth(): number;
|
|
90
|
+
/**
|
|
91
|
+
* Get total ask depth (sum of all ask sizes).
|
|
92
|
+
*/
|
|
93
|
+
totalAskDepth(): number;
|
|
94
|
+
/** Number of bid levels */
|
|
95
|
+
bidCount(): number;
|
|
96
|
+
/** Number of ask levels */
|
|
97
|
+
askCount(): number;
|
|
98
|
+
/** Whether the orderbook has received its initial snapshot */
|
|
99
|
+
hasSnapshot(): boolean;
|
|
100
|
+
/** Current expected sequence number */
|
|
101
|
+
expectedSequence(): number;
|
|
102
|
+
/** Last update timestamp */
|
|
103
|
+
lastTimestamp(): string | undefined;
|
|
104
|
+
/** Clear the orderbook state (for resync) */
|
|
105
|
+
clear(): void;
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=orderbook.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orderbook.d.ts","sourceRoot":"","sources":["../../../src/websocket/state/orderbook.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAG3D;;GAEG;AACH,qBAAa,cAAc;IACzB,0DAA0D;IAC1D,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAQ;IAE1C,2BAA2B;IAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,+CAA+C;IAC/C,OAAO,CAAC,IAAI,CAAkC;IAC9C,+CAA+C;IAC/C,OAAO,CAAC,IAAI,CAAkC;IAC9C,oCAAoC;IACpC,OAAO,CAAC,WAAW,CAAa;IAChC,iDAAiD;IACjD,OAAO,CAAC,YAAY,CAAkB;IACtC,4BAA4B;IAC5B,OAAO,CAAC,cAAc,CAAC,CAAS;gBAEpB,WAAW,EAAE,MAAM;IAI/B;;OAEG;IACH,aAAa,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI;IAmC3C;;;;OAIG;IACH,UAAU,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI;IAwCxC;;;;OAIG;IACH,WAAW,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI;IAQzC;;OAEG;IACH,OAAO,IAAI,UAAU,EAAE;IAWvB;;OAEG;IACH,OAAO,IAAI,UAAU,EAAE;IAWvB;;OAEG;IACH,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG,UAAU,EAAE;IAInC;;OAEG;IACH,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG,UAAU,EAAE;IAInC;;OAEG;IACH,OAAO,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS;IAMvC;;OAEG;IACH,OAAO,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS;IAMvC;;OAEG;IACH,MAAM,IAAI,MAAM,GAAG,SAAS;IAiB5B;;OAEG;IACH,QAAQ,IAAI,MAAM,GAAG,SAAS;IAc9B;;OAEG;IACH,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAI5C;;OAEG;IACH,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAI5C;;OAEG;IACH,aAAa,IAAI,MAAM;IAYvB;;OAEG;IACH,aAAa,IAAI,MAAM;IAYvB,2BAA2B;IAC3B,QAAQ,IAAI,MAAM;IAIlB,2BAA2B;IAC3B,QAAQ,IAAI,MAAM;IAIlB,8DAA8D;IAC9D,WAAW,IAAI,OAAO;IAItB,uCAAuC;IACvC,gBAAgB,IAAI,MAAM;IAI1B,4BAA4B;IAC5B,aAAa,IAAI,MAAM,GAAG,SAAS;IAInC,6CAA6C;IAC7C,KAAK,IAAI,IAAI;CAOd"}
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Local orderbook state management.
|
|
4
|
+
*
|
|
5
|
+
* Maintains a local copy of the orderbook state, applying deltas from
|
|
6
|
+
* WebSocket updates.
|
|
7
|
+
*
|
|
8
|
+
* Note: Internally uses string keys/values to match the string-based API.
|
|
9
|
+
* For numeric comparisons, parse the strings as needed.
|
|
10
|
+
*/
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.LocalOrderbook = void 0;
|
|
16
|
+
const decimal_js_1 = __importDefault(require("decimal.js"));
|
|
17
|
+
const error_1 = require("../error");
|
|
18
|
+
const price_1 = require("../../shared/price");
|
|
19
|
+
/**
|
|
20
|
+
* Local orderbook state.
|
|
21
|
+
*/
|
|
22
|
+
class LocalOrderbook {
|
|
23
|
+
/** Maximum number of price levels to maintain per side */
|
|
24
|
+
static MAX_LEVELS = 1000;
|
|
25
|
+
/** Orderbook identifier */
|
|
26
|
+
orderbookId;
|
|
27
|
+
/** Bid levels (price string -> size string) */
|
|
28
|
+
bids = new Map();
|
|
29
|
+
/** Ask levels (price string -> size string) */
|
|
30
|
+
asks = new Map();
|
|
31
|
+
/** Expected next sequence number */
|
|
32
|
+
expectedSeq = 0;
|
|
33
|
+
/** Whether initial snapshot has been received */
|
|
34
|
+
_hasSnapshot = false;
|
|
35
|
+
/** Last update timestamp */
|
|
36
|
+
_lastTimestamp;
|
|
37
|
+
constructor(orderbookId) {
|
|
38
|
+
this.orderbookId = orderbookId;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Apply a snapshot (full orderbook state).
|
|
42
|
+
*/
|
|
43
|
+
applySnapshot(update) {
|
|
44
|
+
// Validate sequence number
|
|
45
|
+
if (typeof update.seq !== 'number' || update.seq < 0 || !Number.isFinite(update.seq)) {
|
|
46
|
+
console.warn(`Invalid sequence number in snapshot: ${update.seq}`);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
// Clear existing state
|
|
50
|
+
this.bids.clear();
|
|
51
|
+
this.asks.clear();
|
|
52
|
+
// Apply all levels (respecting max depth)
|
|
53
|
+
for (const level of update.bids) {
|
|
54
|
+
if (!(0, price_1.isZero)(level.size)) {
|
|
55
|
+
if (this.bids.size >= LocalOrderbook.MAX_LEVELS && !this.bids.has(level.price)) {
|
|
56
|
+
continue; // Skip if at limit and new level
|
|
57
|
+
}
|
|
58
|
+
this.bids.set(level.price, level.size);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
for (const level of update.asks) {
|
|
62
|
+
if (!(0, price_1.isZero)(level.size)) {
|
|
63
|
+
if (this.asks.size >= LocalOrderbook.MAX_LEVELS && !this.asks.has(level.price)) {
|
|
64
|
+
continue; // Skip if at limit and new level
|
|
65
|
+
}
|
|
66
|
+
this.asks.set(level.price, level.size);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
this.expectedSeq = update.seq + 1;
|
|
70
|
+
this._hasSnapshot = true;
|
|
71
|
+
this._lastTimestamp = update.timestamp;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Apply a delta update.
|
|
75
|
+
*
|
|
76
|
+
* @throws {WebSocketError} If a sequence gap is detected
|
|
77
|
+
*/
|
|
78
|
+
applyDelta(update) {
|
|
79
|
+
// Validate sequence number
|
|
80
|
+
if (typeof update.seq !== 'number' || update.seq < 0 || !Number.isFinite(update.seq)) {
|
|
81
|
+
console.warn(`Invalid sequence number in delta: ${update.seq}`);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
// Check sequence number
|
|
85
|
+
if (update.seq !== this.expectedSeq) {
|
|
86
|
+
throw error_1.WebSocketError.sequenceGap(this.expectedSeq, update.seq);
|
|
87
|
+
}
|
|
88
|
+
// Apply bid updates (respecting max depth)
|
|
89
|
+
for (const level of update.bids) {
|
|
90
|
+
if ((0, price_1.isZero)(level.size)) {
|
|
91
|
+
this.bids.delete(level.price);
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
if (this.bids.size >= LocalOrderbook.MAX_LEVELS && !this.bids.has(level.price)) {
|
|
95
|
+
continue; // Skip if at limit and new level
|
|
96
|
+
}
|
|
97
|
+
this.bids.set(level.price, level.size);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
// Apply ask updates (respecting max depth)
|
|
101
|
+
for (const level of update.asks) {
|
|
102
|
+
if ((0, price_1.isZero)(level.size)) {
|
|
103
|
+
this.asks.delete(level.price);
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
if (this.asks.size >= LocalOrderbook.MAX_LEVELS && !this.asks.has(level.price)) {
|
|
107
|
+
continue; // Skip if at limit and new level
|
|
108
|
+
}
|
|
109
|
+
this.asks.set(level.price, level.size);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
this.expectedSeq = update.seq + 1;
|
|
113
|
+
this._lastTimestamp = update.timestamp;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Apply an update (snapshot or delta).
|
|
117
|
+
*
|
|
118
|
+
* @throws {WebSocketError} If a sequence gap is detected
|
|
119
|
+
*/
|
|
120
|
+
applyUpdate(update) {
|
|
121
|
+
if (update.is_snapshot) {
|
|
122
|
+
this.applySnapshot(update);
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
this.applyDelta(update);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Get all bid levels sorted by price (descending).
|
|
130
|
+
*/
|
|
131
|
+
getBids() {
|
|
132
|
+
const entries = Array.from(this.bids.entries());
|
|
133
|
+
// Sort by price descending (higher prices first)
|
|
134
|
+
entries.sort((a, b) => parseFloat(b[0]) - parseFloat(a[0]));
|
|
135
|
+
return entries.map(([price, size]) => ({
|
|
136
|
+
side: "bid",
|
|
137
|
+
price,
|
|
138
|
+
size,
|
|
139
|
+
}));
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Get all ask levels sorted by price (ascending).
|
|
143
|
+
*/
|
|
144
|
+
getAsks() {
|
|
145
|
+
const entries = Array.from(this.asks.entries());
|
|
146
|
+
// Sort by price ascending (lower prices first)
|
|
147
|
+
entries.sort((a, b) => parseFloat(a[0]) - parseFloat(b[0]));
|
|
148
|
+
return entries.map(([price, size]) => ({
|
|
149
|
+
side: "ask",
|
|
150
|
+
price,
|
|
151
|
+
size,
|
|
152
|
+
}));
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Get top N bid levels.
|
|
156
|
+
*/
|
|
157
|
+
getTopBids(n) {
|
|
158
|
+
return this.getBids().slice(0, n);
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Get top N ask levels.
|
|
162
|
+
*/
|
|
163
|
+
getTopAsks(n) {
|
|
164
|
+
return this.getAsks().slice(0, n);
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Get the best bid (highest bid price) as [price, size].
|
|
168
|
+
*/
|
|
169
|
+
bestBid() {
|
|
170
|
+
const bids = this.getBids();
|
|
171
|
+
if (bids.length === 0)
|
|
172
|
+
return undefined;
|
|
173
|
+
return [bids[0].price, bids[0].size];
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Get the best ask (lowest ask price) as [price, size].
|
|
177
|
+
*/
|
|
178
|
+
bestAsk() {
|
|
179
|
+
const asks = this.getAsks();
|
|
180
|
+
if (asks.length === 0)
|
|
181
|
+
return undefined;
|
|
182
|
+
return [asks[0].price, asks[0].size];
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Get the spread as a string (best_ask - best_bid).
|
|
186
|
+
*/
|
|
187
|
+
spread() {
|
|
188
|
+
const bid = this.bestBid();
|
|
189
|
+
const ask = this.bestAsk();
|
|
190
|
+
if (!bid || !ask)
|
|
191
|
+
return undefined;
|
|
192
|
+
try {
|
|
193
|
+
const bidPrice = new decimal_js_1.default(bid[0]);
|
|
194
|
+
const askPrice = new decimal_js_1.default(ask[0]);
|
|
195
|
+
const spread = askPrice.greaterThan(bidPrice)
|
|
196
|
+
? askPrice.minus(bidPrice)
|
|
197
|
+
: new decimal_js_1.default(0);
|
|
198
|
+
return spread.toFixed(6);
|
|
199
|
+
}
|
|
200
|
+
catch {
|
|
201
|
+
return undefined;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Get the midpoint price as a string.
|
|
206
|
+
*/
|
|
207
|
+
midpoint() {
|
|
208
|
+
const bid = this.bestBid();
|
|
209
|
+
const ask = this.bestAsk();
|
|
210
|
+
if (!bid || !ask)
|
|
211
|
+
return undefined;
|
|
212
|
+
try {
|
|
213
|
+
const bidPrice = new decimal_js_1.default(bid[0]);
|
|
214
|
+
const askPrice = new decimal_js_1.default(ask[0]);
|
|
215
|
+
return bidPrice.plus(askPrice).dividedBy(2).toFixed(6);
|
|
216
|
+
}
|
|
217
|
+
catch {
|
|
218
|
+
return undefined;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Get size at a specific bid price.
|
|
223
|
+
*/
|
|
224
|
+
bidSizeAt(price) {
|
|
225
|
+
return this.bids.get(price);
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Get size at a specific ask price.
|
|
229
|
+
*/
|
|
230
|
+
askSizeAt(price) {
|
|
231
|
+
return this.asks.get(price);
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Get total bid depth (sum of all bid sizes).
|
|
235
|
+
*/
|
|
236
|
+
totalBidDepth() {
|
|
237
|
+
let total = new decimal_js_1.default(0);
|
|
238
|
+
for (const size of this.bids.values()) {
|
|
239
|
+
try {
|
|
240
|
+
total = total.plus(new decimal_js_1.default(size));
|
|
241
|
+
}
|
|
242
|
+
catch {
|
|
243
|
+
// skip unparseable values
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
return total.toNumber();
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Get total ask depth (sum of all ask sizes).
|
|
250
|
+
*/
|
|
251
|
+
totalAskDepth() {
|
|
252
|
+
let total = new decimal_js_1.default(0);
|
|
253
|
+
for (const size of this.asks.values()) {
|
|
254
|
+
try {
|
|
255
|
+
total = total.plus(new decimal_js_1.default(size));
|
|
256
|
+
}
|
|
257
|
+
catch {
|
|
258
|
+
// skip unparseable values
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
return total.toNumber();
|
|
262
|
+
}
|
|
263
|
+
/** Number of bid levels */
|
|
264
|
+
bidCount() {
|
|
265
|
+
return this.bids.size;
|
|
266
|
+
}
|
|
267
|
+
/** Number of ask levels */
|
|
268
|
+
askCount() {
|
|
269
|
+
return this.asks.size;
|
|
270
|
+
}
|
|
271
|
+
/** Whether the orderbook has received its initial snapshot */
|
|
272
|
+
hasSnapshot() {
|
|
273
|
+
return this._hasSnapshot;
|
|
274
|
+
}
|
|
275
|
+
/** Current expected sequence number */
|
|
276
|
+
expectedSequence() {
|
|
277
|
+
return this.expectedSeq;
|
|
278
|
+
}
|
|
279
|
+
/** Last update timestamp */
|
|
280
|
+
lastTimestamp() {
|
|
281
|
+
return this._lastTimestamp;
|
|
282
|
+
}
|
|
283
|
+
/** Clear the orderbook state (for resync) */
|
|
284
|
+
clear() {
|
|
285
|
+
this.bids.clear();
|
|
286
|
+
this.asks.clear();
|
|
287
|
+
this.expectedSeq = 0;
|
|
288
|
+
this._hasSnapshot = false;
|
|
289
|
+
this._lastTimestamp = undefined;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
exports.LocalOrderbook = LocalOrderbook;
|
|
293
|
+
//# sourceMappingURL=orderbook.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orderbook.js","sourceRoot":"","sources":["../../../src/websocket/state/orderbook.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;;;;AAEH,4DAAiC;AACjC,oCAA0C;AAE1C,8CAA4C;AAE5C;;GAEG;AACH,MAAa,cAAc;IACzB,0DAA0D;IAClD,MAAM,CAAU,UAAU,GAAG,IAAI,CAAC;IAE1C,2BAA2B;IAClB,WAAW,CAAS;IAC7B,+CAA+C;IACvC,IAAI,GAAwB,IAAI,GAAG,EAAE,CAAC;IAC9C,+CAA+C;IACvC,IAAI,GAAwB,IAAI,GAAG,EAAE,CAAC;IAC9C,oCAAoC;IAC5B,WAAW,GAAW,CAAC,CAAC;IAChC,iDAAiD;IACzC,YAAY,GAAY,KAAK,CAAC;IACtC,4BAA4B;IACpB,cAAc,CAAU;IAEhC,YAAY,WAAmB;QAC7B,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;IACjC,CAAC;IAED;;OAEG;IACH,aAAa,CAAC,MAAsB;QAClC,2BAA2B;QAC3B,IAAI,OAAO,MAAM,CAAC,GAAG,KAAK,QAAQ,IAAI,MAAM,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;YACrF,OAAO,CAAC,IAAI,CAAC,wCAAwC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC;YACnE,OAAO;QACT,CAAC;QAED,uBAAuB;QACvB,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QAClB,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QAElB,0CAA0C;QAC1C,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;YAChC,IAAI,CAAC,IAAA,cAAM,EAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;gBACxB,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,cAAc,CAAC,UAAU,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;oBAC/E,SAAS,CAAC,iCAAiC;gBAC7C,CAAC;gBACD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;YACzC,CAAC;QACH,CAAC;QAED,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;YAChC,IAAI,CAAC,IAAA,cAAM,EAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;gBACxB,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,cAAc,CAAC,UAAU,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;oBAC/E,SAAS,CAAC,iCAAiC;gBAC7C,CAAC;gBACD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;YACzC,CAAC;QACH,CAAC;QAED,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC;QAClC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,IAAI,CAAC,cAAc,GAAG,MAAM,CAAC,SAAS,CAAC;IACzC,CAAC;IAED;;;;OAIG;IACH,UAAU,CAAC,MAAsB;QAC/B,2BAA2B;QAC3B,IAAI,OAAO,MAAM,CAAC,GAAG,KAAK,QAAQ,IAAI,MAAM,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;YACrF,OAAO,CAAC,IAAI,CAAC,qCAAqC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC;YAChE,OAAO;QACT,CAAC;QAED,wBAAwB;QACxB,IAAI,MAAM,CAAC,GAAG,KAAK,IAAI,CAAC,WAAW,EAAE,CAAC;YACpC,MAAM,sBAAc,CAAC,WAAW,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;QACjE,CAAC;QAED,2CAA2C;QAC3C,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;YAChC,IAAI,IAAA,cAAM,EAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;gBACvB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAChC,CAAC;iBAAM,CAAC;gBACN,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,cAAc,CAAC,UAAU,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;oBAC/E,SAAS,CAAC,iCAAiC;gBAC7C,CAAC;gBACD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;YACzC,CAAC;QACH,CAAC;QAED,2CAA2C;QAC3C,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;YAChC,IAAI,IAAA,cAAM,EAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;gBACvB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAChC,CAAC;iBAAM,CAAC;gBACN,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,cAAc,CAAC,UAAU,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;oBAC/E,SAAS,CAAC,iCAAiC;gBAC7C,CAAC;gBACD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;YACzC,CAAC;QACH,CAAC;QAED,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC;QAClC,IAAI,CAAC,cAAc,GAAG,MAAM,CAAC,SAAS,CAAC;IACzC,CAAC;IAED;;;;OAIG;IACH,WAAW,CAAC,MAAsB;QAChC,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;YACvB,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QAC7B,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;IAED;;OAEG;IACH,OAAO;QACL,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;QAChD,iDAAiD;QACjD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5D,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;YACrC,IAAI,EAAE,KAAK;YACX,KAAK;YACL,IAAI;SACL,CAAC,CAAC,CAAC;IACN,CAAC;IAED;;OAEG;IACH,OAAO;QACL,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;QAChD,+CAA+C;QAC/C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5D,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;YACrC,IAAI,EAAE,KAAK;YACX,KAAK;YACL,IAAI;SACL,CAAC,CAAC,CAAC;IACN,CAAC;IAED;;OAEG;IACH,UAAU,CAAC,CAAS;QAClB,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACpC,CAAC;IAED;;OAEG;IACH,UAAU,CAAC,CAAS;QAClB,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACpC,CAAC;IAED;;OAEG;IACH,OAAO;QACL,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;QAC5B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,SAAS,CAAC;QACxC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACvC,CAAC;IAED;;OAEG;IACH,OAAO;QACL,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;QAC5B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,SAAS,CAAC;QACxC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACvC,CAAC;IAED;;OAEG;IACH,MAAM;QACJ,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;QAC3B,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;QAC3B,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG;YAAE,OAAO,SAAS,CAAC;QAEnC,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,IAAI,oBAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YACrC,MAAM,QAAQ,GAAG,IAAI,oBAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YACrC,MAAM,MAAM,GAAG,QAAQ,CAAC,WAAW,CAAC,QAAQ,CAAC;gBAC3C,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC;gBAC1B,CAAC,CAAC,IAAI,oBAAO,CAAC,CAAC,CAAC,CAAC;YACnB,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAC3B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,SAAS,CAAC;QACnB,CAAC;IACH,CAAC;IAED;;OAEG;IACH,QAAQ;QACN,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;QAC3B,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;QAC3B,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG;YAAE,OAAO,SAAS,CAAC;QAEnC,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,IAAI,oBAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YACrC,MAAM,QAAQ,GAAG,IAAI,oBAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YACrC,OAAO,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACzD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,SAAS,CAAC;QACnB,CAAC;IACH,CAAC;IAED;;OAEG;IACH,SAAS,CAAC,KAAa;QACrB,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC;IAED;;OAEG;IACH,SAAS,CAAC,KAAa;QACrB,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC;IAED;;OAEG;IACH,aAAa;QACX,IAAI,KAAK,GAAG,IAAI,oBAAO,CAAC,CAAC,CAAC,CAAC;QAC3B,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;YACtC,IAAI,CAAC;gBACH,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,oBAAO,CAAC,IAAI,CAAC,CAAC,CAAC;YACxC,CAAC;YAAC,MAAM,CAAC;gBACP,0BAA0B;YAC5B,CAAC;QACH,CAAC;QACD,OAAO,KAAK,CAAC,QAAQ,EAAE,CAAC;IAC1B,CAAC;IAED;;OAEG;IACH,aAAa;QACX,IAAI,KAAK,GAAG,IAAI,oBAAO,CAAC,CAAC,CAAC,CAAC;QAC3B,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;YACtC,IAAI,CAAC;gBACH,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,oBAAO,CAAC,IAAI,CAAC,CAAC,CAAC;YACxC,CAAC;YAAC,MAAM,CAAC;gBACP,0BAA0B;YAC5B,CAAC;QACH,CAAC;QACD,OAAO,KAAK,CAAC,QAAQ,EAAE,CAAC;IAC1B,CAAC;IAED,2BAA2B;IAC3B,QAAQ;QACN,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;IACxB,CAAC;IAED,2BAA2B;IAC3B,QAAQ;QACN,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;IACxB,CAAC;IAED,8DAA8D;IAC9D,WAAW;QACT,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;IAED,uCAAuC;IACvC,gBAAgB;QACd,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAED,4BAA4B;IAC5B,aAAa;QACX,OAAO,IAAI,CAAC,cAAc,CAAC;IAC7B,CAAC;IAED,6CAA6C;IAC7C,KAAK;QACH,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QAClB,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QAClB,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC;QACrB,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;QAC1B,IAAI,CAAC,cAAc,GAAG,SAAS,CAAC;IAClC,CAAC;;AAlSH,wCAmSC","sourcesContent":["/**\n * Local orderbook state management.\n *\n * Maintains a local copy of the orderbook state, applying deltas from\n * WebSocket updates.\n *\n * Note: Internally uses string keys/values to match the string-based API.\n * For numeric comparisons, parse the strings as needed.\n */\n\nimport Decimal from \"decimal.js\";\nimport { WebSocketError } from \"../error\";\nimport type { BookUpdateData, PriceLevel } from \"../types\";\nimport { isZero } from \"../../shared/price\";\n\n/**\n * Local orderbook state.\n */\nexport class LocalOrderbook {\n /** Maximum number of price levels to maintain per side */\n private static readonly MAX_LEVELS = 1000;\n\n /** Orderbook identifier */\n readonly orderbookId: string;\n /** Bid levels (price string -> size string) */\n private bids: Map<string, string> = new Map();\n /** Ask levels (price string -> size string) */\n private asks: Map<string, string> = new Map();\n /** Expected next sequence number */\n private expectedSeq: number = 0;\n /** Whether initial snapshot has been received */\n private _hasSnapshot: boolean = false;\n /** Last update timestamp */\n private _lastTimestamp?: string;\n\n constructor(orderbookId: string) {\n this.orderbookId = orderbookId;\n }\n\n /**\n * Apply a snapshot (full orderbook state).\n */\n applySnapshot(update: BookUpdateData): void {\n // Validate sequence number\n if (typeof update.seq !== 'number' || update.seq < 0 || !Number.isFinite(update.seq)) {\n console.warn(`Invalid sequence number in snapshot: ${update.seq}`);\n return;\n }\n\n // Clear existing state\n this.bids.clear();\n this.asks.clear();\n\n // Apply all levels (respecting max depth)\n for (const level of update.bids) {\n if (!isZero(level.size)) {\n if (this.bids.size >= LocalOrderbook.MAX_LEVELS && !this.bids.has(level.price)) {\n continue; // Skip if at limit and new level\n }\n this.bids.set(level.price, level.size);\n }\n }\n\n for (const level of update.asks) {\n if (!isZero(level.size)) {\n if (this.asks.size >= LocalOrderbook.MAX_LEVELS && !this.asks.has(level.price)) {\n continue; // Skip if at limit and new level\n }\n this.asks.set(level.price, level.size);\n }\n }\n\n this.expectedSeq = update.seq + 1;\n this._hasSnapshot = true;\n this._lastTimestamp = update.timestamp;\n }\n\n /**\n * Apply a delta update.\n *\n * @throws {WebSocketError} If a sequence gap is detected\n */\n applyDelta(update: BookUpdateData): void {\n // Validate sequence number\n if (typeof update.seq !== 'number' || update.seq < 0 || !Number.isFinite(update.seq)) {\n console.warn(`Invalid sequence number in delta: ${update.seq}`);\n return;\n }\n\n // Check sequence number\n if (update.seq !== this.expectedSeq) {\n throw WebSocketError.sequenceGap(this.expectedSeq, update.seq);\n }\n\n // Apply bid updates (respecting max depth)\n for (const level of update.bids) {\n if (isZero(level.size)) {\n this.bids.delete(level.price);\n } else {\n if (this.bids.size >= LocalOrderbook.MAX_LEVELS && !this.bids.has(level.price)) {\n continue; // Skip if at limit and new level\n }\n this.bids.set(level.price, level.size);\n }\n }\n\n // Apply ask updates (respecting max depth)\n for (const level of update.asks) {\n if (isZero(level.size)) {\n this.asks.delete(level.price);\n } else {\n if (this.asks.size >= LocalOrderbook.MAX_LEVELS && !this.asks.has(level.price)) {\n continue; // Skip if at limit and new level\n }\n this.asks.set(level.price, level.size);\n }\n }\n\n this.expectedSeq = update.seq + 1;\n this._lastTimestamp = update.timestamp;\n }\n\n /**\n * Apply an update (snapshot or delta).\n *\n * @throws {WebSocketError} If a sequence gap is detected\n */\n applyUpdate(update: BookUpdateData): void {\n if (update.is_snapshot) {\n this.applySnapshot(update);\n } else {\n this.applyDelta(update);\n }\n }\n\n /**\n * Get all bid levels sorted by price (descending).\n */\n getBids(): PriceLevel[] {\n const entries = Array.from(this.bids.entries());\n // Sort by price descending (higher prices first)\n entries.sort((a, b) => parseFloat(b[0]) - parseFloat(a[0]));\n return entries.map(([price, size]) => ({\n side: \"bid\",\n price,\n size,\n }));\n }\n\n /**\n * Get all ask levels sorted by price (ascending).\n */\n getAsks(): PriceLevel[] {\n const entries = Array.from(this.asks.entries());\n // Sort by price ascending (lower prices first)\n entries.sort((a, b) => parseFloat(a[0]) - parseFloat(b[0]));\n return entries.map(([price, size]) => ({\n side: \"ask\",\n price,\n size,\n }));\n }\n\n /**\n * Get top N bid levels.\n */\n getTopBids(n: number): PriceLevel[] {\n return this.getBids().slice(0, n);\n }\n\n /**\n * Get top N ask levels.\n */\n getTopAsks(n: number): PriceLevel[] {\n return this.getAsks().slice(0, n);\n }\n\n /**\n * Get the best bid (highest bid price) as [price, size].\n */\n bestBid(): [string, string] | undefined {\n const bids = this.getBids();\n if (bids.length === 0) return undefined;\n return [bids[0].price, bids[0].size];\n }\n\n /**\n * Get the best ask (lowest ask price) as [price, size].\n */\n bestAsk(): [string, string] | undefined {\n const asks = this.getAsks();\n if (asks.length === 0) return undefined;\n return [asks[0].price, asks[0].size];\n }\n\n /**\n * Get the spread as a string (best_ask - best_bid).\n */\n spread(): string | undefined {\n const bid = this.bestBid();\n const ask = this.bestAsk();\n if (!bid || !ask) return undefined;\n\n try {\n const bidPrice = new Decimal(bid[0]);\n const askPrice = new Decimal(ask[0]);\n const spread = askPrice.greaterThan(bidPrice)\n ? askPrice.minus(bidPrice)\n : new Decimal(0);\n return spread.toFixed(6);\n } catch {\n return undefined;\n }\n }\n\n /**\n * Get the midpoint price as a string.\n */\n midpoint(): string | undefined {\n const bid = this.bestBid();\n const ask = this.bestAsk();\n if (!bid || !ask) return undefined;\n\n try {\n const bidPrice = new Decimal(bid[0]);\n const askPrice = new Decimal(ask[0]);\n return bidPrice.plus(askPrice).dividedBy(2).toFixed(6);\n } catch {\n return undefined;\n }\n }\n\n /**\n * Get size at a specific bid price.\n */\n bidSizeAt(price: string): string | undefined {\n return this.bids.get(price);\n }\n\n /**\n * Get size at a specific ask price.\n */\n askSizeAt(price: string): string | undefined {\n return this.asks.get(price);\n }\n\n /**\n * Get total bid depth (sum of all bid sizes).\n */\n totalBidDepth(): number {\n let total = new Decimal(0);\n for (const size of this.bids.values()) {\n try {\n total = total.plus(new Decimal(size));\n } catch {\n // skip unparseable values\n }\n }\n return total.toNumber();\n }\n\n /**\n * Get total ask depth (sum of all ask sizes).\n */\n totalAskDepth(): number {\n let total = new Decimal(0);\n for (const size of this.asks.values()) {\n try {\n total = total.plus(new Decimal(size));\n } catch {\n // skip unparseable values\n }\n }\n return total.toNumber();\n }\n\n /** Number of bid levels */\n bidCount(): number {\n return this.bids.size;\n }\n\n /** Number of ask levels */\n askCount(): number {\n return this.asks.size;\n }\n\n /** Whether the orderbook has received its initial snapshot */\n hasSnapshot(): boolean {\n return this._hasSnapshot;\n }\n\n /** Current expected sequence number */\n expectedSequence(): number {\n return this.expectedSeq;\n }\n\n /** Last update timestamp */\n lastTimestamp(): string | undefined {\n return this._lastTimestamp;\n }\n\n /** Clear the orderbook state (for resync) */\n clear(): void {\n this.bids.clear();\n this.asks.clear();\n this.expectedSeq = 0;\n this._hasSnapshot = false;\n this._lastTimestamp = undefined;\n }\n}\n"]}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Price history state management.
|
|
3
|
+
*
|
|
4
|
+
* Maintains local state for price history candles.
|
|
5
|
+
*/
|
|
6
|
+
import { Resolution } from "../../shared";
|
|
7
|
+
import type { Candle, PriceHistoryData } from "../types";
|
|
8
|
+
/**
|
|
9
|
+
* Key for price history subscriptions.
|
|
10
|
+
*/
|
|
11
|
+
export declare class PriceHistoryKey {
|
|
12
|
+
readonly orderbookId: string;
|
|
13
|
+
readonly resolution: string;
|
|
14
|
+
constructor(orderbookId: string, resolution: string);
|
|
15
|
+
toString(): string;
|
|
16
|
+
equals(other: PriceHistoryKey): boolean;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Price history state for a single orderbook/resolution pair.
|
|
20
|
+
*/
|
|
21
|
+
export declare class PriceHistory {
|
|
22
|
+
/** Maximum number of candles to maintain */
|
|
23
|
+
private static readonly MAX_CANDLES;
|
|
24
|
+
/** Orderbook identifier */
|
|
25
|
+
readonly orderbookId: string;
|
|
26
|
+
/** Resolution (1m, 5m, 15m, 1h, 4h, 1d) */
|
|
27
|
+
readonly resolution: string;
|
|
28
|
+
/** Whether OHLCV data is included */
|
|
29
|
+
includeOhlcv: boolean;
|
|
30
|
+
/** Candles sorted by timestamp (newest first) */
|
|
31
|
+
private _candles;
|
|
32
|
+
/** Index by timestamp for fast lookup */
|
|
33
|
+
private candleIndex;
|
|
34
|
+
/** Last server timestamp */
|
|
35
|
+
private _lastTimestamp?;
|
|
36
|
+
/** Server time from last message */
|
|
37
|
+
private _serverTime?;
|
|
38
|
+
/** Whether initial snapshot has been received */
|
|
39
|
+
private _hasSnapshot;
|
|
40
|
+
constructor(orderbookId: string, resolution: string, includeOhlcv: boolean);
|
|
41
|
+
/**
|
|
42
|
+
* Apply a snapshot (historical candles).
|
|
43
|
+
*/
|
|
44
|
+
applySnapshot(data: PriceHistoryData): void;
|
|
45
|
+
/**
|
|
46
|
+
* Apply an update (new or updated candle).
|
|
47
|
+
*/
|
|
48
|
+
applyUpdate(data: PriceHistoryData): void;
|
|
49
|
+
/**
|
|
50
|
+
* Update an existing candle or append a new one.
|
|
51
|
+
*/
|
|
52
|
+
private updateOrAppendCandle;
|
|
53
|
+
/**
|
|
54
|
+
* Handle heartbeat (update server time).
|
|
55
|
+
*/
|
|
56
|
+
applyHeartbeat(data: PriceHistoryData): void;
|
|
57
|
+
/**
|
|
58
|
+
* Apply any price history event.
|
|
59
|
+
*/
|
|
60
|
+
applyEvent(data: PriceHistoryData): void;
|
|
61
|
+
/**
|
|
62
|
+
* Get all candles (newest first).
|
|
63
|
+
*/
|
|
64
|
+
candles(): Candle[];
|
|
65
|
+
/**
|
|
66
|
+
* Get the N most recent candles.
|
|
67
|
+
*/
|
|
68
|
+
recentCandles(n: number): Candle[];
|
|
69
|
+
/**
|
|
70
|
+
* Get a candle by timestamp.
|
|
71
|
+
*/
|
|
72
|
+
getCandle(timestamp: number): Candle | undefined;
|
|
73
|
+
/**
|
|
74
|
+
* Get the most recent candle.
|
|
75
|
+
*/
|
|
76
|
+
latestCandle(): Candle | undefined;
|
|
77
|
+
/**
|
|
78
|
+
* Get the oldest candle.
|
|
79
|
+
*/
|
|
80
|
+
oldestCandle(): Candle | undefined;
|
|
81
|
+
/**
|
|
82
|
+
* Get current midpoint price (from most recent candle).
|
|
83
|
+
*/
|
|
84
|
+
currentMidpoint(): string | undefined;
|
|
85
|
+
/**
|
|
86
|
+
* Get current best bid (from most recent candle).
|
|
87
|
+
*/
|
|
88
|
+
currentBestBid(): string | undefined;
|
|
89
|
+
/**
|
|
90
|
+
* Get current best ask (from most recent candle).
|
|
91
|
+
*/
|
|
92
|
+
currentBestAsk(): string | undefined;
|
|
93
|
+
/** Number of candles */
|
|
94
|
+
candleCount(): number;
|
|
95
|
+
/** Whether the price history has received its initial snapshot */
|
|
96
|
+
hasSnapshot(): boolean;
|
|
97
|
+
/** Last candle timestamp */
|
|
98
|
+
lastTimestamp(): number | undefined;
|
|
99
|
+
/** Server time from last message */
|
|
100
|
+
serverTime(): number | undefined;
|
|
101
|
+
/**
|
|
102
|
+
* Get resolution as enum.
|
|
103
|
+
*/
|
|
104
|
+
resolutionEnum(): Resolution | undefined;
|
|
105
|
+
/** Clear the price history (for disconnect/resync) */
|
|
106
|
+
clear(): void;
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=price.d.ts.map
|