@imbingox/acex 0.3.1-beta.0 → 0.4.0-beta.2
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 +7 -7
- package/docs/api.md +66 -66
- package/package.json +1 -1
- package/src/adapters/binance/market-catalog.ts +42 -21
- package/src/adapters/binance/private-adapter.ts +78 -19
- package/src/adapters/juplend/private-adapter.ts +91 -55
- package/src/client/private-subscription-coordinator.ts +31 -7
- package/src/internal/decimal.ts +19 -0
- package/src/internal/http-client.ts +608 -0
- package/src/managers/account-manager.ts +40 -32
- package/src/managers/market-manager.ts +37 -26
- package/src/managers/order-manager.ts +7 -8
- package/src/types/account.ts +27 -28
- package/src/types/market.ts +12 -12
- package/src/types/order.ts +6 -7
package/README.md
CHANGED
|
@@ -30,7 +30,7 @@ const book = client.market.getL1Book({
|
|
|
30
30
|
symbol: "BTC/USDT:USDT",
|
|
31
31
|
});
|
|
32
32
|
const books = client.market.getL1Books("BTC/USDT:USDT");
|
|
33
|
-
console.log(`bid=${book?.bidPrice
|
|
33
|
+
console.log(`bid=${book?.bidPrice} ask=${book?.askPrice}`);
|
|
34
34
|
console.log(`venues=${books.length}`);
|
|
35
35
|
console.log(`book freshness=${book?.status.freshness}`);
|
|
36
36
|
|
|
@@ -44,14 +44,14 @@ const funding = client.market.getFundingRate({
|
|
|
44
44
|
symbol: "BTC/USDT:USDT",
|
|
45
45
|
});
|
|
46
46
|
const fundingRates = client.market.getFundingRates("BTC/USDT:USDT");
|
|
47
|
-
console.log(`funding=${funding?.fundingRate
|
|
47
|
+
console.log(`funding=${funding?.fundingRate}`);
|
|
48
48
|
console.log(`funding venues=${fundingRates.length}`);
|
|
49
49
|
|
|
50
50
|
for await (const event of client.market.events.l1BookUpdates({
|
|
51
51
|
venue: "binance",
|
|
52
52
|
symbol: "BTC/USDT:USDT",
|
|
53
53
|
})) {
|
|
54
|
-
console.log(event.snapshot.bidPrice
|
|
54
|
+
console.log(event.snapshot.bidPrice);
|
|
55
55
|
break;
|
|
56
56
|
}
|
|
57
57
|
|
|
@@ -113,11 +113,11 @@ const juplendRisk = client.account.getRiskSnapshot("jup-loop-a");
|
|
|
113
113
|
const juplendBalances = client.account.getBalances("jup-loop-a");
|
|
114
114
|
|
|
115
115
|
for (const balance of juplendBalances) {
|
|
116
|
-
console.log(balance.asset, balance.lending?.netAsset
|
|
116
|
+
console.log(balance.asset, balance.lending?.netAsset);
|
|
117
117
|
}
|
|
118
118
|
console.log({
|
|
119
|
-
binanceRiskRatio: binanceRisk?.riskRatio
|
|
120
|
-
juplendRiskRatio: juplendRisk?.riskRatio
|
|
119
|
+
binanceRiskRatio: binanceRisk?.riskRatio,
|
|
120
|
+
juplendRiskRatio: juplendRisk?.riskRatio,
|
|
121
121
|
});
|
|
122
122
|
|
|
123
123
|
await client.stop();
|
|
@@ -141,7 +141,7 @@ console.log(juplend.order.reason); // "read_only"
|
|
|
141
141
|
const capabilities = client.listVenueCapabilities();
|
|
142
142
|
```
|
|
143
143
|
|
|
144
|
-
|
|
144
|
+
价格、数量等公共输出字段统一是 canonical decimal string(无科学计数法、不补尾零);输入侧保持宽进严出,`createOrder()` 的 `price` / `amount` 是 decimal string,`DecimalInput` 仍接受 string / number / `BigNumber`。如需运算,使用 SDK re-export 的 `BigNumber`:`new BigNumber(field)`。详见手册 [§3 核心概念](./docs/api.md#3-核心概念)。
|
|
145
145
|
|
|
146
146
|
## 核心能力
|
|
147
147
|
|
package/docs/api.md
CHANGED
|
@@ -51,13 +51,13 @@ const book = client.market.getL1Book({
|
|
|
51
51
|
venue: "binance",
|
|
52
52
|
symbol: "BTC/USDT:USDT",
|
|
53
53
|
});
|
|
54
|
-
console.log(`bid=${book?.bidPrice
|
|
54
|
+
console.log(`bid=${book?.bidPrice} ask=${book?.askPrice}`);
|
|
55
55
|
|
|
56
56
|
for await (const event of client.market.events.l1BookUpdates({
|
|
57
57
|
venue: "binance",
|
|
58
58
|
symbol: "BTC/USDT:USDT",
|
|
59
59
|
})) {
|
|
60
|
-
console.log(event.snapshot.bidPrice
|
|
60
|
+
console.log(event.snapshot.bidPrice);
|
|
61
61
|
break;
|
|
62
62
|
}
|
|
63
63
|
|
|
@@ -114,8 +114,8 @@ await client.account.subscribeAccount({ accountId: "jup-loop-a" });
|
|
|
114
114
|
const binanceRisk = client.account.getRiskSnapshot("main-binance");
|
|
115
115
|
const juplendRisk = client.account.getRiskSnapshot("jup-loop-a");
|
|
116
116
|
|
|
117
|
-
console.log(binanceRisk?.riskRatio
|
|
118
|
-
console.log(juplendRisk?.riskRatio
|
|
117
|
+
console.log(binanceRisk?.riskRatio);
|
|
118
|
+
console.log(juplendRisk?.riskRatio);
|
|
119
119
|
```
|
|
120
120
|
|
|
121
121
|
需要账户或订单能力时,在 `start()` 前后任意时刻 `registerAccount()`:
|
|
@@ -182,19 +182,19 @@ await client.market.subscribeL1Book({ venue, symbol });
|
|
|
182
182
|
|
|
183
183
|
退订后 `activity` 变为 `"inactive"`,但最后一份快照仍可读——不要把它当实时值。
|
|
184
184
|
|
|
185
|
-
### 3.5
|
|
185
|
+
### 3.5 Decimal string 约定
|
|
186
186
|
|
|
187
|
-
输出侧的价格、数量、金额统一是 `BigNumber`(来自 [bignumber.js](https://github.com/MikeMcl/bignumber.js)
|
|
187
|
+
输出侧的价格、数量、金额统一是 canonical 十进制 string:无损、无科学计数法、不补尾零。SDK 仍 re-export `BigNumber`(来自 [bignumber.js](https://github.com/MikeMcl/bignumber.js))作为可选工具;需要运算时由调用方显式解析:
|
|
188
188
|
|
|
189
189
|
```ts
|
|
190
190
|
import { BigNumber } from "@imbingox/acex";
|
|
191
191
|
|
|
192
192
|
const book = client.market.getL1Book({ venue, symbol });
|
|
193
|
-
const spread = book!.askPrice.minus(book!.bidPrice);
|
|
193
|
+
const spread = new BigNumber(book!.askPrice).minus(new BigNumber(book!.bidPrice));
|
|
194
194
|
console.log(spread.toFixed());
|
|
195
195
|
```
|
|
196
196
|
|
|
197
|
-
|
|
197
|
+
不要用 `parseFloat()` 解析输出字段,否则会退回 JS 浮点精度。输入侧保持宽进严出:`createOrder()` 的 `price` / `amount` 是 decimal string,`normalizeOrderInput()` 的 `DecimalInput` 仍接受 string / number / `BigNumber`,但公共输出一律是 canonical decimal string。
|
|
198
198
|
|
|
199
199
|
## 4. Client 生命周期
|
|
200
200
|
|
|
@@ -378,7 +378,7 @@ const allBtcPerp = client.market.getMarkets("BTC/USDT:USDT");
|
|
|
378
378
|
|
|
379
379
|
`getMarkets(symbol)` 严格按完整统一 symbol 匹配。
|
|
380
380
|
|
|
381
|
-
`MarketDefinition` 见 [§9](#9-数据类型参考)。价格/数量相关字段(`priceStep`、`amountStep`、`contractSize`、`minAmount`、`minNotional`)都是 `BigNumber
|
|
381
|
+
`MarketDefinition` 见 [§9](#9-数据类型参考)。价格/数量相关字段(`priceStep`、`amountStep`、`contractSize`、`minAmount`、`minNotional`)都是 canonical decimal string;需要运算时用 `new BigNumber(field)` 自行解析。
|
|
382
382
|
|
|
383
383
|
归一化下单价格和数量:
|
|
384
384
|
|
|
@@ -459,7 +459,7 @@ const book = client.market.getL1Book({
|
|
|
459
459
|
});
|
|
460
460
|
|
|
461
461
|
if (book) {
|
|
462
|
-
const spread = book.askPrice.minus(book.bidPrice);
|
|
462
|
+
const spread = new BigNumber(book.askPrice).minus(new BigNumber(book.bidPrice));
|
|
463
463
|
console.log(`spread=${spread.toFixed()}`);
|
|
464
464
|
}
|
|
465
465
|
```
|
|
@@ -471,7 +471,7 @@ for await (const event of client.market.events.l1BookUpdates({
|
|
|
471
471
|
venue: "binance",
|
|
472
472
|
symbol: "BTC/USDT:USDT",
|
|
473
473
|
})) {
|
|
474
|
-
console.log(event.snapshot.bidPrice
|
|
474
|
+
console.log(event.snapshot.bidPrice);
|
|
475
475
|
}
|
|
476
476
|
```
|
|
477
477
|
|
|
@@ -529,9 +529,9 @@ const funding = client.market.getFundingRate({
|
|
|
529
529
|
});
|
|
530
530
|
|
|
531
531
|
if (funding) {
|
|
532
|
-
console.log(funding.fundingRate
|
|
533
|
-
console.log(funding.markPrice
|
|
534
|
-
console.log(funding.indexPrice
|
|
532
|
+
console.log(funding.fundingRate);
|
|
533
|
+
console.log(funding.markPrice);
|
|
534
|
+
console.log(funding.indexPrice);
|
|
535
535
|
console.log(funding.nextFundingTime);
|
|
536
536
|
console.log(funding.status.freshness);
|
|
537
537
|
}
|
|
@@ -544,7 +544,7 @@ for await (const event of client.market.events.fundingRateUpdates({
|
|
|
544
544
|
venue: "binance",
|
|
545
545
|
symbol: "BTC/USDT:USDT",
|
|
546
546
|
})) {
|
|
547
|
-
console.log(event.snapshot.fundingRate
|
|
547
|
+
console.log(event.snapshot.fundingRate);
|
|
548
548
|
}
|
|
549
549
|
```
|
|
550
550
|
|
|
@@ -638,7 +638,7 @@ const btcPosition = client.account.getPosition({
|
|
|
638
638
|
const risk = client.account.getRiskSnapshot("main-binance");
|
|
639
639
|
```
|
|
640
640
|
|
|
641
|
-
所有数量字段(`free` / `used` / `total` / `size` / `entryPrice` / `netEquity` / `riskEquity` / ...)都是 `BigNumber
|
|
641
|
+
所有数量字段(`free` / `used` / `total` / `size` / `entryPrice` / `netEquity` / `riskEquity` / ...)都是 canonical decimal string;需要运算时用 `new BigNumber(field)` 自行解析。
|
|
642
642
|
|
|
643
643
|
`RiskSnapshot.netEquity` 表示不含风控折算的净资产价值;`riskEquity` 表示抵押系数或清算阈值折算后的风控净权益。Binance 使用 `actualEquity` / `accountEquity` 映射这两个字段;Juplend 使用 `totalCollateralUsd - totalDebtUsd` / `Σ(suppliedValue × liquidationThreshold) - totalDebtUsd`。
|
|
644
644
|
|
|
@@ -652,13 +652,13 @@ for await (const event of client.account.events.updates({
|
|
|
652
652
|
})) {
|
|
653
653
|
switch (event.type) {
|
|
654
654
|
case "balance.updated":
|
|
655
|
-
console.log(event.asset, event.snapshot.free
|
|
655
|
+
console.log(event.asset, event.snapshot.free);
|
|
656
656
|
break;
|
|
657
657
|
case "position.updated":
|
|
658
|
-
console.log(event.symbol, event.snapshot.size
|
|
658
|
+
console.log(event.symbol, event.snapshot.size);
|
|
659
659
|
break;
|
|
660
660
|
case "risk.updated":
|
|
661
|
-
console.log(event.snapshot.riskRatio
|
|
661
|
+
console.log(event.snapshot.riskRatio);
|
|
662
662
|
break;
|
|
663
663
|
case "account.snapshot_replaced":
|
|
664
664
|
// 私有链路重连/重对账后的全量替换
|
|
@@ -801,10 +801,10 @@ for await (const event of client.order.events.updates({
|
|
|
801
801
|
})) {
|
|
802
802
|
switch (event.type) {
|
|
803
803
|
case "order.updated":
|
|
804
|
-
console.log("更新", event.snapshot.status, event.snapshot.filled
|
|
804
|
+
console.log("更新", event.snapshot.status, event.snapshot.filled);
|
|
805
805
|
break;
|
|
806
806
|
case "order.filled":
|
|
807
|
-
console.log("全部成交", event.snapshot.avgFillPrice
|
|
807
|
+
console.log("全部成交", event.snapshot.avgFillPrice);
|
|
808
808
|
break;
|
|
809
809
|
case "order.canceled":
|
|
810
810
|
console.log("已撤单");
|
|
@@ -1100,13 +1100,13 @@ interface MarketDefinition {
|
|
|
1100
1100
|
contract: boolean;
|
|
1101
1101
|
linear?: boolean;
|
|
1102
1102
|
inverse?: boolean;
|
|
1103
|
-
contractSize?:
|
|
1103
|
+
contractSize?: string;
|
|
1104
1104
|
pricePrecision: number;
|
|
1105
1105
|
amountPrecision: number;
|
|
1106
|
-
priceStep:
|
|
1107
|
-
amountStep:
|
|
1108
|
-
minAmount?:
|
|
1109
|
-
minNotional?:
|
|
1106
|
+
priceStep: string;
|
|
1107
|
+
amountStep: string;
|
|
1108
|
+
minAmount?: string;
|
|
1109
|
+
minNotional?: string;
|
|
1110
1110
|
expiry?: number;
|
|
1111
1111
|
raw: Record<string, unknown>;
|
|
1112
1112
|
}
|
|
@@ -1155,10 +1155,10 @@ interface MarketEventFilter {
|
|
|
1155
1155
|
interface L1Book {
|
|
1156
1156
|
venue: Venue;
|
|
1157
1157
|
symbol: string;
|
|
1158
|
-
bidPrice:
|
|
1159
|
-
bidSize:
|
|
1160
|
-
askPrice:
|
|
1161
|
-
askSize:
|
|
1158
|
+
bidPrice: string;
|
|
1159
|
+
bidSize: string;
|
|
1160
|
+
askPrice: string;
|
|
1161
|
+
askSize: string;
|
|
1162
1162
|
exchangeTs?: number;
|
|
1163
1163
|
receivedAt: number;
|
|
1164
1164
|
updatedAt: number;
|
|
@@ -1169,10 +1169,10 @@ interface L1Book {
|
|
|
1169
1169
|
interface FundingRateSnapshot {
|
|
1170
1170
|
venue: Venue;
|
|
1171
1171
|
symbol: string;
|
|
1172
|
-
fundingRate:
|
|
1172
|
+
fundingRate: string;
|
|
1173
1173
|
nextFundingTime?: number;
|
|
1174
|
-
markPrice?:
|
|
1175
|
-
indexPrice?:
|
|
1174
|
+
markPrice?: string;
|
|
1175
|
+
indexPrice?: string;
|
|
1176
1176
|
exchangeTs?: number;
|
|
1177
1177
|
receivedAt: number;
|
|
1178
1178
|
updatedAt: number;
|
|
@@ -1210,9 +1210,9 @@ interface BalanceSnapshot {
|
|
|
1210
1210
|
accountId: string;
|
|
1211
1211
|
venue: Venue;
|
|
1212
1212
|
asset: string;
|
|
1213
|
-
free:
|
|
1214
|
-
used:
|
|
1215
|
-
total:
|
|
1213
|
+
free: string;
|
|
1214
|
+
used: string;
|
|
1215
|
+
total: string;
|
|
1216
1216
|
exchangeTs?: number;
|
|
1217
1217
|
receivedAt: number;
|
|
1218
1218
|
updatedAt: number;
|
|
@@ -1221,12 +1221,12 @@ interface BalanceSnapshot {
|
|
|
1221
1221
|
}
|
|
1222
1222
|
|
|
1223
1223
|
interface LendingBalanceFacet {
|
|
1224
|
-
supplied:
|
|
1225
|
-
borrowed:
|
|
1226
|
-
interest:
|
|
1227
|
-
netAsset:
|
|
1228
|
-
supplyAPY?:
|
|
1229
|
-
borrowAPY?:
|
|
1224
|
+
supplied: string;
|
|
1225
|
+
borrowed: string;
|
|
1226
|
+
interest: string;
|
|
1227
|
+
netAsset: string;
|
|
1228
|
+
supplyAPY?: string;
|
|
1229
|
+
borrowAPY?: string;
|
|
1230
1230
|
}
|
|
1231
1231
|
|
|
1232
1232
|
interface PositionSnapshot {
|
|
@@ -1234,12 +1234,12 @@ interface PositionSnapshot {
|
|
|
1234
1234
|
venue: Venue;
|
|
1235
1235
|
symbol: string;
|
|
1236
1236
|
side: PositionSide;
|
|
1237
|
-
size:
|
|
1238
|
-
entryPrice?:
|
|
1239
|
-
markPrice?:
|
|
1240
|
-
unrealizedPnl?:
|
|
1241
|
-
leverage?:
|
|
1242
|
-
liquidationPrice?:
|
|
1237
|
+
size: string;
|
|
1238
|
+
entryPrice?: string;
|
|
1239
|
+
markPrice?: string;
|
|
1240
|
+
unrealizedPnl?: string;
|
|
1241
|
+
leverage?: string;
|
|
1242
|
+
liquidationPrice?: string;
|
|
1243
1243
|
exchangeTs?: number;
|
|
1244
1244
|
receivedAt: number;
|
|
1245
1245
|
updatedAt: number;
|
|
@@ -1249,12 +1249,12 @@ interface PositionSnapshot {
|
|
|
1249
1249
|
interface RiskSnapshot {
|
|
1250
1250
|
accountId: string;
|
|
1251
1251
|
venue: Venue;
|
|
1252
|
-
netEquity?:
|
|
1253
|
-
riskEquity?:
|
|
1254
|
-
riskRatio?:
|
|
1255
|
-
riskLeverage?:
|
|
1256
|
-
initialMargin?:
|
|
1257
|
-
maintenanceMargin?:
|
|
1252
|
+
netEquity?: string;
|
|
1253
|
+
riskEquity?: string;
|
|
1254
|
+
riskRatio?: string;
|
|
1255
|
+
riskLeverage?: string;
|
|
1256
|
+
initialMargin?: string;
|
|
1257
|
+
maintenanceMargin?: string;
|
|
1258
1258
|
exchangeTs?: number;
|
|
1259
1259
|
receivedAt: number;
|
|
1260
1260
|
updatedAt: number;
|
|
@@ -1263,12 +1263,12 @@ interface RiskSnapshot {
|
|
|
1263
1263
|
}
|
|
1264
1264
|
|
|
1265
1265
|
interface LendingRiskFacet {
|
|
1266
|
-
marginLevel?:
|
|
1267
|
-
healthFactor?:
|
|
1268
|
-
ltv?:
|
|
1269
|
-
liquidationThreshold?:
|
|
1270
|
-
totalCollateralUSD?:
|
|
1271
|
-
totalDebtUSD?:
|
|
1266
|
+
marginLevel?: string;
|
|
1267
|
+
healthFactor?: string;
|
|
1268
|
+
ltv?: string;
|
|
1269
|
+
liquidationThreshold?: string;
|
|
1270
|
+
totalCollateralUSD?: string;
|
|
1271
|
+
totalDebtUSD?: string;
|
|
1272
1272
|
}
|
|
1273
1273
|
|
|
1274
1274
|
interface AccountSnapshot {
|
|
@@ -1350,14 +1350,14 @@ interface OrderSnapshot {
|
|
|
1350
1350
|
side: OrderSide;
|
|
1351
1351
|
type: string; // 交易所原始 type 字符串
|
|
1352
1352
|
status: OrderStatus;
|
|
1353
|
-
price?:
|
|
1354
|
-
triggerPrice?:
|
|
1355
|
-
amount:
|
|
1356
|
-
filled:
|
|
1357
|
-
remaining?:
|
|
1353
|
+
price?: string;
|
|
1354
|
+
triggerPrice?: string;
|
|
1355
|
+
amount: string;
|
|
1356
|
+
filled: string;
|
|
1357
|
+
remaining?: string;
|
|
1358
1358
|
reduceOnly?: boolean;
|
|
1359
1359
|
positionSide?: PositionSide;
|
|
1360
|
-
avgFillPrice?:
|
|
1360
|
+
avgFillPrice?: string;
|
|
1361
1361
|
exchangeTs?: number;
|
|
1362
1362
|
receivedAt: number;
|
|
1363
1363
|
updatedAt: number;
|
package/package.json
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { toCanonical } from "../../internal/decimal.ts";
|
|
2
|
+
import {
|
|
3
|
+
type HttpClientMessages,
|
|
4
|
+
httpRequest,
|
|
5
|
+
} from "../../internal/http-client.ts";
|
|
2
6
|
import type { MarketDefinition, MarketType } from "../../types/index.ts";
|
|
3
7
|
|
|
4
8
|
type FetchLike = typeof fetch;
|
|
@@ -54,6 +58,11 @@ const BINANCE_USDM_EXCHANGE_INFO_URL =
|
|
|
54
58
|
"https://fapi.binance.com/fapi/v1/exchangeInfo";
|
|
55
59
|
const BINANCE_COINM_EXCHANGE_INFO_URL =
|
|
56
60
|
"https://dapi.binance.com/dapi/v1/exchangeInfo";
|
|
61
|
+
const DEFAULT_HTTP_TIMEOUT_MS = 10_000;
|
|
62
|
+
const BINANCE_CATALOG_HTTP_MESSAGES: HttpClientMessages = {
|
|
63
|
+
http: ({ status, statusText }) =>
|
|
64
|
+
`Binance request failed: ${status} ${statusText ?? ""}`,
|
|
65
|
+
};
|
|
57
66
|
|
|
58
67
|
function toRecord(value: unknown): Record<string, unknown> {
|
|
59
68
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
@@ -146,12 +155,12 @@ function normalizeSpotSymbol(
|
|
|
146
155
|
contract: false,
|
|
147
156
|
pricePrecision: precisionFromStep(priceStep),
|
|
148
157
|
amountPrecision: precisionFromStep(amountStep),
|
|
149
|
-
priceStep:
|
|
150
|
-
amountStep:
|
|
158
|
+
priceStep: toCanonical(priceStep),
|
|
159
|
+
amountStep: toCanonical(amountStep),
|
|
151
160
|
minAmount: lotSizeFilter?.minQty
|
|
152
|
-
?
|
|
161
|
+
? toCanonical(lotSizeFilter.minQty)
|
|
153
162
|
: undefined,
|
|
154
|
-
minNotional: notionalValue ?
|
|
163
|
+
minNotional: notionalValue ? toCanonical(notionalValue) : undefined,
|
|
155
164
|
raw: toRecord(symbol),
|
|
156
165
|
};
|
|
157
166
|
}
|
|
@@ -198,29 +207,38 @@ function normalizeDerivativesSymbol(
|
|
|
198
207
|
contract: true,
|
|
199
208
|
linear: family === "usdm",
|
|
200
209
|
inverse: family === "coinm",
|
|
201
|
-
contractSize: contractSize ?
|
|
210
|
+
contractSize: contractSize ? toCanonical(contractSize) : undefined,
|
|
202
211
|
pricePrecision: precisionFromStep(priceStep),
|
|
203
212
|
amountPrecision: precisionFromStep(amountStep),
|
|
204
|
-
priceStep:
|
|
205
|
-
amountStep:
|
|
213
|
+
priceStep: toCanonical(priceStep),
|
|
214
|
+
amountStep: toCanonical(amountStep),
|
|
206
215
|
minAmount: lotSizeFilter?.minQty
|
|
207
|
-
?
|
|
216
|
+
? toCanonical(lotSizeFilter.minQty)
|
|
208
217
|
: undefined,
|
|
209
|
-
minNotional: notionalValue ?
|
|
218
|
+
minNotional: notionalValue ? toCanonical(notionalValue) : undefined,
|
|
210
219
|
expiry: type === "future" ? symbol.deliveryDate : undefined,
|
|
211
220
|
raw: toRecord(symbol),
|
|
212
221
|
};
|
|
213
222
|
}
|
|
214
223
|
|
|
215
|
-
async function
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
224
|
+
async function requestCatalogJson<T>(
|
|
225
|
+
fetchFn: FetchLike,
|
|
226
|
+
url: string,
|
|
227
|
+
): Promise<T> {
|
|
228
|
+
const response = await httpRequest<T>({
|
|
229
|
+
fetchFn,
|
|
230
|
+
url,
|
|
231
|
+
timeoutMs: DEFAULT_HTTP_TIMEOUT_MS,
|
|
232
|
+
parseAs: "json",
|
|
233
|
+
jsonParseMode: "response",
|
|
234
|
+
retryPolicy: {
|
|
235
|
+
idempotent: true,
|
|
236
|
+
maxAttempts: 3,
|
|
237
|
+
},
|
|
238
|
+
messages: BINANCE_CATALOG_HTTP_MESSAGES,
|
|
239
|
+
});
|
|
222
240
|
|
|
223
|
-
return
|
|
241
|
+
return response.body;
|
|
224
242
|
}
|
|
225
243
|
|
|
226
244
|
function sortMarkets(
|
|
@@ -235,12 +253,15 @@ export async function loadBinanceMarkets(
|
|
|
235
253
|
fetchFn: FetchLike = fetch,
|
|
236
254
|
): Promise<BinanceMarketDefinition[]> {
|
|
237
255
|
const [spot, usdm, coinm] = await Promise.all([
|
|
238
|
-
|
|
239
|
-
|
|
256
|
+
requestCatalogJson<BinanceSpotExchangeInfo>(
|
|
257
|
+
fetchFn,
|
|
258
|
+
BINANCE_SPOT_EXCHANGE_INFO_URL,
|
|
259
|
+
),
|
|
260
|
+
requestCatalogJson<BinanceDerivativesExchangeInfo>(
|
|
240
261
|
fetchFn,
|
|
241
262
|
BINANCE_USDM_EXCHANGE_INFO_URL,
|
|
242
263
|
),
|
|
243
|
-
|
|
264
|
+
requestCatalogJson<BinanceDerivativesExchangeInfo>(
|
|
244
265
|
fetchFn,
|
|
245
266
|
BINANCE_COINM_EXCHANGE_INFO_URL,
|
|
246
267
|
),
|