ccxt 4.2.38__py2.py3-none-any.whl → 4.2.40__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.
Potentially problematic release.
This version of ccxt might be problematic. Click here for more details.
- ccxt/__init__.py +1 -1
- ccxt/abstract/bingx.py +4 -0
- ccxt/abstract/coinbase.py +1 -0
- ccxt/abstract/coinbasepro.py +1 -0
- ccxt/abstract/okx.py +1 -0
- ccxt/ascendex.py +31 -27
- ccxt/async_support/__init__.py +1 -1
- ccxt/async_support/ascendex.py +31 -27
- ccxt/async_support/base/exchange.py +19 -7
- ccxt/async_support/bigone.py +2 -2
- ccxt/async_support/binance.py +478 -188
- ccxt/async_support/bingx.py +250 -28
- ccxt/async_support/bitfinex.py +3 -3
- ccxt/async_support/bitfinex2.py +2 -2
- ccxt/async_support/bitget.py +16 -7
- ccxt/async_support/bitmart.py +2 -2
- ccxt/async_support/bitmex.py +2 -2
- ccxt/async_support/bitrue.py +2 -2
- ccxt/async_support/bitso.py +19 -3
- ccxt/async_support/bitstamp.py +25 -3
- ccxt/async_support/bitvavo.py +1 -1
- ccxt/async_support/bl3p.py +6 -0
- ccxt/async_support/blockchaincom.py +21 -0
- ccxt/async_support/blofin.py +2 -2
- ccxt/async_support/btcalpha.py +9 -0
- ccxt/async_support/btcbox.py +9 -0
- ccxt/async_support/btcmarkets.py +19 -0
- ccxt/async_support/bybit.py +9 -7
- ccxt/async_support/cex.py +1 -1
- ccxt/async_support/coinbase.py +20 -9
- ccxt/async_support/coinbasepro.py +1 -0
- ccxt/async_support/coinex.py +4 -4
- ccxt/async_support/coinlist.py +11 -9
- ccxt/async_support/coinmetro.py +2 -1
- ccxt/async_support/coinone.py +1 -1
- ccxt/async_support/delta.py +2 -2
- ccxt/async_support/deribit.py +3 -3
- ccxt/async_support/digifinex.py +3 -3
- ccxt/async_support/exmo.py +2 -2
- ccxt/async_support/gate.py +6 -6
- ccxt/async_support/hitbtc.py +2 -2
- ccxt/async_support/hollaex.py +1 -1
- ccxt/async_support/htx.py +3 -3
- ccxt/async_support/huobijp.py +1 -1
- ccxt/async_support/kraken.py +2 -2
- ccxt/async_support/krakenfutures.py +117 -16
- ccxt/async_support/kucoin.py +5 -5
- ccxt/async_support/kucoinfutures.py +2 -2
- ccxt/async_support/latoken.py +1 -1
- ccxt/async_support/lbank.py +2 -2
- ccxt/async_support/luno.py +2 -2
- ccxt/async_support/mexc.py +5 -5
- ccxt/async_support/ndax.py +1 -1
- ccxt/async_support/novadax.py +1 -1
- ccxt/async_support/okcoin.py +2 -2
- ccxt/async_support/okx.py +18 -21
- ccxt/async_support/paymium.py +2 -2
- ccxt/async_support/phemex.py +5 -4
- ccxt/async_support/poloniex.py +2 -2
- ccxt/async_support/poloniexfutures.py +10 -6
- ccxt/async_support/probit.py +1 -1
- ccxt/async_support/timex.py +1 -1
- ccxt/async_support/upbit.py +1 -1
- ccxt/async_support/wavesexchange.py +1 -1
- ccxt/async_support/whitebit.py +2 -2
- ccxt/async_support/woo.py +4 -4
- ccxt/async_support/zonda.py +3 -3
- ccxt/base/exchange.py +37 -25
- ccxt/bigone.py +2 -2
- ccxt/binance.py +478 -188
- ccxt/bingx.py +250 -28
- ccxt/bitfinex.py +3 -3
- ccxt/bitfinex2.py +2 -2
- ccxt/bitget.py +16 -7
- ccxt/bitmart.py +2 -2
- ccxt/bitmex.py +2 -2
- ccxt/bitrue.py +2 -2
- ccxt/bitso.py +19 -3
- ccxt/bitstamp.py +25 -3
- ccxt/bitvavo.py +1 -1
- ccxt/bl3p.py +6 -0
- ccxt/blockchaincom.py +21 -0
- ccxt/blofin.py +2 -2
- ccxt/btcalpha.py +9 -0
- ccxt/btcbox.py +9 -0
- ccxt/btcmarkets.py +19 -0
- ccxt/bybit.py +9 -7
- ccxt/cex.py +1 -1
- ccxt/coinbase.py +20 -9
- ccxt/coinbasepro.py +1 -0
- ccxt/coinex.py +4 -4
- ccxt/coinlist.py +11 -9
- ccxt/coinmetro.py +2 -1
- ccxt/coinone.py +1 -1
- ccxt/delta.py +2 -2
- ccxt/deribit.py +3 -3
- ccxt/digifinex.py +3 -3
- ccxt/exmo.py +2 -2
- ccxt/gate.py +6 -6
- ccxt/hitbtc.py +2 -2
- ccxt/hollaex.py +1 -1
- ccxt/htx.py +3 -3
- ccxt/huobijp.py +1 -1
- ccxt/kraken.py +2 -2
- ccxt/krakenfutures.py +117 -16
- ccxt/kucoin.py +5 -5
- ccxt/kucoinfutures.py +2 -2
- ccxt/latoken.py +1 -1
- ccxt/lbank.py +2 -2
- ccxt/luno.py +2 -2
- ccxt/mexc.py +5 -5
- ccxt/ndax.py +1 -1
- ccxt/novadax.py +1 -1
- ccxt/okcoin.py +2 -2
- ccxt/okx.py +18 -21
- ccxt/paymium.py +2 -2
- ccxt/phemex.py +5 -4
- ccxt/poloniex.py +2 -2
- ccxt/poloniexfutures.py +10 -6
- ccxt/pro/__init__.py +1 -1
- ccxt/pro/bitmart.py +129 -46
- ccxt/pro/bitvavo.py +1 -1
- ccxt/pro/bybit.py +6 -6
- ccxt/pro/cex.py +2 -2
- ccxt/pro/coinbase.py +2 -2
- ccxt/pro/coinex.py +1 -1
- ccxt/pro/lbank.py +1 -1
- ccxt/pro/mexc.py +1 -1
- ccxt/probit.py +1 -1
- ccxt/test/test_async.py +3 -1
- ccxt/test/test_sync.py +3 -1
- ccxt/timex.py +1 -1
- ccxt/upbit.py +1 -1
- ccxt/wavesexchange.py +1 -1
- ccxt/whitebit.py +2 -2
- ccxt/woo.py +4 -4
- ccxt/zonda.py +3 -3
- {ccxt-4.2.38.dist-info → ccxt-4.2.40.dist-info}/METADATA +4 -4
- {ccxt-4.2.38.dist-info → ccxt-4.2.40.dist-info}/RECORD +141 -141
- {ccxt-4.2.38.dist-info → ccxt-4.2.40.dist-info}/WHEEL +0 -0
- {ccxt-4.2.38.dist-info → ccxt-4.2.40.dist-info}/top_level.txt +0 -0
ccxt/phemex.py
CHANGED
@@ -50,6 +50,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
50
50
|
'addMargin': False,
|
51
51
|
'cancelAllOrders': True,
|
52
52
|
'cancelOrder': True,
|
53
|
+
'closePosition': False,
|
53
54
|
'createOrder': True,
|
54
55
|
'createReduceOnlyOrder': True,
|
55
56
|
'createStopLimitOrder': True,
|
@@ -2589,7 +2590,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
2589
2590
|
data = self.safe_value(response, 'data', {})
|
2590
2591
|
return self.parse_order(data, market)
|
2591
2592
|
|
2592
|
-
def edit_order(self, id: str, symbol, type=None, side=None, amount=None, price=None, params={}):
|
2593
|
+
def edit_order(self, id: str, symbol: str, type: OrderType = None, side: OrderSide = None, amount: float = None, price: float = None, params={}):
|
2593
2594
|
"""
|
2594
2595
|
edit a trade order
|
2595
2596
|
:see: https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#amend-order-by-orderid
|
@@ -3797,7 +3798,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
3797
3798
|
'status': self.parse_margin_status(self.safe_string(data, 'code')),
|
3798
3799
|
}
|
3799
3800
|
|
3800
|
-
def set_margin_mode(self, marginMode, symbol: Str = None, params={}):
|
3801
|
+
def set_margin_mode(self, marginMode: str, symbol: Str = None, params={}):
|
3801
3802
|
"""
|
3802
3803
|
set margin mode to 'cross' or 'isolated'
|
3803
3804
|
:param str marginMode: 'cross' or 'isolated'
|
@@ -3825,7 +3826,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
3825
3826
|
}
|
3826
3827
|
return self.privatePutPositionsLeverage(self.extend(request, params))
|
3827
3828
|
|
3828
|
-
def set_position_mode(self, hedged, symbol: Str = None, params={}):
|
3829
|
+
def set_position_mode(self, hedged: bool, symbol: Str = None, params={}):
|
3829
3830
|
"""
|
3830
3831
|
set hedged to True or False for a market
|
3831
3832
|
:see: https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#switch-position-mode-synchronously
|
@@ -4054,7 +4055,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
4054
4055
|
response = self.privatePutPositionsLeverage(self.extend(request, params))
|
4055
4056
|
return response
|
4056
4057
|
|
4057
|
-
def transfer(self, code: str, amount: float, fromAccount, toAccount, params={}) -> TransferEntry:
|
4058
|
+
def transfer(self, code: str, amount: float, fromAccount: str, toAccount: str, params={}) -> TransferEntry:
|
4058
4059
|
"""
|
4059
4060
|
transfer currency internally between wallets on the same account
|
4060
4061
|
:param str code: unified currency code
|
ccxt/poloniex.py
CHANGED
@@ -1300,7 +1300,7 @@ class poloniex(Exchange, ImplicitAPI):
|
|
1300
1300
|
# remember the timestamp before issuing the request
|
1301
1301
|
return [request, params]
|
1302
1302
|
|
1303
|
-
def edit_order(self, id: str, symbol, type, side, amount=None, price=None, params={}):
|
1303
|
+
def edit_order(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: float = None, price: float = None, params={}):
|
1304
1304
|
"""
|
1305
1305
|
edit a trade order
|
1306
1306
|
:see: https://docs.poloniex.com/#authenticated-endpoints-orders-cancel-replace-order
|
@@ -1736,7 +1736,7 @@ class poloniex(Exchange, ImplicitAPI):
|
|
1736
1736
|
'info': response,
|
1737
1737
|
}
|
1738
1738
|
|
1739
|
-
def transfer(self, code: str, amount: float, fromAccount, toAccount, params={}) -> TransferEntry:
|
1739
|
+
def transfer(self, code: str, amount: float, fromAccount: str, toAccount: str, params={}) -> TransferEntry:
|
1740
1740
|
"""
|
1741
1741
|
transfer currency internally between wallets on the same account
|
1742
1742
|
:see: https://docs.poloniex.com/#authenticated-endpoints-accounts-accounts-transfer
|
ccxt/poloniexfutures.py
CHANGED
@@ -1321,7 +1321,7 @@ class poloniexfutures(Exchange, ImplicitAPI):
|
|
1321
1321
|
"""
|
1322
1322
|
return self.fetch_orders_by_status('closed', symbol, since, limit, params)
|
1323
1323
|
|
1324
|
-
def fetch_order(self, id=None, symbol: Str = None, params={}):
|
1324
|
+
def fetch_order(self, id: str = None, symbol: Str = None, params={}):
|
1325
1325
|
"""
|
1326
1326
|
fetches information on an order made by the user
|
1327
1327
|
:see: https://futures-docs.poloniex.com/#get-details-of-a-single-order
|
@@ -1619,24 +1619,28 @@ class poloniexfutures(Exchange, ImplicitAPI):
|
|
1619
1619
|
trades = self.safe_value(data, 'items', {})
|
1620
1620
|
return self.parse_trades(trades, market, since, limit)
|
1621
1621
|
|
1622
|
-
def set_margin_mode(self, marginMode, symbol, params={}):
|
1622
|
+
def set_margin_mode(self, marginMode: str, symbol: str = None, params={}):
|
1623
1623
|
"""
|
1624
1624
|
set margin mode to 'cross' or 'isolated'
|
1625
1625
|
:see: https://futures-docs.poloniex.com/#change-margin-mode
|
1626
|
-
:param
|
1626
|
+
:param str marginMode: "0"(isolated) or "1"(cross)
|
1627
1627
|
:param str symbol: unified market symbol
|
1628
1628
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1629
1629
|
:returns dict: response from the exchange
|
1630
1630
|
"""
|
1631
1631
|
if symbol is None:
|
1632
1632
|
raise ArgumentsRequired(self.id + ' setMarginMode() requires a symbol argument')
|
1633
|
-
if (marginMode != 0) and (marginMode != 1):
|
1634
|
-
raise ArgumentsRequired(self.id + ' setMarginMode() marginMode must be 0
|
1633
|
+
if (marginMode != '0') and (marginMode != '1') and (marginMode != 'isolated') and (marginMode != 'cross'):
|
1634
|
+
raise ArgumentsRequired(self.id + ' setMarginMode() marginMode must be 0/isolated or 1/cross')
|
1635
1635
|
self.load_markets()
|
1636
|
+
if marginMode == 'isolated':
|
1637
|
+
marginMode = '0'
|
1638
|
+
if marginMode == 'cross':
|
1639
|
+
marginMode = '1'
|
1636
1640
|
market = self.market(symbol)
|
1637
1641
|
request = {
|
1638
1642
|
'symbol': market['id'],
|
1639
|
-
'marginType': marginMode,
|
1643
|
+
'marginType': self.parse_to_int(marginMode),
|
1640
1644
|
}
|
1641
1645
|
return self.privatePostMarginTypeChange(request)
|
1642
1646
|
|
ccxt/pro/__init__.py
CHANGED
ccxt/pro/bitmart.py
CHANGED
@@ -33,8 +33,10 @@ class bitmart(ccxt.async_support.bitmart):
|
|
33
33
|
'watchTicker': True,
|
34
34
|
'watchTickers': True,
|
35
35
|
'watchOrderBook': True,
|
36
|
+
'watchOrderBookForSymbols': True,
|
36
37
|
'watchOrders': True,
|
37
38
|
'watchTrades': True,
|
39
|
+
'watchTradesForSymbols': True,
|
38
40
|
'watchOHLCV': True,
|
39
41
|
'watchPosition': 'emulated',
|
40
42
|
'watchPositions': True,
|
@@ -59,8 +61,15 @@ class bitmart(ccxt.async_support.bitmart):
|
|
59
61
|
'fetchBalanceSnapshot': True, # or False
|
60
62
|
'awaitBalanceSnapshot': False, # whether to wait for the balance snapshot before providing updates
|
61
63
|
},
|
64
|
+
#
|
65
|
+
# orderbook channels can have:
|
66
|
+
# - 'depth5', 'depth20', 'depth50' # these endpoints emit full Orderbooks once in every 500ms
|
67
|
+
# - 'depth/increase100' # self endpoint is preferred, because it emits once in 100ms. however, when self value is chosen, it only affects spot-market, but contracts markets automatically `depth50` will be being used
|
62
68
|
'watchOrderBook': {
|
63
|
-
'depth': 'depth/increase100',
|
69
|
+
'depth': 'depth/increase100',
|
70
|
+
},
|
71
|
+
'watchOrderBookForSymbols': {
|
72
|
+
'depth': 'depth/increase100',
|
64
73
|
},
|
65
74
|
'ws': {
|
66
75
|
'inflate': True,
|
@@ -105,6 +114,23 @@ class bitmart(ccxt.async_support.bitmart):
|
|
105
114
|
}
|
106
115
|
return await self.watch(url, messageHash, self.deep_extend(request, params), messageHash)
|
107
116
|
|
117
|
+
async def subscribe_multiple(self, channel: str, type: str, symbols: List[str], params={}):
|
118
|
+
url = self.implode_hostname(self.urls['api']['ws'][type]['public'])
|
119
|
+
channelType = 'spot' if (type == 'spot') else 'futures'
|
120
|
+
actionType = 'op' if (type == 'spot') else 'action'
|
121
|
+
rawSubscriptions = []
|
122
|
+
messageHashes = []
|
123
|
+
for i in range(0, len(symbols)):
|
124
|
+
market = self.market(symbols[i])
|
125
|
+
message = channelType + '/' + channel + ':' + market['id']
|
126
|
+
rawSubscriptions.append(message)
|
127
|
+
messageHashes.append(channel + ':' + market['symbol'])
|
128
|
+
request = {
|
129
|
+
'args': rawSubscriptions,
|
130
|
+
}
|
131
|
+
request[actionType] = 'subscribe'
|
132
|
+
return await self.watch_multiple(url, messageHashes, self.deep_extend(request, params), rawSubscriptions)
|
133
|
+
|
108
134
|
async def watch_balance(self, params={}) -> Balances:
|
109
135
|
"""
|
110
136
|
:see: https://developer-pro.bitmart.com/en/spot/#private-balance-change
|
@@ -236,16 +262,39 @@ class bitmart(ccxt.async_support.bitmart):
|
|
236
262
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
237
263
|
:returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
|
238
264
|
"""
|
265
|
+
return await self.watch_trades_for_symbols([symbol], since, limit, params)
|
266
|
+
|
267
|
+
async def watch_trades_for_symbols(self, symbols: List[str], since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
268
|
+
"""
|
269
|
+
:see: https://developer-pro.bitmart.com/en/spot/#public-trade-channel
|
270
|
+
get the list of most recent trades for a list of symbols
|
271
|
+
:param str[] symbols: unified symbol of the market to fetch trades for
|
272
|
+
:param int [since]: timestamp in ms of the earliest trade to fetch
|
273
|
+
:param int [limit]: the maximum amount of trades to fetch
|
274
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
275
|
+
:returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
|
276
|
+
"""
|
239
277
|
await self.load_markets()
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
trades = await self.subscribe('trade', symbol, type, params)
|
278
|
+
marketType = None
|
279
|
+
symbols, marketType, params = self.get_params_for_multiple_sub('watchTradesForSymbols', symbols, limit, params)
|
280
|
+
channelName = 'trade'
|
281
|
+
trades = await self.subscribe_multiple(channelName, marketType, symbols, params)
|
245
282
|
if self.newUpdates:
|
246
|
-
|
283
|
+
first = self.safe_dict(trades, 0)
|
284
|
+
tradeSymbol = self.safe_string(first, 'symbol')
|
285
|
+
limit = trades.getLimit(tradeSymbol, limit)
|
247
286
|
return self.filter_by_since_limit(trades, since, limit, 'timestamp', True)
|
248
287
|
|
288
|
+
def get_params_for_multiple_sub(self, methodName: str, symbols: List[str], limit: Int = None, params={}):
|
289
|
+
symbols = self.market_symbols(symbols, None, False, True)
|
290
|
+
length = len(symbols)
|
291
|
+
if length > 20:
|
292
|
+
raise NotSupported(self.id + ' ' + methodName + '() accepts a maximum of 20 symbols in one request')
|
293
|
+
market = self.market(symbols[0])
|
294
|
+
marketType = None
|
295
|
+
marketType, params = self.handle_market_type_and_params(methodName, market, params)
|
296
|
+
return [symbols, marketType, params]
|
297
|
+
|
249
298
|
async def watch_ticker(self, symbol: str, params={}) -> Ticker:
|
250
299
|
"""
|
251
300
|
:see: https://developer-pro.bitmart.com/en/spot/#public-ticker-channel
|
@@ -747,12 +796,11 @@ class bitmart(ccxt.async_support.bitmart):
|
|
747
796
|
# ]
|
748
797
|
# }
|
749
798
|
#
|
750
|
-
channel = self.safe_string_2(message, 'table', 'group')
|
751
|
-
isSpot = (channel.find('spot') >= 0)
|
752
799
|
data = self.safe_value(message, 'data')
|
753
800
|
if data is None:
|
754
801
|
return
|
755
802
|
stored = None
|
803
|
+
symbol = None
|
756
804
|
for i in range(0, len(data)):
|
757
805
|
trade = self.parse_ws_trade(data[i])
|
758
806
|
symbol = trade['symbol']
|
@@ -762,9 +810,7 @@ class bitmart(ccxt.async_support.bitmart):
|
|
762
810
|
stored = ArrayCache(tradesLimit)
|
763
811
|
self.trades[symbol] = stored
|
764
812
|
stored.append(trade)
|
765
|
-
messageHash =
|
766
|
-
if isSpot:
|
767
|
-
messageHash += ':' + self.safe_string(data[0], 'symbol')
|
813
|
+
messageHash = 'trade:' + symbol
|
768
814
|
client.resolve(stored, messageHash)
|
769
815
|
|
770
816
|
def parse_ws_trade(self, trade, market: Market = None):
|
@@ -1084,8 +1130,8 @@ class bitmart(ccxt.async_support.bitmart):
|
|
1084
1130
|
# "symbol": "BTC_USDT"
|
1085
1131
|
# }
|
1086
1132
|
#
|
1087
|
-
asks = self.
|
1088
|
-
bids = self.
|
1133
|
+
asks = self.safe_list(message, 'asks', [])
|
1134
|
+
bids = self.safe_list(message, 'bids', [])
|
1089
1135
|
self.handle_deltas(orderbook['asks'], asks)
|
1090
1136
|
self.handle_deltas(orderbook['bids'], bids)
|
1091
1137
|
timestamp = self.safe_integer(message, 'ms_t')
|
@@ -1099,6 +1145,7 @@ class bitmart(ccxt.async_support.bitmart):
|
|
1099
1145
|
def handle_order_book(self, client: Client, message):
|
1100
1146
|
#
|
1101
1147
|
# spot depth-all
|
1148
|
+
#
|
1102
1149
|
# {
|
1103
1150
|
# "data": [
|
1104
1151
|
# {
|
@@ -1118,33 +1165,31 @@ class bitmart(ccxt.async_support.bitmart):
|
|
1118
1165
|
# ],
|
1119
1166
|
# "table": "spot/depth5"
|
1120
1167
|
# }
|
1168
|
+
#
|
1121
1169
|
# spot increse depth snapshot
|
1170
|
+
#
|
1122
1171
|
# {
|
1123
1172
|
# "data":[
|
1124
1173
|
# {
|
1125
|
-
#
|
1126
|
-
#
|
1127
|
-
#
|
1128
|
-
# "0.02039"
|
1129
|
-
# ],
|
1130
|
-
# ...
|
1131
|
-
# ],
|
1132
|
-
# "bids":[
|
1133
|
-
# [
|
1134
|
-
# "43652.51",
|
1135
|
-
# "0.00500"
|
1174
|
+
# "asks":[
|
1175
|
+
# ["43652.52", "0.02039"],
|
1176
|
+
# ...
|
1136
1177
|
# ],
|
1137
|
-
#
|
1138
|
-
#
|
1139
|
-
#
|
1140
|
-
#
|
1141
|
-
#
|
1142
|
-
#
|
1178
|
+
# "bids":[
|
1179
|
+
# ["43652.51", "0.00500"],
|
1180
|
+
# ...
|
1181
|
+
# ],
|
1182
|
+
# "ms_t":1703376836487,
|
1183
|
+
# "symbol":"BTC_USDT",
|
1184
|
+
# "type":"snapshot", # or update
|
1185
|
+
# "version":2141731
|
1143
1186
|
# }
|
1144
1187
|
# ],
|
1145
1188
|
# "table":"spot/depth/increase100"
|
1146
1189
|
# }
|
1190
|
+
#
|
1147
1191
|
# swap
|
1192
|
+
#
|
1148
1193
|
# {
|
1149
1194
|
# "group":"futures/depth50:BTCUSDT",
|
1150
1195
|
# "data":{
|
@@ -1165,43 +1210,58 @@ class bitmart(ccxt.async_support.bitmart):
|
|
1165
1210
|
# }
|
1166
1211
|
# }
|
1167
1212
|
#
|
1168
|
-
|
1169
|
-
|
1213
|
+
isSpot = ('table' in message)
|
1214
|
+
datas = []
|
1215
|
+
if isSpot:
|
1216
|
+
datas = self.safe_list(message, 'data', datas)
|
1217
|
+
else:
|
1218
|
+
orderBookEntry = self.safe_dict(message, 'data')
|
1219
|
+
if orderBookEntry is not None:
|
1220
|
+
datas.append(orderBookEntry)
|
1221
|
+
length = len(datas)
|
1222
|
+
if length <= 0:
|
1170
1223
|
return
|
1171
|
-
|
1172
|
-
isSpot = (depths is None)
|
1173
|
-
table = self.safe_string_2(message, 'table', 'group')
|
1224
|
+
channelName = self.safe_string_2(message, 'table', 'group')
|
1174
1225
|
# find limit subscribed to
|
1175
1226
|
limitsToCheck = ['100', '50', '20', '10', '5']
|
1176
1227
|
limit = 0
|
1177
1228
|
for i in range(0, len(limitsToCheck)):
|
1178
1229
|
limitString = limitsToCheck[i]
|
1179
|
-
if
|
1230
|
+
if channelName.find(limitString) >= 0:
|
1180
1231
|
limit = self.parse_to_int(limitString)
|
1181
1232
|
break
|
1182
1233
|
if isSpot:
|
1183
|
-
|
1184
|
-
|
1234
|
+
channel = channelName.replace('spot/', '')
|
1235
|
+
for i in range(0, len(datas)):
|
1236
|
+
update = datas[i]
|
1185
1237
|
marketId = self.safe_string(update, 'symbol')
|
1186
1238
|
symbol = self.safe_symbol(marketId)
|
1187
|
-
orderbook = self.
|
1239
|
+
orderbook = self.safe_dict(self.orderbooks, symbol)
|
1188
1240
|
if orderbook is None:
|
1189
1241
|
orderbook = self.order_book({}, limit)
|
1190
1242
|
orderbook['symbol'] = symbol
|
1191
1243
|
self.orderbooks[symbol] = orderbook
|
1192
1244
|
type = self.safe_value(update, 'type')
|
1193
|
-
if (type == 'snapshot') or (not(
|
1245
|
+
if (type == 'snapshot') or (not(channelName.find('increase') >= 0)):
|
1194
1246
|
orderbook.reset({})
|
1195
1247
|
self.handle_order_book_message(client, update, orderbook)
|
1196
1248
|
timestamp = self.safe_integer(update, 'ms_t')
|
1197
|
-
orderbook['timestamp']
|
1198
|
-
|
1199
|
-
|
1249
|
+
if orderbook['timestamp'] is None:
|
1250
|
+
orderbook['timestamp'] = timestamp
|
1251
|
+
orderbook['datetime'] = self.iso8601(timestamp)
|
1252
|
+
messageHash = channelName + ':' + marketId
|
1200
1253
|
client.resolve(orderbook, messageHash)
|
1254
|
+
# resolve ForSymbols
|
1255
|
+
messageHashForMulti = channel + ':' + symbol
|
1256
|
+
client.resolve(orderbook, messageHashForMulti)
|
1201
1257
|
else:
|
1258
|
+
tableParts = channelName.split(':')
|
1259
|
+
channel = tableParts[0].replace('futures/', '')
|
1260
|
+
data = datas[0] # contract markets always contain only one member
|
1261
|
+
depths = data['depths']
|
1202
1262
|
marketId = self.safe_string(data, 'symbol')
|
1203
1263
|
symbol = self.safe_symbol(marketId)
|
1204
|
-
orderbook = self.
|
1264
|
+
orderbook = self.safe_dict(self.orderbooks, symbol)
|
1205
1265
|
if orderbook is None:
|
1206
1266
|
orderbook = self.order_book({}, limit)
|
1207
1267
|
orderbook['symbol'] = symbol
|
@@ -1225,8 +1285,31 @@ class bitmart(ccxt.async_support.bitmart):
|
|
1225
1285
|
timestamp = self.safe_integer(data, 'ms_t')
|
1226
1286
|
orderbook['timestamp'] = timestamp
|
1227
1287
|
orderbook['datetime'] = self.iso8601(timestamp)
|
1228
|
-
messageHash =
|
1288
|
+
messageHash = channelName
|
1229
1289
|
client.resolve(orderbook, messageHash)
|
1290
|
+
# resolve ForSymbols
|
1291
|
+
messageHashForMulti = channel + ':' + symbol
|
1292
|
+
client.resolve(orderbook, messageHashForMulti)
|
1293
|
+
|
1294
|
+
async def watch_order_book_for_symbols(self, symbols: List[str], limit: Int = None, params={}) -> OrderBook:
|
1295
|
+
"""
|
1296
|
+
watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
1297
|
+
:see: https://developer-pro.bitmart.com/en/spot/#public-depth-increase-channel
|
1298
|
+
:param str[] symbols: unified array of symbols
|
1299
|
+
:param int [limit]: the maximum amount of order book entries to return
|
1300
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1301
|
+
:param str [params.depth]: the type of order book to subscribe to, default is 'depth/increase100', also accepts 'depth5' or 'depth20' or depth50
|
1302
|
+
:returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
|
1303
|
+
"""
|
1304
|
+
await self.load_markets()
|
1305
|
+
type = None
|
1306
|
+
symbols, type, params = self.get_params_for_multiple_sub('watchOrderBookForSymbols', symbols, limit, params)
|
1307
|
+
channel = None
|
1308
|
+
channel, params = self.handle_option_and_params(params, 'watchOrderBookForSymbols', 'depth', 'depth/increase100')
|
1309
|
+
if type == 'swap' and channel == 'depth/increase100':
|
1310
|
+
channel = 'depth50'
|
1311
|
+
orderbook = await self.subscribe_multiple(channel, type, symbols, params)
|
1312
|
+
return orderbook.limit()
|
1230
1313
|
|
1231
1314
|
async def authenticate(self, type, params={}):
|
1232
1315
|
self.check_required_credentials()
|
ccxt/pro/bitvavo.py
CHANGED
@@ -530,7 +530,7 @@ class bitvavo(ccxt.async_support.bitvavo):
|
|
530
530
|
request = self.create_order_request(symbol, type, side, amount, price, params)
|
531
531
|
return await self.watch_request('privateCreateOrder', request)
|
532
532
|
|
533
|
-
async def edit_order_ws(self, id: str, symbol, type, side, amount=None, price=None, params={}) -> Order:
|
533
|
+
async def edit_order_ws(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: float = None, price: float = None, params={}) -> Order:
|
534
534
|
"""
|
535
535
|
edit a trade order
|
536
536
|
:see: https://docs.bitvavo.com/#tag/Orders/paths/~1order/put
|
ccxt/pro/bybit.py
CHANGED
@@ -136,7 +136,7 @@ class bybit(ccxt.async_support.bybit):
|
|
136
136
|
self.options['requestId'] = requestId
|
137
137
|
return requestId
|
138
138
|
|
139
|
-
def get_url_by_market_type(self, symbol: Str = None, isPrivate=False, method=None, params={}):
|
139
|
+
def get_url_by_market_type(self, symbol: Str = None, isPrivate=False, method: str = None, params={}):
|
140
140
|
accessibility = 'private' if isPrivate else 'public'
|
141
141
|
isUsdcSettled = None
|
142
142
|
isSpot = None
|
@@ -185,7 +185,7 @@ class bybit(ccxt.async_support.bybit):
|
|
185
185
|
market = self.market(symbol)
|
186
186
|
symbol = market['symbol']
|
187
187
|
messageHash = 'ticker:' + symbol
|
188
|
-
url = self.get_url_by_market_type(symbol, False, params)
|
188
|
+
url = self.get_url_by_market_type(symbol, False, 'watchTicker', params)
|
189
189
|
params = self.clean_params(params)
|
190
190
|
options = self.safe_value(self.options, 'watchTicker', {})
|
191
191
|
topic = self.safe_string(options, 'name', 'tickers')
|
@@ -207,7 +207,7 @@ class bybit(ccxt.async_support.bybit):
|
|
207
207
|
await self.load_markets()
|
208
208
|
symbols = self.market_symbols(symbols, None, False)
|
209
209
|
messageHashes = []
|
210
|
-
url = self.get_url_by_market_type(symbols[0], False, params)
|
210
|
+
url = self.get_url_by_market_type(symbols[0], False, 'watchTickers', params)
|
211
211
|
params = self.clean_params(params)
|
212
212
|
options = self.safe_value(self.options, 'watchTickers', {})
|
213
213
|
topic = self.safe_string(options, 'name', 'tickers')
|
@@ -368,7 +368,7 @@ class bybit(ccxt.async_support.bybit):
|
|
368
368
|
await self.load_markets()
|
369
369
|
market = self.market(symbol)
|
370
370
|
symbol = market['symbol']
|
371
|
-
url = self.get_url_by_market_type(symbol, False, params)
|
371
|
+
url = self.get_url_by_market_type(symbol, False, 'watchOHLCV', params)
|
372
372
|
params = self.clean_params(params)
|
373
373
|
ohlcv = None
|
374
374
|
timeframeId = self.safe_string(self.timeframes, timeframe, timeframe)
|
@@ -477,7 +477,7 @@ class bybit(ccxt.async_support.bybit):
|
|
477
477
|
if symbolsLength == 0:
|
478
478
|
raise ArgumentsRequired(self.id + ' watchOrderBookForSymbols() requires a non-empty array of symbols')
|
479
479
|
symbols = self.market_symbols(symbols)
|
480
|
-
url = self.get_url_by_market_type(symbols[0], False, params)
|
480
|
+
url = self.get_url_by_market_type(symbols[0], False, 'watchOrderBook', params)
|
481
481
|
params = self.clean_params(params)
|
482
482
|
market = self.market(symbols[0])
|
483
483
|
if limit is None:
|
@@ -595,7 +595,7 @@ class bybit(ccxt.async_support.bybit):
|
|
595
595
|
if symbolsLength == 0:
|
596
596
|
raise ArgumentsRequired(self.id + ' watchTradesForSymbols() requires a non-empty array of symbols')
|
597
597
|
params = self.clean_params(params)
|
598
|
-
url = self.get_url_by_market_type(symbols[0], False, params)
|
598
|
+
url = self.get_url_by_market_type(symbols[0], False, 'watchTrades', params)
|
599
599
|
topics = []
|
600
600
|
messageHashes = []
|
601
601
|
for i in range(0, len(symbols)):
|
ccxt/pro/cex.py
CHANGED
@@ -1196,7 +1196,7 @@ class cex(ccxt.async_support.cex):
|
|
1196
1196
|
rawOrder = await self.watch(url, messageHash, request, messageHash)
|
1197
1197
|
return self.parse_order(rawOrder, market)
|
1198
1198
|
|
1199
|
-
async def edit_order_ws(self, id: str, symbol, type, side, amount=None, price=None, params={}) -> Order:
|
1199
|
+
async def edit_order_ws(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: float = None, price: float = None, params={}) -> Order:
|
1200
1200
|
"""
|
1201
1201
|
edit a trade order
|
1202
1202
|
:see: https://docs.cex.io/#ws-api-cancel-replace
|
@@ -1260,7 +1260,7 @@ class cex(ccxt.async_support.cex):
|
|
1260
1260
|
response = await self.watch(url, messageHash, request, messageHash, messageHash)
|
1261
1261
|
return self.parse_order(response, market)
|
1262
1262
|
|
1263
|
-
async def cancel_orders_ws(self, ids, symbol: str = None, params={}):
|
1263
|
+
async def cancel_orders_ws(self, ids: List[str], symbol: str = None, params={}):
|
1264
1264
|
"""
|
1265
1265
|
cancel multiple orders
|
1266
1266
|
:see: https://docs.cex.io/#ws-api-mass-cancel-place
|
ccxt/pro/coinbase.py
CHANGED
@@ -88,7 +88,7 @@ class coinbase(ccxt.async_support.coinbase):
|
|
88
88
|
}
|
89
89
|
return await self.watch(url, messageHash, subscribe, messageHash)
|
90
90
|
|
91
|
-
async def watch_ticker(self, symbol, params={}) -> Ticker:
|
91
|
+
async def watch_ticker(self, symbol: str, params={}) -> Ticker:
|
92
92
|
"""
|
93
93
|
watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
94
94
|
:see: https://docs.cloud.coinbase.com/advanced-trade-api/docs/ws-channels#ticker-channel
|
@@ -251,7 +251,7 @@ class coinbase(ccxt.async_support.coinbase):
|
|
251
251
|
limit = trades.getLimit(symbol, limit)
|
252
252
|
return self.filter_by_since_limit(trades, since, limit, 'timestamp', True)
|
253
253
|
|
254
|
-
async def watch_orders(self, symbol=None, since=None, limit=None, params={}) -> List[Order]:
|
254
|
+
async def watch_orders(self, symbol: str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
255
255
|
"""
|
256
256
|
watches information on multiple orders made by the user
|
257
257
|
:see: https://docs.cloud.coinbase.com/advanced-trade-api/docs/ws-channels#user-channel
|
ccxt/pro/coinex.py
CHANGED
@@ -554,7 +554,7 @@ class coinex(ccxt.async_support.coinex):
|
|
554
554
|
limit = ohlcvs.getLimit(symbol, limit)
|
555
555
|
return self.filter_by_since_limit(ohlcvs, since, limit, 0)
|
556
556
|
|
557
|
-
async def fetch_ohlcv_ws(self, symbol, timeframe='1m', since=None, limit=None, params={}) -> List[list]:
|
557
|
+
async def fetch_ohlcv_ws(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
|
558
558
|
"""
|
559
559
|
:see: https://viabtc.github.io/coinex_api_en_doc/spot/#docsspot004_websocket005_kline_query
|
560
560
|
query historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
ccxt/pro/lbank.py
CHANGED
@@ -248,7 +248,7 @@ class lbank(ccxt.async_support.lbank):
|
|
248
248
|
requestId = self.request_id()
|
249
249
|
return await self.watch(url, messageHash, request, requestId, request)
|
250
250
|
|
251
|
-
async def watch_ticker(self, symbol, params={}) -> Ticker:
|
251
|
+
async def watch_ticker(self, symbol: str, params={}) -> Ticker:
|
252
252
|
"""
|
253
253
|
:see: https://www.lbank.com/en-US/docs/index.html#market
|
254
254
|
watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
ccxt/pro/mexc.py
CHANGED
@@ -455,7 +455,7 @@ class mexc(ccxt.async_support.mexc):
|
|
455
455
|
return
|
456
456
|
try:
|
457
457
|
self.handle_delta(storedOrderBook, data)
|
458
|
-
timestamp = self.
|
458
|
+
timestamp = self.safe_integer_2(message, 't', 'ts')
|
459
459
|
storedOrderBook['timestamp'] = timestamp
|
460
460
|
storedOrderBook['datetime'] = self.iso8601(timestamp)
|
461
461
|
except Exception as e:
|
ccxt/probit.py
CHANGED
@@ -1311,7 +1311,7 @@ class probit(Exchange, ImplicitAPI):
|
|
1311
1311
|
raise InvalidAddress(self.id + ' fetchDepositAddress() returned an empty response')
|
1312
1312
|
return self.parse_deposit_address(firstAddress, currency)
|
1313
1313
|
|
1314
|
-
def fetch_deposit_addresses(self, codes=None, params={}):
|
1314
|
+
def fetch_deposit_addresses(self, codes: List[str] = None, params={}):
|
1315
1315
|
"""
|
1316
1316
|
:see: https://docs-en.probit.com/reference/deposit_address
|
1317
1317
|
fetch deposit addresses for multiple currencies and chain types
|
ccxt/test/test_async.py
CHANGED
@@ -373,7 +373,8 @@ class testMainClass(baseMainTestClass):
|
|
373
373
|
final_value = exchange_settings[key]
|
374
374
|
set_exchange_prop(exchange, key, final_value)
|
375
375
|
# credentials
|
376
|
-
self.
|
376
|
+
if self.load_keys:
|
377
|
+
self.load_credentials_from_env(exchange)
|
377
378
|
# skipped tests
|
378
379
|
skipped_file = self.root_dir_for_skips + 'skip-tests.json'
|
379
380
|
skipped_settings = io_file_read(skipped_file)
|
@@ -1053,6 +1054,7 @@ class testMainClass(baseMainTestClass):
|
|
1053
1054
|
currencies = self.load_currencies_from_file(exchange_name)
|
1054
1055
|
exchange = init_exchange(exchange_name, {
|
1055
1056
|
'markets': markets,
|
1057
|
+
'currencies': currencies,
|
1056
1058
|
'enableRateLimit': False,
|
1057
1059
|
'rateLimit': 1,
|
1058
1060
|
'httpProxy': 'http://fake:8080',
|
ccxt/test/test_sync.py
CHANGED
@@ -372,7 +372,8 @@ class testMainClass(baseMainTestClass):
|
|
372
372
|
final_value = exchange_settings[key]
|
373
373
|
set_exchange_prop(exchange, key, final_value)
|
374
374
|
# credentials
|
375
|
-
self.
|
375
|
+
if self.load_keys:
|
376
|
+
self.load_credentials_from_env(exchange)
|
376
377
|
# skipped tests
|
377
378
|
skipped_file = self.root_dir_for_skips + 'skip-tests.json'
|
378
379
|
skipped_settings = io_file_read(skipped_file)
|
@@ -1052,6 +1053,7 @@ class testMainClass(baseMainTestClass):
|
|
1052
1053
|
currencies = self.load_currencies_from_file(exchange_name)
|
1053
1054
|
exchange = init_exchange(exchange_name, {
|
1054
1055
|
'markets': markets,
|
1056
|
+
'currencies': currencies,
|
1055
1057
|
'enableRateLimit': False,
|
1056
1058
|
'rateLimit': 1,
|
1057
1059
|
'httpProxy': 'http://fake:8080',
|
ccxt/timex.py
CHANGED
@@ -755,7 +755,7 @@ class timex(Exchange, ImplicitAPI):
|
|
755
755
|
order = self.safe_value(orders, 0, {})
|
756
756
|
return self.parse_order(order, market)
|
757
757
|
|
758
|
-
def edit_order(self, id: str, symbol, type, side, amount=None, price=None, params={}):
|
758
|
+
def edit_order(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: float = None, price: float = None, params={}):
|
759
759
|
self.load_markets()
|
760
760
|
market = self.market(symbol)
|
761
761
|
request = {
|
ccxt/upbit.py
CHANGED
@@ -1522,7 +1522,7 @@ class upbit(Exchange, ImplicitAPI):
|
|
1522
1522
|
#
|
1523
1523
|
return self.parse_order(response)
|
1524
1524
|
|
1525
|
-
def fetch_deposit_addresses(self, codes=None, params={}):
|
1525
|
+
def fetch_deposit_addresses(self, codes: List[str] = None, params={}):
|
1526
1526
|
"""
|
1527
1527
|
:see: https://docs.upbit.com/reference/%EC%A0%84%EC%B2%B4-%EC%9E%85%EA%B8%88-%EC%A3%BC%EC%86%8C-%EC%A1%B0%ED%9A%8C
|
1528
1528
|
fetch deposit addresses for multiple currencies and chain types
|
ccxt/wavesexchange.py
CHANGED
@@ -324,7 +324,7 @@ class wavesexchange(Exchange, ImplicitAPI):
|
|
324
324
|
},
|
325
325
|
},
|
326
326
|
'currencies': {
|
327
|
-
'WX': self.safe_currency_structure({'id': 'EMAMLxDnv3xiz8RXg8Btj33jcEw3wLczL3JKYYmuubpc', 'numericId': None, 'code': 'WX', 'precision': self.
|
327
|
+
'WX': self.safe_currency_structure({'id': 'EMAMLxDnv3xiz8RXg8Btj33jcEw3wLczL3JKYYmuubpc', 'numericId': None, 'code': 'WX', 'precision': self.parse_to_int('8')}),
|
328
328
|
},
|
329
329
|
'precisionMode': DECIMAL_PLACES,
|
330
330
|
'options': {
|
ccxt/whitebit.py
CHANGED
@@ -456,7 +456,7 @@ class whitebit(Exchange, ImplicitAPI):
|
|
456
456
|
}
|
457
457
|
return result
|
458
458
|
|
459
|
-
def fetch_transaction_fees(self, codes=None, params={}):
|
459
|
+
def fetch_transaction_fees(self, codes: List[str] = None, params={}):
|
460
460
|
"""
|
461
461
|
* @deprecated
|
462
462
|
please use fetchDepositWithdrawFees instead
|
@@ -1616,7 +1616,7 @@ class whitebit(Exchange, ImplicitAPI):
|
|
1616
1616
|
# "leverage": 5
|
1617
1617
|
# }
|
1618
1618
|
|
1619
|
-
def transfer(self, code: str, amount: float, fromAccount, toAccount, params={}) -> TransferEntry:
|
1619
|
+
def transfer(self, code: str, amount: float, fromAccount: str, toAccount: str, params={}) -> TransferEntry:
|
1620
1620
|
"""
|
1621
1621
|
transfer currency internally between wallets on the same account
|
1622
1622
|
:see: https://docs.whitebit.com/private/http-main-v4/#transfer-between-main-and-trade-balances
|