From b7762ee3ac03de7eb3db42bb54c461bb329a155c Mon Sep 17 00:00:00 2001 From: carlosmiei <43336371+carlosmiei@users.noreply.github.com> Date: Tue, 15 Apr 2025 15:31:30 +0100 Subject: [PATCH 1/5] fix(client): candles return type --- src/node-binance-api.ts | 56 ++++++++++++++++++++++++++++++++++++----- src/types.ts | 4 +-- 2 files changed, 52 insertions(+), 8 deletions(-) diff --git a/src/node-binance-api.ts b/src/node-binance-api.ts index 8c083158..3b5b8270 100644 --- a/src/node-binance-api.ts +++ b/src/node-binance-api.ts @@ -3809,7 +3809,8 @@ export default class Binance { async candlesticks(symbol: string, interval: Interval = '5m', params: Dict = {}): Promise { if (!params.limit) params.limit = 500; params = Object.assign({ symbol: symbol, interval: interval }, params); - return await this.publicSpotRequest('v3/klines', params); + const res = await this.publicSpotRequest('v3/klines', params); + return this.parseCandles(res); } /** @@ -3825,6 +3826,42 @@ export default class Binance { return await this.candlesticks(symbol, interval, params); // make name consistent with futures } + parseCandles(candles: any[]): Candle[] { + const res: Candle[] = []; + // spot + // [ + // [ + // 1499040000000, // Open time + // "0.01634790", // Open + // "0.80000000", // High + // "0.01575800", // Low + // "0.01577100", // Close + // "148976.11427815", // Volume + // 1499644799999, // Close time + // "2434.19055334", // Quote asset volume + // 308, // Number of trades + // "1756.87402397", // Taker buy base asset volume + // "28.46694368", // Taker buy quote asset volume + // "17928899.62484339" // Ignore. + // ] + // ] + for (const rawCandle of candles) { + const candle: Candle = { + openTime: rawCandle[0], + open: rawCandle[1], + high: rawCandle[2], + low: rawCandle[3], + close: rawCandle[4], + volume: rawCandle[5], + closeTime: rawCandle[6], + quoteAssetVolume: rawCandle[7], + trades: rawCandle[8], + }; + res.push(candle); + } + return res; + } + // /** // * Queries the public api // * @param {string} url - the public api endpoint @@ -3958,16 +3995,15 @@ export default class Binance { async futuresCandles(symbol: string, interval: Interval = "30m", params: Dict = {}): Promise { params.symbol = symbol; params.interval = interval; - return await this.publicFuturesRequest('v1/klines', params); + const res = await this.publicFuturesRequest('v1/klines', params); + return this.parseCandles(res); } /** * @see https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/Kline-Candlestick-Data */ async futuresCandlesticks(symbol: string, interval: Interval = "30m", params: Dict = {}): Promise { - params.symbol = symbol; - params.interval = interval; - return await this.publicFuturesRequest('v1/klines', params); + return await this.futuresCandles(symbol, interval, params); // make name consistent with spot } /** @@ -4480,10 +4516,18 @@ export default class Binance { return res; } + /** + * @see https://developers.binance.com/docs/derivatives/coin-margined-futures/market-data/rest-api/Kline-Candlestick-Data + * @param symbol + * @param interval + * @param params + * @returns + */ async deliveryCandles(symbol: string, interval: Interval = "30m", params: Dict = {}): Promise { params.symbol = symbol; params.interval = interval; - return await this.publicDeliveryRequest('v1/klines', params); + const res = await this.publicDeliveryRequest('v1/klines', params); + return this.parseCandles(res); } async deliveryContinuousKlines(pair: string, contractType = "CURRENT_QUARTER", interval: Interval = "30m", params: Dict = {}) { diff --git a/src/types.ts b/src/types.ts index d90b9e56..0b6292a5 100644 --- a/src/types.ts +++ b/src/types.ts @@ -52,9 +52,9 @@ export interface Candle { close: string volume: string closeTime: number - quoteVolume: string + quoteVolume?: string trades: number - baseAssetVolume: string + baseAssetVolume?: string quoteAssetVolume: string } From fea3a3c4f7446a4ff12cf53eb6eb868987a65c77 Mon Sep 17 00:00:00 2001 From: carlosmiei <43336371+carlosmiei@users.noreply.github.com> Date: Tue, 15 Apr 2025 15:34:24 +0100 Subject: [PATCH 2/5] fix tests --- tests/binance-class-static.test.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/tests/binance-class-static.test.ts b/tests/binance-class-static.test.ts index 4edd61dc..52e7d600 100644 --- a/tests/binance-class-static.test.ts +++ b/tests/binance-class-static.test.ts @@ -65,13 +65,21 @@ describe( 'Static tests', async function () { }) it( 'OHLCVS', async function ( ) { - await binance.candlesticks( 'BTCUSDT' ) + try { + await binance.candlesticks( 'BTCUSDT' ) + } catch (e) { + // console.log(e) + } assert.equal( interceptedUrl, 'https://api.binance.com/api/v3/klines?symbol=BTCUSDT&interval=5m&limit=500' ) }) it( 'Futures OHLCVS', async function ( ) { - await binance.futuresCandles( 'BTCUSDT' ) + try { + await binance.futuresCandles( 'BTCUSDT' ) + } catch (e) { + // console.log(e) + } assert.equal( interceptedUrl, 'https://fapi.binance.com/fapi/v1/klines?symbol=BTCUSDT&interval=30m' ) }) From 3082745cc11bf8eeefd4583ec2b9c88db22aaa6e Mon Sep 17 00:00:00 2001 From: carlosmiei <43336371+carlosmiei@users.noreply.github.com> Date: Tue, 15 Apr 2025 15:43:32 +0100 Subject: [PATCH 3/5] aggTrades fix --- src/node-binance-api.ts | 22 +++++++++++++++++++++- src/types.ts | 2 +- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/node-binance-api.ts b/src/node-binance-api.ts index 3b5b8270..c42a223b 100644 --- a/src/node-binance-api.ts +++ b/src/node-binance-api.ts @@ -3718,6 +3718,25 @@ export default class Binance { return await this.publicSpotRequest('v3/ping', {}); } + parseAggTrades(symbol: string, trades: any[]): AggregatedTrade[] { + const parsedTrades: AggregatedTrade[] = []; + for (const trade of trades) { + const aggT: AggregatedTrade = { + aggId: trade.a, + symbol: symbol, + price: trade.p, + quantity: trade.q, + firstId: trade.f, + lastId: trade.l, + timestamp: trade.T, + isBuyerMaker: trade.m, + }; + if (trade.M) aggT.wasBestPrice = trade.M; + parsedTrades.push(aggT); + } + return parsedTrades; + } + /** * Get agg trades for given symbol * @see https://developers.binance.com/docs/binance-spot-api-docs/rest-api/market-data-endpoints#compressedaggregate-trades-list @@ -3727,7 +3746,8 @@ export default class Binance { */ async aggTrades(symbol: string, params: Dict = {}): Promise { //fromId startTime endTime limit const parameters = Object.assign({ symbol }, params); - return await this.publicSpotRequest('v3/aggTrades', parameters); + const res = await this.publicSpotRequest('v3/aggTrades', parameters); + return this.parseAggTrades(symbol, res); } /** diff --git a/src/types.ts b/src/types.ts index 0b6292a5..6ee30827 100644 --- a/src/types.ts +++ b/src/types.ts @@ -258,7 +258,7 @@ export interface AggregatedTrade { lastId: number timestamp: number isBuyerMaker: boolean - wasBestPrice: boolean + wasBestPrice?: boolean } export interface Trade { From 411e145a6588141cf9208238b2bd9dea22837e64 Mon Sep 17 00:00:00 2001 From: carlosmiei <43336371+carlosmiei@users.noreply.github.com> Date: Tue, 15 Apr 2025 15:57:58 +0100 Subject: [PATCH 4/5] add tests --- tests/binance-class-static.test.ts | 25 +++++++++++++++++++++++-- tests/static-tests.mjs | 18 +++++++++++++++--- 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/tests/binance-class-static.test.ts b/tests/binance-class-static.test.ts index 52e7d600..1ef4a078 100644 --- a/tests/binance-class-static.test.ts +++ b/tests/binance-class-static.test.ts @@ -84,8 +84,21 @@ describe( 'Static tests', async function () { }) - it( 'Trades', async function ( ) { - await binance.aggTrades( 'BTCUSDT' ) + it( 'Recent Trades', async function ( ) { + try { + await binance.recentTrades( 'BTCUSDT' ) + } catch (e) { + // console.log(e) + } + assert.equal( interceptedUrl, 'https://api.binance.com/api/v3/trades?symbol=BTCUSDT&limit=500' ) + }) + + it( 'Agg Trades', async function ( ) { + try { + await binance.aggTrades( 'BTCUSDT' ) + } catch (e) { + // console.log(e) + } assert.equal( interceptedUrl, 'https://api.binance.com/api/v3/aggTrades?symbol=BTCUSDT' ) }) @@ -93,7 +106,15 @@ describe( 'Static tests', async function () { it( 'FuturesTrades', async function ( ) { await binance.futuresTrades( 'BTCUSDT' ) assert.equal( interceptedUrl, 'https://fapi.binance.com/fapi/v1/trades?symbol=BTCUSDT' ) + }) + it( 'FuturesAggTrades', async function ( ) { + try { + await binance.futuresAggTrades( 'BTCUSDT' ) + } catch (e) { + // console.log(e) + } + assert.equal( interceptedUrl, 'https://fapi.binance.com/fapi/v1/aggTrades?symbol=BTCUSDT' ) }) it( 'PositionRisk V3', async function ( ) { diff --git a/tests/static-tests.mjs b/tests/static-tests.mjs index 85a3d24d..7a33a6e3 100644 --- a/tests/static-tests.mjs +++ b/tests/static-tests.mjs @@ -75,19 +75,31 @@ describe( 'Static tests', async function () { }) it( 'OHLCVS', async function ( ) { - await binance.candlesticks( 'BTCUSDT' ) + try { + await binance.candlesticks( 'BTCUSDT' ) + } catch (e) { + // console.log(e) + } assert.equal( interceptedUrl, 'https://api.binance.com/api/v3/klines?symbol=BTCUSDT&interval=5m&limit=500' ) }) it( 'Futures OHLCVS', async function ( ) { - await binance.futuresCandles( 'BTCUSDT' ) + try { + await binance.futuresCandles( 'BTCUSDT' ) + } catch (e) { + // console.log(e) + } assert.equal( interceptedUrl, 'https://fapi.binance.com/fapi/v1/klines?symbol=BTCUSDT&interval=30m' ) }) it( 'Trades', async function ( ) { - await binance.aggTrades( 'BTCUSDT' ) + try { + await binance.aggTrades( 'BTCUSDT' ) + } catch (e) { + // console.log(e) + } assert.equal( interceptedUrl, 'https://api.binance.com/api/v3/aggTrades?symbol=BTCUSDT' ) }) From e53da9d6b224cf3d5c2034b54b0cb1ec1959ea41 Mon Sep 17 00:00:00 2001 From: carlosmiei <43336371+carlosmiei@users.noreply.github.com> Date: Tue, 15 Apr 2025 16:07:46 +0100 Subject: [PATCH 5/5] fix maplimit --- src/node-binance-api.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/node-binance-api.ts b/src/node-binance-api.ts index c42a223b..5fc44497 100644 --- a/src/node-binance-api.ts +++ b/src/node-binance-api.ts @@ -5803,10 +5803,11 @@ export default class Binance { } }; - const getSymbolDepthSnapshot = async (symbol: string, cb: Function) => { + const getSymbolDepthSnapshot = async (symbol: string) => { const json = await this.publicSpotRequest('v3/depth', { symbol: symbol, limit: limit }); json.symbol = symbol; - cb(null, json); + // cb(null, json); + return json; }; const updateSymbolDepthCache = json => { @@ -5842,12 +5843,13 @@ export default class Binance { const streams = symbols.map(function (symbol) { return symbol.toLowerCase() + `@depth@100ms`; }); + const mapLimit = this.mapLimit.bind(this); subscription = this.subscribeCombined(streams, handleDepthStreamData, reconnect, function () { // async.mapLimit(symbols, 50, getSymbolDepthSnapshot, (err, results) => { // if (err) throw err; // results.forEach(updateSymbolDepthCache); // }); - this.mapLimit(symbols, 50, getSymbolDepthSnapshot) + mapLimit(symbols, 50, getSymbolDepthSnapshot) .then(results => { results.forEach(updateSymbolDepthCache); }) @@ -5859,12 +5861,13 @@ export default class Binance { } else { const symbol = symbols; symbolDepthInit(symbol); + const mapLimit = this.mapLimit.bind(this); subscription = this.subscribe(symbol.toLowerCase() + `@depth@100ms`, handleDepthStreamData, reconnect, function () { // async.mapLimit([symbol], 1, getSymbolDepthSnapshot, (err, results) => { // if (err) throw err; // results.forEach(updateSymbolDepthCache); // }); - this.mapLimit([symbol], 1, getSymbolDepthSnapshot) + mapLimit([symbol], 1, getSymbolDepthSnapshot) .then(results => { results.forEach(updateSymbolDepthCache); })