ccxt 4.1.95__py2.py3-none-any.whl → 4.1.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.

Potentially problematic release.


This version of ccxt might be problematic. Click here for more details.

Files changed (163) hide show
  1. ccxt/__init__.py +2 -1
  2. ccxt/abstract/bingx.py +2 -0
  3. ccxt/abstract/kucoin.py +12 -0
  4. ccxt/abstract/kucoinfutures.py +12 -1
  5. ccxt/ace.py +1 -1
  6. ccxt/ascendex.py +1 -1
  7. ccxt/async_support/__init__.py +2 -1
  8. ccxt/async_support/ace.py +1 -1
  9. ccxt/async_support/ascendex.py +1 -1
  10. ccxt/async_support/base/exchange.py +29 -23
  11. ccxt/async_support/bigone.py +2 -2
  12. ccxt/async_support/binance.py +116 -114
  13. ccxt/async_support/bingx.py +46 -7
  14. ccxt/async_support/bit2c.py +2 -3
  15. ccxt/async_support/bitfinex.py +1 -1
  16. ccxt/async_support/bitfinex2.py +3 -4
  17. ccxt/async_support/bitflyer.py +2 -2
  18. ccxt/async_support/bitmart.py +2 -2
  19. ccxt/async_support/bitmex.py +2 -2
  20. ccxt/async_support/bitopro.py +1 -1
  21. ccxt/async_support/bitpanda.py +1 -1
  22. ccxt/async_support/bitvavo.py +1 -1
  23. ccxt/async_support/blockchaincom.py +1 -1
  24. ccxt/async_support/btcalpha.py +2 -2
  25. ccxt/async_support/btcbox.py +3 -4
  26. ccxt/async_support/btcmarkets.py +2 -2
  27. ccxt/async_support/btcturk.py +1 -1
  28. ccxt/async_support/bybit.py +2 -2
  29. ccxt/async_support/cex.py +1 -1
  30. ccxt/async_support/coinbase.py +11 -5
  31. ccxt/async_support/coinbasepro.py +2 -2
  32. ccxt/async_support/coinex.py +1 -1
  33. ccxt/async_support/coinlist.py +1 -1
  34. ccxt/async_support/cryptocom.py +2 -1
  35. ccxt/async_support/delta.py +24 -1
  36. ccxt/async_support/deribit.py +1 -1
  37. ccxt/async_support/digifinex.py +1 -1
  38. ccxt/async_support/gate.py +2 -2
  39. ccxt/async_support/hitbtc.py +1 -1
  40. ccxt/async_support/hollaex.py +2 -2
  41. ccxt/async_support/htx.py +1 -1
  42. ccxt/async_support/huobijp.py +2 -2
  43. ccxt/async_support/idex.py +1 -1
  44. ccxt/async_support/independentreserve.py +1 -1
  45. ccxt/async_support/kraken.py +45 -41
  46. ccxt/async_support/krakenfutures.py +46 -23
  47. ccxt/async_support/kucoin.py +68 -5
  48. ccxt/async_support/kucoinfutures.py +2 -2
  49. ccxt/async_support/kuna.py +1 -1
  50. ccxt/async_support/latoken.py +1 -1
  51. ccxt/async_support/luno.py +2 -2
  52. ccxt/async_support/lykke.py +1 -1
  53. ccxt/async_support/mexc.py +2 -2
  54. ccxt/async_support/ndax.py +1 -1
  55. ccxt/async_support/novadax.py +2 -2
  56. ccxt/async_support/oceanex.py +1 -1
  57. ccxt/async_support/okcoin.py +1 -1
  58. ccxt/async_support/okx.py +1 -1
  59. ccxt/async_support/poloniexfutures.py +1 -1
  60. ccxt/async_support/probit.py +1 -1
  61. ccxt/async_support/timex.py +1 -1
  62. ccxt/async_support/tokocrypto.py +1 -1
  63. ccxt/async_support/upbit.py +1 -1
  64. ccxt/async_support/wavesexchange.py +1 -1
  65. ccxt/async_support/whitebit.py +1 -1
  66. ccxt/async_support/woo.py +1 -1
  67. ccxt/async_support/zaif.py +1 -1
  68. ccxt/base/errors.py +6 -0
  69. ccxt/base/exchange.py +10 -7
  70. ccxt/bigone.py +2 -2
  71. ccxt/binance.py +116 -114
  72. ccxt/bingx.py +46 -7
  73. ccxt/bit2c.py +2 -3
  74. ccxt/bitfinex.py +1 -1
  75. ccxt/bitfinex2.py +3 -4
  76. ccxt/bitflyer.py +2 -2
  77. ccxt/bitmart.py +2 -2
  78. ccxt/bitmex.py +2 -2
  79. ccxt/bitopro.py +1 -1
  80. ccxt/bitpanda.py +1 -1
  81. ccxt/bitvavo.py +1 -1
  82. ccxt/blockchaincom.py +1 -1
  83. ccxt/btcalpha.py +2 -2
  84. ccxt/btcbox.py +3 -4
  85. ccxt/btcmarkets.py +2 -2
  86. ccxt/btcturk.py +1 -1
  87. ccxt/bybit.py +2 -2
  88. ccxt/cex.py +1 -1
  89. ccxt/coinbase.py +11 -5
  90. ccxt/coinbasepro.py +2 -2
  91. ccxt/coinex.py +1 -1
  92. ccxt/coinlist.py +1 -1
  93. ccxt/cryptocom.py +2 -1
  94. ccxt/delta.py +24 -1
  95. ccxt/deribit.py +1 -1
  96. ccxt/digifinex.py +1 -1
  97. ccxt/gate.py +2 -2
  98. ccxt/hitbtc.py +1 -1
  99. ccxt/hollaex.py +2 -2
  100. ccxt/htx.py +1 -1
  101. ccxt/huobijp.py +2 -2
  102. ccxt/idex.py +1 -1
  103. ccxt/independentreserve.py +1 -1
  104. ccxt/kraken.py +45 -41
  105. ccxt/krakenfutures.py +46 -23
  106. ccxt/kucoin.py +68 -5
  107. ccxt/kucoinfutures.py +2 -2
  108. ccxt/kuna.py +1 -1
  109. ccxt/latoken.py +1 -1
  110. ccxt/luno.py +2 -2
  111. ccxt/lykke.py +1 -1
  112. ccxt/mexc.py +2 -2
  113. ccxt/ndax.py +1 -1
  114. ccxt/novadax.py +2 -2
  115. ccxt/oceanex.py +1 -1
  116. ccxt/okcoin.py +1 -1
  117. ccxt/okx.py +1 -1
  118. ccxt/poloniexfutures.py +1 -1
  119. ccxt/pro/__init__.py +1 -1
  120. ccxt/pro/alpaca.py +1 -1
  121. ccxt/pro/ascendex.py +1 -1
  122. ccxt/pro/binance.py +5 -6
  123. ccxt/pro/bingx.py +6 -3
  124. ccxt/pro/bitfinex.py +3 -4
  125. ccxt/pro/bitfinex2.py +1 -1
  126. ccxt/pro/bitmex.py +1 -1
  127. ccxt/pro/bitpanda.py +1 -1
  128. ccxt/pro/blockchaincom.py +1 -1
  129. ccxt/pro/bybit.py +2 -2
  130. ccxt/pro/cex.py +1 -1
  131. ccxt/pro/coinbase.py +1 -1
  132. ccxt/pro/coinbasepro.py +1 -1
  133. ccxt/pro/cryptocom.py +1 -1
  134. ccxt/pro/deribit.py +1 -1
  135. ccxt/pro/gate.py +3 -3
  136. ccxt/pro/gemini.py +1 -1
  137. ccxt/pro/hitbtc.py +1 -1
  138. ccxt/pro/hollaex.py +1 -1
  139. ccxt/pro/htx.py +1 -1
  140. ccxt/pro/idex.py +1 -1
  141. ccxt/pro/kraken.py +3 -4
  142. ccxt/pro/krakenfutures.py +1 -1
  143. ccxt/pro/kucoinfutures.py +1 -1
  144. ccxt/pro/mexc.py +1 -1
  145. ccxt/pro/okcoin.py +1 -1
  146. ccxt/pro/okx.py +4 -4
  147. ccxt/pro/phemex.py +1 -1
  148. ccxt/pro/poloniexfutures.py +1 -1
  149. ccxt/pro/woo.py +2 -3
  150. ccxt/probit.py +1 -1
  151. ccxt/test/test_async.py +3 -1
  152. ccxt/test/test_sync.py +3 -1
  153. ccxt/timex.py +1 -1
  154. ccxt/tokocrypto.py +1 -1
  155. ccxt/upbit.py +1 -1
  156. ccxt/wavesexchange.py +1 -1
  157. ccxt/whitebit.py +1 -1
  158. ccxt/woo.py +1 -1
  159. ccxt/zaif.py +1 -1
  160. {ccxt-4.1.95.dist-info → ccxt-4.1.97.dist-info}/METADATA +4 -4
  161. {ccxt-4.1.95.dist-info → ccxt-4.1.97.dist-info}/RECORD +163 -163
  162. {ccxt-4.1.95.dist-info → ccxt-4.1.97.dist-info}/WHEEL +0 -0
  163. {ccxt-4.1.95.dist-info → ccxt-4.1.97.dist-info}/top_level.txt +0 -0
