ccxt 4.2.93__py2.py3-none-any.whl → 4.2.94__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/base/exchange.py CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # -----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.2.93'
7
+ __version__ = '4.2.94'
8
8
 
9
9
  # -----------------------------------------------------------------------------
10
10
 
@@ -3225,6 +3225,14 @@ class Exchange(object):
3225
3225
  result.append(self.market_id(symbols[i]))
3226
3226
  return result
3227
3227
 
3228
+ def markets_for_symbols(self, symbols: Strings = None):
3229
+ if symbols is None:
3230
+ return symbols
3231
+ result = []
3232
+ for i in range(0, len(symbols)):
3233
+ result.append(self.market(symbols[i]))
3234
+ return result
3235
+
3228
3236
  def market_symbols(self, symbols: Strings = None, type: Str = None, allowEmpty=True, sameTypeOnly=False, sameSubTypeOnly=False):
3229
3237
  if symbols is None:
3230
3238
  if not allowEmpty:
@@ -4369,6 +4377,9 @@ class Exchange(object):
4369
4377
  def fetch_option(self, symbol: str, params={}):
4370
4378
  raise NotSupported(self.id + ' fetchOption() is not supported yet')
4371
4379
 
4380
+ def fetch_convert_quote(self, fromCode: str, toCode: str, amount: Num = None, params={}):
4381
+ raise NotSupported(self.id + ' fetchConvertQuote() is not supported yet')
4382
+
4372
4383
  def fetch_deposits_withdrawals(self, code: Str = None, since: Int = None, limit: Int = None, params={}):
