@solncebro/exchange-engine 0.1.1 → 0.2.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/CHANGELOG.md +42 -0
- package/README.md +7 -7
- package/dist/auth/binanceAuth.js +3 -6
- package/dist/auth/binanceAuth.js.map +1 -1
- package/dist/auth/bybitAuth.d.ts +0 -1
- package/dist/auth/bybitAuth.d.ts.map +1 -1
- package/dist/auth/bybitAuth.js +2 -9
- package/dist/auth/bybitAuth.js.map +1 -1
- package/dist/constants/binance.d.ts +8 -5
- package/dist/constants/binance.d.ts.map +1 -1
- package/dist/constants/binance.js +10 -23
- package/dist/constants/binance.js.map +1 -1
- package/dist/constants/bybit.d.ts +7 -9
- package/dist/constants/bybit.d.ts.map +1 -1
- package/dist/constants/bybit.js +10 -13
- package/dist/constants/bybit.js.map +1 -1
- package/dist/constants/mappings.d.ts +9 -0
- package/dist/constants/mappings.d.ts.map +1 -0
- package/dist/constants/mappings.js +40 -0
- package/dist/constants/mappings.js.map +1 -0
- package/dist/exchanges/BaseExchangeClient.d.ts +37 -0
- package/dist/exchanges/BaseExchangeClient.d.ts.map +1 -0
- package/dist/exchanges/BaseExchangeClient.js +91 -0
- package/dist/exchanges/BaseExchangeClient.js.map +1 -0
- package/dist/exchanges/BinanceBaseClient.d.ts +21 -0
- package/dist/exchanges/BinanceBaseClient.d.ts.map +1 -0
- package/dist/exchanges/BinanceBaseClient.js +64 -0
- package/dist/exchanges/BinanceBaseClient.js.map +1 -0
- package/dist/exchanges/BinanceFutures.d.ts +9 -21
- package/dist/exchanges/BinanceFutures.d.ts.map +1 -1
- package/dist/exchanges/BinanceFutures.js +23 -94
- package/dist/exchanges/BinanceFutures.js.map +1 -1
- package/dist/exchanges/BinanceSpot.d.ts +9 -21
- package/dist/exchanges/BinanceSpot.d.ts.map +1 -1
- package/dist/exchanges/BinanceSpot.js +16 -94
- package/dist/exchanges/BinanceSpot.js.map +1 -1
- package/dist/exchanges/BybitLinear.d.ts +19 -20
- package/dist/exchanges/BybitLinear.d.ts.map +1 -1
- package/dist/exchanges/BybitLinear.js +66 -71
- package/dist/exchanges/BybitLinear.js.map +1 -1
- package/dist/exchanges/BybitSpot.d.ts +17 -19
- package/dist/exchanges/BybitSpot.d.ts.map +1 -1
- package/dist/exchanges/BybitSpot.js +42 -64
- package/dist/exchanges/BybitSpot.js.map +1 -1
- package/dist/exchanges/Exchange.d.ts +1 -1
- package/dist/exchanges/Exchange.d.ts.map +1 -1
- package/dist/exchanges/Exchange.js +3 -2
- package/dist/exchanges/Exchange.js.map +1 -1
- package/dist/http/BaseHttpClient.d.ts +10 -1
- package/dist/http/BaseHttpClient.d.ts.map +1 -1
- package/dist/http/BaseHttpClient.js +27 -5
- package/dist/http/BaseHttpClient.js.map +1 -1
- package/dist/http/BinanceBaseHttpClient.d.ts +49 -0
- package/dist/http/BinanceBaseHttpClient.d.ts.map +1 -0
- package/dist/http/BinanceBaseHttpClient.js +86 -0
- package/dist/http/BinanceBaseHttpClient.js.map +1 -0
- package/dist/http/BinanceFuturesHttpClient.d.ts +11 -40
- package/dist/http/BinanceFuturesHttpClient.d.ts.map +1 -1
- package/dist/http/BinanceFuturesHttpClient.js +38 -185
- package/dist/http/BinanceFuturesHttpClient.js.map +1 -1
- package/dist/http/BinanceSpotHttpClient.d.ts +5 -24
- package/dist/http/BinanceSpotHttpClient.d.ts.map +1 -1
- package/dist/http/BinanceSpotHttpClient.js +15 -90
- package/dist/http/BinanceSpotHttpClient.js.map +1 -1
- package/dist/http/BybitHttpClient.d.ts +82 -134
- package/dist/http/BybitHttpClient.d.ts.map +1 -1
- package/dist/http/BybitHttpClient.js +61 -94
- package/dist/http/BybitHttpClient.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -1
- package/dist/index.js.map +1 -1
- package/dist/normalizers/binanceNormalizer.d.ts +29 -19
- package/dist/normalizers/binanceNormalizer.d.ts.map +1 -1
- package/dist/normalizers/binanceNormalizer.js +55 -35
- package/dist/normalizers/binanceNormalizer.js.map +1 -1
- package/dist/normalizers/bybitNormalizer.d.ts +25 -19
- package/dist/normalizers/bybitNormalizer.d.ts.map +1 -1
- package/dist/normalizers/bybitNormalizer.js +60 -45
- package/dist/normalizers/bybitNormalizer.js.map +1 -1
- package/dist/precision/precision.d.ts +3 -3
- package/dist/precision/precision.d.ts.map +1 -1
- package/dist/precision/precision.js +4 -4
- package/dist/precision/precision.js.map +1 -1
- package/dist/types/common.d.ts +57 -22
- package/dist/types/common.d.ts.map +1 -1
- package/dist/types/common.js +40 -0
- package/dist/types/common.js.map +1 -1
- package/dist/types/exchange.d.ts +14 -8
- package/dist/types/exchange.d.ts.map +1 -1
- package/dist/types/index.d.ts +2 -2
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/stream.d.ts +9 -0
- package/dist/types/stream.d.ts.map +1 -0
- package/dist/types/stream.js +3 -0
- package/dist/types/stream.js.map +1 -0
- package/dist/utils/crypto.d.ts +2 -0
- package/dist/utils/crypto.d.ts.map +1 -0
- package/dist/utils/crypto.js +11 -0
- package/dist/utils/crypto.js.map +1 -0
- package/dist/utils/httpParams.d.ts +3 -0
- package/dist/utils/httpParams.d.ts.map +1 -0
- package/dist/utils/httpParams.js +15 -0
- package/dist/utils/httpParams.js.map +1 -0
- package/dist/utils/klineLoader.d.ts +10 -0
- package/dist/utils/klineLoader.d.ts.map +1 -0
- package/dist/utils/klineLoader.js +19 -0
- package/dist/utils/klineLoader.js.map +1 -0
- package/dist/ws/BinanceFuturesPublicStream.d.ts +8 -7
- package/dist/ws/BinanceFuturesPublicStream.d.ts.map +1 -1
- package/dist/ws/BinanceFuturesPublicStream.js +49 -79
- package/dist/ws/BinanceFuturesPublicStream.js.map +1 -1
- package/dist/ws/BinanceSpotPublicStream.d.ts +7 -5
- package/dist/ws/BinanceSpotPublicStream.d.ts.map +1 -1
- package/dist/ws/BinanceSpotPublicStream.js +24 -31
- package/dist/ws/BinanceSpotPublicStream.js.map +1 -1
- package/dist/ws/BinanceUserDataStream.d.ts +3 -3
- package/dist/ws/BinanceUserDataStream.d.ts.map +1 -1
- package/dist/ws/BinanceUserDataStream.js +10 -10
- package/dist/ws/BinanceUserDataStream.js.map +1 -1
- package/dist/ws/BybitPrivateStream.d.ts +1 -1
- package/dist/ws/BybitPrivateStream.d.ts.map +1 -1
- package/dist/ws/BybitPrivateStream.js +12 -29
- package/dist/ws/BybitPrivateStream.js.map +1 -1
- package/dist/ws/BybitPublicStream.d.ts +5 -4
- package/dist/ws/BybitPublicStream.d.ts.map +1 -1
- package/dist/ws/BybitPublicStream.js +18 -24
- package/dist/ws/BybitPublicStream.js.map +1 -1
- package/dist/ws/BybitTradeStream.d.ts +4 -2
- package/dist/ws/BybitTradeStream.d.ts.map +1 -1
- package/dist/ws/BybitTradeStream.js +32 -44
- package/dist/ws/BybitTradeStream.js.map +1 -1
- package/dist/ws/binanceWebSocketUtils.d.ts +4 -0
- package/dist/ws/binanceWebSocketUtils.d.ts.map +1 -0
- package/dist/ws/binanceWebSocketUtils.js +7 -0
- package/dist/ws/binanceWebSocketUtils.js.map +1 -0
- package/dist/ws/bybitWebSocketUtils.d.ts +28 -0
- package/dist/ws/bybitWebSocketUtils.d.ts.map +1 -0
- package/dist/ws/bybitWebSocketUtils.js +29 -0
- package/dist/ws/bybitWebSocketUtils.js.map +1 -0
- package/package.json +21 -3
package/dist/types/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export type { ExchangeName, OrderSide, OrderType, MarginMode, PositionSide,
|
|
2
|
-
export type { ExchangeArgs,
|
|
1
|
+
export type { ExchangeName, OrderSide, OrderType, MarginMode, PositionSide, TradeSymbolType, TimeInForce, KlineInterval, ExchangeConfig, ExchangeLogger, Ticker, TickerBySymbol, Kline, TradeSymbolFilter, TradeSymbol, TradeSymbolBySymbol, Position, Order, Balance, BalanceByAsset, FundingRateHistory, } from './common';
|
|
2
|
+
export type { ExchangeArgs, CreateOrderWebSocketArgs, FetchPageWithLimitArgs, SubscribeKlinesArgs, ExchangeClient, } from './exchange';
|
|
3
3
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,YAAY,EACZ,SAAS,EACT,SAAS,EACT,UAAU,EACV,YAAY,EACZ,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,YAAY,EACZ,SAAS,EACT,SAAS,EACT,UAAU,EACV,YAAY,EACZ,eAAe,EACf,WAAW,EACX,aAAa,EACb,cAAc,EACd,cAAc,EACd,MAAM,EACN,cAAc,EACd,KAAK,EACL,iBAAiB,EACjB,WAAW,EACX,mBAAmB,EACnB,QAAQ,EACR,KAAK,EACL,OAAO,EACP,cAAc,EACd,kBAAkB,GACnB,MAAM,UAAU,CAAC;AAElB,YAAY,EACV,YAAY,EACZ,wBAAwB,EACxB,sBAAsB,EACtB,mBAAmB,EACnB,cAAc,GACf,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { KlineInterval, TickerBySymbol } from './common';
|
|
2
|
+
import type { KlineHandler } from './exchange';
|
|
3
|
+
export interface PublicStreamLike {
|
|
4
|
+
subscribeAllTickers(handler: (tickers: TickerBySymbol) => void): void;
|
|
5
|
+
subscribeKlines(symbol: string, interval: KlineInterval, handler: KlineHandler): void;
|
|
6
|
+
unsubscribeKlines(symbol: string, interval: KlineInterval, handler: KlineHandler): void;
|
|
7
|
+
close(): void;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=stream.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../../src/types/stream.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC9D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,MAAM,WAAW,gBAAgB;IAC/B,mBAAmB,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,GAAG,IAAI,CAAC;IACtE,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,OAAO,EAAE,YAAY,GAAG,IAAI,CAAC;IACtF,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,OAAO,EAAE,YAAY,GAAG,IAAI,CAAC;IACxF,KAAK,IAAI,IAAI,CAAC;CACf"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream.js","sourceRoot":"","sources":["../../src/types/stream.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../../src/utils/crypto.ts"],"names":[],"mappings":"AAEA,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAElE"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.hmacSha256 = hmacSha256;
|
|
7
|
+
const node_crypto_1 = __importDefault(require("node:crypto"));
|
|
8
|
+
function hmacSha256(payload, secret) {
|
|
9
|
+
return node_crypto_1.default.createHmac('sha256', secret).update(payload).digest('hex');
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=crypto.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypto.js","sourceRoot":"","sources":["../../src/utils/crypto.ts"],"names":[],"mappings":";;;;;AAEA,gCAEC;AAJD,8DAAiC;AAEjC,SAAgB,UAAU,CAAC,OAAe,EAAE,MAAc;IACxD,OAAO,qBAAM,CAAC,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC3E,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"httpParams.d.ts","sourceRoot":"","sources":["../../src/utils/httpParams.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAEhE,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,EACjD,OAAO,CAAC,EAAE,sBAAsB,GAC/B,IAAI,CAYN"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.applyTimeRangeOptions = applyTimeRangeOptions;
|
|
4
|
+
function applyTimeRangeOptions(params, options) {
|
|
5
|
+
if (options?.startTime !== undefined) {
|
|
6
|
+
params.startTime = options.startTime;
|
|
7
|
+
}
|
|
8
|
+
if (options?.endTime !== undefined) {
|
|
9
|
+
params.endTime = options.endTime;
|
|
10
|
+
}
|
|
11
|
+
if (options?.limit !== undefined) {
|
|
12
|
+
params.limit = options.limit;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=httpParams.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"httpParams.js","sourceRoot":"","sources":["../../src/utils/httpParams.ts"],"names":[],"mappings":";;AAEA,sDAeC;AAfD,SAAgB,qBAAqB,CACnC,MAAiD,EACjD,OAAgC;IAEhC,IAAI,OAAO,EAAE,SAAS,KAAK,SAAS,EAAE,CAAC;QACrC,MAAM,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;IACvC,CAAC;IAED,IAAI,OAAO,EAAE,OAAO,KAAK,SAAS,EAAE,CAAC;QACnC,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IACnC,CAAC;IAED,IAAI,OAAO,EAAE,KAAK,KAAK,SAAS,EAAE,CAAC;QACjC,MAAM,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;IAC/B,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ExchangeLogger, Kline } from '../types/common';
|
|
2
|
+
export declare const KLINE_CHUNK_SIZE = 200;
|
|
3
|
+
export interface LoadKlinesInChunksArgs {
|
|
4
|
+
fetchKlines: (symbol: string) => Promise<Kline[]>;
|
|
5
|
+
symbolList: string[];
|
|
6
|
+
logger: ExchangeLogger;
|
|
7
|
+
chunkSize?: number;
|
|
8
|
+
}
|
|
9
|
+
export declare function loadKlinesInChunks(args: LoadKlinesInChunksArgs): Promise<Map<string, Kline[]>>;
|
|
10
|
+
//# sourceMappingURL=klineLoader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"klineLoader.d.ts","sourceRoot":"","sources":["../../src/utils/klineLoader.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAE7D,eAAO,MAAM,gBAAgB,MAAM,CAAC;AAEpC,MAAM,WAAW,sBAAsB;IACrC,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;IAClD,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,MAAM,EAAE,cAAc,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,sBAAsB,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,CAmBpG"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.KLINE_CHUNK_SIZE = void 0;
|
|
4
|
+
exports.loadKlinesInChunks = loadKlinesInChunks;
|
|
5
|
+
exports.KLINE_CHUNK_SIZE = 200;
|
|
6
|
+
async function loadKlinesInChunks(args) {
|
|
7
|
+
const { fetchKlines, symbolList, logger, chunkSize = exports.KLINE_CHUNK_SIZE } = args;
|
|
8
|
+
const klineListBySymbol = new Map();
|
|
9
|
+
for (let i = 0; i < symbolList.length; i += chunkSize) {
|
|
10
|
+
const chunk = symbolList.slice(i, i + chunkSize);
|
|
11
|
+
const chunkResultList = await Promise.all(chunk.map(async (symbol) => ({ symbol, klineList: await fetchKlines(symbol) })));
|
|
12
|
+
for (const { symbol, klineList } of chunkResultList) {
|
|
13
|
+
klineListBySymbol.set(symbol, klineList);
|
|
14
|
+
}
|
|
15
|
+
logger.info(`Loaded klines for ${Math.min(i + chunkSize, symbolList.length)}/${symbolList.length} symbols`);
|
|
16
|
+
}
|
|
17
|
+
return klineListBySymbol;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=klineLoader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"klineLoader.js","sourceRoot":"","sources":["../../src/utils/klineLoader.ts"],"names":[],"mappings":";;;AAWA,gDAmBC;AA5BY,QAAA,gBAAgB,GAAG,GAAG,CAAC;AAS7B,KAAK,UAAU,kBAAkB,CAAC,IAA4B;IACnE,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,GAAG,wBAAgB,EAAE,GAAG,IAAI,CAAC;IAC/E,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAmB,CAAC;IAErD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,IAAI,SAAS,EAAE,CAAC;QACtD,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC;QAEjD,MAAM,eAAe,GAAG,MAAM,OAAO,CAAC,GAAG,CACvC,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAChF,CAAC;QAEF,KAAK,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,eAAe,EAAE,CAAC;YACpD,iBAAiB,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QAC3C,CAAC;QAED,MAAM,CAAC,IAAI,CAAC,qBAAqB,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,SAAS,EAAE,UAAU,CAAC,MAAM,CAAC,IAAI,UAAU,CAAC,MAAM,UAAU,CAAC,CAAC;IAC9G,CAAC;IAED,OAAO,iBAAiB,CAAC;AAC3B,CAAC"}
|
|
@@ -1,28 +1,29 @@
|
|
|
1
|
-
import type { ExchangeLogger,
|
|
1
|
+
import type { ExchangeLogger, KlineInterval, TickerBySymbol } from '../types/common';
|
|
2
|
+
import type { KlineHandler } from '../types/exchange';
|
|
2
3
|
interface BinanceCombinedMessage {
|
|
3
4
|
stream?: string;
|
|
4
5
|
data?: unknown;
|
|
5
6
|
}
|
|
6
7
|
declare class BinanceFuturesPublicStream {
|
|
8
|
+
private readonly webSocketCombinedUrl;
|
|
7
9
|
private readonly logger;
|
|
8
10
|
private readonly onNotify?;
|
|
9
11
|
private readonly tickerHandlerSet;
|
|
10
12
|
private readonly klineHandlerByKey;
|
|
11
|
-
private readonly
|
|
12
|
-
private
|
|
13
|
+
private readonly connectionList;
|
|
14
|
+
private isConnectScheduled;
|
|
13
15
|
private subscriptionIdCounter;
|
|
14
|
-
constructor(logger: ExchangeLogger, onNotify?: (message: string) => void | Promise<void>);
|
|
16
|
+
constructor(webSocketCombinedUrl: string, logger: ExchangeLogger, onNotify?: (message: string) => void | Promise<void>);
|
|
15
17
|
subscribeAllTickers(handler: (tickers: TickerBySymbol) => void): void;
|
|
16
18
|
unsubscribeAllTickers(handler: (tickers: TickerBySymbol) => void): void;
|
|
17
|
-
subscribeKlines(symbol: string, interval: KlineInterval, handler:
|
|
18
|
-
unsubscribeKlines(symbol: string, interval: KlineInterval, handler:
|
|
19
|
+
subscribeKlines(symbol: string, interval: KlineInterval, handler: KlineHandler): void;
|
|
20
|
+
unsubscribeKlines(symbol: string, interval: KlineInterval, handler: KlineHandler): void;
|
|
19
21
|
close(): void;
|
|
20
22
|
private scheduleConnect;
|
|
21
23
|
private createConnections;
|
|
22
24
|
private createConnection;
|
|
23
25
|
private addStreamToConnection;
|
|
24
26
|
private removeStreamFromConnection;
|
|
25
|
-
private sendSubscribe;
|
|
26
27
|
private handleMessage;
|
|
27
28
|
}
|
|
28
29
|
export { BinanceFuturesPublicStream };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BinanceFuturesPublicStream.d.ts","sourceRoot":"","sources":["../../src/ws/BinanceFuturesPublicStream.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,
|
|
1
|
+
{"version":3,"file":"BinanceFuturesPublicStream.d.ts","sourceRoot":"","sources":["../../src/ws/BinanceFuturesPublicStream.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACrF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAOtD,UAAU,sBAAsB;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AA0BD,cAAM,0BAA0B;IAC9B,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAS;IAC9C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiB;IACxC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAA4C;IACtE,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAqD;IACtF,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAA6C;IAC/E,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA2B;IAC1D,OAAO,CAAC,kBAAkB,CAAS;IACnC,OAAO,CAAC,qBAAqB,CAAK;gBAEtB,oBAAoB,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAMtH,mBAAmB,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,GAAG,IAAI;IAKrE,qBAAqB,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,GAAG,IAAI;IAIvE,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,OAAO,EAAE,YAAY,GAAG,IAAI;IAgBrF,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,OAAO,EAAE,YAAY,GAAG,IAAI;IAmBvF,KAAK,IAAI,IAAI;IAQb,OAAO,CAAC,eAAe;IAavB,OAAO,CAAC,iBAAiB;IAmBzB,OAAO,CAAC,gBAAgB;IAkBxB,OAAO,CAAC,qBAAqB;IAuB7B,OAAO,CAAC,0BAA0B;IAsBlC,OAAO,CAAC,aAAa;CAsCtB;AAED,OAAO,EAAE,0BAA0B,EAAE,CAAC;AACtC,YAAY,EAAE,sBAAsB,EAAE,CAAC"}
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.BinanceFuturesPublicStream = void 0;
|
|
4
4
|
const websocket_engine_1 = require("@solncebro/websocket-engine");
|
|
5
5
|
const binanceNormalizer_1 = require("../normalizers/binanceNormalizer");
|
|
6
|
-
const
|
|
6
|
+
const binanceWebSocketUtils_1 = require("./binanceWebSocketUtils");
|
|
7
7
|
const MAX_STREAMS_PER_CONNECTION = 200;
|
|
8
8
|
function parseBinanceCombinedMessage(rawData) {
|
|
9
9
|
return JSON.parse(rawData.toString());
|
|
@@ -14,28 +14,22 @@ function buildKlineStreamList(klineHandlerByKey) {
|
|
|
14
14
|
const separatorIndex = key.lastIndexOf('_');
|
|
15
15
|
const symbol = key.slice(0, separatorIndex);
|
|
16
16
|
const interval = key.slice(separatorIndex + 1);
|
|
17
|
-
const binanceInterval =
|
|
17
|
+
const binanceInterval = interval;
|
|
18
18
|
streamList.push(`${symbol.toLowerCase()}_perpetual@continuousKline_${binanceInterval}`);
|
|
19
19
|
}
|
|
20
20
|
return streamList;
|
|
21
21
|
}
|
|
22
|
-
function resolveUnifiedInterval(binanceInterval) {
|
|
23
|
-
for (const [unified, binance] of Object.entries(binance_1.BINANCE_KLINE_INTERVAL)) {
|
|
24
|
-
if (binance === binanceInterval) {
|
|
25
|
-
return unified;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
return '1m';
|
|
29
|
-
}
|
|
30
22
|
class BinanceFuturesPublicStream {
|
|
23
|
+
webSocketCombinedUrl;
|
|
31
24
|
logger;
|
|
32
25
|
onNotify;
|
|
33
26
|
tickerHandlerSet = new Set();
|
|
34
27
|
klineHandlerByKey = new Map();
|
|
35
|
-
|
|
36
|
-
|
|
28
|
+
connectionList = [];
|
|
29
|
+
isConnectScheduled = false;
|
|
37
30
|
subscriptionIdCounter = 1;
|
|
38
|
-
constructor(logger, onNotify) {
|
|
31
|
+
constructor(webSocketCombinedUrl, logger, onNotify) {
|
|
32
|
+
this.webSocketCombinedUrl = webSocketCombinedUrl;
|
|
39
33
|
this.logger = logger;
|
|
40
34
|
this.onNotify = onNotify;
|
|
41
35
|
}
|
|
@@ -48,12 +42,11 @@ class BinanceFuturesPublicStream {
|
|
|
48
42
|
}
|
|
49
43
|
subscribeKlines(symbol, interval, handler) {
|
|
50
44
|
const key = `${symbol}_${interval}`;
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
this.
|
|
55
|
-
|
|
56
|
-
const binanceInterval = binance_1.BINANCE_KLINE_INTERVAL[interval];
|
|
45
|
+
const handlerSet = this.klineHandlerByKey.get(key) ?? new Set();
|
|
46
|
+
handlerSet.add(handler);
|
|
47
|
+
this.klineHandlerByKey.set(key, handlerSet);
|
|
48
|
+
if (this.connectionList.length > 0) {
|
|
49
|
+
const binanceInterval = interval;
|
|
57
50
|
const stream = `${symbol.toLowerCase()}_perpetual@continuousKline_${binanceInterval}`;
|
|
58
51
|
this.addStreamToConnection(stream);
|
|
59
52
|
}
|
|
@@ -70,116 +63,93 @@ class BinanceFuturesPublicStream {
|
|
|
70
63
|
handlerSet.delete(handler);
|
|
71
64
|
if (handlerSet.size === 0) {
|
|
72
65
|
this.klineHandlerByKey.delete(key);
|
|
73
|
-
const binanceInterval =
|
|
66
|
+
const binanceInterval = interval;
|
|
74
67
|
const stream = `${symbol.toLowerCase()}_perpetual@continuousKline_${binanceInterval}`;
|
|
75
68
|
this.removeStreamFromConnection(stream);
|
|
76
69
|
}
|
|
77
70
|
}
|
|
78
71
|
close() {
|
|
79
|
-
for (const
|
|
80
|
-
|
|
72
|
+
for (const connection of this.connectionList) {
|
|
73
|
+
connection.webSocket.close();
|
|
81
74
|
}
|
|
82
|
-
this.
|
|
75
|
+
this.connectionList.length = 0;
|
|
83
76
|
}
|
|
84
77
|
scheduleConnect() {
|
|
85
|
-
if (this.
|
|
78
|
+
if (this.isConnectScheduled || this.connectionList.length > 0) {
|
|
86
79
|
return;
|
|
87
80
|
}
|
|
88
|
-
this.
|
|
81
|
+
this.isConnectScheduled = true;
|
|
89
82
|
queueMicrotask(() => {
|
|
90
|
-
this.
|
|
83
|
+
this.isConnectScheduled = false;
|
|
91
84
|
this.createConnections();
|
|
92
85
|
});
|
|
93
86
|
}
|
|
94
87
|
createConnections() {
|
|
95
|
-
const
|
|
96
|
-
const
|
|
97
|
-
const
|
|
98
|
-
if (
|
|
88
|
+
const tickerStreamList = this.tickerHandlerSet.size > 0 ? ['!miniTicker@arr'] : [];
|
|
89
|
+
const klineStreamList = buildKlineStreamList(this.klineHandlerByKey);
|
|
90
|
+
const allStreamList = [...tickerStreamList, ...klineStreamList];
|
|
91
|
+
if (allStreamList.length === 0) {
|
|
99
92
|
return;
|
|
100
93
|
}
|
|
101
|
-
for (let i = 0; i <
|
|
102
|
-
const
|
|
103
|
-
this.createConnection(
|
|
94
|
+
for (let i = 0; i < allStreamList.length; i += MAX_STREAMS_PER_CONNECTION) {
|
|
95
|
+
const streamChunk = allStreamList.slice(i, i + MAX_STREAMS_PER_CONNECTION);
|
|
96
|
+
this.createConnection(streamChunk, this.connectionList.length);
|
|
104
97
|
}
|
|
105
|
-
this.logger.info(`BinanceFuturesPublicStream: created ${this.
|
|
98
|
+
this.logger.info(`BinanceFuturesPublicStream: created ${this.connectionList.length} connection(s) for ${allStreamList.length} streams`);
|
|
106
99
|
}
|
|
107
|
-
createConnection(
|
|
108
|
-
const
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
100
|
+
createConnection(streamList, index) {
|
|
101
|
+
const label = `BinanceFuturesPublicStream-${index}`;
|
|
102
|
+
const url = `${this.webSocketCombinedUrl}?streams=${streamList.join('/')}`;
|
|
103
|
+
const webSocket = new websocket_engine_1.ReliableWebSocket({
|
|
104
|
+
label,
|
|
105
|
+
url,
|
|
112
106
|
logger: this.logger,
|
|
113
107
|
parseMessage: parseBinanceCombinedMessage,
|
|
114
108
|
onMessage: (message) => this.handleMessage(message),
|
|
115
|
-
onOpen: async () => {
|
|
116
|
-
this.logger.info(`BinanceFuturesPublicStream connected (${conn.streams.length} streams)`);
|
|
117
|
-
this.sendSubscribe(conn);
|
|
118
|
-
},
|
|
119
|
-
onReconnectSuccess: () => this.sendSubscribe(conn),
|
|
120
109
|
onNotify: this.onNotify,
|
|
121
|
-
heartbeat: {
|
|
122
|
-
buildPayload: () => ({ method: 'PING' }),
|
|
123
|
-
isResponse: (message) => {
|
|
124
|
-
const raw = message;
|
|
125
|
-
return raw['id'] !== undefined && raw['result'] === null;
|
|
126
|
-
},
|
|
127
|
-
},
|
|
128
110
|
configuration: {
|
|
129
111
|
pingInterval: 30000,
|
|
130
112
|
},
|
|
131
113
|
});
|
|
132
|
-
this.
|
|
114
|
+
this.connectionList.push({ webSocket, label, streamList });
|
|
133
115
|
}
|
|
134
116
|
addStreamToConnection(stream) {
|
|
135
|
-
let
|
|
136
|
-
if (!
|
|
137
|
-
this.createConnection([stream]);
|
|
117
|
+
let targetConnection = this.connectionList.find((connection) => connection.streamList.length < MAX_STREAMS_PER_CONNECTION);
|
|
118
|
+
if (!targetConnection) {
|
|
119
|
+
this.createConnection([stream], this.connectionList.length);
|
|
138
120
|
return;
|
|
139
121
|
}
|
|
140
|
-
|
|
122
|
+
targetConnection.streamList.push(stream);
|
|
141
123
|
try {
|
|
142
|
-
|
|
124
|
+
targetConnection.webSocket.sendToConnectedSocket({
|
|
143
125
|
method: 'SUBSCRIBE',
|
|
144
126
|
params: [stream],
|
|
145
127
|
id: this.subscriptionIdCounter++,
|
|
146
128
|
});
|
|
147
129
|
}
|
|
148
130
|
catch {
|
|
149
|
-
|
|
131
|
+
this.logger.warn('BinanceFuturesPublicStream: failed to subscribe, socket not connected');
|
|
150
132
|
}
|
|
151
133
|
}
|
|
152
134
|
removeStreamFromConnection(stream) {
|
|
153
|
-
for (const
|
|
154
|
-
const
|
|
155
|
-
if (
|
|
156
|
-
|
|
135
|
+
for (const connection of this.connectionList) {
|
|
136
|
+
const index = connection.streamList.indexOf(stream);
|
|
137
|
+
if (index !== -1) {
|
|
138
|
+
connection.streamList.splice(index, 1);
|
|
157
139
|
try {
|
|
158
|
-
|
|
140
|
+
connection.webSocket.sendToConnectedSocket({
|
|
159
141
|
method: 'UNSUBSCRIBE',
|
|
160
142
|
params: [stream],
|
|
161
143
|
id: this.subscriptionIdCounter++,
|
|
162
144
|
});
|
|
163
145
|
}
|
|
164
146
|
catch {
|
|
165
|
-
|
|
147
|
+
this.logger.warn('BinanceFuturesPublicStream: failed to unsubscribe, socket not connected');
|
|
166
148
|
}
|
|
167
149
|
break;
|
|
168
150
|
}
|
|
169
151
|
}
|
|
170
152
|
}
|
|
171
|
-
sendSubscribe(conn) {
|
|
172
|
-
try {
|
|
173
|
-
conn.ws.sendToConnectedSocket({
|
|
174
|
-
method: 'SUBSCRIBE',
|
|
175
|
-
params: conn.streams,
|
|
176
|
-
id: this.subscriptionIdCounter++,
|
|
177
|
-
});
|
|
178
|
-
}
|
|
179
|
-
catch {
|
|
180
|
-
this.logger.warn('BinanceFuturesPublicStream: failed to subscribe, socket not connected');
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
153
|
handleMessage(message) {
|
|
184
154
|
if (message.data === undefined) {
|
|
185
155
|
return;
|
|
@@ -196,17 +166,17 @@ class BinanceFuturesPublicStream {
|
|
|
196
166
|
if (!klineRaw) {
|
|
197
167
|
return;
|
|
198
168
|
}
|
|
199
|
-
const kline = (0, binanceNormalizer_1.
|
|
169
|
+
const kline = (0, binanceNormalizer_1.normalizeBinanceKlineWebSocketMessage)(klineRaw);
|
|
200
170
|
const continuousKlineIndex = message.stream.indexOf('@continuousKline_');
|
|
201
171
|
const symbolLower = message.stream.slice(0, continuousKlineIndex).replace(/_perpetual$/, '');
|
|
202
172
|
const symbol = symbolLower.toUpperCase();
|
|
203
173
|
const binanceInterval = message.stream.slice(continuousKlineIndex + '@continuousKline_'.length);
|
|
204
|
-
const unifiedInterval =
|
|
174
|
+
const unifiedInterval = (0, binanceWebSocketUtils_1.resolveUnifiedBinanceInterval)(binanceInterval);
|
|
205
175
|
const key = `${symbol}_${unifiedInterval}`;
|
|
206
176
|
const handlerSet = this.klineHandlerByKey.get(key);
|
|
207
177
|
if (handlerSet) {
|
|
208
178
|
for (const handler of handlerSet) {
|
|
209
|
-
handler(kline);
|
|
179
|
+
handler(symbol, kline);
|
|
210
180
|
}
|
|
211
181
|
}
|
|
212
182
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BinanceFuturesPublicStream.js","sourceRoot":"","sources":["../../src/ws/BinanceFuturesPublicStream.ts"],"names":[],"mappings":";;;AACA,kEAAgE;
|
|
1
|
+
{"version":3,"file":"BinanceFuturesPublicStream.js","sourceRoot":"","sources":["../../src/ws/BinanceFuturesPublicStream.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,16 +1,18 @@
|
|
|
1
|
-
import type { ExchangeLogger,
|
|
1
|
+
import type { ExchangeLogger, KlineInterval, TickerBySymbol } from '../types/common';
|
|
2
|
+
import type { KlineHandler } from '../types/exchange';
|
|
2
3
|
declare class BinanceSpotPublicStream {
|
|
3
|
-
private
|
|
4
|
+
private webSocket;
|
|
5
|
+
private readonly webSocketUrl;
|
|
4
6
|
private readonly logger;
|
|
5
7
|
private readonly onNotify?;
|
|
6
8
|
private readonly tickerHandlerSet;
|
|
7
9
|
private readonly klineHandlerByKey;
|
|
8
10
|
private subscriptionIdCounter;
|
|
9
|
-
constructor(logger: ExchangeLogger, onNotify?: (message: string) => void | Promise<void>);
|
|
11
|
+
constructor(webSocketUrl: string, logger: ExchangeLogger, onNotify?: (message: string) => void | Promise<void>);
|
|
10
12
|
subscribeAllTickers(handler: (tickers: TickerBySymbol) => void): void;
|
|
11
13
|
unsubscribeAllTickers(handler: (tickers: TickerBySymbol) => void): void;
|
|
12
|
-
subscribeKlines(symbol: string, interval: KlineInterval, handler:
|
|
13
|
-
unsubscribeKlines(symbol: string, interval: KlineInterval, handler:
|
|
14
|
+
subscribeKlines(symbol: string, interval: KlineInterval, handler: KlineHandler): void;
|
|
15
|
+
unsubscribeKlines(symbol: string, interval: KlineInterval, handler: KlineHandler): void;
|
|
14
16
|
close(): void;
|
|
15
17
|
private ensureConnected;
|
|
16
18
|
private handleOpen;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BinanceSpotPublicStream.d.ts","sourceRoot":"","sources":["../../src/ws/BinanceSpotPublicStream.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,
|
|
1
|
+
{"version":3,"file":"BinanceSpotPublicStream.d.ts","sourceRoot":"","sources":["../../src/ws/BinanceSpotPublicStream.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACrF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAgBtD,cAAM,uBAAuB;IAC3B,OAAO,CAAC,SAAS,CAAgE;IACjF,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiB;IACxC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAA4C;IACtE,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAqD;IACtF,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAA6C;IAC/E,OAAO,CAAC,qBAAqB,CAAK;gBAEtB,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAM9G,mBAAmB,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,GAAG,IAAI;IAKrE,qBAAqB,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,GAAG,IAAI;IAIvE,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,OAAO,EAAE,YAAY,GAAG,IAAI;IAgBrF,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,OAAO,EAAE,YAAY,GAAG,IAAI;IAqBvF,KAAK,IAAI,IAAI;IAQb,OAAO,CAAC,eAAe;YAwBT,UAAU;IAKxB,OAAO,CAAC,aAAa;IA8BrB,OAAO,CAAC,qBAAqB;IA4B7B,OAAO,CAAC,cAAc;IAoBtB,OAAO,CAAC,aAAa;IAYrB,OAAO,CAAC,eAAe;CAWxB;AAED,OAAO,EAAE,uBAAuB,EAAE,CAAC"}
|
|
@@ -3,26 +3,20 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.BinanceSpotPublicStream = void 0;
|
|
4
4
|
const websocket_engine_1 = require("@solncebro/websocket-engine");
|
|
5
5
|
const binanceNormalizer_1 = require("../normalizers/binanceNormalizer");
|
|
6
|
-
const
|
|
6
|
+
const binanceWebSocketUtils_1 = require("./binanceWebSocketUtils");
|
|
7
7
|
function parseBinanceSpotMessage(rawData) {
|
|
8
8
|
return JSON.parse(rawData.toString());
|
|
9
9
|
}
|
|
10
|
-
function resolveUnifiedInterval(binanceInterval) {
|
|
11
|
-
for (const [unified, binance] of Object.entries(binance_1.BINANCE_KLINE_INTERVAL)) {
|
|
12
|
-
if (binance === binanceInterval) {
|
|
13
|
-
return unified;
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
return '1m';
|
|
17
|
-
}
|
|
18
10
|
class BinanceSpotPublicStream {
|
|
19
|
-
|
|
11
|
+
webSocket = null;
|
|
12
|
+
webSocketUrl;
|
|
20
13
|
logger;
|
|
21
14
|
onNotify;
|
|
22
15
|
tickerHandlerSet = new Set();
|
|
23
16
|
klineHandlerByKey = new Map();
|
|
24
17
|
subscriptionIdCounter = 1;
|
|
25
|
-
constructor(logger, onNotify) {
|
|
18
|
+
constructor(webSocketUrl, logger, onNotify) {
|
|
19
|
+
this.webSocketUrl = webSocketUrl;
|
|
26
20
|
this.logger = logger;
|
|
27
21
|
this.onNotify = onNotify;
|
|
28
22
|
}
|
|
@@ -35,12 +29,11 @@ class BinanceSpotPublicStream {
|
|
|
35
29
|
}
|
|
36
30
|
subscribeKlines(symbol, interval, handler) {
|
|
37
31
|
const key = `${symbol}_${interval}`;
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
this.
|
|
42
|
-
|
|
43
|
-
const binanceInterval = binance_1.BINANCE_KLINE_INTERVAL[interval];
|
|
32
|
+
const handlerSet = this.klineHandlerByKey.get(key) ?? new Set();
|
|
33
|
+
handlerSet.add(handler);
|
|
34
|
+
this.klineHandlerByKey.set(key, handlerSet);
|
|
35
|
+
if (this.webSocket !== null) {
|
|
36
|
+
const binanceInterval = interval;
|
|
44
37
|
const stream = `${symbol.toLowerCase()}@kline_${binanceInterval}`;
|
|
45
38
|
this.sendSubscribe([stream]);
|
|
46
39
|
}
|
|
@@ -57,26 +50,26 @@ class BinanceSpotPublicStream {
|
|
|
57
50
|
handlerSet.delete(handler);
|
|
58
51
|
if (handlerSet.size === 0) {
|
|
59
52
|
this.klineHandlerByKey.delete(key);
|
|
60
|
-
if (this.
|
|
61
|
-
const binanceInterval =
|
|
53
|
+
if (this.webSocket !== null) {
|
|
54
|
+
const binanceInterval = interval;
|
|
62
55
|
const stream = `${symbol.toLowerCase()}@kline_${binanceInterval}`;
|
|
63
56
|
this.sendUnsubscribe([stream]);
|
|
64
57
|
}
|
|
65
58
|
}
|
|
66
59
|
}
|
|
67
60
|
close() {
|
|
68
|
-
if (this.
|
|
69
|
-
this.
|
|
70
|
-
this.
|
|
61
|
+
if (this.webSocket !== null) {
|
|
62
|
+
this.webSocket.close();
|
|
63
|
+
this.webSocket = null;
|
|
71
64
|
}
|
|
72
65
|
}
|
|
73
66
|
ensureConnected() {
|
|
74
|
-
if (this.
|
|
67
|
+
if (this.webSocket !== null) {
|
|
75
68
|
return;
|
|
76
69
|
}
|
|
77
|
-
this.
|
|
70
|
+
this.webSocket = new websocket_engine_1.ReliableWebSocket({
|
|
78
71
|
label: 'BinanceSpotPublicStream',
|
|
79
|
-
url:
|
|
72
|
+
url: this.webSocketUrl,
|
|
80
73
|
logger: this.logger,
|
|
81
74
|
parseMessage: parseBinanceSpotMessage,
|
|
82
75
|
onMessage: (message) => this.handleMessage(message),
|
|
@@ -127,17 +120,17 @@ class BinanceSpotPublicStream {
|
|
|
127
120
|
if (!klineRaw) {
|
|
128
121
|
return;
|
|
129
122
|
}
|
|
130
|
-
const kline = (0, binanceNormalizer_1.
|
|
123
|
+
const kline = (0, binanceNormalizer_1.normalizeBinanceKlineWebSocketMessage)(klineRaw);
|
|
131
124
|
const atIndex = stream.indexOf('@kline_');
|
|
132
125
|
const symbolLower = stream.slice(0, atIndex);
|
|
133
126
|
const binanceInterval = stream.slice(atIndex + '@kline_'.length);
|
|
134
127
|
const symbol = symbolLower.toUpperCase();
|
|
135
|
-
const unifiedInterval =
|
|
128
|
+
const unifiedInterval = (0, binanceWebSocketUtils_1.resolveUnifiedBinanceInterval)(binanceInterval);
|
|
136
129
|
const key = `${symbol}_${unifiedInterval}`;
|
|
137
130
|
const handlerSet = this.klineHandlerByKey.get(key);
|
|
138
131
|
if (handlerSet) {
|
|
139
132
|
for (const handler of handlerSet) {
|
|
140
|
-
handler(kline);
|
|
133
|
+
handler(symbol, kline);
|
|
141
134
|
}
|
|
142
135
|
}
|
|
143
136
|
}
|
|
@@ -150,7 +143,7 @@ class BinanceSpotPublicStream {
|
|
|
150
143
|
const separatorIndex = key.lastIndexOf('_');
|
|
151
144
|
const symbol = key.slice(0, separatorIndex);
|
|
152
145
|
const interval = key.slice(separatorIndex + 1);
|
|
153
|
-
const binanceInterval =
|
|
146
|
+
const binanceInterval = interval;
|
|
154
147
|
streamList.push(`${symbol.toLowerCase()}@kline_${binanceInterval}`);
|
|
155
148
|
}
|
|
156
149
|
if (streamList.length > 0) {
|
|
@@ -159,7 +152,7 @@ class BinanceSpotPublicStream {
|
|
|
159
152
|
}
|
|
160
153
|
sendSubscribe(streamList) {
|
|
161
154
|
try {
|
|
162
|
-
this.
|
|
155
|
+
this.webSocket?.sendToConnectedSocket({
|
|
163
156
|
method: 'SUBSCRIBE',
|
|
164
157
|
params: streamList,
|
|
165
158
|
id: this.subscriptionIdCounter++,
|
|
@@ -171,7 +164,7 @@ class BinanceSpotPublicStream {
|
|
|
171
164
|
}
|
|
172
165
|
sendUnsubscribe(streamList) {
|
|
173
166
|
try {
|
|
174
|
-
this.
|
|
167
|
+
this.webSocket?.sendToConnectedSocket({
|
|
175
168
|
method: 'UNSUBSCRIBE',
|
|
176
169
|
params: streamList,
|
|
177
170
|
id: this.subscriptionIdCounter++,
|