ccxt/base/exchange.py CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # -----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.1.95'
7
+ __version__ = '4.1.97'
8
8
 
9
9
  # -----------------------------------------------------------------------------
10
10
 
@@ -23,6 +23,7 @@ from ccxt.base.errors import NullResponse
23
23
  from ccxt.base.errors import RateLimitExceeded
24
24
  from ccxt.base.errors import BadRequest
25
25
  from ccxt.base.errors import BadResponse
26
+ from ccxt.base.errors import ProxyError
26
27
 
27
28
  # -----------------------------------------------------------------------------
28
29
 
@@ -111,11 +112,12 @@ class Exchange(object):
111
112
  timeout = 10000 # milliseconds = seconds * 1000
112
113
  asyncio_loop = None
113
114
  aiohttp_proxy = None
115
+ ssl_context = None
114
116
  trust_env = False
115
117
  aiohttp_trust_env = False
116
118
  requests_trust_env = False
117
119
  session = None # Session () by default
118
- socks_proxy_session = None
120
+ socks_proxy_sessions = None
119
121
  verify = True # SSL verification
120
122
  validateServerSsl = True
121
123
  validateClientSsl = False
@@ -1767,7 +1769,7 @@ class Exchange(object):
1767
1769
  length = len(usedProxies)
1768
1770
  if length > 1:
1769
1771
  joinedProxyNames = ','.join(usedProxies)
1770
- raise ExchangeError(self.id + ' you have multiple conflicting proxy_url settings(' + joinedProxyNames + '), please use only one from : proxyUrl, proxy_url, proxyUrlCallback, proxy_url_callback')
1772
+ raise ProxyError(self.id + ' you have multiple conflicting proxy settings(' + joinedProxyNames + '), please use only one from : proxyUrl, proxy_url, proxyUrlCallback, proxy_url_callback')
1771
1773
  return proxyUrl
1772
1774
 
1773
1775
  def check_proxy_settings(self, url=None, method=None, headers=None, body=None):
@@ -1818,7 +1820,7 @@ class Exchange(object):
1818
1820
  length = len(usedProxies)
