Skip to content

Commit 44ab2d0

Browse files
committed
Merge branch 'master' of github.com:ccxt/binance-api-node
2 parents 9c4f558 + 8430125 commit 44ab2d0

5 files changed

Lines changed: 343 additions & 19 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "binance-api-node",
3-
"version": "0.13.7",
3+
"version": "0.13.8",
44
"description": "A node API wrapper for Binance",
55
"main": "dist",
66
"types": "index.d.ts",

src/websocket.js

Lines changed: 260 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ import { createHmacSignature, createAsymmetricSignature } from 'signature'
77

88
const endpoints = {
99
base: 'wss://stream.binance.com:9443/ws',
10-
futures: 'wss://fstream.binance.com/ws',
10+
futures: 'wss://fstream.binance.com/market/ws',
11+
futuresPublic: 'wss://fstream.binance.com/public/ws',
12+
futuresMarket: 'wss://fstream.binance.com/market/ws',
13+
futuresPrivate: 'wss://fstream.binance.com/private/ws',
1114
delivery: 'wss://dstream.binance.com/ws',
1215
}
1316

@@ -56,9 +59,13 @@ const depth = (payload, cb, transform = true, variator) => {
5659
const cache = (Array.isArray(payload) ? payload : [payload]).map(symbol => {
5760
const [symbolName, updateSpeed] = symbol.toLowerCase().split('@')
5861
const w = openWebSocket(
59-
`${variator ? endpoints[variator] : endpoints.base}/${symbolName}@depth${
60-
updateSpeed ? `@${updateSpeed}` : ''
61-
}`,
62+
`${
63+
variator === 'futures'
64+
? endpoints.futuresPublic
65+
: variator
66+
? endpoints[variator]
67+
: endpoints.base
68+
}/${symbolName}@depth${updateSpeed ? `@${updateSpeed}` : ''}`,
6269
)
6370
w.onmessage = msg => {
6471
const obj = JSONbig.parse(msg.data)
@@ -86,7 +93,7 @@ const depth = (payload, cb, transform = true, variator) => {
8693
const futuresRpiDepth = (payload, cb, transform = true) => {
8794
const cache = (Array.isArray(payload) ? payload : [payload]).map(symbol => {
8895
const symbolName = symbol.toLowerCase()
89-
const w = openWebSocket(`${endpoints.futures}/${symbolName}@rpiDepth@500ms`)
96+
const w = openWebSocket(`${endpoints.futuresPublic}/${symbolName}@rpiDepth@500ms`)
9097
w.onmessage = msg => {
9198
const obj = JSONbig.parse(msg.data)
9299
cb(transform ? futuresDepthTransform(obj) : obj)
@@ -140,9 +147,13 @@ const partialDepth = (payload, cb, transform = true, variator) => {
140147
const cache = (Array.isArray(payload) ? payload : [payload]).map(({ symbol, level }) => {
141148
const [symbolName, updateSpeed] = symbol.toLowerCase().split('@')
142149
const w = openWebSocket(
143-
`${variator ? endpoints[variator] : endpoints.base}/${symbolName}@depth${level}${
144-
updateSpeed ? `@${updateSpeed}` : ''
145-
}`,
150+
`${
151+
variator === 'futures'
152+
? endpoints.futuresPublic
153+
: variator
154+
? endpoints[variator]
155+
: endpoints.base
156+
}/${symbolName}@depth${level}${updateSpeed ? `@${updateSpeed}` : ''}`,
146157
)
147158
w.onmessage = msg => {
148159
const obj = JSONbig.parse(msg.data)
@@ -211,7 +222,11 @@ const candles = (payload, interval, cb, transform = true, variator) => {
211222
const cache = (Array.isArray(payload) ? payload : [payload]).map(symbol => {
212223
const w = openWebSocket(
213224
`${
214-
variator ? endpoints[variator] : endpoints.base
225+
variator === 'futures'
226+
? endpoints.futuresMarket
227+
: variator === 'delivery'
228+
? endpoints.delivery
229+
: endpoints.base
215230
}/${symbol.toLowerCase()}@kline_${interval}`,
216231
)
217232
w.onmessage = msg => {
@@ -367,7 +382,7 @@ const ticker = (payload, cb, transform = true, variator) => {
367382
const w = openWebSocket(
368383
`${
369384
variator === 'futures'
370-
? endpoints.futures
385+
? endpoints.futuresMarket
371386
: variator === 'delivery'
372387
? endpoints.delivery
373388
: endpoints.base
@@ -400,7 +415,7 @@ const allTickers = (cb, transform = true, variator) => {
400415
const w = new openWebSocket(
401416
`${
402417
variator === 'futures'
403-
? endpoints.futures
418+
? endpoints.futuresMarket
404419
: variator === 'delivery'
405420
? endpoints.delivery
406421
: endpoints.base
@@ -550,7 +565,7 @@ const aggTrades = (payload, cb, transform = true, variator) => {
550565
const w = openWebSocket(
551566
`${
552567
variator === 'futures'
553-
? endpoints.futures
568+
? endpoints.futuresMarket
554569
: variator === 'delivery'
555570
? endpoints.delivery
556571
: endpoints.base
@@ -593,7 +608,7 @@ const futuresLiqsTransform = m => ({
593608

594609
const futuresLiquidations = (payload, cb, transform = true) => {
595610
const cache = (Array.isArray(payload) ? payload : [payload]).map(symbol => {
596-
const w = openWebSocket(`${endpoints.futures}/${symbol.toLowerCase()}@forceOrder`)
611+
const w = openWebSocket(`${endpoints.futuresMarket}/${symbol.toLowerCase()}@forceOrder`)
597612
w.onmessage = msg => {
598613
const obj = JSONbig.parse(msg.data)
599614

@@ -610,7 +625,7 @@ const futuresLiquidations = (payload, cb, transform = true) => {
610625
}
611626

612627
const futuresAllLiquidations = (cb, transform = true) => {
613-
const w = new openWebSocket(`${endpoints.futures}/!forceOrder@arr`)
628+
const w = new openWebSocket(`${endpoints.futuresMarket}/!forceOrder@arr`)
614629

615630
w.onmessage = msg => {
616631
const obj = JSONbig.parse(msg.data)
@@ -620,6 +635,218 @@ const futuresAllLiquidations = (cb, transform = true) => {
620635
return options => w.close(1000, 'Close handle was called', { keepClosed: true, ...options })
621636
}
622637

638+
const futuresBookTicker = (payload, cb, transform = true) => {
639+
const cache = (Array.isArray(payload) ? payload : [payload]).map(symbol => {
640+
const w = openWebSocket(`${endpoints.futuresPublic}/${symbol.toLowerCase()}@bookTicker`)
641+
642+
w.onmessage = msg => {
643+
const obj = JSONbig.parse(msg.data)
644+
cb(transform ? bookTickerTransform(obj) : obj)
645+
}
646+
647+
return w
648+
})
649+
650+
return options =>
651+
cache.forEach(w =>
652+
w.close(1000, 'Close handle was called', { keepClosed: true, ...options }),
653+
)
654+
}
655+
656+
const futuresAllBookTickers = (cb, transform = true) => {
657+
const w = openWebSocket(`${endpoints.futuresPublic}/!bookTicker`)
658+
659+
w.onmessage = msg => {
660+
const obj = JSONbig.parse(msg.data)
661+
cb(transform ? bookTickerTransform(obj) : obj)
662+
}
663+
664+
return options => w.close(1000, 'Close handle was called', { keepClosed: true, ...options })
665+
}
666+
667+
const futuresMarkPriceTransform = m => ({
668+
eventType: m.e,
669+
eventTime: m.E,
670+
symbol: m.s,
671+
markPrice: m.p,
672+
indexPrice: m.i,
673+
settlePrice: m.P,
674+
fundingRate: m.r,
675+
nextFundingRate: m.T,
676+
})
677+
678+
const futuresMarkPrice = (payload, cb, transform = true) => {
679+
const cache = (Array.isArray(payload) ? payload : [payload]).map(input => {
680+
const symbol = typeof input === 'object' ? input.symbol : input
681+
const updateSpeed = typeof input === 'object' ? input.updateSpeed : undefined
682+
const stream =
683+
updateSpeed === '1s'
684+
? `${symbol.toLowerCase()}@markPrice@1s`
685+
: `${symbol.toLowerCase()}@markPrice`
686+
687+
const w = openWebSocket(`${endpoints.futuresMarket}/${stream}`)
688+
689+
w.onmessage = msg => {
690+
const obj = JSONbig.parse(msg.data)
691+
cb(transform ? futuresMarkPriceTransform(obj) : obj)
692+
}
693+
694+
return w
695+
})
696+
697+
return options =>
698+
cache.forEach(w =>
699+
w.close(1000, 'Close handle was called', { keepClosed: true, ...options }),
700+
)
701+
}
702+
703+
const futuresContinuousCandles = (payload, interval, cb, transform = true) => {
704+
if (!interval || !cb) {
705+
throw new Error('Please pass a pair, contractType, interval and callback.')
706+
}
707+
708+
const pair = payload.pair.toLowerCase()
709+
const contractType = payload.contractType.toLowerCase()
710+
711+
const w = openWebSocket(
712+
`${endpoints.futuresMarket}/${pair}_${contractType}@continuousKline_${interval}`,
713+
)
714+
715+
w.onmessage = msg => {
716+
const obj = JSONbig.parse(msg.data)
717+
const { e: eventType, E: eventTime, ps: pairSymbol, ct: contType, k: tick } = obj
718+
719+
cb(
720+
transform
721+
? {
722+
eventType,
723+
eventTime,
724+
pair: pairSymbol,
725+
contractType: contType,
726+
...candleTransform(tick),
727+
}
728+
: obj,
729+
)
730+
}
731+
732+
return options => w.close(1000, 'Close handle was called', { keepClosed: true, ...options })
733+
}
734+
735+
const futuresCompositeIndex = (payload, cb, transform = true) => {
736+
const cache = (Array.isArray(payload) ? payload : [payload]).map(symbol => {
737+
const w = openWebSocket(`${endpoints.futuresMarket}/${symbol.toLowerCase()}@compositeIndex`)
738+
739+
w.onmessage = msg => {
740+
const obj = JSONbig.parse(msg.data)
741+
cb(
742+
transform
743+
? {
744+
eventType: obj.e,
745+
eventTime: obj.E,
746+
symbol: obj.s,
747+
price: obj.p,
748+
composition: obj.c
749+
? obj.c.map(c => ({
750+
baseAsset: c.b,
751+
quoteAsset: c.q,
752+
weightInQuantity: c.w,
753+
weightInPercentage: c.W,
754+
indexPrice: c.i,
755+
}))
756+
: [],
757+
}
758+
: obj,
759+
)
760+
}
761+
762+
return w
763+
})
764+
765+
return options =>
766+
cache.forEach(w =>
767+
w.close(1000, 'Close handle was called', { keepClosed: true, ...options }),
768+
)
769+
}
770+
771+
const futuresContractInfo = (cb, transform = true) => {
772+
const w = openWebSocket(`${endpoints.futuresMarket}/!contractInfo`)
773+
774+
w.onmessage = msg => {
775+
const obj = JSONbig.parse(msg.data)
776+
cb(
777+
transform
778+
? {
779+
eventType: obj.e,
780+
eventTime: obj.E,
781+
symbol: obj.s,
782+
pair: obj.ps,
783+
contractType: obj.ct,
784+
deliveryDate: obj.dt,
785+
onboardDate: obj.ot,
786+
contractStatus: obj.cs,
787+
brackets: obj.bks
788+
? obj.bks.map(b => ({
789+
notionalBracket: b.bs,
790+
floorNotional: b.bnf,
791+
capNotional: b.bnc,
792+
maintenanceRatio: b.mmr,
793+
auxiliaryNumber: b.cf,
794+
minLeverage: b.mi,
795+
maxLeverage: b.ma,
796+
}))
797+
: [],
798+
}
799+
: obj,
800+
)
801+
}
802+
803+
return options => w.close(1000, 'Close handle was called', { keepClosed: true, ...options })
804+
}
805+
806+
const futuresAssetIndexTransform = m => ({
807+
eventType: m.e,
808+
eventTime: m.E,
809+
symbol: m.s,
810+
index: m.i,
811+
bidBuffer: m.b,
812+
askBuffer: m.a,
813+
bidRate: m.B,
814+
askRate: m.A,
815+
autoExchangeBidBuffer: m.q,
816+
autoExchangeAskBuffer: m.Q,
817+
autoExchangeBidRate: m.g,
818+
autoExchangeAskRate: m.G,
819+
})
820+
821+
const futuresAssetIndex = (payload, cb, transform = true) => {
822+
const cache = (Array.isArray(payload) ? payload : [payload]).map(symbol => {
823+
const w = openWebSocket(`${endpoints.futuresMarket}/${symbol.toLowerCase()}@assetIndex`)
824+
825+
w.onmessage = msg => {
826+
const obj = JSONbig.parse(msg.data)
827+
cb(transform ? futuresAssetIndexTransform(obj) : obj)
828+
}
829+
830+
return w
831+
})
832+
833+
return options =>
834+
cache.forEach(w =>
835+
w.close(1000, 'Close handle was called', { keepClosed: true, ...options }),
836+
)
837+
}
838+
839+
const futuresAllAssetIndex = (cb, transform = true) => {
840+
const w = openWebSocket(`${endpoints.futuresMarket}/!assetIndex@arr`)
841+
842+
w.onmessage = msg => {
843+
const arr = JSONbig.parse(msg.data)
844+
cb(transform ? arr.map(futuresAssetIndexTransform) : arr)
845+
}
846+
847+
return options => w.close(1000, 'Close handle was called', { keepClosed: true, ...options })
848+
}
849+
623850
const tradesTransform = m => ({
624851
eventType: m.e,
625852
eventTime: m.E,
@@ -1225,7 +1452,7 @@ const user = (opts, variator) => (cb, transform) => {
12251452
w = openWebSocket(
12261453
`${
12271454
variator === 'futures'
1228-
? endpoints.futures
1455+
? endpoints.futuresPrivate
12291456
: variator === 'delivery'
12301457
? endpoints.delivery
12311458
: endpoints.base
@@ -1282,7 +1509,7 @@ const futuresAllMarkPricesTransform = m =>
12821509
const futuresAllMarkPrices = (payload, cb, transform = true) => {
12831510
const variant = payload.updateSpeed === '1s' ? '!markPrice@arr@1s' : '!markPrice@arr'
12841511

1285-
const w = openWebSocket(`${endpoints.futures}/${variant}`)
1512+
const w = openWebSocket(`${endpoints.futuresMarket}/${variant}`)
12861513

12871514
w.onmessage = msg => {
12881515
const arr = JSONbig.parse(msg.data)
@@ -1294,7 +1521,15 @@ const futuresAllMarkPrices = (payload, cb, transform = true) => {
12941521

12951522
export default opts => {
12961523
if (opts && opts.wsBase) endpoints.base = opts.wsBase
1297-
if (opts && opts.wsFutures) endpoints.futures = opts.wsFutures
1524+
if (opts && opts.wsFutures) {
1525+
endpoints.futures = opts.wsFutures
1526+
endpoints.futuresPublic = opts.wsFutures
1527+
endpoints.futuresMarket = opts.wsFutures
1528+
endpoints.futuresPrivate = opts.wsFutures
1529+
}
1530+
if (opts && opts.wsFuturesPublic) endpoints.futuresPublic = opts.wsFuturesPublic
1531+
if (opts && opts.wsFuturesMarket) endpoints.futuresMarket = opts.wsFuturesMarket
1532+
if (opts && opts.wsFuturesPrivate) endpoints.futuresPrivate = opts.wsFuturesPrivate
12981533
if (opts && opts.wsDelivery) endpoints.delivery = opts.wsDelivery
12991534

13001535
if (opts && opts.proxy) {
@@ -1344,6 +1579,14 @@ export default opts => {
13441579
aggTrades(payload, cb, transform, 'delivery'),
13451580
futuresLiquidations,
13461581
futuresAllLiquidations,
1582+
futuresBookTicker,
1583+
futuresAllBookTickers,
1584+
futuresMarkPrice,
1585+
futuresContinuousCandles,
1586+
futuresCompositeIndex,
1587+
futuresContractInfo,
1588+
futuresAssetIndex,
1589+
futuresAllAssetIndex,
13471590
futuresUser: user(opts, 'futures'),
13481591
deliveryUser: user(opts, 'delivery'),
13491592
futuresCustomSubStream: (payload, cb) => customSubStream(payload, cb, 'futures'),

test/utils.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import http from 'http'
22

33
export const checkFields = (t, object, fields) => {
44
fields.forEach(field => {
5-
t.truthy(object[field])
5+
t.truthy(field in object)
66
})
77
}
88

0 commit comments

Comments
 (0)