@imbingox/acex 0.4.0-beta.1 → 0.4.0-beta.10
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 +4 -3
- package/docs/api.md +474 -1002
- package/package.json +1 -1
- package/src/adapters/binance/adapter.ts +19 -1
- package/src/adapters/binance/market-catalog.ts +83 -12
- package/src/adapters/binance/private-adapter.ts +302 -59
- package/src/adapters/binance/rate-limit.ts +47 -0
- package/src/adapters/binance/server-time.ts +106 -0
- package/src/adapters/juplend/private-adapter.ts +97 -68
- package/src/adapters/types.ts +25 -1
- package/src/client/context.ts +26 -9
- package/src/client/private-subscription-coordinator.ts +898 -63
- package/src/client/runtime.ts +49 -11
- package/src/client/venue-capabilities.ts +1 -0
- package/src/errors.ts +156 -2
- package/src/index.ts +8 -1
- package/src/internal/http-client.ts +608 -0
- package/src/internal/rate-limiter.ts +181 -0
- package/src/internal/watermark.ts +83 -0
- package/src/managers/account-manager.ts +227 -23
- package/src/managers/market-manager.ts +224 -34
- package/src/managers/order-manager.ts +791 -76
- package/src/types/client.ts +1 -0
- package/src/types/market.ts +25 -0
- package/src/types/order.ts +1 -0
- package/src/types/shared.ts +66 -0
package/package.json
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { SubscriptionMultiplexer } from "../../internal/subscription-multiplexer.ts";
|
|
2
2
|
import type {
|
|
3
3
|
MarketDefinition,
|
|
4
|
+
RateLimiter,
|
|
4
5
|
VenueMarketCapabilities,
|
|
6
|
+
VenueServerTime,
|
|
5
7
|
} from "../../types/index.ts";
|
|
6
8
|
import type {
|
|
7
9
|
FundingRateStreamCallbacks,
|
|
@@ -15,6 +17,7 @@ import {
|
|
|
15
17
|
type BinanceMarketDefinition,
|
|
16
18
|
loadBinanceMarkets,
|
|
17
19
|
} from "./market-catalog.ts";
|
|
20
|
+
import { fetchBinanceServerTime } from "./server-time.ts";
|
|
18
21
|
import {
|
|
19
22
|
type BinanceStreamDescriptor,
|
|
20
23
|
type BinanceStreamMessage,
|
|
@@ -44,6 +47,7 @@ export class BinanceMarketAdapter implements MarketAdapter {
|
|
|
44
47
|
readonly venue = "binance" as const;
|
|
45
48
|
readonly marketCapabilities: VenueMarketCapabilities = {
|
|
46
49
|
catalog: "supported",
|
|
50
|
+
serverTime: "supported",
|
|
47
51
|
l1Book: "supported",
|
|
48
52
|
fundingRate: "market_dependent",
|
|
49
53
|
marketTypes: ["spot", "swap", "future"],
|
|
@@ -53,8 +57,16 @@ export class BinanceMarketAdapter implements MarketAdapter {
|
|
|
53
57
|
private multiplexer: BinanceMarketMultiplexer | undefined;
|
|
54
58
|
private multiplexerConfig: BinanceMultiplexerConfig | undefined;
|
|
55
59
|
|
|
60
|
+
constructor(
|
|
61
|
+
private readonly options: {
|
|
62
|
+
readonly rateLimiter?: RateLimiter;
|
|
63
|
+
} = {},
|
|
64
|
+
) {}
|
|
65
|
+
|
|
56
66
|
async loadMarkets(): Promise<MarketDefinition[]> {
|
|
57
|
-
const markets = await loadBinanceMarkets(
|
|
67
|
+
const markets = await loadBinanceMarkets(fetch, {
|
|
68
|
+
rateLimiter: this.options.rateLimiter,
|
|
69
|
+
});
|
|
58
70
|
this.definitions.clear();
|
|
59
71
|
|
|
60
72
|
for (const market of markets) {
|
|
@@ -64,6 +76,12 @@ export class BinanceMarketAdapter implements MarketAdapter {
|
|
|
64
76
|
return markets;
|
|
65
77
|
}
|
|
66
78
|
|
|
79
|
+
async fetchServerTime(): Promise<VenueServerTime> {
|
|
80
|
+
return await fetchBinanceServerTime({
|
|
81
|
+
rateLimiter: this.options.rateLimiter,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
67
85
|
createL1BookStream(
|
|
68
86
|
market: MarketDefinition,
|
|
69
87
|
callbacks: L1BookStreamCallbacks,
|
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
import { toCanonical } from "../../internal/decimal.ts";
|
|
2
|
-
import
|
|
2
|
+
import {
|
|
3
|
+
type HttpClientMessages,
|
|
4
|
+
httpRequest,
|
|
5
|
+
isTransportError,
|
|
6
|
+
} from "../../internal/http-client.ts";
|
|
7
|
+
import type {
|
|
8
|
+
MarketDefinition,
|
|
9
|
+
MarketType,
|
|
10
|
+
RateLimiter,
|
|
11
|
+
RateLimitScope,
|
|
12
|
+
} from "../../types/index.ts";
|
|
13
|
+
import { parseBinanceRateLimitUsage } from "./rate-limit.ts";
|
|
3
14
|
|
|
4
15
|
type FetchLike = typeof fetch;
|
|
5
16
|
|
|
@@ -54,6 +65,11 @@ const BINANCE_USDM_EXCHANGE_INFO_URL =
|
|
|
54
65
|
"https://fapi.binance.com/fapi/v1/exchangeInfo";
|
|
55
66
|
const BINANCE_COINM_EXCHANGE_INFO_URL =
|
|
56
67
|
"https://dapi.binance.com/dapi/v1/exchangeInfo";
|
|
68
|
+
const DEFAULT_HTTP_TIMEOUT_MS = 10_000;
|
|
69
|
+
const BINANCE_CATALOG_HTTP_MESSAGES: HttpClientMessages = {
|
|
70
|
+
http: ({ status, statusText }) =>
|
|
71
|
+
`Binance request failed: ${status} ${statusText ?? ""}`,
|
|
72
|
+
};
|
|
57
73
|
|
|
58
74
|
function toRecord(value: unknown): Record<string, unknown> {
|
|
59
75
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
@@ -96,7 +112,9 @@ function inferContractType(
|
|
|
96
112
|
contractType: string | undefined,
|
|
97
113
|
deliveryDate: number | undefined,
|
|
98
114
|
): MarketType {
|
|
99
|
-
|
|
115
|
+
// Binance TradFi perpetuals expose a far-future deliveryDate, so the
|
|
116
|
+
// contractType is authoritative for perpetual classification.
|
|
117
|
+
if (contractType === "PERPETUAL" || contractType === "TRADIFI_PERPETUAL") {
|
|
100
118
|
return "swap";
|
|
101
119
|
}
|
|
102
120
|
|
|
@@ -212,15 +230,58 @@ function normalizeDerivativesSymbol(
|
|
|
212
230
|
};
|
|
213
231
|
}
|
|
214
232
|
|
|
215
|
-
async function
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
233
|
+
async function requestCatalogJson<T>(
|
|
234
|
+
fetchFn: FetchLike,
|
|
235
|
+
url: string,
|
|
236
|
+
rateLimiter: RateLimiter | undefined,
|
|
237
|
+
endpointKey: string,
|
|
238
|
+
): Promise<T> {
|
|
239
|
+
const scope: RateLimitScope = {
|
|
240
|
+
venue: "binance",
|
|
241
|
+
endpointKey,
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
await rateLimiter?.beforeRequest({ scope });
|
|
245
|
+
|
|
246
|
+
try {
|
|
247
|
+
const response = await httpRequest<T>({
|
|
248
|
+
fetchFn,
|
|
249
|
+
url,
|
|
250
|
+
timeoutMs: DEFAULT_HTTP_TIMEOUT_MS,
|
|
251
|
+
parseAs: "json",
|
|
252
|
+
jsonParseMode: "response",
|
|
253
|
+
retryPolicy: {
|
|
254
|
+
idempotent: true,
|
|
255
|
+
maxAttempts: 3,
|
|
256
|
+
},
|
|
257
|
+
messages: BINANCE_CATALOG_HTTP_MESSAGES,
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
await rateLimiter?.afterResponse(
|
|
261
|
+
{ scope },
|
|
262
|
+
{
|
|
263
|
+
status: response.status,
|
|
264
|
+
headers: response.headers,
|
|
265
|
+
usage: parseBinanceRateLimitUsage(response.headers),
|
|
266
|
+
},
|
|
220
267
|
);
|
|
221
|
-
}
|
|
222
268
|
|
|
223
|
-
|
|
269
|
+
return response.body;
|
|
270
|
+
} catch (error) {
|
|
271
|
+
if (isTransportError(error)) {
|
|
272
|
+
await rateLimiter?.onTransportError(
|
|
273
|
+
{ scope },
|
|
274
|
+
{
|
|
275
|
+
status: error.status,
|
|
276
|
+
headers: error.headers,
|
|
277
|
+
retryAfterMs: error.retryAfterMs,
|
|
278
|
+
usage: parseBinanceRateLimitUsage(error.headers),
|
|
279
|
+
},
|
|
280
|
+
);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
throw error;
|
|
284
|
+
}
|
|
224
285
|
}
|
|
225
286
|
|
|
226
287
|
function sortMarkets(
|
|
@@ -233,16 +294,26 @@ function sortMarkets(
|
|
|
233
294
|
|
|
234
295
|
export async function loadBinanceMarkets(
|
|
235
296
|
fetchFn: FetchLike = fetch,
|
|
297
|
+
options: { readonly rateLimiter?: RateLimiter } = {},
|
|
236
298
|
): Promise<BinanceMarketDefinition[]> {
|
|
237
299
|
const [spot, usdm, coinm] = await Promise.all([
|
|
238
|
-
|
|
239
|
-
|
|
300
|
+
requestCatalogJson<BinanceSpotExchangeInfo>(
|
|
301
|
+
fetchFn,
|
|
302
|
+
BINANCE_SPOT_EXCHANGE_INFO_URL,
|
|
303
|
+
options.rateLimiter,
|
|
304
|
+
"GET /api/v3/exchangeInfo",
|
|
305
|
+
),
|
|
306
|
+
requestCatalogJson<BinanceDerivativesExchangeInfo>(
|
|
240
307
|
fetchFn,
|
|
241
308
|
BINANCE_USDM_EXCHANGE_INFO_URL,
|
|
309
|
+
options.rateLimiter,
|
|
310
|
+
"GET /fapi/v1/exchangeInfo",
|
|
242
311
|
),
|
|
243
|
-
|
|
312
|
+
requestCatalogJson<BinanceDerivativesExchangeInfo>(
|
|
244
313
|
fetchFn,
|
|
245
314
|
BINANCE_COINM_EXCHANGE_INFO_URL,
|
|
315
|
+
options.rateLimiter,
|
|
316
|
+
"GET /dapi/v1/exchangeInfo",
|
|
246
317
|
),
|
|
247
318
|
]);
|
|
248
319
|
|