ccxt 4.2.84__py2.py3-none-any.whl → 4.2.85__py2.py3-none-any.whl
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.
- ccxt/__init__.py +1 -1
- ccxt/ace.py +5 -5
- ccxt/ascendex.py +8 -8
- ccxt/async_support/__init__.py +1 -1
- ccxt/async_support/ace.py +5 -5
- ccxt/async_support/ascendex.py +8 -8
- ccxt/async_support/base/exchange.py +3 -27
- ccxt/async_support/bigone.py +12 -12
- ccxt/async_support/binance.py +20 -32
- ccxt/async_support/bingx.py +12 -9
- ccxt/async_support/bit2c.py +1 -1
- ccxt/async_support/bitbank.py +8 -8
- ccxt/async_support/bitbns.py +5 -5
- ccxt/async_support/bitfinex.py +1 -1
- ccxt/async_support/bitfinex2.py +1 -1
- ccxt/async_support/bitget.py +29 -24
- ccxt/async_support/bithumb.py +5 -5
- ccxt/async_support/bitmart.py +16 -16
- ccxt/async_support/bitopro.py +1 -1
- ccxt/async_support/bitrue.py +4 -4
- ccxt/async_support/bitso.py +5 -5
- ccxt/async_support/bitstamp.py +1 -1
- ccxt/async_support/bitteam.py +8 -8
- ccxt/async_support/bl3p.py +1 -1
- ccxt/async_support/btcturk.py +6 -6
- ccxt/async_support/bybit.py +30 -83
- ccxt/async_support/coincheck.py +4 -4
- ccxt/async_support/coinex.py +11 -11
- ccxt/async_support/coinlist.py +7 -7
- ccxt/async_support/coinmate.py +4 -4
- ccxt/async_support/coinmetro.py +3 -3
- ccxt/async_support/coinone.py +5 -5
- ccxt/async_support/coinspot.py +2 -2
- ccxt/async_support/cryptocom.py +17 -17
- ccxt/async_support/currencycom.py +1 -1
- ccxt/async_support/delta.py +0 -8
- ccxt/async_support/deribit.py +16 -80
- ccxt/async_support/digifinex.py +8 -8
- ccxt/async_support/exmo.py +8 -8
- ccxt/async_support/gate.py +0 -8
- ccxt/async_support/hitbtc.py +5 -4
- ccxt/async_support/hollaex.py +7 -7
- ccxt/async_support/htx.py +7 -7
- ccxt/async_support/huobijp.py +3 -3
- ccxt/async_support/idex.py +2 -2
- ccxt/async_support/independentreserve.py +2 -2
- ccxt/async_support/indodax.py +2 -2
- ccxt/async_support/kraken.py +8 -8
- ccxt/async_support/krakenfutures.py +6 -6
- ccxt/async_support/kucoin.py +4 -1
- ccxt/async_support/kucoinfutures.py +8 -8
- ccxt/async_support/kuna.py +16 -16
- ccxt/async_support/latoken.py +2 -2
- ccxt/async_support/lbank.py +10 -10
- ccxt/async_support/luno.py +4 -4
- ccxt/async_support/mercado.py +5 -5
- ccxt/async_support/mexc.py +6 -6
- ccxt/async_support/ndax.py +1 -1
- ccxt/async_support/novadax.py +9 -9
- ccxt/async_support/oceanex.py +7 -7
- ccxt/async_support/okcoin.py +13 -13
- ccxt/async_support/okx.py +23 -31
- ccxt/async_support/onetrading.py +4 -4
- ccxt/async_support/p2b.py +7 -7
- ccxt/async_support/phemex.py +12 -12
- ccxt/async_support/poloniexfutures.py +5 -5
- ccxt/async_support/probit.py +11 -11
- ccxt/async_support/timex.py +7 -7
- ccxt/async_support/tokocrypto.py +9 -9
- ccxt/async_support/wavesexchange.py +3 -3
- ccxt/async_support/whitebit.py +5 -5
- ccxt/async_support/woo.py +1 -1
- ccxt/async_support/zaif.py +1 -1
- ccxt/async_support/zonda.py +7 -7
- ccxt/base/exchange.py +66 -23
- ccxt/bigone.py +12 -12
- ccxt/binance.py +20 -32
- ccxt/bingx.py +12 -9
- ccxt/bit2c.py +1 -1
- ccxt/bitbank.py +8 -8
- ccxt/bitbns.py +5 -5
- ccxt/bitfinex.py +1 -1
- ccxt/bitfinex2.py +1 -1
- ccxt/bitget.py +29 -24
- ccxt/bithumb.py +5 -5
- ccxt/bitmart.py +16 -16
- ccxt/bitopro.py +1 -1
- ccxt/bitrue.py +4 -4
- ccxt/bitso.py +5 -5
- ccxt/bitstamp.py +1 -1
- ccxt/bitteam.py +8 -8
- ccxt/bl3p.py +1 -1
- ccxt/btcturk.py +6 -6
- ccxt/bybit.py +30 -83
- ccxt/coincheck.py +4 -4
- ccxt/coinex.py +11 -11
- ccxt/coinlist.py +7 -7
- ccxt/coinmate.py +4 -4
- ccxt/coinmetro.py +3 -3
- ccxt/coinone.py +5 -5
- ccxt/coinspot.py +2 -2
- ccxt/cryptocom.py +17 -17
- ccxt/currencycom.py +1 -1
- ccxt/delta.py +0 -8
- ccxt/deribit.py +16 -80
- ccxt/digifinex.py +8 -8
- ccxt/exmo.py +8 -8
- ccxt/gate.py +0 -8
- ccxt/hitbtc.py +5 -4
- ccxt/hollaex.py +7 -7
- ccxt/htx.py +7 -7
- ccxt/huobijp.py +3 -3
- ccxt/idex.py +2 -2
- ccxt/independentreserve.py +2 -2
- ccxt/indodax.py +2 -2
- ccxt/kraken.py +8 -8
- ccxt/krakenfutures.py +6 -6
- ccxt/kucoin.py +4 -1
- ccxt/kucoinfutures.py +8 -8
- ccxt/kuna.py +16 -16
- ccxt/latoken.py +2 -2
- ccxt/lbank.py +10 -10
- ccxt/luno.py +4 -4
- ccxt/mercado.py +5 -5
- ccxt/mexc.py +6 -6
- ccxt/ndax.py +1 -1
- ccxt/novadax.py +9 -9
- ccxt/oceanex.py +7 -7
- ccxt/okcoin.py +13 -13
- ccxt/okx.py +23 -31
- ccxt/onetrading.py +4 -4
- ccxt/p2b.py +7 -7
- ccxt/phemex.py +12 -12
- ccxt/poloniexfutures.py +5 -5
- ccxt/pro/__init__.py +1 -1
- ccxt/pro/binance.py +150 -112
- ccxt/pro/kucoin.py +6 -7
- ccxt/pro/okx.py +12 -1
- ccxt/probit.py +11 -11
- ccxt/timex.py +7 -7
- ccxt/tokocrypto.py +9 -9
- ccxt/wavesexchange.py +3 -3
- ccxt/whitebit.py +5 -5
- ccxt/woo.py +1 -1
- ccxt/zaif.py +1 -1
- ccxt/zonda.py +7 -7
- {ccxt-4.2.84.dist-info → ccxt-4.2.85.dist-info}/METADATA +4 -4
- {ccxt-4.2.84.dist-info → ccxt-4.2.85.dist-info}/RECORD +150 -150
- {ccxt-4.2.84.dist-info → ccxt-4.2.85.dist-info}/WHEEL +0 -0
- {ccxt-4.2.84.dist-info → ccxt-4.2.85.dist-info}/top_level.txt +0 -0
ccxt/phemex.py
CHANGED
@@ -1266,7 +1266,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
1266
1266
|
# }
|
1267
1267
|
#
|
1268
1268
|
data = self.safe_value(response, 'data', {})
|
1269
|
-
rows = self.
|
1269
|
+
rows = self.safe_list(data, 'rows', [])
|
1270
1270
|
return self.parse_ohlcvs(rows, market, timeframe, since, userLimit)
|
1271
1271
|
|
1272
1272
|
def parse_ticker(self, ticker, market: Market = None) -> Ticker:
|
@@ -1422,7 +1422,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
1422
1422
|
# }
|
1423
1423
|
# }
|
1424
1424
|
#
|
1425
|
-
result = self.
|
1425
|
+
result = self.safe_dict(response, 'result', {})
|
1426
1426
|
return self.parse_ticker(result, market)
|
1427
1427
|
|
1428
1428
|
def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
|
@@ -1452,7 +1452,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
1452
1452
|
response = self.v1GetMdTicker24hrAll(query)
|
1453
1453
|
else:
|
1454
1454
|
response = self.v2GetMdV2Ticker24hrAll(query)
|
1455
|
-
result = self.
|
1455
|
+
result = self.safe_list(response, 'result', [])
|
1456
1456
|
return self.parse_tickers(result, symbols)
|
1457
1457
|
|
1458
1458
|
def fetch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
@@ -2587,7 +2587,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
2587
2587
|
# }
|
2588
2588
|
# }
|
2589
2589
|
#
|
2590
|
-
data = self.
|
2590
|
+
data = self.safe_dict(response, 'data', {})
|
2591
2591
|
return self.parse_order(data, market)
|
2592
2592
|
|
2593
2593
|
def edit_order(self, id: str, symbol: str, type: OrderType = None, side: OrderSide = None, amount: Num = None, price: Num = None, params={}):
|
@@ -2648,7 +2648,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
2648
2648
|
response = self.privatePutOrdersReplace(self.extend(request, params))
|
2649
2649
|
else:
|
2650
2650
|
response = self.privatePutSpotOrders(self.extend(request, params))
|
2651
|
-
data = self.
|
2651
|
+
data = self.safe_dict(response, 'data', {})
|
2652
2652
|
return self.parse_order(data, market)
|
2653
2653
|
|
2654
2654
|
def cancel_order(self, id: str, symbol: Str = None, params={}):
|
@@ -2684,7 +2684,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
2684
2684
|
response = self.privateDeleteOrdersCancel(self.extend(request, params))
|
2685
2685
|
else:
|
2686
2686
|
response = self.privateDeleteSpotOrders(self.extend(request, params))
|
2687
|
-
data = self.
|
2687
|
+
data = self.safe_dict(response, 'data', {})
|
2688
2688
|
return self.parse_order(data, market)
|
2689
2689
|
|
2690
2690
|
def cancel_all_orders(self, symbol: Str = None, params={}):
|
@@ -2782,7 +2782,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
2782
2782
|
else:
|
2783
2783
|
response = self.privateGetSpotOrders(self.extend(request, params))
|
2784
2784
|
data = self.safe_value(response, 'data', {})
|
2785
|
-
rows = self.
|
2785
|
+
rows = self.safe_list(data, 'rows', data)
|
2786
2786
|
return self.parse_orders(rows, market, since, limit)
|
2787
2787
|
|
2788
2788
|
def fetch_open_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
@@ -2821,7 +2821,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
2821
2821
|
if isinstance(data, list):
|
2822
2822
|
return self.parse_orders(data, market, since, limit)
|
2823
2823
|
else:
|
2824
|
-
rows = self.
|
2824
|
+
rows = self.safe_list(data, 'rows', [])
|
2825
2825
|
return self.parse_orders(rows, market, since, limit)
|
2826
2826
|
|
2827
2827
|
def fetch_closed_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
@@ -2898,7 +2898,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
2898
2898
|
if isinstance(data, list):
|
2899
2899
|
return self.parse_orders(data, market, since, limit)
|
2900
2900
|
else:
|
2901
|
-
rows = self.
|
2901
|
+
rows = self.safe_list(data, 'rows', [])
|
2902
2902
|
return self.parse_orders(rows, market, since, limit)
|
2903
2903
|
|
2904
2904
|
def fetch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
|
@@ -3942,7 +3942,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
3942
3942
|
#
|
3943
3943
|
#
|
3944
3944
|
data = self.safe_value(response, 'data', {})
|
3945
|
-
riskLimits = self.
|
3945
|
+
riskLimits = self.safe_list(data, 'riskLimits')
|
3946
3946
|
return self.parse_leverage_tiers(riskLimits, symbols, 'symbol')
|
3947
3947
|
|
3948
3948
|
def parse_market_leverage_tiers(self, info, market: Market = None):
|
@@ -4173,7 +4173,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
4173
4173
|
# }
|
4174
4174
|
#
|
4175
4175
|
data = self.safe_value(response, 'data', {})
|
4176
|
-
transfers = self.
|
4176
|
+
transfers = self.safe_list(data, 'rows', [])
|
4177
4177
|
return self.parse_transfers(transfers, currency, since, limit)
|
4178
4178
|
|
4179
4179
|
def parse_transfer(self, transfer, currency: Currency = None):
|
@@ -4375,7 +4375,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
4375
4375
|
# }
|
4376
4376
|
# }
|
4377
4377
|
#
|
4378
|
-
data = self.
|
4378
|
+
data = self.safe_dict(response, 'data', {})
|
4379
4379
|
return self.parse_transaction(data, currency)
|
4380
4380
|
|
4381
4381
|
def handle_errors(self, httpCode, reason, url, method, headers, body, response, requestHeaders, requestBody):
|
ccxt/poloniexfutures.py
CHANGED
@@ -665,7 +665,7 @@ class poloniexfutures(Exchange, ImplicitAPI):
|
|
665
665
|
# },
|
666
666
|
# }
|
667
667
|
#
|
668
|
-
trades = self.
|
668
|
+
trades = self.safe_list(response, 'data', [])
|
669
669
|
return self.parse_trades(trades, market, since, limit)
|
670
670
|
|
671
671
|
def fetch_time(self, params={}):
|
@@ -729,7 +729,7 @@ class poloniexfutures(Exchange, ImplicitAPI):
|
|
729
729
|
# ]
|
730
730
|
# }
|
731
731
|
#
|
732
|
-
data = self.
|
732
|
+
data = self.safe_list(response, 'data', [])
|
733
733
|
return self.parse_ohlcvs(data, market, timeframe, since, limit)
|
734
734
|
|
735
735
|
def parse_balance(self, response) -> Balances:
|
@@ -970,7 +970,7 @@ class poloniexfutures(Exchange, ImplicitAPI):
|
|
970
970
|
# ]
|
971
971
|
# }
|
972
972
|
#
|
973
|
-
data = self.
|
973
|
+
data = self.safe_list(response, 'data')
|
974
974
|
return self.parse_positions(data, symbols)
|
975
975
|
|
976
976
|
def parse_position(self, position, market: Market = None):
|
@@ -1389,7 +1389,7 @@ class poloniexfutures(Exchange, ImplicitAPI):
|
|
1389
1389
|
# }
|
1390
1390
|
#
|
1391
1391
|
market = self.market(symbol) if (symbol is not None) else None
|
1392
|
-
responseData = self.
|
1392
|
+
responseData = self.safe_dict(response, 'data')
|
1393
1393
|
return self.parse_order(responseData, market)
|
1394
1394
|
|
1395
1395
|
def parse_order(self, order, market: Market = None) -> Order:
|
@@ -1616,7 +1616,7 @@ class poloniexfutures(Exchange, ImplicitAPI):
|
|
1616
1616
|
# }
|
1617
1617
|
#
|
1618
1618
|
data = self.safe_value(response, 'data', {})
|
1619
|
-
trades = self.
|
1619
|
+
trades = self.safe_list(data, 'items', [])
|
1620
1620
|
return self.parse_trades(trades, market, since, limit)
|
1621
1621
|
|
1622
1622
|
def set_margin_mode(self, marginMode: str, symbol: Str = None, params={}):
|
ccxt/pro/__init__.py
CHANGED
ccxt/pro/binance.py
CHANGED
@@ -12,6 +12,7 @@ from typing import List
|
|
12
12
|
from ccxt.base.errors import ExchangeError
|
13
13
|
from ccxt.base.errors import ArgumentsRequired
|
14
14
|
from ccxt.base.errors import BadRequest
|
15
|
+
from ccxt.base.errors import NotSupported
|
15
16
|
from ccxt.base.precise import Precise
|
16
17
|
|
17
18
|
|
@@ -22,6 +23,7 @@ class binance(ccxt.async_support.binance):
|
|
22
23
|
'has': {
|
23
24
|
'ws': True,
|
24
25
|
'watchBalance': True,
|
26
|
+
'watchBidsAsks': True,
|
25
27
|
'watchMyTrades': True,
|
26
28
|
'watchOHLCV': True,
|
27
29
|
'watchOHLCVForSymbols': False,
|
@@ -103,10 +105,10 @@ class binance(ccxt.async_support.binance):
|
|
103
105
|
'name': 'trade', # 'trade' or 'aggTrade'
|
104
106
|
},
|
105
107
|
'watchTicker': {
|
106
|
-
'name': 'ticker', # ticker
|
108
|
+
'name': 'ticker', # ticker or miniTicker or ticker_<window_size>
|
107
109
|
},
|
108
110
|
'watchTickers': {
|
109
|
-
'name': 'ticker', # ticker or miniTicker or
|
111
|
+
'name': 'ticker', # ticker or miniTicker or ticker_<window_size>
|
110
112
|
},
|
111
113
|
'watchOHLCV': {
|
112
114
|
'name': 'kline', # or indexPriceKline or markPriceKline(coin-m futures)
|
@@ -127,6 +129,15 @@ class binance(ccxt.async_support.binance):
|
|
127
129
|
'ws': {
|
128
130
|
'cost': 5,
|
129
131
|
},
|
132
|
+
'tickerChannelsMap': {
|
133
|
+
'24hrTicker': 'ticker',
|
134
|
+
'24hrMiniTicker': 'miniTicker',
|
135
|
+
# rolling window tickers
|
136
|
+
'1hTicker': 'ticker_1h',
|
137
|
+
'4hTicker': 'ticker_4h',
|
138
|
+
'1dTicker': 'ticker_1d',
|
139
|
+
'bookTicker': 'bookTicker',
|
140
|
+
},
|
130
141
|
},
|
131
142
|
})
|
132
143
|
|
@@ -867,33 +878,13 @@ class binance(ccxt.async_support.binance):
|
|
867
878
|
watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
868
879
|
:param str symbol: unified symbol of the market to fetch the ticker for
|
869
880
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
870
|
-
:param str [params.name]: stream to use can be ticker or
|
881
|
+
:param str [params.name]: stream to use can be ticker or miniTicker
|
871
882
|
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
872
883
|
"""
|
873
884
|
await self.load_markets()
|
874
|
-
|
875
|
-
|
876
|
-
|
877
|
-
if market['contract']:
|
878
|
-
type = 'future' if market['linear'] else 'delivery'
|
879
|
-
options = self.safe_value(self.options, 'watchTicker', {})
|
880
|
-
name = self.safe_string(options, 'name', 'ticker')
|
881
|
-
name = self.safe_string(params, 'name', name)
|
882
|
-
params = self.omit(params, 'name')
|
883
|
-
messageHash = marketId + '@' + name
|
884
|
-
url = self.urls['api']['ws'][type] + '/' + self.stream(type, messageHash)
|
885
|
-
requestId = self.request_id(url)
|
886
|
-
request = {
|
887
|
-
'method': 'SUBSCRIBE',
|
888
|
-
'params': [
|
889
|
-
messageHash,
|
890
|
-
],
|
891
|
-
'id': requestId,
|
892
|
-
}
|
893
|
-
subscribe = {
|
894
|
-
'id': requestId,
|
895
|
-
}
|
896
|
-
return await self.watch(url, messageHash, self.extend(request, params), messageHash, subscribe)
|
885
|
+
symbol = self.symbol(symbol)
|
886
|
+
tickers = await self.watch_tickers([symbol], self.extend(params, {'callerMethodName': 'watchTicker'}))
|
887
|
+
return tickers[symbol]
|
897
888
|
|
898
889
|
async def watch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
|
899
890
|
"""
|
@@ -902,52 +893,89 @@ class binance(ccxt.async_support.binance):
|
|
902
893
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
903
894
|
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
904
895
|
"""
|
896
|
+
channelName = None
|
897
|
+
channelName, params = self.handle_option_and_params(params, 'watchTickers', 'name', 'ticker')
|
898
|
+
if channelName == 'bookTicker':
|
899
|
+
raise BadRequest(self.id + ' deprecation notice - to subscribe for bids-asks, use watch_bids_asks() method instead')
|
900
|
+
newTickers = await self.watch_multi_ticker_helper('watchTickers', channelName, symbols, params)
|
901
|
+
if self.newUpdates:
|
902
|
+
return newTickers
|
903
|
+
return self.filter_by_array(self.tickers, 'symbol', symbols)
|
904
|
+
|
905
|
+
async def watch_bids_asks(self, symbols: Strings = None, params={}) -> Tickers:
|
906
|
+
"""
|
907
|
+
:see: https://binance-docs.github.io/apidocs/spot/en/#individual-symbol-book-ticker-streams
|
908
|
+
:see: https://binance-docs.github.io/apidocs/futures/en/#all-book-tickers-stream
|
909
|
+
:see: https://binance-docs.github.io/apidocs/delivery/en/#all-book-tickers-stream
|
910
|
+
watches best bid & ask for symbols
|
911
|
+
:param str[] symbols: unified symbol of the market to fetch the ticker for
|
912
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
913
|
+
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
914
|
+
"""
|
915
|
+
result = await self.watch_multi_ticker_helper('watchBidsAsks', 'bookTicker', symbols, params)
|
916
|
+
if self.newUpdates:
|
917
|
+
return result
|
918
|
+
return self.filter_by_array(self.tickers, 'symbol', symbols)
|
919
|
+
|
920
|
+
async def watch_multi_ticker_helper(self, methodName, channelName: str, symbols: Strings = None, params={}):
|
905
921
|
await self.load_markets()
|
906
|
-
symbols = self.market_symbols(symbols, None, True,
|
907
|
-
|
908
|
-
|
909
|
-
|
910
|
-
if
|
911
|
-
|
912
|
-
|
922
|
+
symbols = self.market_symbols(symbols, None, True, False, True)
|
923
|
+
firstMarket = None
|
924
|
+
marketType = None
|
925
|
+
symbolsDefined = (symbols is not None)
|
926
|
+
if symbolsDefined:
|
927
|
+
firstMarket = self.market(symbols[0])
|
928
|
+
marketType, params = self.handle_market_type_and_params(methodName, firstMarket, params)
|
913
929
|
subType = None
|
914
|
-
subType, params = self.handle_sub_type_and_params(
|
915
|
-
|
916
|
-
|
917
|
-
|
918
|
-
|
919
|
-
|
920
|
-
|
921
|
-
|
922
|
-
params = self.omit(params, 'name')
|
923
|
-
wsParams = []
|
924
|
-
messageHash = 'tickers'
|
925
|
-
if symbols is not None:
|
926
|
-
messageHash = 'tickers::' + ','.join(symbols)
|
927
|
-
if name == 'bookTicker':
|
928
|
-
if marketIds is None:
|
929
|
-
raise ArgumentsRequired(self.id + ' watchTickers() requires symbols for bookTicker')
|
930
|
-
# simulate watchTickers with subscribe multiple individual bookTicker topic
|
931
|
-
for i in range(0, len(marketIds)):
|
932
|
-
wsParams.append(marketIds[i].lower() + '@bookTicker')
|
930
|
+
subType, params = self.handle_sub_type_and_params(methodName, firstMarket, params)
|
931
|
+
rawMarketType = None
|
932
|
+
if self.isLinear(marketType, subType):
|
933
|
+
rawMarketType = 'future'
|
934
|
+
elif self.isInverse(marketType, subType):
|
935
|
+
rawMarketType = 'delivery'
|
936
|
+
elif marketType == 'spot':
|
937
|
+
rawMarketType = marketType
|
933
938
|
else:
|
934
|
-
|
935
|
-
|
936
|
-
|
937
|
-
|
939
|
+
raise NotSupported(self.id + ' ' + methodName + '() does not support options markets')
|
940
|
+
isBidAsk = (channelName == 'bookTicker')
|
941
|
+
subscriptionArgs = []
|
942
|
+
messageHashes = []
|
943
|
+
if symbolsDefined:
|
944
|
+
for i in range(0, len(symbols)):
|
945
|
+
symbol = symbols[i]
|
946
|
+
market = self.market(symbol)
|
947
|
+
subscriptionArgs.append(market['lowercaseId'] + '@' + channelName)
|
948
|
+
messageHashes.append(self.get_message_hash(channelName, market['symbol'], isBidAsk))
|
949
|
+
else:
|
950
|
+
if isBidAsk:
|
951
|
+
if marketType == 'spot':
|
952
|
+
raise ArgumentsRequired(self.id + ' ' + methodName + '() requires symbols for self channel for spot markets')
|
953
|
+
subscriptionArgs.append('!' + channelName)
|
954
|
+
else:
|
955
|
+
subscriptionArgs.append('!' + channelName + '@arr')
|
956
|
+
messageHashes.append(self.get_message_hash(channelName, None, isBidAsk))
|
957
|
+
streamHash = channelName
|
958
|
+
if symbolsDefined:
|
959
|
+
streamHash = channelName + '::' + ','.join(symbols)
|
960
|
+
url = self.urls['api']['ws'][rawMarketType] + '/' + self.stream(rawMarketType, streamHash)
|
938
961
|
requestId = self.request_id(url)
|
939
962
|
request = {
|
940
963
|
'method': 'SUBSCRIBE',
|
941
|
-
'params':
|
964
|
+
'params': subscriptionArgs,
|
942
965
|
'id': requestId,
|
943
966
|
}
|
944
967
|
subscribe = {
|
945
968
|
'id': requestId,
|
946
969
|
}
|
947
|
-
|
948
|
-
if
|
949
|
-
|
950
|
-
|
970
|
+
result = await self.watch_multiple(url, messageHashes, self.deep_extend(request, params), subscriptionArgs, subscribe)
|
971
|
+
# for efficiency, we have two type of returned structure here - if symbols array was provided, then individual
|
972
|
+
# ticker dict comes in, otherwise all-tickers dict comes in
|
973
|
+
if not symbolsDefined:
|
974
|
+
return result
|
975
|
+
else:
|
976
|
+
newDict = {}
|
977
|
+
newDict[result['symbol']] = result
|
978
|
+
return newDict
|
951
979
|
|
952
980
|
def parse_ws_ticker(self, message, marketType):
|
953
981
|
#
|
@@ -1028,11 +1056,24 @@ class binance(ccxt.async_support.binance):
|
|
1028
1056
|
'info': message,
|
1029
1057
|
}, market)
|
1030
1058
|
|
1031
|
-
def
|
1059
|
+
def handle_bids_asks(self, client: Client, message):
|
1060
|
+
#
|
1061
|
+
# arrives one symbol dict or array of symbol dicts
|
1062
|
+
#
|
1063
|
+
# {
|
1064
|
+
# "u": 7488717758,
|
1065
|
+
# "s": "BTCUSDT",
|
1066
|
+
# "b": "28621.74000000",
|
1067
|
+
# "B": "1.43278800",
|
1068
|
+
# "a": "28621.75000000",
|
1069
|
+
# "A": "2.52500800"
|
1070
|
+
# }
|
1071
|
+
#
|
1072
|
+
self.handle_tickers_and_bids_asks(client, message, 'bidasks')
|
1073
|
+
|
1074
|
+
def handle_tickers(self, client: Client, message):
|
1032
1075
|
#
|
1033
|
-
#
|
1034
|
-
# These are NOT the statistics of the UTC day, but a 24hr rolling window for the previous 24hrs
|
1035
|
-
# Update Speed 1000ms
|
1076
|
+
# arrives one symbol dict or array of symbol dicts
|
1036
1077
|
#
|
1037
1078
|
# {
|
1038
1079
|
# "e": "24hrTicker", # event type
|
@@ -1060,34 +1101,14 @@ class binance(ccxt.async_support.binance):
|
|
1060
1101
|
# "n": 163222, # total number of trades
|
1061
1102
|
# }
|
1062
1103
|
#
|
1063
|
-
|
1064
|
-
if event == '24hrTicker':
|
1065
|
-
event = 'ticker'
|
1066
|
-
elif event == '24hrMiniTicker':
|
1067
|
-
event = 'miniTicker'
|
1068
|
-
wsMarketId = self.safe_string_lower(message, 's')
|
1069
|
-
messageHash = wsMarketId + '@' + event
|
1070
|
-
isSpot = ((client.url.find('/stream') > -1) or (client.url.find('/testnet.binance') > -1))
|
1071
|
-
marketType = 'spot' if (isSpot) else 'contract'
|
1072
|
-
result = self.parse_ws_ticker(message, marketType)
|
1073
|
-
symbol = result['symbol']
|
1074
|
-
self.tickers[symbol] = result
|
1075
|
-
client.resolve(result, messageHash)
|
1076
|
-
if event == 'bookTicker':
|
1077
|
-
# watch bookTickers
|
1078
|
-
client.resolve(result, '!' + 'bookTicker@arr')
|
1079
|
-
messageHashes = self.find_message_hashes(client, 'tickers::')
|
1080
|
-
for i in range(0, len(messageHashes)):
|
1081
|
-
currentMessageHash = messageHashes[i]
|
1082
|
-
parts = currentMessageHash.split('::')
|
1083
|
-
symbolsString = parts[1]
|
1084
|
-
symbols = symbolsString.split(',')
|
1085
|
-
if self.in_array(symbol, symbols):
|
1086
|
-
client.resolve(result, currentMessageHash)
|
1104
|
+
self.handle_tickers_and_bids_asks(client, message, 'tickers')
|
1087
1105
|
|
1088
|
-
def
|
1106
|
+
def handle_tickers_and_bids_asks(self, client: Client, message, methodType):
|
1089
1107
|
isSpot = ((client.url.find('/stream') > -1) or (client.url.find('/testnet.binance') > -1))
|
1090
1108
|
marketType = 'spot' if (isSpot) else 'contract'
|
1109
|
+
isBidAsk = (methodType == 'bidasks')
|
1110
|
+
channelName = None
|
1111
|
+
resolvedMessageHashes = []
|
1091
1112
|
rawTickers = []
|
1092
1113
|
newTickers = {}
|
1093
1114
|
if isinstance(message, list):
|
@@ -1096,22 +1117,34 @@ class binance(ccxt.async_support.binance):
|
|
1096
1117
|
rawTickers.append(message)
|
1097
1118
|
for i in range(0, len(rawTickers)):
|
1098
1119
|
ticker = rawTickers[i]
|
1099
|
-
|
1100
|
-
|
1101
|
-
|
1102
|
-
|
1103
|
-
|
1104
|
-
|
1105
|
-
|
1106
|
-
|
1107
|
-
|
1108
|
-
|
1109
|
-
|
1110
|
-
|
1111
|
-
|
1112
|
-
|
1113
|
-
|
1114
|
-
|
1120
|
+
event = self.safe_string(ticker, 'e')
|
1121
|
+
if isBidAsk:
|
1122
|
+
event = 'bookTicker' # in `handleMessage`, bookTicker doesn't have identifier, so manually set here
|
1123
|
+
channelName = self.safe_string(self.options['tickerChannelsMap'], event, event)
|
1124
|
+
if channelName is None:
|
1125
|
+
continue
|
1126
|
+
parsedTicker = self.parse_ws_ticker(ticker, marketType)
|
1127
|
+
symbol = parsedTicker['symbol']
|
1128
|
+
newTickers[symbol] = parsedTicker
|
1129
|
+
if isBidAsk:
|
1130
|
+
self.bidsasks[symbol] = parsedTicker
|
1131
|
+
else:
|
1132
|
+
self.tickers[symbol] = parsedTicker
|
1133
|
+
messageHash = self.get_message_hash(channelName, symbol, isBidAsk)
|
1134
|
+
resolvedMessageHashes.append(messageHash)
|
1135
|
+
client.resolve(parsedTicker, messageHash)
|
1136
|
+
# resolve batch endpoint
|
1137
|
+
length = len(resolvedMessageHashes)
|
1138
|
+
if length > 0:
|
1139
|
+
batchMessageHash = self.get_message_hash(channelName, None, isBidAsk)
|
1140
|
+
client.resolve(newTickers, batchMessageHash)
|
1141
|
+
|
1142
|
+
def get_message_hash(self, channelName: str, symbol: Str, isBidAsk: bool):
|
1143
|
+
prefix = 'bidask' if isBidAsk else 'ticker'
|
1144
|
+
if symbol is not None:
|
1145
|
+
return prefix + ':' + channelName + '@' + symbol
|
1146
|
+
else:
|
1147
|
+
return prefix + 's' + ':' + channelName
|
1115
1148
|
|
1116
1149
|
def sign_params(self, params={}):
|
1117
1150
|
self.check_required_credentials()
|
@@ -2741,11 +2774,17 @@ class binance(ccxt.async_support.binance):
|
|
2741
2774
|
'kline': self.handle_ohlcv,
|
2742
2775
|
'markPrice_kline': self.handle_ohlcv,
|
2743
2776
|
'indexPrice_kline': self.handle_ohlcv,
|
2777
|
+
'1hTicker@arr': self.handle_tickers,
|
2778
|
+
'4hTicker@arr': self.handle_tickers,
|
2779
|
+
'1dTicker@arr': self.handle_tickers,
|
2744
2780
|
'24hrTicker@arr': self.handle_tickers,
|
2745
2781
|
'24hrMiniTicker@arr': self.handle_tickers,
|
2746
|
-
'
|
2747
|
-
'
|
2748
|
-
'
|
2782
|
+
'1hTicker': self.handle_tickers,
|
2783
|
+
'4hTicker': self.handle_tickers,
|
2784
|
+
'1dTicker': self.handle_tickers,
|
2785
|
+
'24hrTicker': self.handle_tickers,
|
2786
|
+
'24hrMiniTicker': self.handle_tickers,
|
2787
|
+
'bookTicker': self.handle_bids_asks, # there is no "bookTicker@arr" endpoint
|
2749
2788
|
'outboundAccountPosition': self.handle_balance,
|
2750
2789
|
'balanceUpdate': self.handle_balance,
|
2751
2790
|
'ACCOUNT_UPDATE': self.handle_acount_update,
|
@@ -2773,8 +2812,7 @@ class binance(ccxt.async_support.binance):
|
|
2773
2812
|
# "A": "2.52500800"
|
2774
2813
|
# }
|
2775
2814
|
#
|
2776
|
-
if event is None:
|
2777
|
-
self.
|
2778
|
-
self.handle_tickers(client, message)
|
2815
|
+
if event is None and ('a' in message) and ('b' in message):
|
2816
|
+
self.handle_bids_asks(client, message)
|
2779
2817
|
else:
|
2780
2818
|
method(client, message)
|
ccxt/pro/kucoin.py
CHANGED
@@ -824,17 +824,16 @@ class kucoin(ccxt.async_support.kucoin):
|
|
824
824
|
return self.filter_by_symbol_since_limit(trades, symbol, since, limit, True)
|
825
825
|
|
826
826
|
def handle_my_trade(self, client: Client, message):
|
827
|
-
|
828
|
-
if trades is None:
|
827
|
+
if self.myTrades is None:
|
829
828
|
limit = self.safe_integer(self.options, 'tradesLimit', 1000)
|
830
|
-
|
831
|
-
data = self.
|
829
|
+
self.myTrades = ArrayCacheBySymbolById(limit)
|
830
|
+
data = self.safe_dict(message, 'data')
|
832
831
|
parsed = self.parse_ws_trade(data)
|
833
|
-
|
832
|
+
self.myTrades.append(parsed)
|
834
833
|
messageHash = 'myTrades'
|
835
|
-
client.resolve(
|
834
|
+
client.resolve(self.myTrades, messageHash)
|
836
835
|
symbolSpecificMessageHash = messageHash + ':' + parsed['symbol']
|
837
|
-
client.resolve(
|
836
|
+
client.resolve(self.myTrades, symbolSpecificMessageHash)
|
838
837
|
|
839
838
|
def parse_ws_trade(self, trade, market=None):
|
840
839
|
#
|
ccxt/pro/okx.py
CHANGED
@@ -459,7 +459,7 @@ class okx(ccxt.async_support.okx):
|
|
459
459
|
"""
|
460
460
|
watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
461
461
|
:param str[] symbols: unified array of symbols
|
462
|
-
:param int [limit]: the maximum amount of order book entries to return
|
462
|
+
:param int [limit]: 1,5, 400, 50(l2-tbt, vip4+) or 40000(vip5+) the maximum amount of order book entries to return
|
463
463
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
464
464
|
:returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
|
465
465
|
"""
|
@@ -467,6 +467,17 @@ class okx(ccxt.async_support.okx):
|
|
467
467
|
symbols = self.market_symbols(symbols)
|
468
468
|
options = self.safe_value(self.options, 'watchOrderBook', {})
|
469
469
|
depth = self.safe_string(options, 'depth', 'books')
|
470
|
+
if limit is not None:
|
471
|
+
if limit == 1:
|
472
|
+
depth = 'bbo-tbt'
|
473
|
+
elif limit > 1 and limit <= 5:
|
474
|
+
depth = 'books5'
|
475
|
+
elif limit == 400:
|
476
|
+
depth = 'books'
|
477
|
+
elif limit == 50:
|
478
|
+
depth = 'books50-l2-tbt' # Make sure you have VIP4 and above
|
479
|
+
elif limit == 4000:
|
480
|
+
depth = 'books-l2-tbt' # Make sure you have VIP5 and above
|
470
481
|
if (depth == 'books-l2-tbt') or (depth == 'books50-l2-tbt'):
|
471
482
|
await self.authenticate({'access': 'public'})
|
472
483
|
topics = []
|