@usherlabs/cex-broker 0.2.37 → 0.2.38
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/dist/commands/cli.js +68 -11
- package/dist/helpers/binance-user-data-normalization.d.ts +3 -0
- package/dist/index.js +69 -12
- package/dist/index.js.map +5 -4
- package/package.json +1 -1
package/dist/commands/cli.js
CHANGED
|
@@ -334375,6 +334375,62 @@ function isBinanceBalanceUserDataEvent(event) {
|
|
|
334375
334375
|
function isBinanceOrderUserDataEvent(event) {
|
|
334376
334376
|
return event.e === "executionReport" || event.e === "listStatus";
|
|
334377
334377
|
}
|
|
334378
|
+
|
|
334379
|
+
// src/helpers/binance-user-data-normalization.ts
|
|
334380
|
+
function requireQuantity(entry, key) {
|
|
334381
|
+
const value = entry[key];
|
|
334382
|
+
if (typeof value === "string" && value.trim().length > 0) {
|
|
334383
|
+
return value;
|
|
334384
|
+
}
|
|
334385
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
334386
|
+
return String(value);
|
|
334387
|
+
}
|
|
334388
|
+
throw new Error(`Invalid Binance balance quantity: ${key}`);
|
|
334389
|
+
}
|
|
334390
|
+
async function normalizeBinanceSpotBalanceEvent(exchange, event) {
|
|
334391
|
+
if (event.e !== "outboundAccountPosition") {
|
|
334392
|
+
return exchange.fetchBalance({ type: "spot" });
|
|
334393
|
+
}
|
|
334394
|
+
if (!Array.isArray(event.B)) {
|
|
334395
|
+
throw new Error("Invalid Binance outboundAccountPosition balances");
|
|
334396
|
+
}
|
|
334397
|
+
const timestamp = typeof event.E === "number" && Number.isFinite(event.E) ? event.E : undefined;
|
|
334398
|
+
const balance = {
|
|
334399
|
+
info: event,
|
|
334400
|
+
...timestamp !== undefined && {
|
|
334401
|
+
timestamp,
|
|
334402
|
+
datetime: new Date(timestamp).toISOString()
|
|
334403
|
+
}
|
|
334404
|
+
};
|
|
334405
|
+
for (const rawEntry of event.B) {
|
|
334406
|
+
const entry = asRecord(rawEntry);
|
|
334407
|
+
const asset = entry?.a;
|
|
334408
|
+
if (!entry || typeof asset !== "string" || asset.length === 0) {
|
|
334409
|
+
throw new Error("Invalid Binance outboundAccountPosition asset");
|
|
334410
|
+
}
|
|
334411
|
+
balance[asset] = {
|
|
334412
|
+
free: requireQuantity(entry, "f"),
|
|
334413
|
+
used: requireQuantity(entry, "l")
|
|
334414
|
+
};
|
|
334415
|
+
}
|
|
334416
|
+
return exchange.safeBalance(balance);
|
|
334417
|
+
}
|
|
334418
|
+
function getTradeId(value) {
|
|
334419
|
+
if (typeof value === "number" && Number.isFinite(value) || typeof value === "string" && value.length > 0) {
|
|
334420
|
+
const tradeId = String(value);
|
|
334421
|
+
return tradeId === "-1" ? undefined : tradeId;
|
|
334422
|
+
}
|
|
334423
|
+
return;
|
|
334424
|
+
}
|
|
334425
|
+
function normalizeBinanceExecutionReport(exchange, event) {
|
|
334426
|
+
const parsed = asRecord(exchange.parseWsOrder(event));
|
|
334427
|
+
if (!parsed) {
|
|
334428
|
+
throw new Error("Binance executionReport did not parse as an order");
|
|
334429
|
+
}
|
|
334430
|
+
const { fee: _fee, fees: _fees, ...order } = parsed;
|
|
334431
|
+
const tradeId = getTradeId(event.t);
|
|
334432
|
+
return tradeId === undefined ? order : { ...order, tradeId };
|
|
334433
|
+
}
|
|
334378
334434
|
// src/helpers/market-data-archive/ohlcv-bootstrap.ts
|
|
334379
334435
|
var DEFAULT_OHLCV_BOOTSTRAP_LIMIT = 100;
|
|
334380
334436
|
var MAX_OHLCV_BOOTSTRAP_LIMIT = 1000;
|
|
@@ -334521,17 +334577,6 @@ async function streamBinanceUserData(call, broker, symbol2, subscriptionType, is
|
|
|
334521
334577
|
}
|
|
334522
334578
|
}
|
|
334523
334579
|
const receivedTimestamp = Date.now();
|
|
334524
|
-
if (!await writeSubscribeFrame(call, isClosed, {
|
|
334525
|
-
data: JSON.stringify({
|
|
334526
|
-
subscriptionId: message.subscriptionId,
|
|
334527
|
-
event
|
|
334528
|
-
}),
|
|
334529
|
-
timestamp: receivedTimestamp,
|
|
334530
|
-
symbol: symbol2,
|
|
334531
|
-
type: subscriptionType
|
|
334532
|
-
})) {
|
|
334533
|
-
break;
|
|
334534
|
-
}
|
|
334535
334580
|
const archiveSubscriptionType = subscriptionType === SubscriptionType.BALANCE ? "BALANCE" : "ORDERS";
|
|
334536
334581
|
archiveSubscribeStreamInBackground(archiveContext?.archiver, {
|
|
334537
334582
|
exchange: archiveContext?.exchange ?? "binance",
|
|
@@ -334552,6 +334597,18 @@ async function streamBinanceUserData(call, broker, symbol2, subscriptionType, is
|
|
|
334552
334597
|
receivedTimestamp
|
|
334553
334598
|
});
|
|
334554
334599
|
}
|
|
334600
|
+
if (subscriptionType === SubscriptionType.ORDERS && event.e === "listStatus") {
|
|
334601
|
+
continue;
|
|
334602
|
+
}
|
|
334603
|
+
const data = subscriptionType === SubscriptionType.BALANCE ? await normalizeBinanceSpotBalanceEvent(broker, event) : normalizeBinanceExecutionReport(broker, event);
|
|
334604
|
+
if (!await writeSubscribeFrame(call, isClosed, {
|
|
334605
|
+
data: JSON.stringify(data),
|
|
334606
|
+
timestamp: receivedTimestamp,
|
|
334607
|
+
symbol: symbol2,
|
|
334608
|
+
type: subscriptionType
|
|
334609
|
+
})) {
|
|
334610
|
+
break;
|
|
334611
|
+
}
|
|
334555
334612
|
}
|
|
334556
334613
|
} finally {
|
|
334557
334614
|
userDataStream.close();
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { Exchange } from "@usherlabs/ccxt";
|
|
2
|
+
export declare function normalizeBinanceSpotBalanceEvent(exchange: Exchange, event: Record<string, unknown>): Promise<unknown>;
|
|
3
|
+
export declare function normalizeBinanceExecutionReport(exchange: Exchange, event: Record<string, unknown>): Record<string, unknown>;
|
package/dist/index.js
CHANGED
|
@@ -309889,6 +309889,62 @@ function isBinanceBalanceUserDataEvent(event) {
|
|
|
309889
309889
|
function isBinanceOrderUserDataEvent(event) {
|
|
309890
309890
|
return event.e === "executionReport" || event.e === "listStatus";
|
|
309891
309891
|
}
|
|
309892
|
+
|
|
309893
|
+
// src/helpers/binance-user-data-normalization.ts
|
|
309894
|
+
function requireQuantity(entry, key) {
|
|
309895
|
+
const value = entry[key];
|
|
309896
|
+
if (typeof value === "string" && value.trim().length > 0) {
|
|
309897
|
+
return value;
|
|
309898
|
+
}
|
|
309899
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
309900
|
+
return String(value);
|
|
309901
|
+
}
|
|
309902
|
+
throw new Error(`Invalid Binance balance quantity: ${key}`);
|
|
309903
|
+
}
|
|
309904
|
+
async function normalizeBinanceSpotBalanceEvent(exchange, event) {
|
|
309905
|
+
if (event.e !== "outboundAccountPosition") {
|
|
309906
|
+
return exchange.fetchBalance({ type: "spot" });
|
|
309907
|
+
}
|
|
309908
|
+
if (!Array.isArray(event.B)) {
|
|
309909
|
+
throw new Error("Invalid Binance outboundAccountPosition balances");
|
|
309910
|
+
}
|
|
309911
|
+
const timestamp = typeof event.E === "number" && Number.isFinite(event.E) ? event.E : undefined;
|
|
309912
|
+
const balance = {
|
|
309913
|
+
info: event,
|
|
309914
|
+
...timestamp !== undefined && {
|
|
309915
|
+
timestamp,
|
|
309916
|
+
datetime: new Date(timestamp).toISOString()
|
|
309917
|
+
}
|
|
309918
|
+
};
|
|
309919
|
+
for (const rawEntry of event.B) {
|
|
309920
|
+
const entry = asRecord(rawEntry);
|
|
309921
|
+
const asset = entry?.a;
|
|
309922
|
+
if (!entry || typeof asset !== "string" || asset.length === 0) {
|
|
309923
|
+
throw new Error("Invalid Binance outboundAccountPosition asset");
|
|
309924
|
+
}
|
|
309925
|
+
balance[asset] = {
|
|
309926
|
+
free: requireQuantity(entry, "f"),
|
|
309927
|
+
used: requireQuantity(entry, "l")
|
|
309928
|
+
};
|
|
309929
|
+
}
|
|
309930
|
+
return exchange.safeBalance(balance);
|
|
309931
|
+
}
|
|
309932
|
+
function getTradeId(value) {
|
|
309933
|
+
if (typeof value === "number" && Number.isFinite(value) || typeof value === "string" && value.length > 0) {
|
|
309934
|
+
const tradeId = String(value);
|
|
309935
|
+
return tradeId === "-1" ? undefined : tradeId;
|
|
309936
|
+
}
|
|
309937
|
+
return;
|
|
309938
|
+
}
|
|
309939
|
+
function normalizeBinanceExecutionReport(exchange, event) {
|
|
309940
|
+
const parsed = asRecord(exchange.parseWsOrder(event));
|
|
309941
|
+
if (!parsed) {
|
|
309942
|
+
throw new Error("Binance executionReport did not parse as an order");
|
|
309943
|
+
}
|
|
309944
|
+
const { fee: _fee, fees: _fees, ...order } = parsed;
|
|
309945
|
+
const tradeId = getTradeId(event.t);
|
|
309946
|
+
return tradeId === undefined ? order : { ...order, tradeId };
|
|
309947
|
+
}
|
|
309892
309948
|
// src/helpers/market-data-archive/ohlcv-bootstrap.ts
|
|
309893
309949
|
var DEFAULT_OHLCV_BOOTSTRAP_LIMIT = 100;
|
|
309894
309950
|
var MAX_OHLCV_BOOTSTRAP_LIMIT = 1000;
|
|
@@ -310035,17 +310091,6 @@ async function streamBinanceUserData(call, broker, symbol2, subscriptionType, is
|
|
|
310035
310091
|
}
|
|
310036
310092
|
}
|
|
310037
310093
|
const receivedTimestamp = Date.now();
|
|
310038
|
-
if (!await writeSubscribeFrame(call, isClosed, {
|
|
310039
|
-
data: JSON.stringify({
|
|
310040
|
-
subscriptionId: message.subscriptionId,
|
|
310041
|
-
event
|
|
310042
|
-
}),
|
|
310043
|
-
timestamp: receivedTimestamp,
|
|
310044
|
-
symbol: symbol2,
|
|
310045
|
-
type: subscriptionType
|
|
310046
|
-
})) {
|
|
310047
|
-
break;
|
|
310048
|
-
}
|
|
310049
310094
|
const archiveSubscriptionType = subscriptionType === SubscriptionType.BALANCE ? "BALANCE" : "ORDERS";
|
|
310050
310095
|
archiveSubscribeStreamInBackground(archiveContext?.archiver, {
|
|
310051
310096
|
exchange: archiveContext?.exchange ?? "binance",
|
|
@@ -310066,6 +310111,18 @@ async function streamBinanceUserData(call, broker, symbol2, subscriptionType, is
|
|
|
310066
310111
|
receivedTimestamp
|
|
310067
310112
|
});
|
|
310068
310113
|
}
|
|
310114
|
+
if (subscriptionType === SubscriptionType.ORDERS && event.e === "listStatus") {
|
|
310115
|
+
continue;
|
|
310116
|
+
}
|
|
310117
|
+
const data = subscriptionType === SubscriptionType.BALANCE ? await normalizeBinanceSpotBalanceEvent(broker, event) : normalizeBinanceExecutionReport(broker, event);
|
|
310118
|
+
if (!await writeSubscribeFrame(call, isClosed, {
|
|
310119
|
+
data: JSON.stringify(data),
|
|
310120
|
+
timestamp: receivedTimestamp,
|
|
310121
|
+
symbol: symbol2,
|
|
310122
|
+
type: subscriptionType
|
|
310123
|
+
})) {
|
|
310124
|
+
break;
|
|
310125
|
+
}
|
|
310069
310126
|
}
|
|
310070
310127
|
} finally {
|
|
310071
310128
|
userDataStream.close();
|
|
@@ -311031,4 +311088,4 @@ export {
|
|
|
311031
311088
|
CEXBroker as default
|
|
311032
311089
|
};
|
|
311033
311090
|
|
|
311034
|
-
//# debugId=
|
|
311091
|
+
//# debugId=4F503765D539243C64756E2164756E21
|