1819
1821
  if length > 1:
1820
1822
  joinedProxyNames = ','.join(usedProxies)
1821
- raise ExchangeError(self.id + ' you have multiple conflicting settings(' + joinedProxyNames + '), please use only one from: httpProxy, httpsProxy, httpProxyCallback, httpsProxyCallback, socksProxy, socksProxyCallback')
1823
+ raise ProxyError(self.id + ' you have multiple conflicting proxy settings(' + joinedProxyNames + '), please use only one from: httpProxy, httpsProxy, httpProxyCallback, httpsProxyCallback, socksProxy, socksProxyCallback')
1822
1824
  return [httpProxy, httpsProxy, socksProxy]
1823
1825
 
1824
1826
  def check_ws_proxy_settings(self):
@@ -1851,12 +1853,12 @@ class Exchange(object):
1851
1853
  length = len(usedProxies)
1852
1854
  if length > 1:
1853
1855
  joinedProxyNames = ','.join(usedProxies)
1854
- raise ExchangeError(self.id + ' you have multiple conflicting settings(' + joinedProxyNames + '), please use only one from: wsProxy, wssProxy, wsSocksProxy')
1856
+ raise ProxyError(self.id + ' you have multiple conflicting proxy settings(' + joinedProxyNames + '), please use only one from: wsProxy, wssProxy, wsSocksProxy')
1855
1857
  return [wsProxy, wssProxy, wsSocksProxy]
1856
1858
 
1857
1859
  def check_conflicting_proxies(self, proxyAgentSet, proxyUrlSet):
1858
1860
  if proxyAgentSet and proxyUrlSet:
1859
- raise ExchangeError(self.id + ' you have multiple conflicting proxy settings, please use only one from : proxyUrl, httpProxy, httpsProxy, socksProxy')
1861
+ raise ProxyError(self.id + ' you have multiple conflicting proxy settings, please use only one from : proxyUrl, httpProxy, httpsProxy, socksProxy')
1860
1862
 
1861
1863
  def find_message_hashes(self, client, element: str):
1862
1864
  result = []
@@ -2136,6 +2138,7 @@ class Exchange(object):
2136
2138
  if fee is not None:
2137
2139
  fee['cost'] = self.safe_number(fee, 'cost')
2138
2140
  timestamp = self.safe_integer(entry, 'timestamp')
2141
+ info = self.safe_value(entry, 'info', {})
2139
2142
  return {
2140
2143
  'id': self.safe_string(entry, 'id'),
2141
2144
  'timestamp': timestamp,
@@ -2151,7 +2154,7 @@ class Exchange(object):
2151
2154
  'after': self.parse_number(after),
2152
2155
  'status': self.safe_string(entry, 'status'),
2153
2156
  'fee': fee,
2154
- 'info': entry,
2157
+ 'info': info,
2155
2158
  }
2156
2159
 
2157
2160
  def safe_currency_structure(self, currency: object):
ccxt/bigone.py CHANGED
@@ -1289,7 +1289,7 @@ class bigone(Exchange, ImplicitAPI):
1289
1289
  fetches information on multiple orders made by the user
1290
1290
  :param str symbol: unified market symbol of the market orders were made in
1291
1291
  :param int [since]: the earliest time in ms to fetch orders for
1292
- :param int [limit]: the maximum number of orde structures to retrieve
1292
+ :param int [limit]: the maximum number of order structures to retrieve
1293
1293
  :param dict [params]: extra parameters specific to the exchange API endpoint
1294
1294
  :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1295
1295
  """
@@ -1414,7 +1414,7 @@ class bigone(Exchange, ImplicitAPI):
1414
1414
  fetches information on multiple closed orders made by the user
1415
1415
  :param str symbol: unified market symbol of the market orders were made in
1416
1416
  :param int [since]: the earliest time in ms to fetch orders for
1417
- :param int [limit]: the maximum number of orde structures to retrieve
1417
+ :param int [limit]: the maximum number of order structures to retrieve
1418
1418
  :param dict [params]: extra parameters specific to the exchange API endpoint
1419
1419
  :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1420
1420
  """
ccxt/binance.py CHANGED
@@ -2503,22 +2503,21 @@ class binance(Exchange, ImplicitAPI):
2503
2503
  type = self.safe_string(params, 'type', defaultType)
2504
2504
  subType = None
2505
2505
  subType, params = self.handle_sub_type_and_params('fetchBalance', None, params)
2506
+ marginMode = None
2507
+ query = None
2506
2508
  marginMode, query = self.handle_margin_mode_and_params('fetchBalance', params)
2507
- method = 'privateGetAccount'
2509
+ query = self.omit(query, 'type')
2510
+ response = None
2508
2511
  request = {}
2509
2512
  if self.is_linear(type, subType):
2510
- options = self.safe_value(self.options, type, {})
2511
- fetchBalanceOptions = self.safe_value(options, 'fetchBalance', {})
2512
- method = self.safe_string(fetchBalanceOptions, 'method', 'fapiPrivateV2GetAccount')
2513
2513
  type = 'linear'
2514
+ response = self.fapiPrivateV2GetAccount(self.extend(request, query))
2514
2515
  elif self.is_inverse(type, subType):
2515
- options = self.safe_value(self.options, type, {})
2516
- fetchBalanceOptions = self.safe_value(options, 'fetchBalance', {})
2517
- method = self.safe_string(fetchBalanceOptions, 'method', 'dapiPrivateGetAccount')
2518
2516
  type = 'inverse'
2517
+ response = self.dapiPrivateGetAccount(self.extend(request, query))
2519
2518
  elif marginMode == 'isolated':
2520
- method = 'sapiGetMarginIsolatedAccount'
2521
2519
  paramSymbols = self.safe_value(params, 'symbols')
