ccxt 4.2.95__py2.py3-none-any.whl → 4.2.97__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/abstract/coinbase.py +1 -0
- ccxt/async_support/__init__.py +1 -1
- ccxt/async_support/base/exchange.py +1 -1
- ccxt/async_support/binance.py +9 -9
- ccxt/async_support/coinbase.py +590 -102
- ccxt/async_support/deribit.py +7 -3
- ccxt/async_support/gemini.py +26 -11
- ccxt/async_support/okx.py +3 -2
- ccxt/async_support/poloniexfutures.py +4 -1
- ccxt/base/exchange.py +17 -5
- ccxt/binance.py +9 -9
- ccxt/coinbase.py +590 -102
- ccxt/deribit.py +7 -3
- ccxt/gemini.py +26 -11
- ccxt/okx.py +3 -2
- ccxt/poloniexfutures.py +4 -1
- ccxt/pro/__init__.py +1 -1
- ccxt/pro/binance.py +9 -5
- ccxt/pro/coinbase.py +19 -4
- ccxt/pro/poloniexfutures.py +5 -2
- ccxt/test/base/test_order_book.py +21 -15
- ccxt/test/test_async.py +32 -6
- ccxt/test/test_sync.py +32 -6
- {ccxt-4.2.95.dist-info → ccxt-4.2.97.dist-info}/METADATA +4 -4
- {ccxt-4.2.95.dist-info → ccxt-4.2.97.dist-info}/RECORD +28 -28
- {ccxt-4.2.95.dist-info → ccxt-4.2.97.dist-info}/WHEEL +0 -0
- {ccxt-4.2.95.dist-info → ccxt-4.2.97.dist-info}/top_level.txt +0 -0
ccxt/async_support/deribit.py
CHANGED
@@ -1184,13 +1184,17 @@ class deribit(Exchange, ImplicitAPI):
|
|
1184
1184
|
"""
|
1185
1185
|
fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
|
1186
1186
|
:see: https://docs.deribit.com/#public-get_book_summary_by_currency
|
1187
|
-
:param str[]
|
1187
|
+
:param str[] [symbols]: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
|
1188
1188
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1189
|
+
:param str [params.code]: *required* the currency code to fetch the tickers for, eg. 'BTC', 'ETH'
|
1189
1190
|
:returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
|
1190
1191
|
"""
|
1191
1192
|
await self.load_markets()
|
1192
1193
|
symbols = self.market_symbols(symbols)
|
1193
|
-
code = self.
|
1194
|
+
code = self.safe_string_2(params, 'code', 'currency')
|
1195
|
+
params = self.omit(params, ['code'])
|
1196
|
+
if code is None:
|
1197
|
+
raise ArgumentsRequired(self.id + ' fetchTickers requires a currency/code(eg: BTC/ETH/USDT) parameter to fetch tickers for')
|
1194
1198
|
currency = self.currency(code)
|
1195
1199
|
request = {
|
1196
1200
|
'currency': currency['id'],
|
@@ -1226,7 +1230,7 @@ class deribit(Exchange, ImplicitAPI):
|
|
1226
1230
|
# "testnet": False
|
1227
1231
|
# }
|
1228
1232
|
#
|
1229
|
-
result = self.
|
1233
|
+
result = self.safe_list(response, 'result', [])
|
1230
1234
|
tickers = {}
|
1231
1235
|
for i in range(0, len(result)):
|
1232
1236
|
ticker = self.parse_ticker(result[i])
|
ccxt/async_support/gemini.py
CHANGED
@@ -300,7 +300,13 @@ class gemini(Exchange, ImplicitAPI):
|
|
300
300
|
'ATOM': 'cosmos',
|
301
301
|
'DOT': 'polkadot',
|
302
302
|
},
|
303
|
-
'nonce': 'milliseconds', # if getting a Network 400 error change to seconds
|
303
|
+
'nonce': 'milliseconds', # if getting a Network 400 error change to seconds,
|
304
|
+
'conflictingMarkets': {
|
305
|
+
'paxgusd': {
|
306
|
+
'base': 'PAXG',
|
307
|
+
'quote': 'USD',
|
308
|
+
},
|
309
|
+
},
|
304
310
|
},
|
305
311
|
})
|
306
312
|
|
@@ -662,16 +668,25 @@ class gemini(Exchange, ImplicitAPI):
|
|
662
668
|
marketIdUpper = marketId.upper()
|
663
669
|
isPerp = (marketIdUpper.find('PERP') >= 0)
|
664
670
|
marketIdWithoutPerp = marketIdUpper.replace('PERP', '')
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
671
|
+
conflictingMarkets = self.safe_dict(self.options, 'conflictingMarkets', {})
|
672
|
+
lowerCaseId = marketIdWithoutPerp.lower()
|
673
|
+
if lowerCaseId in conflictingMarkets:
|
674
|
+
conflictingMarket = conflictingMarkets[lowerCaseId]
|
675
|
+
baseId = conflictingMarket['base']
|
676
|
+
quoteId = conflictingMarket['quote']
|
677
|
+
if isPerp:
|
678
|
+
settleId = conflictingMarket['quote']
|
679
|
+
else:
|
680
|
+
quoteCurrencies = self.handle_option('fetchMarketsFromAPI', 'quoteCurrencies', [])
|
681
|
+
for i in range(0, len(quoteCurrencies)):
|
682
|
+
quoteCurrency = quoteCurrencies[i]
|
683
|
+
if marketIdWithoutPerp.endswith(quoteCurrency):
|
684
|
+
quoteLength = self.parse_to_int(-1 * len(quoteCurrency))
|
685
|
+
baseId = marketIdWithoutPerp[0:quoteLength]
|
686
|
+
quoteId = quoteCurrency
|
687
|
+
if isPerp:
|
688
|
+
settleId = quoteCurrency # always same
|
689
|
+
break
|
675
690
|
base = self.safe_currency_code(baseId)
|
676
691
|
quote = self.safe_currency_code(quoteId)
|
677
692
|
settle = self.safe_currency_code(settleId)
|
ccxt/async_support/okx.py
CHANGED
@@ -9,6 +9,7 @@ import asyncio
|
|
9
9
|
import hashlib
|
10
10
|
from ccxt.base.types import Account, Balances, Conversion, Currencies, Currency, Greeks, Int, Leverage, MarginModification, Market, MarketInterface, Num, Option, OptionChain, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, Transaction, TransferEntry
|
11
11
|
from typing import List
|
12
|
+
from typing import Any
|
12
13
|
from ccxt.base.errors import ExchangeError
|
13
14
|
from ccxt.base.errors import AuthenticationError
|
14
15
|
from ccxt.base.errors import PermissionDenied
|
@@ -1130,13 +1131,13 @@ class okx(Exchange, ImplicitAPI):
|
|
1130
1131
|
},
|
1131
1132
|
})
|
1132
1133
|
|
1133
|
-
def handle_market_type_and_params(self, methodName, market=None, params={}):
|
1134
|
+
def handle_market_type_and_params(self, methodName: str, market: Market = None, params={}, defaultValue=None) -> Any:
|
1134
1135
|
instType = self.safe_string(params, 'instType')
|
1135
1136
|
params = self.omit(params, 'instType')
|
1136
1137
|
type = self.safe_string(params, 'type')
|
1137
1138
|
if (type is None) and (instType is not None):
|
1138
1139
|
params['type'] = instType
|
1139
|
-
return super(okx, self).handle_market_type_and_params(methodName, market, params)
|
1140
|
+
return super(okx, self).handle_market_type_and_params(methodName, market, params, defaultValue)
|
1140
1141
|
|
1141
1142
|
def convert_to_instrument_type(self, type):
|
1142
1143
|
exchangeTypes = self.safe_dict(self.options, 'exchangeType', {})
|
@@ -382,7 +382,10 @@ class poloniexfutures(Exchange, ImplicitAPI):
|
|
382
382
|
#
|
383
383
|
marketId = self.safe_string(ticker, 'symbol')
|
384
384
|
symbol = self.safe_symbol(marketId, market)
|
385
|
-
|
385
|
+
timestampString = self.safe_string(ticker, 'ts')
|
386
|
+
# check timestamp bcz bug: https://app.travis-ci.com/github/ccxt/ccxt/builds/269959181#L4011
|
387
|
+
multiplier = 0.00001 if (len(timestampString) == 18) else 0.000001
|
388
|
+
timestamp = self.safe_integer_product(ticker, 'ts', multiplier)
|
386
389
|
last = self.safe_string_2(ticker, 'price', 'lastPrice')
|
387
390
|
percentage = Precise.string_mul(self.safe_string(ticker, 'priceChgPct'), '100')
|
388
391
|
return self.safe_ticker({
|
ccxt/base/exchange.py
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
|
5
5
|
# -----------------------------------------------------------------------------
|
6
6
|
|
7
|
-
__version__ = '4.2.
|
7
|
+
__version__ = '4.2.97'
|
8
8
|
|
9
9
|
# -----------------------------------------------------------------------------
|
10
10
|
|
@@ -1341,7 +1341,7 @@ class Exchange(object):
|
|
1341
1341
|
signature = Exchange.base64_to_binary(Exchange.rsa(token, Exchange.decode(secret), algorithm))
|
1342
1342
|
elif algoType == 'ES':
|
1343
1343
|
rawSignature = Exchange.ecdsa(token, secret, 'p256', algorithm)
|
1344
|
-
signature = Exchange.base16_to_binary(rawSignature['r'] + rawSignature['s'])
|
1344
|
+
signature = Exchange.base16_to_binary(rawSignature['r'].rjust(64, "0") + rawSignature['s'].rjust(64, "0"))
|
1345
1345
|
else:
|
1346
1346
|
signature = Exchange.hmac(Exchange.encode(token), secret, algos[algorithm], 'binary')
|
1347
1347
|
return token + '.' + Exchange.base64urlencode(signature)
|
@@ -3971,11 +3971,23 @@ class Exchange(object):
|
|
3971
3971
|
result, empty = self.handle_option_and_params({}, methodName, optionName, defaultValue)
|
3972
3972
|
return result
|
3973
3973
|
|
3974
|
-
def handle_market_type_and_params(self, methodName: str, market: Market = None, params={}):
|
3974
|
+
def handle_market_type_and_params(self, methodName: str, market: Market = None, params={}, defaultValue=None):
|
3975
|
+
"""
|
3976
|
+
* @ignore
|
3977
|
+
* @param methodName the method calling handleMarketTypeAndParams
|
3978
|
+
:param Market market:
|
3979
|
+
:param dict params:
|
3980
|
+
:param str [params.type]: type assigned by user
|
3981
|
+
:param str [params.defaultType]: same.type
|
3982
|
+
:param str [defaultValue]: assigned programatically in the method calling handleMarketTypeAndParams
|
3983
|
+
:returns [str, dict]: the market type and params with type and defaultType omitted
|
3984
|
+
"""
|
3975
3985
|
defaultType = self.safe_string_2(self.options, 'defaultType', 'type', 'spot')
|
3986
|
+
if defaultValue is None: # defaultValue takes precendence over exchange wide defaultType
|
3987
|
+
defaultValue = defaultType
|
3976
3988
|
methodOptions = self.safe_dict(self.options, methodName)
|
3977
|
-
methodType =
|
3978
|
-
if methodOptions is not None:
|
3989
|
+
methodType = defaultValue
|
3990
|
+
if methodOptions is not None: # user defined methodType takes precedence over defaultValue
|
3979
3991
|
if isinstance(methodOptions, str):
|
3980
3992
|
methodType = methodOptions
|
3981
3993
|
else:
|
ccxt/binance.py
CHANGED
@@ -5548,7 +5548,7 @@ class binance(Exchange, ImplicitAPI):
|
|
5548
5548
|
response = self.papiPostCmOrder(request)
|
5549
5549
|
else:
|
5550
5550
|
response = self.dapiPrivatePostOrder(request)
|
5551
|
-
elif marketType == 'margin' or marginMode is not None:
|
5551
|
+
elif marketType == 'margin' or marginMode is not None or isPortfolioMargin:
|
5552
5552
|
if isPortfolioMargin:
|
5553
5553
|
response = self.papiPostMarginOrder(request)
|
5554
5554
|
else:
|
@@ -5630,12 +5630,6 @@ class binance(Exchange, ImplicitAPI):
|
|
5630
5630
|
uppercaseType = 'TAKE_PROFIT_MARKET' if market['contract'] else 'TAKE_PROFIT'
|
5631
5631
|
elif isLimitOrder:
|
5632
5632
|
uppercaseType = 'TAKE_PROFIT' if market['contract'] else 'TAKE_PROFIT_LIMIT'
|
5633
|
-
if (marketType == 'spot') or (marketType == 'margin'):
|
5634
|
-
request['newOrderRespType'] = self.safe_string(self.options['newOrderRespType'], type, 'RESULT') # 'ACK' for order id, 'RESULT' for full order or 'FULL' for order with fills
|
5635
|
-
else:
|
5636
|
-
# swap, futures and options
|
5637
|
-
if not isPortfolioMargin:
|
5638
|
-
request['newOrderRespType'] = 'RESULT' # "ACK", "RESULT", default "ACK"
|
5639
5633
|
if market['option']:
|
5640
5634
|
if type == 'market':
|
5641
5635
|
raise InvalidOrder(self.id + ' ' + type + ' is not a valid order type for the ' + symbol + ' market')
|
@@ -5663,6 +5657,12 @@ class binance(Exchange, ImplicitAPI):
|
|
5663
5657
|
uppercaseType = 'LIMIT_MAKER'
|
5664
5658
|
if marginMode == 'isolated':
|
5665
5659
|
request['isIsolated'] = True
|
5660
|
+
# handle newOrderRespType response type
|
5661
|
+
if ((marketType == 'spot') or (marketType == 'margin')) and not isPortfolioMargin:
|
5662
|
+
request['newOrderRespType'] = self.safe_string(self.options['newOrderRespType'], type, 'FULL') # 'ACK' for order id, 'RESULT' for full order or 'FULL' for order with fills
|
5663
|
+
else:
|
5664
|
+
# swap, futures and options
|
5665
|
+
request['newOrderRespType'] = 'RESULT' # "ACK", "RESULT", default "ACK"
|
5666
5666
|
typeRequest = 'strategyType' if isPortfolioMarginConditional else 'type'
|
5667
5667
|
request[typeRequest] = uppercaseType
|
5668
5668
|
# additional required fields depending on the order type
|
@@ -6216,7 +6216,7 @@ class binance(Exchange, ImplicitAPI):
|
|
6216
6216
|
response = self.papiGetCmOpenOrders(self.extend(request, params))
|
6217
6217
|
else:
|
6218
6218
|
response = self.dapiPrivateGetOpenOrders(self.extend(request, params))
|
6219
|
-
elif type == 'margin' or marginMode is not None:
|
6219
|
+
elif type == 'margin' or marginMode is not None or isPortfolioMargin:
|
6220
6220
|
if isPortfolioMargin:
|
6221
6221
|
response = self.papiGetMarginOpenOrders(self.extend(request, params))
|
6222
6222
|
else:
|
@@ -6645,7 +6645,7 @@ class binance(Exchange, ImplicitAPI):
|
|
6645
6645
|
response = self.papiDeleteCmAllOpenOrders(self.extend(request, params))
|
6646
6646
|
else:
|
6647
6647
|
response = self.dapiPrivateDeleteAllOpenOrders(self.extend(request, params))
|
6648
|
-
elif (type == 'margin') or (marginMode is not None):
|
6648
|
+
elif (type == 'margin') or (marginMode is not None) or isPortfolioMargin:
|
6649
6649
|
if isPortfolioMargin:
|
6650
6650
|
response = self.papiDeleteMarginAllOpenOrders(self.extend(request, params))
|
6651
6651
|
else:
|