ccxt 4.3.73__py2.py3-none-any.whl → 4.3.75__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/binance.py +5 -0
- ccxt/abstract/binancecoinm.py +5 -0
- ccxt/abstract/binanceus.py +5 -0
- ccxt/abstract/binanceusdm.py +5 -0
- ccxt/abstract/bybit.py +1 -0
- ccxt/ace.py +1 -1
- ccxt/async_support/__init__.py +1 -1
- ccxt/async_support/ace.py +1 -1
- ccxt/async_support/base/exchange.py +1 -1
- ccxt/async_support/binance.py +222 -84
- ccxt/async_support/bybit.py +32 -7
- ccxt/async_support/mexc.py +1 -1
- ccxt/async_support/whitebit.py +17 -2
- ccxt/async_support/woo.py +1 -1
- ccxt/async_support/yobit.py +49 -26
- ccxt/base/exchange.py +1 -1
- ccxt/binance.py +222 -84
- ccxt/bybit.py +32 -7
- ccxt/mexc.py +1 -1
- ccxt/pro/__init__.py +1 -1
- ccxt/pro/alpaca.py +5 -0
- ccxt/pro/binance.py +15 -2
- ccxt/pro/bitfinex.py +5 -0
- ccxt/test/tests_async.py +3 -2
- ccxt/test/tests_helpers.py +3 -0
- ccxt/test/tests_sync.py +3 -2
- ccxt/whitebit.py +17 -2
- ccxt/woo.py +1 -1
- ccxt/yobit.py +48 -26
- {ccxt-4.3.73.dist-info → ccxt-4.3.75.dist-info}/METADATA +6 -6
- {ccxt-4.3.73.dist-info → ccxt-4.3.75.dist-info}/RECORD +35 -35
- {ccxt-4.3.73.dist-info → ccxt-4.3.75.dist-info}/LICENSE.txt +0 -0
- {ccxt-4.3.73.dist-info → ccxt-4.3.75.dist-info}/WHEEL +0 -0
- {ccxt-4.3.73.dist-info → ccxt-4.3.75.dist-info}/top_level.txt +0 -0
ccxt/async_support/bybit.py
CHANGED
@@ -255,6 +255,7 @@ class bybit(Exchange, ImplicitAPI):
|
|
255
255
|
},
|
256
256
|
'private': {
|
257
257
|
'get': {
|
258
|
+
'v5/market/instruments-info': 5,
|
258
259
|
# Legacy inverse swap
|
259
260
|
'v2/private/wallet/fund/records': 25, # 120 per minute = 2 per second => cost = 50 / 2 = 25
|
260
261
|
# spot
|
@@ -1000,6 +1001,7 @@ class bybit(Exchange, ImplicitAPI):
|
|
1000
1001
|
},
|
1001
1002
|
'precisionMode': TICK_SIZE,
|
1002
1003
|
'options': {
|
1004
|
+
'usePrivateInstrumentsInfo': False,
|
1003
1005
|
'sandboxMode': False,
|
1004
1006
|
'enableDemoTrading': False,
|
1005
1007
|
'fetchMarkets': ['spot', 'linear', 'inverse', 'option'],
|
@@ -1458,7 +1460,12 @@ class bybit(Exchange, ImplicitAPI):
|
|
1458
1460
|
request: dict = {
|
1459
1461
|
'category': 'spot',
|
1460
1462
|
}
|
1461
|
-
|
1463
|
+
usePrivateInstrumentsInfo = self.safe_bool(self.options, 'usePrivateInstrumentsInfo', False)
|
1464
|
+
response: dict = None
|
1465
|
+
if usePrivateInstrumentsInfo:
|
1466
|
+
response = await self.privateGetV5MarketInstrumentsInfo(self.extend(request, params))
|
1467
|
+
else:
|
1468
|
+
response = await self.publicGetV5MarketInstrumentsInfo(self.extend(request, params))
|
1462
1469
|
#
|
1463
1470
|
# {
|
1464
1471
|
# "retCode": 0,
|
@@ -1567,14 +1574,23 @@ class bybit(Exchange, ImplicitAPI):
|
|
1567
1574
|
async def fetch_future_markets(self, params):
|
1568
1575
|
params = self.extend(params)
|
1569
1576
|
params['limit'] = 1000 # minimize number of requests
|
1570
|
-
|
1577
|
+
usePrivateInstrumentsInfo = self.safe_bool(self.options, 'usePrivateInstrumentsInfo', False)
|
1578
|
+
response: dict = None
|
1579
|
+
if usePrivateInstrumentsInfo:
|
1580
|
+
response = await self.privateGetV5MarketInstrumentsInfo(params)
|
1581
|
+
else:
|
1582
|
+
response = await self.publicGetV5MarketInstrumentsInfo(params)
|
1571
1583
|
data = self.safe_dict(response, 'result', {})
|
1572
1584
|
markets = self.safe_list(data, 'list', [])
|
1573
1585
|
paginationCursor = self.safe_string(data, 'nextPageCursor')
|
1574
1586
|
if paginationCursor is not None:
|
1575
1587
|
while(paginationCursor is not None):
|
1576
1588
|
params['cursor'] = paginationCursor
|
1577
|
-
responseInner =
|
1589
|
+
responseInner: dict = None
|
1590
|
+
if usePrivateInstrumentsInfo:
|
1591
|
+
responseInner = await self.privateGetV5MarketInstrumentsInfo(params)
|
1592
|
+
else:
|
1593
|
+
responseInner = await self.publicGetV5MarketInstrumentsInfo(params)
|
1578
1594
|
dataNew = self.safe_dict(responseInner, 'result', {})
|
1579
1595
|
rawMarkets = self.safe_list(dataNew, 'list', [])
|
1580
1596
|
rawMarketsLength = len(rawMarkets)
|
@@ -1731,7 +1747,12 @@ class bybit(Exchange, ImplicitAPI):
|
|
1731
1747
|
request: dict = {
|
1732
1748
|
'category': 'option',
|
1733
1749
|
}
|
1734
|
-
|
1750
|
+
usePrivateInstrumentsInfo = self.safe_bool(self.options, 'usePrivateInstrumentsInfo', False)
|
1751
|
+
response: dict = None
|
1752
|
+
if usePrivateInstrumentsInfo:
|
1753
|
+
response = await self.privateGetV5MarketInstrumentsInfo(self.extend(request, params))
|
1754
|
+
else:
|
1755
|
+
response = await self.publicGetV5MarketInstrumentsInfo(self.extend(request, params))
|
1735
1756
|
data = self.safe_dict(response, 'result', {})
|
1736
1757
|
markets = self.safe_list(data, 'list', [])
|
1737
1758
|
if self.options['loadAllOptions']:
|
@@ -1740,7 +1761,11 @@ class bybit(Exchange, ImplicitAPI):
|
|
1740
1761
|
if paginationCursor is not None:
|
1741
1762
|
while(paginationCursor is not None):
|
1742
1763
|
request['cursor'] = paginationCursor
|
1743
|
-
responseInner =
|
1764
|
+
responseInner: dict = None
|
1765
|
+
if usePrivateInstrumentsInfo:
|
1766
|
+
responseInner = await self.privateGetV5MarketInstrumentsInfo(self.extend(request, params))
|
1767
|
+
else:
|
1768
|
+
responseInner = await self.publicGetV5MarketInstrumentsInfo(self.extend(request, params))
|
1744
1769
|
dataNew = self.safe_dict(responseInner, 'result', {})
|
1745
1770
|
rawMarkets = self.safe_list(dataNew, 'list', [])
|
1746
1771
|
rawMarketsLength = len(rawMarkets)
|
@@ -6739,8 +6764,8 @@ class bybit(Exchange, ImplicitAPI):
|
|
6739
6764
|
currency = None
|
6740
6765
|
request: dict = {}
|
6741
6766
|
if code is not None:
|
6742
|
-
currency = self.
|
6743
|
-
request['coin'] = currency
|
6767
|
+
currency = self.safe_currency(code)
|
6768
|
+
request['coin'] = currency['id']
|
6744
6769
|
if since is not None:
|
6745
6770
|
request['startTime'] = since
|
6746
6771
|
if limit is not None:
|
ccxt/async_support/mexc.py
CHANGED
@@ -4908,7 +4908,7 @@ class mexc(Exchange, ImplicitAPI):
|
|
4908
4908
|
networks = self.safe_dict(self.options, 'networks', {})
|
4909
4909
|
network = self.safe_string_2(params, 'network', 'netWork') # self line allows the user to specify either ERC20 or ETH
|
4910
4910
|
network = self.safe_string(networks, network, network) # handle ETH > ERC-20 alias
|
4911
|
-
network = self.
|
4911
|
+
network = self.network_id_to_code(network)
|
4912
4912
|
self.check_address(address)
|
4913
4913
|
await self.load_markets()
|
4914
4914
|
currency = self.currency(code)
|
ccxt/async_support/whitebit.py
CHANGED
@@ -794,8 +794,23 @@ class whitebit(Exchange, ImplicitAPI):
|
|
794
794
|
# "change": "2.12" # in percent
|
795
795
|
# }
|
796
796
|
#
|
797
|
+
# WS market_update
|
798
|
+
#
|
799
|
+
# {
|
800
|
+
# "open": "52853.04",
|
801
|
+
# "close": "55913.88",
|
802
|
+
# "high": "56272",
|
803
|
+
# "low": "49549.67",
|
804
|
+
# "volume": "57331.067185",
|
805
|
+
# "deal": "3063860382.42985338",
|
806
|
+
# "last": "55913.88",
|
807
|
+
# "period": 86400
|
808
|
+
# }
|
797
809
|
market = self.safe_market(None, market)
|
798
|
-
last
|
810
|
+
# last price is provided as "last" or "last_price"
|
811
|
+
last = self.safe_string_2(ticker, 'last', 'last_price')
|
812
|
+
# if "close" is provided, use it, otherwise use <last>
|
813
|
+
close = self.safe_string(ticker, 'close', last)
|
799
814
|
return self.safe_ticker({
|
800
815
|
'symbol': market['symbol'],
|
801
816
|
'timestamp': None,
|
@@ -808,7 +823,7 @@ class whitebit(Exchange, ImplicitAPI):
|
|
808
823
|
'askVolume': None,
|
809
824
|
'vwap': None,
|
810
825
|
'open': self.safe_string(ticker, 'open'),
|
811
|
-
'close':
|
826
|
+
'close': close,
|
812
827
|
'last': last,
|
813
828
|
'previousClose': None,
|
814
829
|
'change': None,
|
ccxt/async_support/woo.py
CHANGED
@@ -155,7 +155,7 @@ class woo(Exchange, ImplicitAPI):
|
|
155
155
|
'https://support.woo.org/hc/en-001/articles/4404611795353--Trading-Fees',
|
156
156
|
],
|
157
157
|
'referral': {
|
158
|
-
'url': 'https://x.woo.org/register?ref=
|
158
|
+
'url': 'https://x.woo.org/register?ref=DIJT0CNL',
|
159
159
|
'discount': 0.35,
|
160
160
|
},
|
161
161
|
},
|
ccxt/async_support/yobit.py
CHANGED
@@ -5,6 +5,7 @@
|
|
5
5
|
|
6
6
|
from ccxt.async_support.base.exchange import Exchange
|
7
7
|
from ccxt.abstract.yobit import ImplicitAPI
|
8
|
+
import asyncio
|
8
9
|
import hashlib
|
9
10
|
from ccxt.base.types import Balances, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFees
|
10
11
|
from typing import List
|
@@ -541,31 +542,7 @@ class yobit(Exchange, ImplicitAPI):
|
|
541
542
|
'info': ticker,
|
542
543
|
}, market)
|
543
544
|
|
544
|
-
async def
|
545
|
-
"""
|
546
|
-
:see: https://yobit.net/en/api
|
547
|
-
fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
|
548
|
-
:param str[]|None symbols: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
|
549
|
-
:param dict [params]: extra parameters specific to the exchange API endpoint
|
550
|
-
:returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
|
551
|
-
"""
|
552
|
-
if symbols is None:
|
553
|
-
raise ArgumentsRequired(self.id + ' fetchTickers() requires "symbols" argument')
|
554
|
-
await self.load_markets()
|
555
|
-
symbols = self.market_symbols(symbols)
|
556
|
-
ids = None
|
557
|
-
if symbols is None:
|
558
|
-
ids = self.ids
|
559
|
-
else:
|
560
|
-
ids = self.market_ids(symbols)
|
561
|
-
idsLength: number = len(ids)
|
562
|
-
idsString = '-'.join(ids)
|
563
|
-
maxLength = self.safe_integer(self.options, 'maxUrlLength', 2048)
|
564
|
-
# max URL length is 2048 symbols, including http schema, hostname, tld, etc...
|
565
|
-
lenghtOfBaseUrl = 30 # the url including api-base and endpoint dir is 30 chars
|
566
|
-
actualLength = len(idsString) + lenghtOfBaseUrl
|
567
|
-
if actualLength > maxLength:
|
568
|
-
raise ArgumentsRequired(self.id + ' fetchTickers() is being requested for ' + str(idsLength) + ' markets(which has an URL length of ' + str(actualLength) + ' characters), but it exceedes max URL length(' + str(maxLength) + '), please pass limisted symbols array to fetchTickers to fit in one request')
|
545
|
+
async def fetch_tickers_helper(self, idsString: str, params={}) -> Tickers:
|
569
546
|
request: dict = {
|
570
547
|
'pair': idsString,
|
571
548
|
}
|
@@ -578,7 +555,53 @@ class yobit(Exchange, ImplicitAPI):
|
|
578
555
|
market = self.safe_market(id)
|
579
556
|
symbol = market['symbol']
|
580
557
|
result[symbol] = self.parse_ticker(ticker, market)
|
581
|
-
return
|
558
|
+
return result
|
559
|
+
|
560
|
+
async def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
|
561
|
+
"""
|
562
|
+
:see: https://yobit.net/en/api
|
563
|
+
fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
|
564
|
+
:param str[]|None symbols: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
|
565
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
566
|
+
:param dict [params.all]: you can set to `true` for convenience to fetch all tickers from self exchange by sending multiple requests
|
567
|
+
:returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
|
568
|
+
"""
|
569
|
+
allSymbols = None
|
570
|
+
allSymbols, params = self.handle_param_bool(params, 'all', False)
|
571
|
+
if symbols is None and not allSymbols:
|
572
|
+
raise ArgumentsRequired(self.id + ' fetchTickers() requires "symbols" argument or use `params["all"] = True` to send multiple requests for all markets')
|
573
|
+
await self.load_markets()
|
574
|
+
promises = []
|
575
|
+
maxLength = self.safe_integer(self.options, 'maxUrlLength', 2048)
|
576
|
+
# max URL length is 2048 symbols, including http schema, hostname, tld, etc...
|
577
|
+
lenghtOfBaseUrl = 40 # safe space for the url including api-base and endpoint dir is 30 chars
|
578
|
+
if allSymbols:
|
579
|
+
symbols = self.symbols
|
580
|
+
ids = ''
|
581
|
+
for i in range(0, len(self.ids)):
|
582
|
+
id = self.ids[i]
|
583
|
+
prefix = '' if (ids == '') else '-'
|
584
|
+
ids += prefix + id
|
585
|
+
if len(ids) > maxLength:
|
586
|
+
promises.append(self.fetch_tickers_helper(ids, params))
|
587
|
+
ids = ''
|
588
|
+
if ids != '':
|
589
|
+
promises.append(self.fetch_tickers_helper(ids, params))
|
590
|
+
else:
|
591
|
+
symbols = self.market_symbols(symbols)
|
592
|
+
ids = self.market_ids(symbols)
|
593
|
+
idsLength: number = len(ids)
|
594
|
+
idsString = '-'.join(ids)
|
595
|
+
actualLength = len(idsString) + lenghtOfBaseUrl
|
596
|
+
if actualLength > maxLength:
|
597
|
+
raise ArgumentsRequired(self.id + ' fetchTickers() is being requested for ' + str(idsLength) + ' markets(which has an URL length of ' + str(actualLength) + ' characters), but it exceedes max URL length(' + str(maxLength) + '), please pass limisted symbols array to fetchTickers to fit in one request')
|
598
|
+
promises.append(self.fetch_tickers_helper(idsString, params))
|
599
|
+
resultAll = await asyncio.gather(*promises)
|
600
|
+
finalResult = {}
|
601
|
+
for i in range(0, len(resultAll)):
|
602
|
+
result = self.filter_by_array_tickers(resultAll[i], 'symbol', symbols)
|
603
|
+
finalResult = self.extend(finalResult, result)
|
604
|
+
return finalResult
|
582
605
|
|
583
606
|
async def fetch_ticker(self, symbol: str, params={}) -> Ticker:
|
584
607
|
"""
|