2520
+ query = self.omit(query, 'symbols')
2522
2521
  if paramSymbols is not None:
2523
2522
  symbols = ''
2524
2523
  if isinstance(paramSymbols, list):
@@ -2530,14 +2529,15 @@ class binance(Exchange, ImplicitAPI):
2530
2529
  else:
2531
2530
  symbols = paramSymbols
2532
2531
  request['symbols'] = symbols
2532
+ response = self.sapiGetMarginIsolatedAccount(self.extend(request, query))
2533
2533
  elif (type == 'margin') or (marginMode == 'cross'):
2534
- method = 'sapiGetMarginAccount'
2534
+ response = self.sapiGetMarginAccount(self.extend(request, query))
2535
2535
  elif type == 'savings':
2536
- method = 'sapiGetLendingUnionAccount'
2536
+ response = self.sapiGetLendingUnionAccount(self.extend(request, query))
2537
2537
  elif type == 'funding':
2538
- method = 'sapiPostAssetGetFundingAsset'
2539
- requestParams = self.omit(query, ['type', 'symbols'])
2540
- response = getattr(self, method)(self.extend(request, requestParams))
2538
+ response = self.sapiPostAssetGetFundingAsset(self.extend(request, query))
2539
+ else:
2540
+ response = self.privateGetAccount(self.extend(request, query))
2541
2541
  #
2542
2542
  # spot
2543
2543
  #
@@ -3184,24 +3184,25 @@ class binance(Exchange, ImplicitAPI):
3184
3184
  request['endTime'] = min(now, endTime)
3185
3185
  if until is not None:
3186
3186
  request['endTime'] = until
3187
- method = 'publicGetKlines'
3187
+ response = None
3188
3188
  if market['option']:
3189
- method = 'eapiPublicGetKlines'
3189
+ response = self.eapiPublicGetKlines(self.extend(request, params))
3190
3190
  elif price == 'mark':
3191
3191
  if market['inverse']:
3192
- method = 'dapiPublicGetMarkPriceKlines'
3192
+ response = self.dapiPublicGetMarkPriceKlines(self.extend(request, params))
3193
3193
  else:
3194
- method = 'fapiPublicGetMarkPriceKlines'
3194
+ response = self.fapiPublicGetMarkPriceKlines(self.extend(request, params))
3195
3195
  elif price == 'index':
3196
3196
  if market['inverse']:
3197
- method = 'dapiPublicGetIndexPriceKlines'
3197
+ response = self.dapiPublicGetIndexPriceKlines(self.extend(request, params))
3198
3198
  else:
3199
- method = 'fapiPublicGetIndexPriceKlines'
3199
+ response = self.fapiPublicGetIndexPriceKlines(self.extend(request, params))
3200
3200
  elif market['linear']:
3201
- method = 'fapiPublicGetKlines'
3201
+ response = self.fapiPublicGetKlines(self.extend(request, params))
3202
3202
  elif market['inverse']:
3203
- method = 'dapiPublicGetKlines'
3204
- response = getattr(self, method)(self.extend(request, params))
3203
+ response = self.dapiPublicGetKlines(self.extend(request, params))
3204
+ else:
3205
+ response = self.publicGetKlines(self.extend(request, params))
3205
3206
  #
3206
3207
  # [
3207
3208
  # [1591478520000,"0.02501300","0.02501800","0.02500000","0.02500000","22.19000000",1591478579999,"0.55490906",40,"10.92900000","0.27336462","0"],
@@ -4457,17 +4458,6 @@ class binance(Exchange, ImplicitAPI):
4457
4458
  request = {
4458
4459
  'symbol': market['id'],
4459
4460
  }
4460
- method = 'privateGetOrder'
4461
- if market['option']:
4462
- method = 'eapiPrivateGetOrder'
4463
- elif market['linear']:
4464
- method = 'fapiPrivateGetOrder'
4465
- elif market['inverse']:
4466
- method = 'dapiPrivateGetOrder'
4467
- elif type == 'margin' or marginMode is not None:
4468
- method = 'sapiGetMarginOrder'
4469
- if marginMode == 'isolated':
4470
- request['isIsolated'] = True
4471
4461
  clientOrderId = self.safe_value_2(params, 'origClientOrderId', 'clientOrderId')
4472
4462
  if clientOrderId is not None:
4473
4463
  if market['option']:
@@ -4477,7 +4467,19 @@ class binance(Exchange, ImplicitAPI):
4477
4467
  else:
4478
4468
  request['orderId'] = id
4479
4469
  requestParams = self.omit(query, ['type', 'clientOrderId', 'origClientOrderId'])
4480
- response = getattr(self, method)(self.extend(request, requestParams))
4470
+ response = None
4471
+ if market['option']:
4472
+ response = self.eapiPrivateGetOrder(self.extend(request, requestParams))
4473
+ elif market['linear']:
4474
+ response = self.fapiPrivateGetOrder(self.extend(request, requestParams))
4475
+ elif market['inverse']:
4476
+ response = self.dapiPrivateGetOrder(self.extend(request, requestParams))
4477
+ elif type == 'margin' or marginMode is not None:
4478
+ if marginMode == 'isolated':
4479
+ request['isIsolated'] = True
4480
+ response = self.sapiGetMarginOrder(self.extend(request, requestParams))
4481
+ else:
4482
+ response = self.privateGetOrder(self.extend(request, requestParams))
4481
4483
  return self.parse_order(response, market)
4482
4484
 
4483
4485
  def fetch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
@@ -4511,17 +4513,6 @@ class binance(Exchange, ImplicitAPI):
4511
4513
  request = {
4512
4514
  'symbol': market['id'],
4513
4515
  }