4373
4384
  """
4374
4385
  fetch history of deposits and withdrawals
@@ -4842,6 +4853,9 @@ class Exchange(object):
4842
4853
  fees = self.fetch_trading_fees(params)
4843
4854
  return self.safe_dict(fees, symbol)
4844
4855
 
4856
+ def fetch_convert_currencies(self, params={}):
4857
+ raise NotSupported(self.id + ' fetchConvertCurrencies() is not supported yet')
4858
+
4845
4859
  def parse_open_interest(self, interest, market: Market = None):
4846
4860
  raise NotSupported(self.id + ' parseOpenInterest() is not supported yet')
4847
4861
 
@@ -5425,6 +5439,9 @@ class Exchange(object):
5425
5439
  def parse_leverage(self, leverage, market: Market = None):
5426
5440
  raise NotSupported(self.id + ' parseLeverage() is not supported yet')
5427
5441
 
5442
+ def parse_conversion(self, conversion, fromCurrency: Currency = None, toCurrency: Currency = None):
5443
+ raise NotSupported(self.id + ' parseConversion() is not supported yet')
5444
+
5428
5445
  def convert_expire_date(self, date: str):
5429
5446
  # parse YYMMDD to datetime string
5430
5447
  year = date[0:2]
ccxt/base/types.py CHANGED
@@ -311,6 +311,19 @@ class Greeks(TypedDict):
311
311
  info: Dict[str, Any]
312
312
 
313
313
 
314
+ class Conversion(TypedDict):
315
+ info: Dict[str, Any]
316
+ timestamp: Int
317
+ datetime: Str
318
+ id: Str
319
+ fromCurrency: Str
320
+ fromAmount: Num
321
+ toCurrency: Str
322
+ toAmount: Num
323
+ price: Num
324
+ fee: Num
325
+
326
+
314
327
  class Option(TypedDict):
315
328
  info: Dict[str, Any]
316
329
  currency: Str
ccxt/binance.py CHANGED
@@ -93,6 +93,8 @@ class binance(Exchange, ImplicitAPI):
93
93
  'fetchCanceledOrders': 'emulated',
94
94
  'fetchClosedOrder': False,
95
95
  'fetchClosedOrders': 'emulated',
96
+ 'fetchConvertCurrencies': True,
97
+ 'fetchConvertQuote': False,
96
98
  'fetchCrossBorrowRate': True,
97
99
  'fetchCrossBorrowRates': False,
98
100
  'fetchCurrencies': True,
@@ -992,6 +994,7 @@ class binance(Exchange, ImplicitAPI):
992
994
  },
993
995
  'post': {
994
996
  'order/oco': 0.2,
997
+ 'orderList/oco': 0.2,
995
998
  'sor/order': 0.2,
996
999
  'sor/order/test': 0.2,
997
1000
  'order': 0.2,
@@ -4108,10 +4111,13 @@ class binance(Exchange, ImplicitAPI):
4108
4111
  'interval': self.safe_string(self.timeframes, timeframe, timeframe),
4109
4112
  'limit': limit,
4110
4113
  }
4114
+ marketId = market['id']
4111
4115
  if price == 'index':
4112
- request['pair'] = market['id'] # Index price takes self argument instead of symbol
4116
+ parts = marketId.split('_')
4117
+ pair = self.safe_string(parts, 0)
4118
+ request['pair'] = pair # Index price takes self argument instead of symbol
4113
4119
  else:
4114
- request['symbol'] = market['id']
4120
+ request['symbol'] = marketId
4115
4121
  # duration = self.parse_timeframe(timeframe)
4116
4122
  if since is not None:
4117
4123
  request['startTime'] = since
@@ -11577,3 +11583,55 @@ class binance(Exchange, ImplicitAPI):
11577
11583
  #
11578
11584
  modifications = self.parse_margin_modifications(response)
11579
11585
  return self.filter_by_symbol_since_limit(modifications, symbol, since, limit)
11586
+
11587
+ def fetch_convert_currencies(self, params={}) -> Currencies:
11588
+ """
11589
+ fetches all available currencies that can be converted
11590
+ :see: https://binance-docs.github.io/apidocs/spot/en/#query-order-quantity-precision-per-asset-user_data
11591
+ :param dict [params]: extra parameters specific to the exchange API endpoint
11592
+ :returns dict: an associative dictionary of currencies
11593
+ """
11594
+ self.load_markets()
11595
+ response = self.sapiGetConvertAssetInfo(params)
11596
+ #
11597
+ # [
11598
+ # {
11599
+ # "asset": "BTC",
11600
+ # "fraction": 8
11601
+ # },
11602
+ # ]
11603
+ #
11604
+ result = {}
11605
+ for i in range(0, len(response)):
11606
+ entry = response[i]
11607
+ id = self.safe_string(entry, 'asset')
11608
+ code = self.safe_currency_code(id)
11609
+ result[code] = {
11610
+ 'info': entry,
11611
+ 'id': id,
11612
+ 'code': code,
11613
+ 'networks': None,
11614
+ 'type': None,
11615
+ 'name': None,
11616
+ 'active': None,
11617
+ 'deposit': None,
11618
+ 'withdraw': None,
11619
+ 'fee': None,
11620
+ 'precision': self.safe_integer(entry, 'fraction'),
11621
+ 'limits': {
11622
+ 'amount': {
11623
+ 'min': None,
11624
+ 'max': None,
11625
+ },
11626
+ 'withdraw': {
11627
+ 'min': None,
11628
+ 'max': None,
11629
+ },
11630
+ 'deposit': {
11631
+ 'min': None,
11632
+ 'max': None,
11633
+ },
11634
+ },
11635
+ 'created': None,
11636
+ }
11637
+ return result
ccxt/bitget.py CHANGED
@@ -7,7 +7,7 @@ from ccxt.base.exchange import Exchange
7
7
  from ccxt.abstract.bitget import ImplicitAPI
8
8
  import hashlib
9
9
  import json
10
- from ccxt.base.types import Balances, Currencies, Currency, FundingHistory, Int, Liquidation, Leverage, MarginMode, MarginModification, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, TradingFees, Transaction, TransferEntry
10
+ from ccxt.base.types import Balances, Conversion, Currencies, Currency, FundingHistory, Int, Liquidation, Leverage, MarginMode, MarginModification, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, TradingFees, Transaction, TransferEntry
11
11
  from typing import List
12
12
  from ccxt.base.errors import ExchangeError
13
13
  from ccxt.base.errors import PermissionDenied
@@ -84,6 +84,8 @@ class bitget(Exchange, ImplicitAPI):
84
84
  'fetchCanceledAndClosedOrders': True,
85
85
  'fetchCanceledOrders': True,
86
86
  'fetchClosedOrders': True,
87
+ 'fetchConvertCurrencies': True,
88
+ 'fetchConvertQuote': True,
87
89
  'fetchCrossBorrowRate': True,
88
90
  'fetchCrossBorrowRates': False,
89
91
  'fetchCurrencies': True,
@@ -7852,6 +7854,138 @@ class bitget(Exchange, ImplicitAPI):
7852
7854
  'marginMode': marginType,
7853
7855
  }
7854
7856
 
7857
+ def fetch_convert_quote(self, fromCode: str, toCode: str, amount: Num = None, params={}) -> Conversion:
7858
+ """
7859
+ fetch a quote for converting from one currency to another
7860
+ :see: https://www.bitget.com/api-doc/common/convert/Get-Quoted-Price
7861
+ :param str fromCode: the currency that you want to sell and convert from
7862
+ :param str toCode: the currency that you want to buy and convert into
7863
+ :param float [amount]: how much you want to trade in units of the from currency
7864
+ :param dict [params]: extra parameters specific to the exchange API endpoint
7865
+ :returns dict: a `conversion structure <https://docs.ccxt.com/#/?id=conversion-structure>`
7866
+ """
7867
+ self.load_markets()
7868
+ request = {
7869
+ 'fromCoin': fromCode.upper(),
7870
+ 'toCoin': toCode.upper(),
7871
+ 'fromCoinSize': self.number_to_string(amount),
7872
+ }
7873
+ response = self.privateConvertGetV2ConvertQuotedPrice(self.extend(request, params))
7874
+ #
7875
+ # {
7876
+ # "code": "00000",
7877
+ # "msg": "success",
7878
+ # "requestTime": 1712121940158,
7879
+ # "data": {
7880
+ # "fromCoin": "USDT",
7881
+ # "fromCoinSize": "5",
7882
+ # "cnvtPrice": "0.9993007892377704",
7883
+ # "toCoin": "USDC",
7884
+ # "toCoinSize": "4.99650394",
7885
+ # "traceId": "1159288930228187140",
7886
+ # "fee": "0"
7887
+ # }
7888
+ # }
7889
+ #
7890
+ data = self.safe_dict(response, 'data', {})
7891
+ fromCurrencyId = self.safe_string(data, 'fromCoin', fromCode)
7892
+ fromCurrency = self.currency(fromCurrencyId)
7893
+ toCurrencyId = self.safe_string(data, 'toCoin', toCode)
7894
+ toCurrency = self.currency(toCurrencyId)
7895
+ return self.parse_conversion(data, fromCurrency, toCurrency)
7896
+
7897
+ def parse_conversion(self, conversion, fromCurrency: Currency = None, toCurrency: Currency = None) -> Conversion:
7898
+ #
7899
+ # fetchConvertQuote
7900
+ #
7901
+ # {
7902
+ # "fromCoin": "USDT",
7903
+ # "fromCoinSize": "5",
7904
+ # "cnvtPrice": "0.9993007892377704",
7905
+ # "toCoin": "USDC",
7906
+ # "toCoinSize": "4.99650394",
7907
+ # "traceId": "1159288930228187140",
7908
+ # "fee": "0"
7909
+ # }
7910
+ #
7911
+ timestamp = self.safe_integer(conversion, 'ts')
7912
+ fromCoin = self.safe_string(conversion, 'fromCoin')
7913
+ fromCode = self.safe_currency_code(fromCoin, fromCurrency)
7914
+ to = self.safe_string(conversion, 'toCoin')
7915
+ toCode = self.safe_currency_code(to, toCurrency)
7916
+ return {
7917
+ 'info': conversion,
7918
+ 'timestamp': timestamp,
7919
+ 'datetime': self.iso8601(timestamp),
7920
+ 'id': self.safe_string(conversion, 'traceId'),
7921
+ 'fromCurrency': fromCode,
7922
+ 'fromAmount': self.safe_number(conversion, 'fromCoinSize'),
7923
+ 'toCurrency': toCode,
7924
+ 'toAmount': self.safe_number(conversion, 'toCoinSize'),
7925
+ 'price': self.safe_number(conversion, 'cnvtPrice'),
7926
+ 'fee': self.safe_number(conversion, 'fee'),
7927
+ }
7928
+
7929
+ def fetch_convert_currencies(self, params={}) -> Currencies:
7930
+ """
7931
+ fetches all available currencies that can be converted
7932
+ :see: https://www.bitget.com/api-doc/common/convert/Get-Convert-Currencies
7933
+ :param dict [params]: extra parameters specific to the exchange API endpoint
7934
+ :returns dict: an associative dictionary of currencies
7935
+ """
7936
+ self.load_markets()
7937
+ response = self.privateConvertGetV2ConvertCurrencies(params)
7938
+ #
7939
+ # {
7940
+ # "code": "00000",
7941
+ # "msg": "success",
7942
+ # "requestTime": 1712121755897,
7943
+ # "data": [
7944
+ # {
7945
+ # "coin": "BTC",
7946
+ # "available": "0.00009850",
7947
+ # "maxAmount": "0.756266",
7948
+ # "minAmount": "0.00001"
7949
+ # },
7950
+ # ]
7951
+ # }
7952
+ #
7953
+ result = {}
7954
+ data = self.safe_list(response, 'data', [])
7955
+ for i in range(0, len(data)):
7956
+ entry = data[i]
7957
+ id = self.safe_string(entry, 'coin')
7958
+ code = self.safe_currency_code(id)
7959
+ result[code] = {
7960
+ 'info': entry,
7961
+ 'id': id,
7962
+ 'code': code,
7963
+ 'networks': None,
7964
+ 'type': None,
7965
+ 'name': None,
7966
+ 'active': None,
7967
+ 'deposit': None,
7968
+ 'withdraw': self.safe_number(entry, 'available'),
7969
+ 'fee': None,
7970
+ 'precision': None,
7971
+ 'limits': {
7972
+ 'amount': {
7973
+ 'min': self.safe_number(entry, 'minAmount'),
7974
+ 'max': self.safe_number(entry, 'maxAmount'),
7975
+ },
7976
+ 'withdraw': {
7977
+ 'min': None,
7978
+ 'max': None,
7979
+ },
7980
+ 'deposit': {
7981
+ 'min': None,
7982
+ 'max': None,
7983
+ },
7984
+ },
7985
+ 'created': None,
7986
+ }
7987
+ return result
7988
+
7855
7989
  def handle_errors(self, code, reason, url, method, headers, body, response, requestHeaders, requestBody):
7856
7990
  if not response:
7857
7991
  return None # fallback to default error handler
ccxt/okx.py CHANGED
@@ -6,7 +6,7 @@
6
6
  from ccxt.base.exchange import Exchange
7
7
  from ccxt.abstract.okx import ImplicitAPI
8
8
  import hashlib
9
- from ccxt.base.types import Account, Balances, Currencies, Currency, Greeks, Int, Leverage, MarginModification, Market, MarketInterface, Num, Option, OptionChain, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, Transaction, TransferEntry
9
+ 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
10
10
  from typing import List
11
11
  from ccxt.base.errors import ExchangeError
12
12
  from ccxt.base.errors import PermissionDenied
@@ -82,6 +82,8 @@ class okx(Exchange, ImplicitAPI):
82
82
  'fetchCanceledOrders': True,
83
83
  'fetchClosedOrder': None,
84
84
  'fetchClosedOrders': True,
85
+ 'fetchConvertCurrencies': True,
86
+ 'fetchConvertQuote': True,
85
87
  'fetchCrossBorrowRate': True,
86
88
  'fetchCrossBorrowRates': True,
87
89
  'fetchCurrencies': True,
@@ -7097,6 +7099,152 @@ class okx(Exchange, ImplicitAPI):
7097
7099
  'quoteVolume': None,
7098
7100
  }
7099
7101
 
7102
+ def fetch_convert_quote(self, fromCode: str, toCode: str, amount: Num = None, params={}) -> Conversion:
7103
+ """
7104
+ fetch a quote for converting from one currency to another
7105
+ :see: https://www.okx.com/docs-v5/en/#funding-account-rest-api-estimate-quote
7106
+ :param str fromCode: the currency that you want to sell and convert from
7107
+ :param str toCode: the currency that you want to buy and convert into
7108
+ :param float [amount]: how much you want to trade in units of the from currency
7109
+ :param dict [params]: extra parameters specific to the exchange API endpoint
7110
+ :returns dict: a `conversion structure <https://docs.ccxt.com/#/?id=conversion-structure>`
7111
+ """
7112
+ self.load_markets()
7113
+ request = {
7114
+ 'baseCcy': fromCode.upper(),
7115
+ 'quoteCcy': toCode.upper(),
7116
+ 'rfqSzCcy': fromCode.upper(),
7117
+ 'rfqSz': self.number_to_string(amount),
7118
+ 'side': 'sell',
7119
+ }
7120
+ response = self.privatePostAssetConvertEstimateQuote(self.extend(request, params))
7121
+ #
7122
+ # {
7123
+ # "code": "0",
7124
+ # "data": [
7125
+ # {
7126
+ # "baseCcy": "ETH",
7127
+ # "baseSz": "0.01023052",
7128
+ # "clQReqId": "",
7129
+ # "cnvtPx": "2932.40104429",
7130
+ # "origRfqSz": "30",
7131
+ # "quoteCcy": "USDT",
7132
+ # "quoteId": "quoterETH-USDT16461885104612381",
7133
+ # "quoteSz": "30",
7134
+ # "quoteTime": "1646188510461",
7135
+ # "rfqSz": "30",
7136
+ # "rfqSzCcy": "USDT",
7137
+ # "side": "buy",
7138
+ # "ttlMs": "10000"
7139
+ # }
7140
+ # ],
7141
+ # "msg": ""
7142
+ # }
7143
+ #
7144
+ data = self.safe_list(response, 'data', [])
7145
+ result = self.safe_dict(data, 0, {})
7146
+ fromCurrencyId = self.safe_string(result, 'baseCcy', fromCode)
7147
+ fromCurrency = self.currency(fromCurrencyId)
7148
+ toCurrencyId = self.safe_string(result, 'quoteCcy', toCode)
7149
+ toCurrency = self.currency(toCurrencyId)
7150
+ return self.parse_conversion(result, fromCurrency, toCurrency)
7151
+
7152
+ def parse_conversion(self, conversion, fromCurrency: Currency = None, toCurrency: Currency = None) -> Conversion:
7153
+ #
7154
+ # fetchConvertQuote
7155
+ #
7156
+ # {
7157
+ # "baseCcy": "ETH",
7158
+ # "baseSz": "0.01023052",
7159
+ # "clQReqId": "",
7160
+ # "cnvtPx": "2932.40104429",
7161
+ # "origRfqSz": "30",
7162
+ # "quoteCcy": "USDT",
7163
+ # "quoteId": "quoterETH-USDT16461885104612381",
7164
+ # "quoteSz": "30",
7165
+ # "quoteTime": "1646188510461",
7166
+ # "rfqSz": "30",
7167
+ # "rfqSzCcy": "USDT",
7168
+ # "side": "buy",
7169
+ # "ttlMs": "10000"
7170
+ # }
7171
+ #
7172
+ timestamp = self.safe_integer(conversion, 'quoteTime')
7173
+ fromCoin = self.safe_string(conversion, 'baseCcy')
7174
+ fromCode = self.safe_currency_code(fromCoin, fromCurrency)
7175
+ to = self.safe_string(conversion, 'quoteCcy')
7176
+ toCode = self.safe_currency_code(to, toCurrency)
7177
+ return {
7178
+ 'info': conversion,
7179
+ 'timestamp': timestamp,
7180
+ 'datetime': self.iso8601(timestamp),
7181
+ 'id': self.safe_string(conversion, 'clQReqId'),
7182
+ 'fromCurrency': fromCode,
7183
+ 'fromAmount': self.safe_number(conversion, 'baseSz'),
7184
+ 'toCurrency': toCode,
7185
+ 'toAmount': self.safe_number(conversion, 'quoteSz'),
7186
+ 'price': self.safe_number(conversion, 'cnvtPx'),
7187
+ 'fee': None,
7188
+ }
7189
+
7190
+ def fetch_convert_currencies(self, params={}) -> Currencies:
7191
+ """
7192
+ fetches all available currencies that can be converted
7193
+ :see: https://www.okx.com/docs-v5/en/#funding-account-rest-api-get-convert-currencies
7194
+ :param dict [params]: extra parameters specific to the exchange API endpoint
7195
+ :returns dict: an associative dictionary of currencies
7196
+ """
7197
+ self.load_markets()
7198
+ response = self.privateGetAssetConvertCurrencies(params)
7199
+ #
7200
+ # {
7201
+ # "code": "0",
7202
+ # "data": [
7203
+ # {
7204
+ # "ccy": "BTC",
7205
+ # "max": "",
7206
+ # "min": ""
7207
+ # },
7208
+ # ],
7209
+ # "msg": ""
7210
+ # }
7211
+ #
7212
+ result = {}
7213
+ data = self.safe_list(response, 'data', [])
7214
+ for i in range(0, len(data)):
7215
+ entry = data[i]
7216
+ id = self.safe_string(entry, 'ccy')
7217
+ code = self.safe_currency_code(id)
7218
+ result[code] = {
7219
+ 'info': entry,
7220
+ 'id': id,
7221
+ 'code': code,
7222
+ 'networks': None,
7223
+ 'type': None,
7224
+ 'name': None,
7225
+ 'active': None,
7226
+ 'deposit': None,
7227
+ 'withdraw': None,
7228
+ 'fee': None,
7229
+ 'precision': None,
7230
+ 'limits': {
7231
+ 'amount': {
7232
+ 'min': self.safe_number(entry, 'min'),
7233
+ 'max': self.safe_number(entry, 'max'),
7234
+ },
7235
+ 'withdraw': {
7236
+ 'min': None,
7237
+ 'max': None,
7238
+ },
7239
+ 'deposit': {
7240
+ 'min': None,
7241
+ 'max': None,
7242
+ },
7243
+ },
7244
+ 'created': None,
7245
+ }
7246
+ return result
7247
+
7100
7248
  def handle_errors(self, httpCode, reason, url, method, headers, body, response, requestHeaders, requestBody):
7101
7249
  if not response:
7102
7250
  return None # fallback to default error handler
ccxt/pro/__init__.py CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # ----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.2.93'
7
+ __version__ = '4.2.94'
8
8
 
9
9
  # ----------------------------------------------------------------------------
10
10