@imbingox/acex 0.1.0 → 0.3.0-beta.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.
Files changed (85) hide show
  1. package/README.md +96 -285
  2. package/index.ts +1 -0
  3. package/package.json +40 -23
  4. package/src/adapters/binance/adapter.ts +80 -0
  5. package/src/adapters/binance/book-ticker.ts +123 -0
  6. package/src/adapters/binance/mark-price.ts +126 -0
  7. package/src/adapters/binance/market-catalog.ts +258 -0
  8. package/src/adapters/binance/private-adapter.ts +833 -0
  9. package/src/adapters/types.ts +219 -0
  10. package/src/client/context.ts +123 -0
  11. package/src/client/create-client.ts +6 -0
  12. package/src/client/private-subscription-coordinator.ts +512 -0
  13. package/src/client/runtime.ts +410 -0
  14. package/src/errors.ts +27 -0
  15. package/src/index.ts +5 -0
  16. package/src/internal/async-event-bus.ts +100 -0
  17. package/src/internal/filters.ts +117 -0
  18. package/src/internal/managed-websocket.ts +280 -0
  19. package/src/managers/account-manager.ts +609 -0
  20. package/src/managers/market-manager.ts +912 -0
  21. package/src/managers/order-manager.ts +685 -0
  22. package/src/types/account.ts +157 -0
  23. package/src/types/client.ts +79 -0
  24. package/src/types/index.ts +5 -0
  25. package/src/types/market.ts +152 -0
  26. package/src/types/order.ts +177 -0
  27. package/src/types/shared.ts +93 -0
  28. package/dist/adapters/binance/composite-adapter.d.ts +0 -116
  29. package/dist/adapters/binance/composite-adapter.js +0 -121
  30. package/dist/adapters/binance/market-types.d.ts +0 -63
  31. package/dist/adapters/binance/market-types.js +0 -1
  32. package/dist/adapters/binance/native-market-adapter.d.ts +0 -102
  33. package/dist/adapters/binance/native-market-adapter.js +0 -455
  34. package/dist/adapters/binance/normalizers.d.ts +0 -8
  35. package/dist/adapters/binance/normalizers.js +0 -123
  36. package/dist/adapters/binance/rest-client.d.ts +0 -17
  37. package/dist/adapters/binance/rest-client.js +0 -66
  38. package/dist/adapters/binance/symbol-router.d.ts +0 -9
  39. package/dist/adapters/binance/symbol-router.js +0 -174
  40. package/dist/adapters/binance/ws-client.d.ts +0 -24
  41. package/dist/adapters/binance/ws-client.js +0 -261
  42. package/dist/adapters/ccxt/aster-ccxt-adapter.d.ts +0 -157
  43. package/dist/adapters/ccxt/aster-ccxt-adapter.js +0 -272
  44. package/dist/adapters/ccxt/binance-usdm-ccxt-adapter.d.ts +0 -180
  45. package/dist/adapters/ccxt/binance-usdm-ccxt-adapter.js +0 -539
  46. package/dist/adapters/ccxt/binance-usdm-exchange.d.ts +0 -22
  47. package/dist/adapters/ccxt/binance-usdm-exchange.js +0 -23
  48. package/dist/adapters/fake/fake-aster-adapter.d.ts +0 -130
  49. package/dist/adapters/fake/fake-aster-adapter.js +0 -283
  50. package/dist/adapters/types.d.ts +0 -210
  51. package/dist/adapters/types.js +0 -1
  52. package/dist/core/client.d.ts +0 -50
  53. package/dist/core/client.js +0 -403
  54. package/dist/core/recovery.d.ts +0 -22
  55. package/dist/core/recovery.js +0 -18
  56. package/dist/core/runtime.d.ts +0 -26
  57. package/dist/core/runtime.js +0 -150
  58. package/dist/errors/acex-error.d.ts +0 -25
  59. package/dist/errors/acex-error.js +0 -54
  60. package/dist/index.d.ts +0 -6
  61. package/dist/index.js +0 -3
  62. package/dist/managers/account-manager.d.ts +0 -41
  63. package/dist/managers/account-manager.js +0 -80
  64. package/dist/managers/market-manager.d.ts +0 -16
  65. package/dist/managers/market-manager.js +0 -28
  66. package/dist/managers/order-manager.d.ts +0 -87
  67. package/dist/managers/order-manager.js +0 -122
  68. package/dist/runtime/async-queue.d.ts +0 -8
  69. package/dist/runtime/async-queue.js +0 -88
  70. package/dist/runtime/request-id.d.ts +0 -1
  71. package/dist/runtime/request-id.js +0 -5
  72. package/dist/runtime/ws-connection-supervisor.d.ts +0 -76
  73. package/dist/runtime/ws-connection-supervisor.js +0 -522
  74. package/dist/store/account-store.d.ts +0 -52
  75. package/dist/store/account-store.js +0 -18
  76. package/dist/store/health-store.d.ts +0 -16
  77. package/dist/store/health-store.js +0 -29
  78. package/dist/store/market-store.d.ts +0 -42
  79. package/dist/store/market-store.js +0 -51
  80. package/dist/store/order-store.d.ts +0 -38
  81. package/dist/store/order-store.js +0 -49
  82. package/dist/testing/create-fake-runtime.d.ts +0 -5
  83. package/dist/testing/create-fake-runtime.js +0 -7
  84. package/dist/types/public.d.ts +0 -5
  85. package/dist/types/public.js +0 -1