4514
- method = 'privateGetAllOrders'
4515
- if market['option']:
4516
- method = 'eapiPrivateGetHistoryOrders'
4517
- elif market['linear']:
4518
- method = 'fapiPrivateGetAllOrders'
4519
- elif market['inverse']:
4520
- method = 'dapiPrivateGetAllOrders'
4521
- elif type == 'margin' or marginMode is not None:
4522
- method = 'sapiGetMarginAllOrders'
4523
- if marginMode == 'isolated':
4524
- request['isIsolated'] = True
4525
4516
  until = self.safe_integer(params, 'until')
4526
4517
  if until is not None:
4527
4518
  params = self.omit(params, 'until')
@@ -4530,7 +4521,19 @@ class binance(Exchange, ImplicitAPI):
4530
4521
  request['startTime'] = since
4531
4522
  if limit is not None:
4532
4523
  request['limit'] = limit
4533
- response = getattr(self, method)(self.extend(request, query))
4524
+ response = None
4525
+ if market['option']:
4526
+ response = self.eapiPrivateGetHistoryOrders(self.extend(request, query))
4527
+ elif market['linear']:
4528
+ response = self.fapiPrivateGetAllOrders(self.extend(request, query))
4529
+ elif market['inverse']:
4530
+ response = self.dapiPrivateGetAllOrders(self.extend(request, query))
4531
+ elif type == 'margin' or marginMode is not None:
4532
+ if marginMode == 'isolated':
4533
+ request['isIsolated'] = True
4534
+ response = self.sapiGetMarginAllOrders(self.extend(request, query))
4535
+ else:
4536
+ response = self.privateGetAllOrders(self.extend(request, query))
4534
4537
  #
4535
4538
  # spot
4536
4539
  #
@@ -4650,24 +4653,25 @@ class binance(Exchange, ImplicitAPI):
4650
4653
  subType = None
4651
4654
  subType, query = self.handle_sub_type_and_params('fetchOpenOrders', market, query)
4652
4655
  requestParams = self.omit(query, 'type')
4653
- method = 'privateGetOpenOrders'
4656
+ response = None
4654
4657
  if type == 'option':
4655
- method = 'eapiPrivateGetOpenOrders'
4656
4658
  if since is not None:
4657
4659
  request['startTime'] = since
4658
4660
  if limit is not None:
4659
4661
  request['limit'] = limit
4662
+ response = self.eapiPrivateGetOpenOrders(self.extend(request, requestParams))
4660
4663
  elif self.is_linear(type, subType):
4661
- method = 'fapiPrivateGetOpenOrders'
4664
+ response = self.fapiPrivateGetOpenOrders(self.extend(request, requestParams))
4662
4665
  elif self.is_inverse(type, subType):
4663
- method = 'dapiPrivateGetOpenOrders'
4666
+ response = self.dapiPrivateGetOpenOrders(self.extend(request, requestParams))
4664
4667
  elif type == 'margin' or marginMode is not None:
4665
- method = 'sapiGetMarginOpenOrders'
4666
4668
  if marginMode == 'isolated':
4667
4669
  request['isIsolated'] = True
4668
4670
  if symbol is None:
4669
4671
  raise ArgumentsRequired(self.id + ' fetchOpenOrders() requires a symbol argument for isolated markets')
4670
- response = getattr(self, method)(self.extend(request, requestParams))
4672
+ response = self.sapiGetMarginOpenOrders(self.extend(request, requestParams))
4673
+ else:
4674
+ response = self.privateGetOpenOrders(self.extend(request, requestParams))
4671
4675
  return self.parse_orders(response, market, since, limit)
4672
4676
 
4673
4677
  def fetch_closed_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
@@ -4745,19 +4749,20 @@ class binance(Exchange, ImplicitAPI):
4745
4749
  request['origClientOrderId'] = clientOrderId
4746
4750
  else:
4747
4751
  request['orderId'] = id
4748
- method = 'privateDeleteOrder'
4752
+ requestParams = self.omit(query, ['type', 'origClientOrderId', 'clientOrderId'])
4753
+ response = None
4749
4754
  if market['option']:
4750
- method = 'eapiPrivateDeleteOrder'
4755
+ response = self.eapiPrivateDeleteOrder(self.extend(request, requestParams))
4751
4756
  elif market['linear']:
4752
- method = 'fapiPrivateDeleteOrder'
4757
+ response = self.fapiPrivateDeleteOrder(self.extend(request, requestParams))
4753
4758
  elif market['inverse']:
4754
- method = 'dapiPrivateDeleteOrder'
4759
+ response = self.dapiPrivateDeleteOrder(self.extend(request, requestParams))
4755
4760
  elif type == 'margin' or marginMode is not None:
4756
- method = 'sapiDeleteMarginOrder'
4757
4761
  if marginMode == 'isolated':
4758
4762
  request['isIsolated'] = True
4759
- requestParams = self.omit(query, ['type', 'origClientOrderId', 'clientOrderId'])
4760
- response = getattr(self, method)(self.extend(request, requestParams))
4763
+ response = self.sapiDeleteMarginOrder(self.extend(request, requestParams))
4764
+ else:
4765
+ response = self.privateDeleteOrder(self.extend(request, requestParams))
4761
4766
  return self.parse_order(response, market)
4762
4767
 
4763
4768
  def cancel_all_orders(self, symbol: Str = None, params={}):
@@ -4783,18 +4788,19 @@ class binance(Exchange, ImplicitAPI):
4783
4788
  type = self.safe_string(params, 'type', market['type'])
4784
4789
  params = self.omit(params, ['type'])
4785
4790
  marginMode, query = self.handle_margin_mode_and_params('cancelAllOrders', params)
4786
- method = 'privateDeleteOpenOrders'
4791
+ response = None
4787
4792
  if market['option']:
4788
- method = 'eapiPrivateDeleteAllOpenOrders'
4793
+ response = self.eapiPrivateDeleteAllOpenOrders(self.extend(request, query))
4789
4794
  elif market['linear']:
4790
- method = 'fapiPrivateDeleteAllOpenOrders'
4795
+ response = self.fapiPrivateDeleteAllOpenOrders(self.extend(request, query))
4791
4796
  elif market['inverse']:
4792
- method = 'dapiPrivateDeleteAllOpenOrders'
4797
+ response = self.dapiPrivateDeleteAllOpenOrders(self.extend(request, query))
4793
4798
  elif (type == 'margin') or (marginMode is not None):
4794
- method = 'sapiDeleteMarginOpenOrders'
4795
4799
  if marginMode == 'isolated':
4796
4800
  request['isIsolated'] = True
4797
- response = getattr(self, method)(self.extend(request, query))
4801
+ response = self.sapiDeleteMarginOpenOrders(self.extend(request, query))
4802
+ else:
4803
+ response = self.privateDeleteOpenOrders(self.extend(request, query))
4798
4804
  if isinstance(response, list):
4799
4805
  return self.parse_orders(response, market)
4800
4806
  else:
@@ -4916,28 +4922,11 @@ class binance(Exchange, ImplicitAPI):
4916
4922
  request = {}
4917
4923
  market = None
4918
4924
  type = None
4919
- method = None
4920
4925
  marginMode = None
4921
4926
  if symbol is not None:
4922
4927
  market = self.market(symbol)
4923
4928
  request['symbol'] = market['id']
4924
4929
  type, params = self.handle_market_type_and_params('fetchMyTrades', market, params)
4925
- if type == 'option':
4926
- method = 'eapiPrivateGetUserTrades'
4927
- else:
4928
- if symbol is None:
4929
- raise ArgumentsRequired(self.id + ' fetchMyTrades() requires a symbol argument')
4930
- marginMode, params = self.handle_margin_mode_and_params('fetchMyTrades', params)
4931
- if type == 'spot' or type == 'margin':
4932
- method = 'privateGetMyTrades'
4933
- if (type == 'margin') or (marginMode is not None):
4934
- method = 'sapiGetMarginMyTrades'
4935
- if marginMode == 'isolated':
4936
- request['isIsolated'] = True
4937
- elif market['linear']:
4938
- method = 'fapiPrivateGetUserTrades'
4939
- elif market['inverse']:
4940
- method = 'dapiPrivateGetUserTrades'
4941
4930
  endTime = self.safe_integer_2(params, 'until', 'endTime')
4942
4931
  if since is not None:
4943
4932
  startTime = since
@@ -4959,7 +4948,24 @@ class binance(Exchange, ImplicitAPI):
4959
4948
  if (type == 'option') or market['contract']:
4960
4949
  limit = min(limit, 1000) # above 1000, returns error
4961
4950
  request['limit'] = limit
4962
- response = getattr(self, method)(self.extend(request, params))
4951
+ response = None
4952
+ if type == 'option':
4953
+ response = self.eapiPrivateGetUserTrades(self.extend(request, params))
4954
+ else:
4955
+ if symbol is None:
4956
+ raise ArgumentsRequired(self.id + ' fetchMyTrades() requires a symbol argument')
4957
+ marginMode, params = self.handle_margin_mode_and_params('fetchMyTrades', params)
4958
+ if type == 'spot' or type == 'margin':
4959
+ if (type == 'margin') or (marginMode is not None):
4960
+ if marginMode == 'isolated':
4961
+ request['isIsolated'] = True
4962
+ response = self.sapiGetMarginMyTrades(self.extend(request, params))
4963
+ else:
4964
+ response = self.privateGetMyTrades(self.extend(request, params))
4965
+ elif market['linear']:
4966
+ response = self.fapiPrivateGetUserTrades(self.extend(request, params))
4967
+ elif market['inverse']:
4968
+ response = self.dapiPrivateGetUserTrades(self.extend(request, params))
4963
4969
  #
4964
4970
  # spot trade
4965
4971
  #
@@ -6189,7 +6195,6 @@ class binance(Exchange, ImplicitAPI):
6189
6195
  :returns dict: a dictionary of `fee structures <https://docs.ccxt.com/#/?id=fee-structure>` indexed by market symbols
6190
6196
  """
6191
6197
  self.load_markets()
6192
- method = None
6193
6198
  type = None
6194
6199
  type, params = self.handle_market_type_and_params('fetchTradingFees', None, params)
6195
6200
  subType = None
@@ -6197,13 +6202,13 @@ class binance(Exchange, ImplicitAPI):
6197
6202
  isSpotOrMargin = (type == 'spot') or (type == 'margin')
6198
6203
  isLinear = self.is_linear(type, subType)
6199
6204
  isInverse = self.is_inverse(type, subType)
6205
+ response = None
6200
6206
  if isSpotOrMargin:
6201
- method = 'sapiGetAssetTradeFee'
6207
+ response = self.sapiGetAssetTradeFee(params)
6202
6208
  elif isLinear:
6203
- method = 'fapiPrivateV2GetAccount'
6209
+ response = self.fapiPrivateV2GetAccount(params)
6204
6210
  elif isInverse:
6205
- method = 'dapiPrivateGetAccount'
6206
- response = getattr(self, method)(params)
6211
+ response = self.dapiPrivateGetAccount(params)
6207
6212
  #
6208
6213
  # sapi / spot
6209
6214
  #
@@ -6388,14 +6393,13 @@ class binance(Exchange, ImplicitAPI):
6388
6393
  request = {
6389
6394
  'symbol': market['id'],
6390
6395
  }
6391
- method = None
6396
+ response = None
6392
6397
  if market['linear']:
6393
- method = 'fapiPublicGetPremiumIndex'
6398
+ response = self.fapiPublicGetPremiumIndex(self.extend(request, params))
6394
6399
  elif market['inverse']:
6395
- method = 'dapiPublicGetPremiumIndex'
6400
+ response = self.dapiPublicGetPremiumIndex(self.extend(request, params))
6396
6401
  else:
6397
6402
  raise NotSupported(self.id + ' fetchFundingRate() supports linear and inverse contracts only')
6398
- response = getattr(self, method)(self.extend(request, params))
6399
6403
  if market['inverse']:
6400
6404
  response = response[0]
6401
6405
  #
@@ -6971,17 +6975,17 @@ class binance(Exchange, ImplicitAPI):
6971
6975
  :returns dict: a dictionary of `leverage tiers structures <https://docs.ccxt.com/#/?id=leverage-tiers-structure>`, indexed by market symbols
6972
6976
  """
