ccxt 4.2.21__py2.py3-none-any.whl → 4.2.22__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 +3 -0
- ccxt/abstract/binancecoinm.py +3 -0
- ccxt/abstract/binanceus.py +16 -12
- ccxt/abstract/binanceusdm.py +3 -0
- ccxt/async_support/__init__.py +1 -1
- ccxt/async_support/base/exchange.py +1 -1
- ccxt/async_support/bigone.py +1 -0
- ccxt/async_support/binance.py +14 -3
- ccxt/async_support/bitget.py +11 -1
- ccxt/async_support/bitrue.py +1 -0
- ccxt/async_support/bybit.py +49 -10
- ccxt/async_support/coinbasepro.py +1 -0
- ccxt/async_support/coinex.py +34 -12
- ccxt/async_support/deribit.py +145 -0
- ccxt/async_support/okcoin.py +3 -0
- ccxt/async_support/phemex.py +5 -2
- ccxt/async_support/poloniex.py +1 -0
- ccxt/async_support/woo.py +1 -1
- ccxt/base/exchange.py +1 -1
- ccxt/bigone.py +1 -0
- ccxt/binance.py +14 -3
- ccxt/bitget.py +11 -1
- ccxt/bitrue.py +1 -0
- ccxt/bybit.py +49 -10
- ccxt/coinbasepro.py +1 -0
- ccxt/coinex.py +34 -12
- ccxt/deribit.py +145 -0
- ccxt/okcoin.py +3 -0
- ccxt/phemex.py +5 -2
- ccxt/poloniex.py +1 -0
- ccxt/pro/__init__.py +1 -1
- ccxt/pro/bequant.py +7 -1
- ccxt/pro/binance.py +7 -4
- ccxt/pro/binancecoinm.py +7 -1
- ccxt/pro/binanceus.py +7 -1
- ccxt/pro/bitcoincom.py +7 -1
- ccxt/pro/bitget.py +1 -1
- ccxt/pro/bitrue.py +5 -1
- ccxt/pro/okx.py +10 -2
- ccxt/test/test_async.py +14 -1
- ccxt/test/test_sync.py +14 -1
- ccxt/woo.py +1 -1
- {ccxt-4.2.21.dist-info → ccxt-4.2.22.dist-info}/METADATA +4 -4
- {ccxt-4.2.21.dist-info → ccxt-4.2.22.dist-info}/RECORD +47 -47
- {ccxt-4.2.21.dist-info → ccxt-4.2.22.dist-info}/WHEEL +0 -0
- {ccxt-4.2.21.dist-info → ccxt-4.2.22.dist-info}/top_level.txt +0 -0
ccxt/deribit.py
CHANGED
@@ -415,6 +415,151 @@ class deribit(Exchange, ImplicitAPI):
|
|
415
415
|
},
|
416
416
|
})
|
417
417
|
|
418
|
+
def convert_expire_date(self, date):
|
419
|
+
# parse YYMMDD to timestamp
|
420
|
+
year = date[0:2]
|
421
|
+
month = date[2:4]
|
422
|
+
day = date[4:6]
|
423
|
+
reconstructedDate = '20' + year + '-' + month + '-' + day + 'T00:00:00Z'
|
424
|
+
return reconstructedDate
|
425
|
+
|
426
|
+
def convert_market_id_expire_date(self, date):
|
427
|
+
# parse 19JAN24 to 240119
|
428
|
+
monthMappping = {
|
429
|
+
'JAN': '01',
|
430
|
+
'FEB': '02',
|
431
|
+
'MAR': '03',
|
432
|
+
'APR': '04',
|
433
|
+
'MAY': '05',
|
434
|
+
'JUN': '06',
|
435
|
+
'JUL': '07',
|
436
|
+
'AUG': '08',
|
437
|
+
'SEP': '09',
|
438
|
+
'OCT': '10',
|
439
|
+
'NOV': '11',
|
440
|
+
'DEC': '12',
|
441
|
+
}
|
442
|
+
year = date[0:2]
|
443
|
+
monthName = date[2:5]
|
444
|
+
month = self.safe_string(monthMappping, monthName)
|
445
|
+
day = date[5:7]
|
446
|
+
reconstructedDate = day + month + year
|
447
|
+
return reconstructedDate
|
448
|
+
|
449
|
+
def convert_expire_date_to_market_id_date(self, date):
|
450
|
+
# parse 240119 to 19JAN24
|
451
|
+
year = date[0:2]
|
452
|
+
monthRaw = date[2:4]
|
453
|
+
month = None
|
454
|
+
day = date[4:6]
|
455
|
+
if monthRaw == '01':
|
456
|
+
month = 'JAN'
|
457
|
+
elif monthRaw == '02':
|
458
|
+
month = 'FEB'
|
459
|
+
elif monthRaw == '03':
|
460
|
+
month = 'MAR'
|
461
|
+
elif monthRaw == '04':
|
462
|
+
month = 'APR'
|
463
|
+
elif monthRaw == '05':
|
464
|
+
month = 'MAY'
|
465
|
+
elif monthRaw == '06':
|
466
|
+
month = 'JUN'
|
467
|
+
elif monthRaw == '07':
|
468
|
+
month = 'JUL'
|
469
|
+
elif monthRaw == '08':
|
470
|
+
month = 'AUG'
|
471
|
+
elif monthRaw == '09':
|
472
|
+
month = 'SEP'
|
473
|
+
elif monthRaw == '10':
|
474
|
+
month = 'OCT'
|
475
|
+
elif monthRaw == '11':
|
476
|
+
month = 'NOV'
|
477
|
+
elif monthRaw == '12':
|
478
|
+
month = 'DEC'
|
479
|
+
reconstructedDate = day + month + year
|
480
|
+
return reconstructedDate
|
481
|
+
|
482
|
+
def create_expired_option_market(self, symbol):
|
483
|
+
# support expired option contracts
|
484
|
+
quote = 'USD'
|
485
|
+
settle = None
|
486
|
+
optionParts = symbol.split('-')
|
487
|
+
symbolBase = symbol.split('/')
|
488
|
+
base = None
|
489
|
+
expiry = None
|
490
|
+
if symbol.find('/') > -1:
|
491
|
+
base = self.safe_string(symbolBase, 0)
|
492
|
+
expiry = self.safe_string(optionParts, 1)
|
493
|
+
if symbol.find('USDC') > -1:
|
494
|
+
base = base + '_USDC'
|
495
|
+
else:
|
496
|
+
base = self.safe_string(optionParts, 0)
|
497
|
+
expiry = self.convert_market_id_expire_date(self.safe_string(optionParts, 1))
|
498
|
+
if symbol.find('USDC') > -1:
|
499
|
+
quote = 'USDC'
|
500
|
+
settle = 'USDC'
|
501
|
+
else:
|
502
|
+
settle = base
|
503
|
+
splitBase = base
|
504
|
+
if base.find('_') > -1:
|
505
|
+
splitSymbol = base.split('_')
|
506
|
+
splitBase = self.safe_string(splitSymbol, 0)
|
507
|
+
strike = self.safe_string(optionParts, 2)
|
508
|
+
optionType = self.safe_string(optionParts, 3)
|
509
|
+
datetime = self.convert_expire_date(expiry)
|
510
|
+
timestamp = self.parse8601(datetime)
|
511
|
+
return {
|
512
|
+
'id': base + '-' + self.convert_expire_date_to_market_id_date(expiry) + '-' + strike + '-' + optionType,
|
513
|
+
'symbol': splitBase + '/' + quote + ':' + settle + '-' + expiry + '-' + strike + '-' + optionType,
|
514
|
+
'base': base,
|
515
|
+
'quote': quote,
|
516
|
+
'settle': settle,
|
517
|
+
'baseId': base,
|
518
|
+
'quoteId': quote,
|
519
|
+
'settleId': settle,
|
520
|
+
'active': False,
|
521
|
+
'type': 'option',
|
522
|
+
'linear': None,
|
523
|
+
'inverse': None,
|
524
|
+
'spot': False,
|
525
|
+
'swap': False,
|
526
|
+
'future': False,
|
527
|
+
'option': True,
|
528
|
+
'margin': False,
|
529
|
+
'contract': True,
|
530
|
+
'contractSize': None,
|
531
|
+
'expiry': timestamp,
|
532
|
+
'expiryDatetime': datetime,
|
533
|
+
'optionType': 'call' if (optionType == 'C') else 'put',
|
534
|
+
'strike': self.parse_number(strike),
|
535
|
+
'precision': {
|
536
|
+
'amount': None,
|
537
|
+
'price': None,
|
538
|
+
},
|
539
|
+
'limits': {
|
540
|
+
'amount': {
|
541
|
+
'min': None,
|
542
|
+
'max': None,
|
543
|
+
},
|
544
|
+
'price': {
|
545
|
+
'min': None,
|
546
|
+
'max': None,
|
547
|
+
},
|
548
|
+
'cost': {
|
549
|
+
'min': None,
|
550
|
+
'max': None,
|
551
|
+
},
|
552
|
+
},
|
553
|
+
'info': None,
|
554
|
+
}
|
555
|
+
|
556
|
+
def safe_market(self, marketId=None, market=None, delimiter=None, marketType=None):
|
557
|
+
isOption = (marketId is not None) and ((marketId.endswith('-C')) or (marketId.endswith('-P')))
|
558
|
+
if isOption and not (marketId in self.markets_by_id):
|
559
|
+
# handle expired option contracts
|
560
|
+
return self.create_expired_option_market(marketId)
|
561
|
+
return super(deribit, self).safe_market(marketId, market, delimiter, marketType)
|
562
|
+
|
418
563
|
def fetch_time(self, params={}):
|
419
564
|
"""
|
420
565
|
fetches the current integer timestamp in milliseconds from the exchange server
|
ccxt/okcoin.py
CHANGED
@@ -67,6 +67,9 @@ class okcoin(Exchange, ImplicitAPI):
|
|
67
67
|
'fetchCurrencies': True, # see below
|
68
68
|
'fetchDepositAddress': True,
|
69
69
|
'fetchDeposits': True,
|
70
|
+
'fetchFundingHistory': False,
|
71
|
+
'fetchFundingRate': False,
|
72
|
+
'fetchFundingRateHistory': False,
|
70
73
|
'fetchLedger': True,
|
71
74
|
'fetchMarkets': True,
|
72
75
|
'fetchMyTrades': True,
|
ccxt/phemex.py
CHANGED
@@ -1850,23 +1850,26 @@ class phemex(Exchange, ImplicitAPI):
|
|
1850
1850
|
def fetch_balance(self, params={}) -> Balances:
|
1851
1851
|
"""
|
1852
1852
|
query for balance and get the amount of funds available for trading or funds locked in orders
|
1853
|
+
:see: https://phemex-docs.github.io/#query-wallets
|
1853
1854
|
:see: https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#query-account-positions
|
1855
|
+
:see: https://phemex-docs.github.io/#query-trading-account-and-positions
|
1854
1856
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1855
1857
|
:param str [params.type]: spot or swap
|
1858
|
+
:param str [params.code]: *swap only* currency code of the balance to query(USD, USDT, etc), default is USDT
|
1856
1859
|
:returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
|
1857
1860
|
"""
|
1858
1861
|
self.load_markets()
|
1859
1862
|
type = None
|
1860
1863
|
type, params = self.handle_market_type_and_params('fetchBalance', None, params)
|
1861
1864
|
code = self.safe_string(params, 'code')
|
1862
|
-
params = self.omit(params, ['
|
1865
|
+
params = self.omit(params, ['code'])
|
1863
1866
|
response = None
|
1864
1867
|
request = {}
|
1865
1868
|
if (type != 'spot') and (type != 'swap'):
|
1866
1869
|
raise BadRequest(self.id + ' does not support ' + type + ' markets, only spot and swap')
|
1867
1870
|
if type == 'swap':
|
1868
1871
|
settle = None
|
1869
|
-
settle, params = self.handle_option_and_params(params, 'fetchBalance', 'settle')
|
1872
|
+
settle, params = self.handle_option_and_params(params, 'fetchBalance', 'settle', 'USDT')
|
1870
1873
|
if code is not None or settle is not None:
|
1871
1874
|
coin = None
|
1872
1875
|
if code is not None:
|
ccxt/poloniex.py
CHANGED
@@ -60,6 +60,7 @@ class poloniex(Exchange, ImplicitAPI):
|
|
60
60
|
'fetchDepositsWithdrawals': True,
|
61
61
|
'fetchDepositWithdrawFee': 'emulated',
|
62
62
|
'fetchDepositWithdrawFees': True,
|
63
|
+
'fetchFundingRate': False,
|
63
64
|
'fetchMarginMode': False,
|
64
65
|
'fetchMarkets': True,
|
65
66
|
'fetchMyTrades': True,
|
ccxt/pro/__init__.py
CHANGED
ccxt/pro/bequant.py
CHANGED
@@ -5,11 +5,17 @@
|
|
5
5
|
|
6
6
|
from ccxt.pro.hitbtc import hitbtc
|
7
7
|
|
8
|
+
import ccxt.async_support.bequant as bequantRest
|
9
|
+
|
8
10
|
|
9
11
|
class bequant(hitbtc):
|
10
12
|
|
11
13
|
def describe(self):
|
12
|
-
|
14
|
+
# eslint-disable-next-line new-cap
|
15
|
+
restInstance = bequantRest()
|
16
|
+
restDescribe = restInstance.describe()
|
17
|
+
extended = self.deep_extend(super(bequant, self).describe(), restDescribe)
|
18
|
+
return self.deep_extend(extended, {
|
13
19
|
'id': 'bequant',
|
14
20
|
'name': 'Bequant',
|
15
21
|
'countries': ['MT'], # Malta
|
ccxt/pro/binance.py
CHANGED
@@ -49,7 +49,7 @@ class binance(ccxt.async_support.binance):
|
|
49
49
|
'ws': {
|
50
50
|
'spot': 'wss://testnet.binance.vision/ws',
|
51
51
|
'margin': 'wss://testnet.binance.vision/ws',
|
52
|
-
'future': 'wss://
|
52
|
+
'future': 'wss://fstream.binancefuture.com/ws',
|
53
53
|
'delivery': 'wss://dstream.binancefuture.com/ws',
|
54
54
|
'ws': 'wss://testnet.binance.vision/ws-api/v3',
|
55
55
|
},
|
@@ -1811,12 +1811,13 @@ class binance(ccxt.async_support.binance):
|
|
1811
1811
|
|
1812
1812
|
async def watch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
1813
1813
|
"""
|
1814
|
-
:see: https://binance-docs.github.io/apidocs/spot/en/#payload-order-update
|
1815
1814
|
watches information on multiple orders made by the user
|
1816
|
-
:
|
1815
|
+
:see: https://binance-docs.github.io/apidocs/spot/en/#payload-order-update
|
1816
|
+
:param str symbol: unified market symbol of the market the orders were made in
|
1817
1817
|
:param int [since]: the earliest time in ms to fetch orders for
|
1818
1818
|
:param int [limit]: the maximum number of order structures to retrieve
|
1819
1819
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1820
|
+
:param str|None [params.marginMode]: 'cross' or 'isolated', for spot margin
|
1820
1821
|
:returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
1821
1822
|
"""
|
1822
1823
|
await self.load_markets()
|
@@ -1836,8 +1837,10 @@ class binance(ccxt.async_support.binance):
|
|
1836
1837
|
type = 'delivery'
|
1837
1838
|
params = self.extend(params, {'type': type, 'symbol': symbol}) # needed inside authenticate for isolated margin
|
1838
1839
|
await self.authenticate(params)
|
1840
|
+
marginMode = None
|
1841
|
+
marginMode, params = self.handle_margin_mode_and_params('watchOrders', params)
|
1839
1842
|
urlType = type
|
1840
|
-
if type == 'margin':
|
1843
|
+
if (type == 'margin') or ((type == 'spot') and (marginMode is not None)):
|
1841
1844
|
urlType = 'spot' # spot-margin shares the same stream spot
|
1842
1845
|
url = self.urls['api']['ws'][urlType] + '/' + self.options[type]['listenKey']
|
1843
1846
|
client = self.client(url)
|
ccxt/pro/binancecoinm.py
CHANGED
@@ -5,11 +5,17 @@
|
|
5
5
|
|
6
6
|
from ccxt.pro.binance import binance
|
7
7
|
|
8
|
+
import ccxt.async_support.binancecoinm as binancecoinmRest
|
9
|
+
|
8
10
|
|
9
11
|
class binancecoinm(binance):
|
10
12
|
|
11
13
|
def describe(self):
|
12
|
-
|
14
|
+
# eslint-disable-next-line new-cap
|
15
|
+
restInstance = binancecoinmRest()
|
16
|
+
restDescribe = restInstance.describe()
|
17
|
+
extended = self.deep_extend(super(binancecoinm, self).describe(), restDescribe)
|
18
|
+
return self.deep_extend(extended, {
|
13
19
|
'id': 'binancecoinm',
|
14
20
|
'name': 'Binance COIN-M',
|
15
21
|
'urls': {
|
ccxt/pro/binanceus.py
CHANGED
@@ -5,11 +5,17 @@
|
|
5
5
|
|
6
6
|
from ccxt.pro.binance import binance
|
7
7
|
|
8
|
+
import ccxt.async_support.binanceus as binanceusRest
|
9
|
+
|
8
10
|
|
9
11
|
class binanceus(binance):
|
10
12
|
|
11
13
|
def describe(self):
|
12
|
-
|
14
|
+
# eslint-disable-next-line new-cap
|
15
|
+
restInstance = binanceusRest()
|
16
|
+
restDescribe = restInstance.describe()
|
17
|
+
extended = self.deep_extend(super(binanceus, self).describe(), restDescribe)
|
18
|
+
return self.deep_extend(extended, {
|
13
19
|
'id': 'binanceus',
|
14
20
|
'name': 'Binance US',
|
15
21
|
'countries': ['US'], # US
|
ccxt/pro/bitcoincom.py
CHANGED
@@ -5,11 +5,17 @@
|
|
5
5
|
|
6
6
|
from ccxt.pro.hitbtc import hitbtc
|
7
7
|
|
8
|
+
import ccxt.async_support.bequant as bequantRest
|
9
|
+
|
8
10
|
|
9
11
|
class bitcoincom(hitbtc):
|
10
12
|
|
11
13
|
def describe(self):
|
12
|
-
|
14
|
+
# eslint-disable-next-line new-cap
|
15
|
+
restInstance = bequantRest()
|
16
|
+
restDescribe = restInstance.describe()
|
17
|
+
extended = self.deep_extend(super(bitcoincom, self).describe(), restDescribe)
|
18
|
+
return self.deep_extend(extended, {
|
13
19
|
'id': 'bitcoincom',
|
14
20
|
'name': 'bitcoin.com',
|
15
21
|
'countries': ['KN'],
|
ccxt/pro/bitget.py
CHANGED
@@ -1184,7 +1184,7 @@ class bitget(ccxt.async_support.bitget):
|
|
1184
1184
|
'price': self.safe_string(order, 'price'),
|
1185
1185
|
'stopPrice': triggerPrice,
|
1186
1186
|
'triggerPrice': triggerPrice,
|
1187
|
-
'amount': self.
|
1187
|
+
'amount': self.safe_string(order, 'baseVolume'),
|
1188
1188
|
'cost': self.safe_string_n(order, ['notional', 'notionalUsd', 'quoteSize']),
|
1189
1189
|
'average': self.omit_zero(self.safe_string_2(order, 'priceAvg', 'fillPrice')),
|
1190
1190
|
'filled': self.safe_string_2(order, 'accBaseVolume', 'baseVolume'),
|
ccxt/pro/bitrue.py
CHANGED
@@ -341,7 +341,11 @@ class bitrue(ccxt.async_support.bitrue):
|
|
341
341
|
symbol = market['symbol']
|
342
342
|
timestamp = self.safe_integer(message, 'ts')
|
343
343
|
tick = self.safe_value(message, 'tick', {})
|
344
|
-
orderbook = self.
|
344
|
+
orderbook = self.safe_value(self.orderbooks, symbol)
|
345
|
+
if orderbook is None:
|
346
|
+
orderbook = self.order_book()
|
347
|
+
snapshot = self.parse_order_book(tick, symbol, timestamp, 'buys', 'asks')
|
348
|
+
orderbook.reset(snapshot)
|
345
349
|
self.orderbooks[symbol] = orderbook
|
346
350
|
messageHash = 'orderbook:' + symbol
|
347
351
|
client.resolve(orderbook, messageHash)
|
ccxt/pro/okx.py
CHANGED
@@ -949,17 +949,20 @@ class okx(ccxt.async_support.okx):
|
|
949
949
|
|
950
950
|
async def watch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
951
951
|
"""
|
952
|
-
:see: https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-order-channel
|
953
952
|
watches information on multiple orders made by the user
|
954
|
-
:
|
953
|
+
:see: https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-order-channel
|
954
|
+
:param str [symbol]: unified market symbol of the market the orders were made in
|
955
955
|
:param int [since]: the earliest time in ms to fetch orders for
|
956
956
|
:param int [limit]: the maximum number of order structures to retrieve
|
957
957
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
958
958
|
:param bool [params.stop]: True if fetching trigger or conditional orders
|
959
|
+
:param str [params.type]: 'spot', 'swap', 'future', 'option', 'ANY', 'SPOT', 'MARGIN', 'SWAP', 'FUTURES' or 'OPTION'
|
960
|
+
:param str [params.marginMode]: 'cross' or 'isolated', for automatically setting the type to spot margin
|
959
961
|
:returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
960
962
|
"""
|
961
963
|
type = None
|
962
964
|
# By default, receive order updates from any instrument type
|
965
|
+
type, params = self.handle_option_and_params(params, 'watchOrders', 'defaultType')
|
963
966
|
type, params = self.handle_option_and_params(params, 'watchOrders', 'type', 'ANY')
|
964
967
|
isStop = self.safe_value_2(params, 'stop', 'trigger', False)
|
965
968
|
params = self.omit(params, ['stop', 'trigger'])
|
@@ -973,6 +976,11 @@ class okx(ccxt.async_support.okx):
|
|
973
976
|
if type == 'future':
|
974
977
|
type = 'futures'
|
975
978
|
uppercaseType = type.upper()
|
979
|
+
marginMode = None
|
980
|
+
marginMode, params = self.handle_margin_mode_and_params('watchOrders', params)
|
981
|
+
if uppercaseType == 'SPOT':
|
982
|
+
if marginMode is not None:
|
983
|
+
uppercaseType = 'MARGIN'
|
976
984
|
request = {
|
977
985
|
'instType': uppercaseType,
|
978
986
|
}
|
ccxt/test/test_async.py
CHANGED
@@ -274,6 +274,10 @@ class testMainClass(baseMainTestClass):
|
|
274
274
|
|
275
275
|
async def init(self, exchange_id, symbol_argv):
|
276
276
|
self.parse_cli_args()
|
277
|
+
if self.request_tests and self.response_tests:
|
278
|
+
await self.run_static_request_tests(exchange_id, symbol_argv)
|
279
|
+
await self.run_static_response_tests(exchange_id, symbol_argv)
|
280
|
+
return
|
277
281
|
if self.response_tests:
|
278
282
|
await self.run_static_response_tests(exchange_id, symbol_argv)
|
279
283
|
return
|
@@ -1053,6 +1057,9 @@ class testMainClass(baseMainTestClass):
|
|
1053
1057
|
results = methods[method]
|
1054
1058
|
for j in range(0, len(results)):
|
1055
1059
|
result = results[j]
|
1060
|
+
old_exchange_options = exchange.options # snapshot options;
|
1061
|
+
test_exchange_options = exchange.safe_value(result, 'options', {})
|
1062
|
+
exchange.options = exchange.deep_extend(old_exchange_options, test_exchange_options) # custom options to be used in the tests
|
1056
1063
|
description = exchange.safe_value(result, 'description')
|
1057
1064
|
if (test_name is not None) and (test_name != description):
|
1058
1065
|
continue
|
@@ -1062,6 +1069,8 @@ class testMainClass(baseMainTestClass):
|
|
1062
1069
|
type = exchange.safe_string(exchange_data, 'outputType')
|
1063
1070
|
skip_keys = exchange.safe_value(exchange_data, 'skipKeys', [])
|
1064
1071
|
await self.test_method_statically(exchange, method, result, type, skip_keys)
|
1072
|
+
# reset options
|
1073
|
+
exchange.options = old_exchange_options
|
1065
1074
|
await close(exchange)
|
1066
1075
|
|
1067
1076
|
async def test_exchange_response_statically(self, exchange_name, exchange_data, test_name=None):
|
@@ -1076,6 +1085,9 @@ class testMainClass(baseMainTestClass):
|
|
1076
1085
|
for j in range(0, len(results)):
|
1077
1086
|
result = results[j]
|
1078
1087
|
description = exchange.safe_value(result, 'description')
|
1088
|
+
old_exchange_options = exchange.options # snapshot options;
|
1089
|
+
test_exchange_options = exchange.safe_value(result, 'options', {})
|
1090
|
+
exchange.options = exchange.deep_extend(old_exchange_options, test_exchange_options) # custom options to be used in the tests
|
1079
1091
|
is_disabled = exchange.safe_value(result, 'disabled', False)
|
1080
1092
|
if is_disabled:
|
1081
1093
|
continue
|
@@ -1086,6 +1098,8 @@ class testMainClass(baseMainTestClass):
|
|
1086
1098
|
continue
|
1087
1099
|
skip_keys = exchange.safe_value(exchange_data, 'skipKeys', [])
|
1088
1100
|
await self.test_response_statically(exchange, method, skip_keys, result)
|
1101
|
+
# reset options
|
1102
|
+
exchange.options = old_exchange_options
|
1089
1103
|
await close(exchange)
|
1090
1104
|
|
1091
1105
|
def get_number_of_tests_from_exchange(self, exchange, exchange_data):
|
@@ -1130,7 +1144,6 @@ class testMainClass(baseMainTestClass):
|
|
1130
1144
|
else:
|
1131
1145
|
success_message = '[' + self.lang + '][TEST_SUCCESS] ' + str(sum) + ' static ' + type + ' tests passed.'
|
1132
1146
|
dump('[INFO]' + success_message)
|
1133
|
-
exit_script(0)
|
1134
1147
|
|
1135
1148
|
async def run_static_response_tests(self, exchange_name=None, test=None):
|
1136
1149
|
# -----------------------------------------------------------------------------
|
ccxt/test/test_sync.py
CHANGED
@@ -273,6 +273,10 @@ class testMainClass(baseMainTestClass):
|
|
273
273
|
|
274
274
|
def init(self, exchange_id, symbol_argv):
|
275
275
|
self.parse_cli_args()
|
276
|
+
if self.request_tests and self.response_tests:
|
277
|
+
self.run_static_request_tests(exchange_id, symbol_argv)
|
278
|
+
self.run_static_response_tests(exchange_id, symbol_argv)
|
279
|
+
return
|
276
280
|
if self.response_tests:
|
277
281
|
self.run_static_response_tests(exchange_id, symbol_argv)
|
278
282
|
return
|
@@ -1052,6 +1056,9 @@ class testMainClass(baseMainTestClass):
|
|
1052
1056
|
results = methods[method]
|
1053
1057
|
for j in range(0, len(results)):
|
1054
1058
|
result = results[j]
|
1059
|
+
old_exchange_options = exchange.options # snapshot options;
|
1060
|
+
test_exchange_options = exchange.safe_value(result, 'options', {})
|
1061
|
+
exchange.options = exchange.deep_extend(old_exchange_options, test_exchange_options) # custom options to be used in the tests
|
1055
1062
|
description = exchange.safe_value(result, 'description')
|
1056
1063
|
if (test_name is not None) and (test_name != description):
|
1057
1064
|
continue
|
@@ -1061,6 +1068,8 @@ class testMainClass(baseMainTestClass):
|
|
1061
1068
|
type = exchange.safe_string(exchange_data, 'outputType')
|
1062
1069
|
skip_keys = exchange.safe_value(exchange_data, 'skipKeys', [])
|
1063
1070
|
self.test_method_statically(exchange, method, result, type, skip_keys)
|
1071
|
+
# reset options
|
1072
|
+
exchange.options = old_exchange_options
|
1064
1073
|
close(exchange)
|
1065
1074
|
|
1066
1075
|
def test_exchange_response_statically(self, exchange_name, exchange_data, test_name=None):
|
@@ -1075,6 +1084,9 @@ class testMainClass(baseMainTestClass):
|
|
1075
1084
|
for j in range(0, len(results)):
|
1076
1085
|
result = results[j]
|
1077
1086
|
description = exchange.safe_value(result, 'description')
|
1087
|
+
old_exchange_options = exchange.options # snapshot options;
|
1088
|
+
test_exchange_options = exchange.safe_value(result, 'options', {})
|
1089
|
+
exchange.options = exchange.deep_extend(old_exchange_options, test_exchange_options) # custom options to be used in the tests
|
1078
1090
|
is_disabled = exchange.safe_value(result, 'disabled', False)
|
1079
1091
|
if is_disabled:
|
1080
1092
|
continue
|
@@ -1085,6 +1097,8 @@ class testMainClass(baseMainTestClass):
|
|
1085
1097
|
continue
|
1086
1098
|
skip_keys = exchange.safe_value(exchange_data, 'skipKeys', [])
|
1087
1099
|
self.test_response_statically(exchange, method, skip_keys, result)
|
1100
|
+
# reset options
|
1101
|
+
exchange.options = old_exchange_options
|
1088
1102
|
close(exchange)
|
1089
1103
|
|
1090
1104
|
def get_number_of_tests_from_exchange(self, exchange, exchange_data):
|
@@ -1129,7 +1143,6 @@ class testMainClass(baseMainTestClass):
|
|
1129
1143
|
else:
|
1130
1144
|
success_message = '[' + self.lang + '][TEST_SUCCESS] ' + str(sum) + ' static ' + type + ' tests passed.'
|
1131
1145
|
dump('[INFO]' + success_message)
|
1132
|
-
exit_script(0)
|
1133
1146
|
|
1134
1147
|
def run_static_response_tests(self, exchange_name=None, test=None):
|
1135
1148
|
# -----------------------------------------------------------------------------
|
ccxt/woo.py
CHANGED
@@ -66,7 +66,7 @@ class woo(Exchange, ImplicitAPI):
|
|
66
66
|
'fetchClosedOrder': False,
|
67
67
|
'fetchClosedOrders': False,
|
68
68
|
'fetchCurrencies': True,
|
69
|
-
'fetchDepositAddress':
|
69
|
+
'fetchDepositAddress': True,
|
70
70
|
'fetchDeposits': True,
|
71
71
|
'fetchDepositsWithdrawals': True,
|
72
72
|
'fetchFundingHistory': True,
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: ccxt
|
3
|
-
Version: 4.2.
|
3
|
+
Version: 4.2.22
|
4
4
|
Summary: A JavaScript / TypeScript / Python / C# / PHP cryptocurrency trading library with support for 100+ exchanges
|
5
5
|
Home-page: https://ccxt.com
|
6
6
|
Author: Igor Kroitor
|
@@ -258,13 +258,13 @@ console.log(version, Object.keys(exchanges));
|
|
258
258
|
|
259
259
|
All-in-one browser bundle (dependencies included), served from a CDN of your choice:
|
260
260
|
|
261
|
-
* jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.2.
|
262
|
-
* unpkg: https://unpkg.com/ccxt@4.2.
|
261
|
+
* jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.2.22/dist/ccxt.browser.js
|
262
|
+
* unpkg: https://unpkg.com/ccxt@4.2.22/dist/ccxt.browser.js
|
263
263
|
|
264
264
|
CDNs are not updated in real-time and may have delays. Defaulting to the most recent version without specifying the version number is not recommended. Please, keep in mind that we are not responsible for the correct operation of those CDN servers.
|
265
265
|
|
266
266
|
```HTML
|
267
|
-
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@4.2.
|
267
|
+
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@4.2.22/dist/ccxt.browser.js"></script>
|
268
268
|
```
|
269
269
|
|
270
270
|
Creates a global `ccxt` object:
|