@@ -1,272 +0,0 @@
1
- import { createAsyncQueue } from "../../runtime/async-queue.js";
2
- export class CcxtAsterAdapter {
3
- exchange = "aster";
4
- capabilities = {
5
- publicWs: true,
6
- privateWs: true,
7
- l1BookStream: true,
8
- fundingRateStream: false,
9
- accountStream: true,
10
- orderStream: true,
11
- fetchMarketInfo: true,
12
- fetchBalances: true,
13
- fetchPositions: false,
14
- fetchRisk: false,
15
- fetchOpenOrders: true,
16
- fetchMyTrades: false,
17
- fetchOrderById: false,
18
- };
19
- #exchange;
20
- #started = false;
21
- #marketQueue = createAsyncQueue({ maxBufferSize: 100 });
22
- #marketEventSink;
23
- #internalErrorQueue = createAsyncQueue({ maxBufferSize: 20 });
24
- #orderQueue = createAsyncQueue({ maxBufferSize: 100 });
25
- #orderEventSink;
26
- #accountQueue = createAsyncQueue({ maxBufferSize: 100 });
27
- #accountEventSink;
28
- constructor(input) {
29
- this.#exchange = input.exchange;
30
- }
31
- async start() {
32
- this.#started = true;
33
- }
34
- async stop() {
35
- this.#started = false;
36
- this.#marketQueue.close();
37
- this.#internalErrorQueue.close();
38
- this.#orderQueue.close();
39
- this.#accountQueue.close();
40
- }
41
- async subscribeL1Book(input) {
42
- try {
43
- const snapshot = await this.mapTickerToL1(input.symbol);
44
- this.#emitMarketEvent({
45
- type: "l1_book.updated",
46
- exchange: snapshot.exchange,
47
- symbol: snapshot.symbol,
48
- bidPrice: snapshot.bidPrice,
49
- bidSize: snapshot.bidSize,
50
- askPrice: snapshot.askPrice,
51
- askSize: snapshot.askSize,
52
- ...(snapshot.exchangeTs === undefined ? {} : { exchangeTs: snapshot.exchangeTs }),
53
- receivedAt: snapshot.receivedAt,
54
- });
55
- }
56
- catch (error) {
57
- this.#emitInternalError(asError(error));
58
- throw error;
59
- }
60
- }
61
- async subscribeFundingRate() { }
62
- watchMarketEvents() {
63
- return this.#marketQueue;
64
- }
65
- setMarketEventSink(sink) {
66
- this.#marketEventSink = sink;
67
- }
68
- watchInternalErrors() {
69
- return this.#internalErrorQueue;
70
- }
71
- async subscribeOrders() { }
72
- watchOrderEvents() {
73
- return this.#orderQueue;
74
- }
75
- setOrderEventSink(sink) {
76
- this.#orderEventSink = sink;
77
- }
78
- watchAccountEvents() {
79
- return this.#accountQueue;
80
- }
81
- setAccountEventSink(sink) {
82
- this.#accountEventSink = sink;
83
- }
84
- async mapTickerToL1(symbol) {
85
- const ticker = await this.#exchange.watchTicker(symbol);
86
- if (ticker.bid === undefined ||
87
- ticker.bidVolume === undefined ||
88
- ticker.ask === undefined ||
89
- ticker.askVolume === undefined) {
90
- throw new Error("missing required ticker fields");
91
- }
92
- return {
93
- exchange: this.exchange,
94
- symbol: ticker.symbol,
95
- bidPrice: String(ticker.bid),
96
- bidSize: String(ticker.bidVolume),
97
- askPrice: String(ticker.ask),
98
- askSize: String(ticker.askVolume),
99
- ...(ticker.timestamp === undefined ? {} : { exchangeTs: ticker.timestamp }),
100
- receivedAt: Date.now(),
101
- };
102
- }
103
- async fetchMarketInfo() {
104
- const markets = await this.#exchange.fetchMarkets();
105
- return markets.map((market) => {
106
- return {
107
- exchange: this.exchange,
108
- symbol: market.symbol,
109
- baseAsset: market.base,
110
- quoteAsset: market.quote,
111
- marketType: market.type,
112
- pricePrecision: market.precision.price,
113
- amountPrecision: market.precision.amount,
114
- active: market.active,
115
- };
116
- });
117
- }
118
- async fetchAccountBaseline(accountId) {
119
- const balance = await this.#exchange.fetchBalance();
120
- const assets = new Set([
121
- ...Object.keys(balance.free ?? {}),
122
- ...Object.keys(balance.used ?? {}),
123
- ...Object.keys(balance.total ?? {}),
124
- ]);
125
- const now = Date.now();
126
- const balances = Object.fromEntries([...assets].map((asset) => {
127
- return [
128
- asset,
129
- {
130
- accountId,
131
- exchange: this.exchange,
132
- asset,
133
- free: valueToString(balance.free?.[asset]),
134
- used: valueToString(balance.used?.[asset]),
135
- total: valueToString(balance.total?.[asset]),
136
- seq: 0,
137
- receivedAt: now,
138
- updatedAt: now,
139
- },
140
- ];
141
- }));
142
- return {
143
- balances,
144
- positions: [],
145
- };
146
- }
147
- async fetchOpenOrdersBaseline(accountId) {
148
- const orders = await this.#exchange.fetchOpenOrders();
149
- const now = Date.now();
150
- return orders.map((order) => {
151
- const symbol = requiredString(order.symbol, "symbol");
152
- const side = requiredOrderSide(order.side);
153
- const type = requiredString(order.type, "type");
154
- const status = requiredString(order.status, "status");
155
- const amount = valueToRequiredString(order.amount, "amount");
156
- const filled = valueToRequiredString(order.filled, "filled");
157
- const updatedAt = order.timestamp ?? now;
158
- return {
159
- accountId,
160
- exchange: this.exchange,
161
- symbol,
162
- side,
163
- type,
164
- status,
165
- amount,
166
- filled,
167
- ...(order.price === undefined ? {} : { price: String(order.price) }),
168
- seq: 0,
169
- receivedAt: now,
170
- updatedAt,
171
- ...(order.id === undefined ? {} : { orderId: order.id }),
172
- ...(order.clientOrderId === undefined ? {} : { clientOrderId: order.clientOrderId }),
173
- };
174
- });
175
- }
176
- async placeOrder(input) {
177
- const amount = parseFiniteNumber(input.amount, "amount");
178
- const price = input.price === undefined ? undefined : parseFiniteNumber(input.price, "price");
179
- const order = await this.#exchange.createOrder(input.symbol, input.type, input.side, amount, price, {
180
- clientOrderId: input.clientOrderId,
181
- });
182
- return {
183
- ...(order.clientOrderId === undefined
184
- ? { clientOrderId: input.clientOrderId }
185
- : { clientOrderId: order.clientOrderId }),
186
- ...(order.id === undefined ? {} : { orderId: order.id }),
187
- receivedAt: Date.now(),
188
- };
189
- }
190
- async amendOrder(input) {
191
- return {
192
- ...(input.clientOrderId === undefined ? {} : { clientOrderId: input.clientOrderId }),
193
- ...(input.orderId === undefined ? {} : { orderId: input.orderId }),
194
- receivedAt: Date.now(),
195
- };
196
- }
197
- async cancelOrder(input) {
198
- if (input.orderId === undefined && input.clientOrderId === undefined) {
199
- return { receivedAt: Date.now() };
200
- }
201
- const order = await this.#exchange.cancelOrder(input.orderId, undefined, {
202
- ...(input.clientOrderId === undefined ? {} : { clientOrderId: input.clientOrderId }),
203
- });
204
- return {
205
- ...(order.clientOrderId === undefined
206
- ? input.clientOrderId === undefined
207
- ? {}
208
- : { clientOrderId: input.clientOrderId }
209
- : { clientOrderId: order.clientOrderId }),
210
- ...(order.id === undefined ? {} : { orderId: order.id }),
211
- receivedAt: Date.now(),
212
- };
213
- }
214
- async cancelAllOrders(input) {
215
- return {
216
- accountId: input.accountId,
217
- exchange: input.exchange,
218
- canceledCount: 0,
219
- };
220
- }
221
- getHealth() {
222
- return {
223
- exchange: this.exchange,
224
- status: this.#started ? "healthy" : "idle",
225
- wsConnected: this.#started,
226
- };
227
- }
228
- #emitMarketEvent(event) {
229
- if (this.#marketEventSink !== undefined) {
230
- this.#marketEventSink(event);
231
- return;
232
- }
233
- this.#marketQueue.push(event);
234
- }
235
- #emitInternalError(error) {
236
- this.#internalErrorQueue.push(error);
237
- }
238
- }
239
- function asError(error) {
240
- return error instanceof Error ? error : new Error(String(error));
241
- }
242
- function requiredString(value, field) {
243
- if (value === undefined || value.trim().length === 0) {
244
- throw new Error(`missing required order fields: ${field}`);
245
- }
246
- return value;
247
- }
248
- function requiredOrderSide(value) {
249
- if (value !== "buy" && value !== "sell") {
250
- throw new Error("missing required order fields: side");
251
- }
252
- return value;
253
- }
254
- function valueToRequiredString(value, field) {
255
- if (value === undefined) {
256
- throw new Error(`missing required order fields: ${field}`);
257
- }
258
- return String(value);
259
- }
260
- function valueToString(value) {
261
- return value === undefined ? "0" : String(value);
262
- }
263
- function parseFiniteNumber(value, field) {
264
- if (value.trim().length === 0) {
265
- throw new Error(`invalid order ${field}`);
266
- }
267
- const parsed = Number(value);
268
- if (!Number.isFinite(parsed)) {
269
- throw new Error(`invalid order ${field}`);
270
- }
271
- return parsed;
272
- }
@@ -1,180 +0,0 @@
1
- import type { AdapterAccountBaseline, ExchangeAdapter, ExchangeCapabilities, NormalizedAccountEvent, NormalizedMarketEvent, NormalizedOrderEvent } from "../types.js";
2
- interface CcxtTickerLike {
3
- symbol: string;
4
- bid?: number | string;
5
- bidVolume?: number | string;
6
- ask?: number | string;
7
- askVolume?: number | string;
8
- timestamp?: number;
9
- }
10
- type CcxtBidAskMap = Record<string, CcxtTickerLike | undefined>;
11
- interface CcxtMarketLike {
12
- symbol: string;
13
- base: string;
14
- quote: string;
15
- type: string;
16
- precision: {
17
- price: number;
18
- amount: number;
19
- };
20
- active: boolean;
21
- }
22
- interface CcxtBalanceLike {
23
- free?: Record<string, number | string | undefined>;
24
- used?: Record<string, number | string | undefined>;
25
- total?: Record<string, number | string | undefined>;
26
- info?: {
27
- totalWalletBalance?: number | string;
28
- };
29
- }
30
- interface CcxtPositionLike {
31
- symbol?: string;
32
- side?: string;
33
- contracts?: number | string;
34
- amount?: number | string;
35
- positionAmt?: number | string;
36
- timestamp?: number;
37
- }
38
- interface CcxtOrderLike {
39
- symbol?: string;
40
- side?: string;
41
- type?: string;
42
- status?: string;
43
- amount?: number | string;
44
- filled?: number | string;
45
- price?: number | string;
46
- timestamp?: number;
47
- id?: string;
48
- clientOrderId?: string;
49
- }
50
- interface CcxtCreateOrderResult {
51
- id?: string;
52
- clientOrderId?: string;
53
- }
54
- interface CcxtExchangeLike {
55
- watchBidsAsks(symbols?: string[]): Promise<CcxtBidAskMap>;
56
- fetchMarkets(): Promise<CcxtMarketLike[]>;
57
- fetchBalance(params?: Record<string, unknown>): Promise<CcxtBalanceLike>;
58
- fetchPositions(symbols: string[], params?: Record<string, unknown>): Promise<CcxtPositionLike[]>;
59
- fetchOpenOrders(symbol?: string, since?: number, limit?: number, params?: Record<string, unknown>): Promise<CcxtOrderLike[]>;
60
- createOrder(symbol: string, type: string, side: "buy" | "sell", amount: number, price?: number, params?: Record<string, unknown>): Promise<CcxtCreateOrderResult>;
61
- close?(): Promise<void>;
62
- }
63
- export interface CreateCcxtBinanceUsdMAdapterInput {
64
- exchange: CcxtExchangeLike;
65
- accountId?: string;
66
- }
67
- export declare class CcxtBinanceUsdMAdapter implements ExchangeAdapter {
68
- #private;
69
- readonly exchange = "binance";
70
- readonly capabilities: ExchangeCapabilities;
71
- constructor(input: CreateCcxtBinanceUsdMAdapterInput);
72
- start(): Promise<void>;
73
- stop(): Promise<void>;
74
- subscribeL1Book(input: {
75
- exchange: string;
76
- symbol: string;
77
- }): Promise<void>;
78
- subscribeFundingRate(_input: {
79
- exchange: string;
80
- symbol: string;
81
- }): Promise<void>;
82
- watchMarketEvents(): import("../../runtime/async-queue.js").AsyncQueue<NormalizedMarketEvent>;
83
- setMarketEventSink(sink: ((event: NormalizedMarketEvent) => void) | undefined): void;
84
- watchInternalErrors(): import("../../runtime/async-queue.js").AsyncQueue<Error>;
85
- subscribeOrders(_input: {
86
- accountId: string;
87
- }): Promise<void>;
88
- watchOrderEvents(): import("../../runtime/async-queue.js").AsyncQueue<NormalizedOrderEvent>;
89
- setOrderEventSink(sink: ((event: NormalizedOrderEvent) => void) | undefined): void;
90
- watchAccountEvents(): import("../../runtime/async-queue.js").AsyncQueue<NormalizedAccountEvent>;
91
- setAccountEventSink(sink: ((event: NormalizedAccountEvent) => void) | undefined): void;
92
- mapTickerToL1(symbol: string): Promise<{
93
- receivedAt: number;
94
- exchangeTs?: number;
95
- exchange: string;
96
- symbol: string;
97
- bidPrice: string;
98
- bidSize: string;
99
- askPrice: string;
100
- askSize: string;
101
- }>;
102
- fetchMarketInfo(): Promise<{
103
- exchange: string;
104
- symbol: string;
105
- baseAsset: string;
106
- quoteAsset: string;
107
- marketType: string;
108
- pricePrecision: number;
109
- amountPrecision: number;
110
- active: boolean;
111
- }[]>;
112
- fetchOpenOrdersBaseline(accountId: string): Promise<{
113
- clientOrderId?: string;
114
- orderId?: string;
115
- seq: number;
116
- receivedAt: number;
117
- updatedAt: number;
118
- price?: string;
119
- accountId: string;
120
- exchange: string;
121
- symbol: string;
122
- side: "buy" | "sell";
123
- type: string;
124
- status: string;
125
- amount: string;
126
- filled: string;
127
- }[]>;
128
- fetchAccountBaseline(accountId: string): Promise<AdapterAccountBaseline>;
129
- placeOrder(input: {
130
- accountId: string;
131
- exchange: string;
132
- symbol: string;
133
- side: "buy" | "sell";
134
- amount: string;
135
- clientOrderId: string;
136
- type: string;
137
- price?: string;
138
- reduceOnly?: boolean;
139
- }): Promise<{
140
- receivedAt: number;
141
- orderId?: string;
142
- clientOrderId: string;
143
- }>;
144
- amendOrder(input: {
145
- accountId: string;
146
- exchange: string;
147
- clientOrderId?: string;
148
- orderId?: string;
149
- symbol?: string;
150
- newPrice?: string;
151
- }): Promise<{
152
- receivedAt: number;
153
- orderId?: string;
154
- clientOrderId?: string;
155
- }>;
156
- cancelOrder(input: {
157
- accountId: string;
158
- exchange: string;
159
- clientOrderId?: string;
160
- orderId?: string;
161
- }): Promise<{
162
- receivedAt: number;
163
- orderId?: string;
164
- clientOrderId?: string;
165
- }>;
166
- cancelAllOrders(_input: {
167
- accountId: string;
168
- exchange: string;
169
- }): Promise<{
170
- accountId: string;
171
- exchange: string;
172
- canceledCount: number;
173
- }>;
174
- getHealth(): {
175
- exchange: string;
176
- status: string;
177
- wsConnected: boolean;
178
- };
179
- }
180
- export {};