6973
6977
  self.load_markets()
6974
- type, query = self.handle_market_type_and_params('fetchLeverageTiers', None, params)
6978
+ type = None
6979
+ type, params = self.handle_market_type_and_params('fetchLeverageTiers', None, params)
6975
6980
  subType = None
6976
- subType, params = self.handle_sub_type_and_params('fetchLeverageTiers', None, query, 'linear')
6977
- method = None
6981
+ subType, params = self.handle_sub_type_and_params('fetchLeverageTiers', None, params, 'linear')
6982
+ response = None
6978
6983
  if self.is_linear(type, subType):
6979
- method = 'fapiPrivateGetLeverageBracket'
6984
+ response = self.fapiPrivateGetLeverageBracket(params)
6980
6985
  elif self.is_inverse(type, subType):
6981
- method = 'dapiPrivateV2GetLeverageBracket'
6986
+ response = self.dapiPrivateV2GetLeverageBracket(params)
6982
6987
  else:
6983
6988
  raise NotSupported(self.id + ' fetchLeverageTiers() supports linear and inverse contracts only')
6984
- response = getattr(self, method)(query)
6985
6989
  #
6986
6990
  # usdm
6987
6991
  #
@@ -7408,18 +7412,18 @@ class binance(Exchange, ImplicitAPI):
7408
7412
  raise BadRequest(self.id + ' leverage should be between 1 and 125')
7409
7413
  self.load_markets()
7410
7414
  market = self.market(symbol)
7411
- method: str
7412
- if market['linear']:
7413
- method = 'fapiPrivatePostLeverage'
7414
- elif market['inverse']:
7415
- method = 'dapiPrivatePostLeverage'
7416
- else:
7417
- raise NotSupported(self.id + ' setLeverage() supports linear and inverse contracts only')
7418
7415
  request = {
7419
7416
  'symbol': market['id'],
7420
7417
  'leverage': leverage,
7421
7418
  }
7422
- return getattr(self, method)(self.extend(request, params))
7419
+ response = None
7420
+ if market['linear']:
7421
+ response = self.fapiPrivatePostLeverage(self.extend(request, params))
7422
+ elif market['inverse']:
7423
+ response = self.dapiPrivatePostLeverage(self.extend(request, params))
7424
+ else:
7425
+ raise NotSupported(self.id + ' setLeverage() supports linear and inverse contracts only')
7426
+ return response
7423
7427
 
7424
7428
  def set_margin_mode(self, marginMode: str, symbol: Str = None, params={}):
7425
7429
  """
@@ -7447,20 +7451,18 @@ class binance(Exchange, ImplicitAPI):
7447
7451
  raise BadRequest(self.id + ' marginMode must be either isolated or cross')
7448
7452
  self.load_markets()
7449
7453
  market = self.market(symbol)
7450
- method = None
7451
- if market['linear']:
7452
- method = 'fapiPrivatePostMarginType'
7453
- elif market['inverse']:
7454
- method = 'dapiPrivatePostMarginType'
7455
- else:
7456
- raise NotSupported(self.id + ' setMarginMode() supports linear and inverse contracts only')
7457
7454
  request = {
7458
7455
  'symbol': market['id'],
7459
7456
  'marginType': marginMode,
7460
7457
  }
7461
7458
  response = None
7462
7459
  try:
7463
- response = getattr(self, method)(self.extend(request, params))
7460
+ if market['linear']:
7461
+ response = self.fapiPrivatePostMarginType(self.extend(request, params))
7462
+ elif market['inverse']:
7463
+ response = self.dapiPrivatePostMarginType(self.extend(request, params))
7464
+ else:
7465
+ raise NotSupported(self.id + ' setMarginMode() supports linear and inverse contracts only')
7464
7466
  except Exception as e:
7465
7467
  # not an error
7466
7468
  # https://github.com/ccxt/ccxt/issues/11268
ccxt/bingx.py CHANGED
@@ -157,6 +157,16 @@ class bingx(Exchange, ImplicitAPI):
157
157
  },
158
158
  },
159
159
  'swap': {
160
+ 'v1': {
161
+ 'private': {
162
+ 'get': {
163
+ 'positionSide/dual': 1,
164
+ },
165
+ 'post': {
166
+ 'positionSide/dual': 1,
167
+ },
168
+ },
169
+ },
160
170
  'v2': {
161
171
  'public': {
162
172
  'get': {
@@ -343,6 +353,7 @@ class bingx(Exchange, ImplicitAPI):
343
353
  '100202': InsufficientFunds,
344
354
  '100204': BadRequest,
345
355
  '100400': BadRequest,
356
+ '100421': BadSymbol, # {"code":100421,"msg":"This pair is currently restricted from API trading","debugMsg":""}
346
357
  '100440': ExchangeError,
347
358
  '100500': ExchangeError,
348
359
  '100503': ExchangeError,
@@ -1260,7 +1271,7 @@ class bingx(Exchange, ImplicitAPI):
1260
1271
  # }
1261
1272
  #
1262
1273
  marketId = self.safe_string(ticker, 'symbol')
1263
- change = self.safe_string(ticker, 'priceChange')
1274
+ # change = self.safe_string(ticker, 'priceChange') # self is not ccxt's change because it does high-low instead of last-open
1264
1275
  lastQty = self.safe_string(ticker, 'lastQty')
1265
1276
  # in spot markets, lastQty is not present
1266
1277
  # it's(bad, but) the only way we can check the tickers origin
@@ -1272,9 +1283,10 @@ class bingx(Exchange, ImplicitAPI):
1272
1283
  close = self.safe_string(ticker, 'lastPrice')
1273
1284
  quoteVolume = self.safe_string(ticker, 'quoteVolume')
1274
1285
  baseVolume = self.safe_string(ticker, 'volume')
1275
- percentage = self.safe_string(ticker, 'priceChangePercent')
1276
- if percentage is not None:
1277
- percentage = percentage.replace('%', '')
1286
+ # percentage = self.safe_string(ticker, 'priceChangePercent')
1287
+ # if percentage is not None:
1288
+ # percentage = percentage.replace('%', '')
1289
+ # } similarly to change, it's not ccxt's percentage because it does priceChange/open, and priceChange is high-low
1278
1290
  ts = self.safe_integer(ticker, 'closeTime')
1279
1291
  datetime = self.iso8601(ts)
1280
1292
  bid = self.safe_string(ticker, 'bidPrice')
@@ -1296,8 +1308,8 @@ class bingx(Exchange, ImplicitAPI):
1296
1308
  'close': close,
1297
1309
  'last': None,
1298
1310
  'previousClose': None,
1299
- 'change': change,
1300
- 'percentage': percentage,
1311
+ 'change': None,
1312
+ 'percentage': None,
1301
1313
  'average': None,
1302
1314
  'baseVolume': baseVolume,
1303
1315
  'quoteVolume': quoteVolume,
@@ -2334,7 +2346,7 @@ class bingx(Exchange, ImplicitAPI):
2334
2346
  :see: https://bingx-api.github.io/docs/#/standard/contract-interface.html#Historical%20order
2335
2347
  :param str [symbol]: unified market symbol of the market orders were made in
2336
2348
  :param int [since]: the earliest time in ms to fetch orders for
2337
- :param int [limit]: the maximum number of orde structures to retrieve
2349
+ :param int [limit]: the maximum number of order structures to retrieve
2338
2350
  :param dict [params]: extra parameters specific to the exchange API endpoint
2339
2351
  :param int [params.until]: the latest time in ms to fetch orders for
2340
2352
  :param boolean [params.standard]: whether to fetch standard contract orders
@@ -3209,6 +3221,33 @@ class bingx(Exchange, ImplicitAPI):
3209
3221
  positions.append(position)
3210
3222
  return positions
3211
3223
 
3224
+ def set_position_mode(self, hedged, symbol: Str = None, params={}):
3225
+ """
3226
+ set hedged to True or False for a market
3227
+ :see: https://bingx-api.github.io/docs/#/en-us/swapV2/trade-api.html#Set%20Position%20Mode
3228
+ :param bool hedged: set to True to use dualSidePosition
3229
+ :param str symbol: not used by bingx setPositionMode()
3230
+ :param dict [params]: extra parameters specific to the exchange API endpoint
3231
+ :returns dict: response from the exchange
3232
+ """
3233
+ dualSidePosition = None
3234
+ if hedged:
3235
+ dualSidePosition = 'true'
3236
+ else:
3237
+ dualSidePosition = 'false'
3238
+ request = {
3239
+ 'dualSidePosition': dualSidePosition,
3240
+ }
3241
+ #
3242
+ # {
3243
+ # code: '0',
3244
+ # msg: '',
3245
+ # timeStamp: '1703327432734',
3246
+ # data: {dualSidePosition: 'false'}
3247
+ # }
3248
+ #
3249
+ return self.swapV1PrivatePostPositionSideDual(self.extend(request, params))
3250
+
3212
3251
  def sign(self, path, section='public', method='GET', params={}, headers=None, body=None):
3213
3252
  type = section[0]
3214
3253
  version = section[1]
ccxt/bit2c.py CHANGED
@@ -278,14 +278,13 @@ class bit2c(Exchange, ImplicitAPI):
278
278
 
279
279
  def parse_ticker(self, ticker, market: Market = None) -> Ticker:
280
280
  symbol = self.safe_symbol(None, market)
281
- timestamp = self.milliseconds()
282
281
  averagePrice = self.safe_string(ticker, 'av')
283
282
  baseVolume = self.safe_string(ticker, 'a')
284
283
  last = self.safe_string(ticker, 'll')
285
284
  return self.safe_ticker({
286
285
  'symbol': symbol,
287
- 'timestamp': timestamp,
288
- 'datetime': self.iso8601(timestamp),
286
+ 'timestamp': None,
287
+ 'datetime': None,
289
288
  'high': None,
290
289
  'low': None,
291
290
  'bid': self.safe_string(ticker, 'h'),
ccxt/bitfinex.py CHANGED
@@ -1181,7 +1181,7 @@ class bitfinex(Exchange, ImplicitAPI):
1181
1181
  fetches information on multiple closed orders made by the user
1182
1182
  :param str symbol: unified market symbol of the market orders were made in
1183
1183
  :param int [since]: the earliest time in ms to fetch orders for
1184
- :param int [limit]: the maximum number of orde structures to retrieve
1184
+ :param int [limit]: the maximum number of order structures to retrieve
1185
1185
  :param dict [params]: extra parameters specific to the exchange API endpoint
1186
1186
  :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1187
1187
  """