ccxt 4.2.88__py2.py3-none-any.whl → 4.2.90__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 (156) hide show
  1. ccxt/__init__.py +1 -1
  2. ccxt/abstract/bingx.py +2 -0
  3. ccxt/abstract/bybit.py +2 -0
  4. ccxt/ascendex.py +6 -3
  5. ccxt/async_support/__init__.py +1 -1
  6. ccxt/async_support/ascendex.py +6 -3
  7. ccxt/async_support/base/exchange.py +15 -2
  8. ccxt/async_support/bigone.py +2 -2
  9. ccxt/async_support/binance.py +88 -14
  10. ccxt/async_support/bingx.py +96 -3
  11. ccxt/async_support/bit2c.py +2 -2
  12. ccxt/async_support/bitbank.py +2 -2
  13. ccxt/async_support/bitfinex.py +2 -2
  14. ccxt/async_support/bitfinex2.py +4 -3
  15. ccxt/async_support/bitflyer.py +4 -2
  16. ccxt/async_support/bitget.py +12 -5
  17. ccxt/async_support/bitmart.py +6 -4
  18. ccxt/async_support/bitmex.py +3 -2
  19. ccxt/async_support/bitopro.py +3 -3
  20. ccxt/async_support/bitrue.py +3 -2
  21. ccxt/async_support/bitso.py +2 -2
  22. ccxt/async_support/bitstamp.py +89 -97
  23. ccxt/async_support/bitteam.py +2 -2
  24. ccxt/async_support/bitvavo.py +3 -3
  25. ccxt/async_support/bl3p.py +2 -2
  26. ccxt/async_support/blockchaincom.py +2 -2
  27. ccxt/async_support/blofin.py +4 -2
  28. ccxt/async_support/bybit.py +57 -5
  29. ccxt/async_support/cex.py +3 -3
  30. ccxt/async_support/coinbase.py +42 -22
  31. ccxt/async_support/coinbaseinternational.py +3 -2
  32. ccxt/async_support/coinbasepro.py +3 -3
  33. ccxt/async_support/coincheck.py +2 -2
  34. ccxt/async_support/coinex.py +101 -13
  35. ccxt/async_support/coinlist.py +3 -3
  36. ccxt/async_support/coinmate.py +2 -2
  37. ccxt/async_support/coinmetro.py +2 -2
  38. ccxt/async_support/coinone.py +2 -2
  39. ccxt/async_support/coinsph.py +6 -4
  40. ccxt/async_support/cryptocom.py +1 -0
  41. ccxt/async_support/currencycom.py +3 -3
  42. ccxt/async_support/delta.py +3 -2
  43. ccxt/async_support/deribit.py +3 -3
  44. ccxt/async_support/digifinex.py +7 -4
  45. ccxt/async_support/exmo.py +4 -3
  46. ccxt/async_support/gate.py +8 -4
  47. ccxt/async_support/gemini.py +13 -12
  48. ccxt/async_support/hitbtc.py +8 -5
  49. ccxt/async_support/hollaex.py +3 -3
  50. ccxt/async_support/htx.py +7 -4
  51. ccxt/async_support/huobijp.py +2 -2
  52. ccxt/async_support/hyperliquid.py +3 -2
  53. ccxt/async_support/idex.py +3 -3
  54. ccxt/async_support/independentreserve.py +2 -2
  55. ccxt/async_support/kraken.py +3 -3
  56. ccxt/async_support/kucoin.py +43 -18
  57. ccxt/async_support/kucoinfutures.py +32 -4
  58. ccxt/async_support/kuna.py +2 -2
  59. ccxt/async_support/latoken.py +7 -3
  60. ccxt/async_support/lbank.py +7 -5
  61. ccxt/async_support/luno.py +4 -2
  62. ccxt/async_support/lykke.py +2 -2
  63. ccxt/async_support/mexc.py +57 -9
  64. ccxt/async_support/ndax.py +2 -2
  65. ccxt/async_support/oceanex.py +2 -2
  66. ccxt/async_support/okcoin.py +2 -2
  67. ccxt/async_support/okx.py +149 -12
  68. ccxt/async_support/onetrading.py +3 -3
  69. ccxt/async_support/phemex.py +3 -2
  70. ccxt/async_support/poloniex.py +3 -3
  71. ccxt/async_support/probit.py +2 -2
  72. ccxt/async_support/timex.py +6 -4
  73. ccxt/async_support/upbit.py +2 -2
  74. ccxt/async_support/wazirx.py +2 -2
  75. ccxt/async_support/whitebit.py +3 -3
  76. ccxt/async_support/woo.py +4 -3
  77. ccxt/async_support/yobit.py +2 -2
  78. ccxt/base/exchange.py +65 -12
  79. ccxt/base/types.py +33 -0
  80. ccxt/bigone.py +2 -2
  81. ccxt/binance.py +88 -14
  82. ccxt/bingx.py +96 -3
  83. ccxt/bit2c.py +2 -2
  84. ccxt/bitbank.py +2 -2
  85. ccxt/bitfinex.py +2 -2
  86. ccxt/bitfinex2.py +4 -3
  87. ccxt/bitflyer.py +4 -2
  88. ccxt/bitget.py +12 -5
  89. ccxt/bitmart.py +6 -4
  90. ccxt/bitmex.py +3 -2
  91. ccxt/bitopro.py +3 -3
  92. ccxt/bitrue.py +3 -2
  93. ccxt/bitso.py +2 -2
  94. ccxt/bitstamp.py +89 -97
  95. ccxt/bitteam.py +2 -2
  96. ccxt/bitvavo.py +3 -3
  97. ccxt/bl3p.py +2 -2
  98. ccxt/blockchaincom.py +2 -2
  99. ccxt/blofin.py +4 -2
  100. ccxt/bybit.py +57 -5
  101. ccxt/cex.py +3 -3
  102. ccxt/coinbase.py +42 -22
  103. ccxt/coinbaseinternational.py +3 -2
  104. ccxt/coinbasepro.py +3 -3
  105. ccxt/coincheck.py +2 -2
  106. ccxt/coinex.py +101 -13
  107. ccxt/coinlist.py +3 -3
  108. ccxt/coinmate.py +2 -2
  109. ccxt/coinmetro.py +2 -2
  110. ccxt/coinone.py +2 -2
  111. ccxt/coinsph.py +6 -4
  112. ccxt/cryptocom.py +1 -0
  113. ccxt/currencycom.py +3 -3
  114. ccxt/delta.py +3 -2
  115. ccxt/deribit.py +3 -3
  116. ccxt/digifinex.py +7 -4
  117. ccxt/exmo.py +4 -3
  118. ccxt/gate.py +8 -4
  119. ccxt/gemini.py +13 -12
  120. ccxt/hitbtc.py +8 -5
  121. ccxt/hollaex.py +3 -3
  122. ccxt/htx.py +7 -4
  123. ccxt/huobijp.py +2 -2
  124. ccxt/hyperliquid.py +3 -2
  125. ccxt/idex.py +3 -3
  126. ccxt/independentreserve.py +2 -2
  127. ccxt/kraken.py +3 -3
  128. ccxt/kucoin.py +43 -18
  129. ccxt/kucoinfutures.py +32 -4
  130. ccxt/kuna.py +2 -2
  131. ccxt/latoken.py +7 -3
  132. ccxt/lbank.py +7 -5
  133. ccxt/luno.py +4 -2
  134. ccxt/lykke.py +2 -2
  135. ccxt/mexc.py +57 -9
  136. ccxt/ndax.py +2 -2
  137. ccxt/oceanex.py +2 -2
  138. ccxt/okcoin.py +2 -2
  139. ccxt/okx.py +149 -12
  140. ccxt/onetrading.py +3 -3
  141. ccxt/phemex.py +3 -2
  142. ccxt/poloniex.py +3 -3
  143. ccxt/pro/__init__.py +1 -1
  144. ccxt/pro/bitget.py +2 -0
  145. ccxt/pro/bitvavo.py +2 -2
  146. ccxt/probit.py +2 -2
  147. ccxt/timex.py +6 -4
  148. ccxt/upbit.py +2 -2
  149. ccxt/wazirx.py +2 -2
  150. ccxt/whitebit.py +3 -3
  151. ccxt/woo.py +4 -3
  152. ccxt/yobit.py +2 -2
  153. {ccxt-4.2.88.dist-info → ccxt-4.2.90.dist-info}/METADATA +4 -4
  154. {ccxt-4.2.88.dist-info → ccxt-4.2.90.dist-info}/RECORD +156 -156
  155. {ccxt-4.2.88.dist-info → ccxt-4.2.90.dist-info}/WHEEL +0 -0
  156. {ccxt-4.2.88.dist-info → ccxt-4.2.90.dist-info}/top_level.txt +0 -0
@@ -7,7 +7,7 @@ from ccxt.async_support.base.exchange import Exchange
7
7
  from ccxt.abstract.bybit import ImplicitAPI
8
8
  import asyncio
9
9
  import hashlib
10
- from ccxt.base.types import Balances, Currency, Greeks, Int, Leverage, Market, MarketInterface, Num, Option, OptionChain, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry
10
+ from ccxt.base.types import Balances, Currencies, Currency, Greeks, Int, Leverage, Market, MarketInterface, Num, Option, OptionChain, Order, OrderBook, OrderRequest, OrderSide, OrderType, 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
@@ -96,6 +96,7 @@ class bybit(Exchange, ImplicitAPI):
96
96
  'fetchLedger': True,
97
97
  'fetchLeverage': True,
98
98
  'fetchLeverageTiers': True,
99
+ 'fetchMarginAdjustmentHistory': False,
99
100
  'fetchMarketLeverageTiers': True,
100
101
  'fetchMarkets': True,
101
102
  'fetchMarkOHLCV': True,
@@ -166,6 +167,13 @@ class bybit(Exchange, ImplicitAPI):
166
167
  'public': 'https://api.{hostname}',
167
168
  'private': 'https://api.{hostname}',
168
169
  },
170
+ 'demotrading': {
171
+ 'spot': 'https://api-demo.{hostname}',
172
+ 'futures': 'https://api-demo.{hostname}',
173
+ 'v2': 'https://api-demo.{hostname}',
174
+ 'public': 'https://api-demo.{hostname}',
175
+ 'private': 'https://api-demo.{hostname}',
176
+ },
169
177
  'www': 'https://www.bybit.com',
170
178
  'doc': [
171
179
  'https://bybit-exchange.github.io/docs/inverse/',
@@ -354,6 +362,7 @@ class bybit(Exchange, ImplicitAPI):
354
362
  'v5/user/get-member-type': 5,
355
363
  'v5/user/aff-customer-info': 5,
356
364
  'v5/user/del-submember': 5,
365
+ 'v5/user/submembers': 5,
357
366
  # spot leverage token
358
367
  'v5/spot-lever-token/order-record': 1, # 50/s => cost = 50 / 50 = 1
359
368
  # spot margin trade
@@ -514,6 +523,8 @@ class bybit(Exchange, ImplicitAPI):
514
523
  'v5/lending/redeem-cancel': 5,
515
524
  'v5/account/set-collateral-switch': 5,
516
525
  'v5/account/set-collateral-switch-batch': 5,
526
+ # demo trading
527
+ 'v5/account/demo-apply-money': 5,
517
528
  },
518
529
  },
519
530
  },
@@ -980,6 +991,8 @@ class bybit(Exchange, ImplicitAPI):
980
991
  },
981
992
  'precisionMode': TICK_SIZE,
982
993
  'options': {
994
+ 'sandboxMode': False,
995
+ 'enableDemoTrading': False,
983
996
  'fetchMarkets': ['spot', 'linear', 'inverse', 'option'],
984
997
  'createOrder': {
985
998
  'method': 'privatePostV5OrderCreate', # 'privatePostV5PositionTradingStop'
@@ -1063,6 +1076,32 @@ class bybit(Exchange, ImplicitAPI):
1063
1076
  },
1064
1077
  })
1065
1078
 
1079
+ def set_sandbox_mode(self, enable: bool):
1080
+ """
1081
+ enables or disables sandbox mode
1082
+ :param boolean [enable]: True if demo trading should be enabled, False otherwise
1083
+ """
1084
+ super(bybit, self).set_sandbox_mode(enable)
1085
+ self.options['sandboxMode'] = enable
1086
+
1087
+ def enable_demo_trading(self, enable: bool):
1088
+ """
1089
+ enables or disables demo trading mode
1090
+ :see: https://bybit-exchange.github.io/docs/v5/demo
1091
+ :param boolean [enable]: True if demo trading should be enabled, False otherwise
1092
+ """
1093
+ if self.options['sandboxMode']:
1094
+ raise NotSupported(self.id + ' demo trading does not support in sandbox environment')
1095
+ # enable demo trading in bybit, see: https://bybit-exchange.github.io/docs/v5/demo
1096
+ if enable:
1097
+ self.urls['apiBackupDemoTrading'] = self.urls['api']
1098
+ self.urls['api'] = self.urls['demotrading']
1099
+ elif 'apiBackupDemoTrading' in self.urls:
1100
+ self.urls['api'] = self.urls['apiBackupDemoTrading']
1101
+ newUrls = self.omit(self.urls, 'apiBackupDemoTrading')
1102
+ self.urls = newUrls
1103
+ self.options['enableDemoTrading'] = enable
1104
+
1066
1105
  def nonce(self):
1067
1106
  return self.milliseconds() - self.options['timeDifference']
1068
1107
 
@@ -1078,12 +1117,21 @@ class bybit(Exchange, ImplicitAPI):
1078
1117
  return data
1079
1118
 
1080
1119
  async def is_unified_enabled(self, params={}):
1120
+ """
1121
+ returns [enableUnifiedMargin, enableUnifiedAccount] so the user can check if unified account is enabled
1122
+ """
1081
1123
  # The API key of user id must own one of permissions will be allowed to call following API endpoints.
1082
1124
  # SUB UID: "Account Transfer"
1083
1125
  # MASTER UID: "Account Transfer", "Subaccount Transfer", "Withdrawal"
1084
1126
  enableUnifiedMargin = self.safe_value(self.options, 'enableUnifiedMargin')
1085
1127
  enableUnifiedAccount = self.safe_value(self.options, 'enableUnifiedAccount')
1086
1128
  if enableUnifiedMargin is None or enableUnifiedAccount is None:
1129
+ if self.options['enableDemoTrading']:
1130
+ # info endpoint is not available in demo trading
1131
+ # so we're assuming UTA is enabled
1132
+ self.options['enableUnifiedMargin'] = False
1133
+ self.options['enableUnifiedAccount'] = True
1134
+ return [self.options['enableUnifiedMargin'], self.options['enableUnifiedAccount']]
1087
1135
  response = await self.privateGetV5UserQueryApi(params)
1088
1136
  #
1089
1137
  # {
@@ -1234,7 +1282,7 @@ class bybit(Exchange, ImplicitAPI):
1234
1282
  #
1235
1283
  return self.safe_integer(response, 'time')
1236
1284
 
1237
- async def fetch_currencies(self, params={}):
1285
+ async def fetch_currencies(self, params={}) -> Currencies:
1238
1286
  """
1239
1287
  fetches all available currencies on an exchange
1240
1288
  :see: https://bybit-exchange.github.io/docs/v5/asset/coin-info
@@ -1243,6 +1291,8 @@ class bybit(Exchange, ImplicitAPI):
1243
1291
  """
1244
1292
  if not self.check_required_credentials(False):
1245
1293
  return None
1294
+ if self.options['enableDemoTrading']:
1295
+ return None
1246
1296
  response = await self.privateGetV5AssetCoinQueryInfo(params)
1247
1297
  #
1248
1298
  # {
@@ -6737,7 +6787,7 @@ class bybit(Exchange, ImplicitAPI):
6737
6787
  request['symbol'] = market['id']
6738
6788
  return await self.fetch_derivatives_market_leverage_tiers(symbol, params)
6739
6789
 
6740
- def parse_trading_fee(self, fee, market: Market = None):
6790
+ def parse_trading_fee(self, fee, market: Market = None) -> TradingFeeInterface:
6741
6791
  #
6742
6792
  # {
6743
6793
  # "symbol": "ETHUSDT",
@@ -6753,9 +6803,11 @@ class bybit(Exchange, ImplicitAPI):
6753
6803
  'symbol': symbol,
6754
6804
  'maker': self.safe_number(fee, 'makerFeeRate'),
6755
6805
  'taker': self.safe_number(fee, 'takerFeeRate'),
6806
+ 'percentage': None,
6807
+ 'tierBased': None,
6756
6808
  }
6757
6809
 
6758
- async def fetch_trading_fee(self, symbol: str, params={}):
6810
+ async def fetch_trading_fee(self, symbol: str, params={}) -> TradingFeeInterface:
6759
6811
  """
6760
6812
  fetch the trading fees for a market
6761
6813
  :see: https://bybit-exchange.github.io/docs/v5/account/fee-rate
@@ -6801,7 +6853,7 @@ class bybit(Exchange, ImplicitAPI):
6801
6853
  first = self.safe_value(fees, 0, {})
6802
6854
  return self.parse_trading_fee(first, market)
6803
6855
 
6804
- async def fetch_trading_fees(self, params={}):
6856
+ async def fetch_trading_fees(self, params={}) -> TradingFees:
6805
6857
  """
6806
6858
  fetch the trading fees for multiple markets
6807
6859
  :see: https://bybit-exchange.github.io/docs/v5/account/fee-rate
ccxt/async_support/cex.py CHANGED
@@ -7,7 +7,7 @@ from ccxt.async_support.base.exchange import Exchange
7
7
  from ccxt.abstract.cex import ImplicitAPI
8
8
  import hashlib
9
9
  import json
10
- from ccxt.base.types import Balances, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade
10
+ from ccxt.base.types import Balances, Currencies, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFees
11
11
  from typing import List
12
12
  from ccxt.base.errors import ExchangeError
13
13
  from ccxt.base.errors import ArgumentsRequired
@@ -237,7 +237,7 @@ class cex(Exchange, ImplicitAPI):
237
237
  })
238
238
  return self.safe_value(self.options['fetchCurrencies'], 'response')
239
239
 
240
- async def fetch_currencies(self, params={}):
240
+ async def fetch_currencies(self, params={}) -> Currencies:
241
241
  """
242
242
  fetches all available currencies on an exchange
243
243
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -681,7 +681,7 @@ class cex(Exchange, ImplicitAPI):
681
681
  response = await self.publicGetTradeHistoryPair(self.extend(request, params))
682
682
  return self.parse_trades(response, market, since, limit)
683
683
 
684
- async def fetch_trading_fees(self, params={}):
684
+ async def fetch_trading_fees(self, params={}) -> TradingFees:
685
685
  """
686
686
  :see: https://docs.cex.io/#get-my-fee
687
687
  fetch the trading fees for multiple markets
@@ -7,7 +7,7 @@ from ccxt.async_support.base.exchange import Exchange
7
7
  from ccxt.abstract.coinbase import ImplicitAPI
8
8
  import asyncio
9
9
  import hashlib
10
- from ccxt.base.types import Account, Balances, Currency, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction
10
+ from ccxt.base.types import Account, Balances, Currencies, Currency, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction
11
11
  from typing import List
12
12
  from ccxt.base.errors import ExchangeError
13
13
  from ccxt.base.errors import ArgumentsRequired
@@ -1288,7 +1288,7 @@ class coinbase(Exchange, ImplicitAPI):
1288
1288
  })
1289
1289
  return self.safe_dict(self.options, 'fetchCurrencies', {})
1290
1290
 
1291
- async def fetch_currencies(self, params={}):
1291
+ async def fetch_currencies(self, params={}) -> Currencies:
1292
1292
  """
1293
1293
  fetches all available currencies on an exchange
1294
1294
  :see: https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-currencies#get-fiat-currencies
@@ -3574,25 +3574,14 @@ class coinbase(Exchange, ImplicitAPI):
3574
3574
  url = self.urls['api']['rest'] + fullPath
3575
3575
  if signed:
3576
3576
  authorization = self.safe_string(self.headers, 'Authorization')
3577
+ authorizationString = None
3577
3578
  if authorization is not None:
3578
- headers = {
3579
- 'Authorization': authorization,
3580
- 'Content-Type': 'application/json',
3581
- }
3582
- if method != 'GET':
3583
- if query:
3584
- body = self.json(query)
3579
+ authorizationString = authorization
3585
3580
  elif self.token and not self.check_required_credentials(False):
3586
- headers = {
3587
- 'Authorization': 'Bearer ' + self.token,
3588
- 'Content-Type': 'application/json',
3589
- }
3590
- if method != 'GET':
3591
- if query:
3592
- body = self.json(query)
3581
+ authorizationString = 'Bearer ' + self.token
3593
3582
  else:
3594
3583
  self.check_required_credentials()
3595
- timestampString = str(self.seconds())
3584
+ seconds = self.seconds()
3596
3585
  payload = ''
3597
3586
  if method != 'GET':
3598
3587
  if query:
@@ -3606,14 +3595,45 @@ class coinbase(Exchange, ImplicitAPI):
3606
3595
  # https://docs.cloud.coinbase.com/advanced-trade-api/docs/auth#example-request
3607
3596
  # v2: 'GET' require payload in the signature
3608
3597
  # https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-key-authentication
3609
- auth = timestampString + method + savedPath + payload
3610
- signature = self.hmac(self.encode(auth), self.encode(self.secret), hashlib.sha256)
3598
+ isCloudAPiKey = (self.apiKey.find('organizations/') >= 0) or (self.secret.startswith('-----BEGIN'))
3599
+ if isCloudAPiKey:
3600
+ if self.apiKey.startswith('-----BEGIN'):
3601
+ raise ArgumentsRequired(self.id + ' apiKey should contain the name(eg: organizations/3b910e93....) and not the public key')
3602
+ # it may not work for v2
3603
+ uri = method + ' ' + url.replace('https://', '')
3604
+ quesPos = uri.find('?')
3605
+ if quesPos >= 0:
3606
+ uri = uri[0:quesPos]
3607
+ nonce = self.random_bytes(16)
3608
+ request = {
3609
+ 'aud': ['retail_rest_api_proxy'],
3610
+ 'iss': 'coinbase-cloud',
3611
+ 'nbf': seconds,
3612
+ 'exp': seconds + 120,
3613
+ 'sub': self.apiKey,
3614
+ 'uri': uri,
3615
+ 'iat': seconds,
3616
+ }
3617
+ token = self.jwt(request, self.encode(self.secret), 'sha256', False, {'kid': self.apiKey, 'nonce': nonce, 'alg': 'ES256'})
3618
+ authorizationString = 'Bearer ' + token
3619
+ else:
3620
+ timestampString = str(self.seconds())
3621
+ auth = timestampString + method + savedPath + payload
3622
+ signature = self.hmac(self.encode(auth), self.encode(self.secret), hashlib.sha256)
3623
+ headers = {
3624
+ 'CB-ACCESS-KEY': self.apiKey,
3625
+ 'CB-ACCESS-SIGN': signature,
3626
+ 'CB-ACCESS-TIMESTAMP': timestampString,
3627
+ 'Content-Type': 'application/json',
3628
+ }
3629
+ if authorizationString is not None:
3611
3630
  headers = {
3612
- 'CB-ACCESS-KEY': self.apiKey,
3613
- 'CB-ACCESS-SIGN': signature,
3614
- 'CB-ACCESS-TIMESTAMP': timestampString,
3631
+ 'Authorization': authorizationString,
3615
3632
  'Content-Type': 'application/json',
3616
3633
  }
3634
+ if method != 'GET':
3635
+ if query:
3636
+ body = self.json(query)
3617
3637
  return {'url': url, 'method': method, 'body': body, 'headers': headers}
3618
3638
 
3619
3639
  def handle_errors(self, code, reason, url, method, headers, body, response, requestHeaders, requestBody):
@@ -6,7 +6,7 @@
6
6
  from ccxt.async_support.base.exchange import Exchange
7
7
  from ccxt.abstract.coinbaseinternational import ImplicitAPI
8
8
  import hashlib
9
- from ccxt.base.types import Balances, Currency, Int, Market, Order, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry
9
+ from ccxt.base.types import Balances, Currencies, Currency, Int, Market, Order, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry
10
10
  from typing import List
11
11
  from typing import Any
12
12
  from ccxt.base.errors import ExchangeError
@@ -85,6 +85,7 @@ class coinbaseinternational(Exchange, ImplicitAPI):
85
85
  'fetchLedger': False,
86
86
  'fetchLeverage': False,
87
87
  'fetchLeverageTiers': False,
88
+ 'fetchMarginAdjustmentHistory': False,
88
89
  'fetchMarginMode': False,
89
90
  'fetchMarkets': True,
90
91
  'fetchMarkOHLCV': False,
@@ -1065,7 +1066,7 @@ class coinbaseinternational(Exchange, ImplicitAPI):
1065
1066
  'created': None,
1066
1067
  }
1067
1068
 
1068
- async def fetch_currencies(self, params={}) -> Any:
1069
+ async def fetch_currencies(self, params={}) -> Currencies:
1069
1070
  """
1070
1071
  fetches all available currencies on an exchange
1071
1072
  :see: https://docs.cloud.coinbase.com/intx/reference/getassets
@@ -6,7 +6,7 @@
6
6
  from ccxt.async_support.base.exchange import Exchange
7
7
  from ccxt.abstract.coinbasepro import ImplicitAPI
8
8
  import hashlib
9
- from ccxt.base.types import Account, Balances, Currency, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction
9
+ from ccxt.base.types import Account, Balances, Currencies, Currency, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFees, Transaction
10
10
  from typing import List
11
11
  from ccxt.base.errors import ExchangeError
12
12
  from ccxt.base.errors import PermissionDenied
@@ -239,7 +239,7 @@ class coinbasepro(Exchange, ImplicitAPI):
239
239
  },
240
240
  })
241
241
 
242
- async def fetch_currencies(self, params={}):
242
+ async def fetch_currencies(self, params={}) -> Currencies:
243
243
  """
244
244
  fetches all available currencies on an exchange
245
245
  :see: https://docs.cloud.coinbase.com/exchange/reference/exchangerestapi_getcurrencies
@@ -833,7 +833,7 @@ class coinbasepro(Exchange, ImplicitAPI):
833
833
  #
834
834
  return self.parse_trades(response, market, since, limit)
835
835
 
836
- async def fetch_trading_fees(self, params={}):
836
+ async def fetch_trading_fees(self, params={}) -> TradingFees:
837
837
  """
838
838
  fetch the trading fees for multiple markets
839
839
  :see: https://docs.cloud.coinbase.com/exchange/reference/exchangerestapi_getfees
@@ -6,7 +6,7 @@
6
6
  from ccxt.async_support.base.exchange import Exchange
7
7
  from ccxt.abstract.coincheck import ImplicitAPI
8
8
  import hashlib
9
- from ccxt.base.types import Balances, Currency, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Ticker, Trade, Transaction
9
+ from ccxt.base.types import Balances, Currency, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Ticker, Trade, TradingFees, Transaction
10
10
  from typing import List
11
11
  from ccxt.base.errors import ExchangeError
12
12
  from ccxt.base.errors import BadSymbol
@@ -503,7 +503,7 @@ class coincheck(Exchange, ImplicitAPI):
503
503
  data = self.safe_list(response, 'data', [])
504
504
  return self.parse_trades(data, market, since, limit)
505
505
 
506
- async def fetch_trading_fees(self, params={}):
506
+ async def fetch_trading_fees(self, params={}) -> TradingFees:
507
507
  """
508
508
  fetch the trading fees for multiple markets
509
509
  :see: https://coincheck.com/documents/exchange/api#account-info
@@ -6,7 +6,7 @@
6
6
  from ccxt.async_support.base.exchange import Exchange
7
7
  from ccxt.abstract.coinex import ImplicitAPI
8
8
  import asyncio
9
- from ccxt.base.types import Balances, Currency, Int, Leverage, Leverages, MarginModification, Market, Num, Order, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry
9
+ from ccxt.base.types import Balances, Currencies, Currency, Int, Leverage, Leverages, MarginModification, Market, Num, Order, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, TradingFees, Transaction, TransferEntry
10
10
  from typing import List
11
11
  from ccxt.base.errors import ExchangeError
12
12
  from ccxt.base.errors import PermissionDenied
@@ -93,6 +93,7 @@ class coinex(Exchange, ImplicitAPI):
93
93
  'fetchLeverage': 'emulated',
94
94
  'fetchLeverages': True,
95
95
  'fetchLeverageTiers': True,
96
+ 'fetchMarginAdjustmentHistory': True,
96
97
  'fetchMarketLeverageTiers': 'emulated',
97
98
  'fetchMarkets': True,
98
99
  'fetchMarkOHLCV': False,
@@ -490,7 +491,7 @@ class coinex(Exchange, ImplicitAPI):
490
491
  },
491
492
  })
492
493
 
493
- async def fetch_currencies(self, params={}):
494
+ async def fetch_currencies(self, params={}) -> Currencies:
494
495
  response = await self.v1PublicGetCommonAssetConfig(params)
495
496
  # {
496
497
  # "code": 0,
@@ -1306,7 +1307,7 @@ class coinex(Exchange, ImplicitAPI):
1306
1307
  #
1307
1308
  return self.parse_trades(response['data'], market, since, limit)
1308
1309
 
1309
- async def fetch_trading_fee(self, symbol: str, params={}):
1310
+ async def fetch_trading_fee(self, symbol: str, params={}) -> TradingFeeInterface:
1310
1311
  """
1311
1312
  fetch the trading fees for a market
1312
1313
  :see: https://docs.coinex.com/api/v2/spot/market/http/list-market
@@ -1370,7 +1371,7 @@ class coinex(Exchange, ImplicitAPI):
1370
1371
  result = self.safe_dict(data, 0, {})
1371
1372
  return self.parse_trading_fee(result, market)
1372
1373
 
1373
- async def fetch_trading_fees(self, params={}):
1374
+ async def fetch_trading_fees(self, params={}) -> TradingFees:
1374
1375
  """
1375
1376
  fetch the trading fees for multiple markets
1376
1377
  :see: https://docs.coinex.com/api/v2/spot/market/http/list-market
@@ -1437,7 +1438,7 @@ class coinex(Exchange, ImplicitAPI):
1437
1438
  result[symbol] = self.parse_trading_fee(entry, market)
1438
1439
  return result
1439
1440
 
1440
- def parse_trading_fee(self, fee, market: Market = None):
1441
+ def parse_trading_fee(self, fee, market: Market = None) -> TradingFeeInterface:
1441
1442
  marketId = self.safe_value(fee, 'market')
1442
1443
  symbol = self.safe_symbol(marketId, market)
1443
1444
  return {
@@ -3967,11 +3968,10 @@ class coinex(Exchange, ImplicitAPI):
3967
3968
  # "message":"OK"
3968
3969
  # }
3969
3970
  #
3971
+ data = self.safe_dict(response, 'data')
3970
3972
  status = self.safe_string(response, 'message')
3971
- type = 'add' if (addOrReduce == 1) else 'reduce'
3972
- return self.extend(self.parse_margin_modification(response, market), {
3973
+ return self.extend(self.parse_margin_modification(data, market), {
3973
3974
  'amount': self.parse_number(amount),
3974
- 'type': type,
3975
3975
  'status': status,
3976
3976
  })
3977
3977
 
@@ -4031,13 +4031,34 @@ class coinex(Exchange, ImplicitAPI):
4031
4031
  # "user_id": 3620173
4032
4032
  # }
4033
4033
  #
4034
- timestamp = self.safe_integer_product(data, 'update_time', 1000)
4034
+ # fetchMarginAdjustmentHistory
4035
+ #
4036
+ # {
4037
+ # bkr_price: '0',
4038
+ # leverage: '3',
4039
+ # liq_price: '0',
4040
+ # margin_amount: '5.33236666666666666666',
4041
+ # margin_change: '3',
4042
+ # market: 'XRPUSDT',
4043
+ # position_amount: '11',
4044
+ # position_id: '297155652',
4045
+ # position_type: '2',
4046
+ # settle_price: '0.6361',
4047
+ # time: '1711050906.382891',
4048
+ # type: '1',
4049
+ # user_id: '3685860'
4050
+ # }
4051
+ #
4052
+ marketId = self.safe_string(data, 'market')
4053
+ type = self.safe_string(data, 'type')
4054
+ timestamp = self.safe_integer_product_2(data, 'time', 'update_time', 1000)
4035
4055
  return {
4036
4056
  'info': data,
4037
- 'symbol': self.safe_symbol(None, market),
4038
- 'type': None,
4039
- 'amount': self.safe_number(data, 'margin_amount'),
4040
- 'total': None,
4057
+ 'symbol': self.safe_symbol(marketId, market, None, 'swap'),
4058
+ 'type': 'add' if (type == '1') else 'reduce',
4059
+ 'marginMode': 'isolated',
4060
+ 'amount': self.safe_number(data, 'margin_change'),
4061
+ 'total': self.safe_number(data, 'position_amount'),
4041
4062
  'code': market['quote'],
4042
4063
  'status': None,
4043
4064
  'timestamp': timestamp,
@@ -4645,6 +4666,7 @@ class coinex(Exchange, ImplicitAPI):
4645
4666
  currencyId = self.safe_string(transfer, 'asset')
4646
4667
  currencyCode = self.safe_currency_code(currencyId, currency)
4647
4668
  return {
4669
+ 'info': transfer,
4648
4670
  'id': self.safe_integer(transfer, 'id'),
4649
4671
  'timestamp': timestamp,
4650
4672
  'datetime': self.iso8601(timestamp),
@@ -5411,3 +5433,69 @@ class coinex(Exchange, ImplicitAPI):
5411
5433
  self.throw_exactly_matched_exception(self.exceptions['exact'], code, feedback)
5412
5434
  raise ExchangeError(feedback)
5413
5435
  return None
5436
+
5437
+ async def fetch_margin_adjustment_history(self, symbol: Str = None, type: Str = None, since: Num = None, limit: Num = None, params={}) -> List[MarginModification]:
5438
+ """
5439
+ fetches the history of margin added or reduced from contract isolated positions
5440
+ :see: https://viabtc.github.io/coinex_api_en_doc/futures/#docsfutures001_http046_position_margin_history
5441
+ :param str [symbol]: unified market symbol
5442
+ :param str [type]: not used by coinex fetchMarginAdjustmentHistory
5443
+ :param int [since]: timestamp in ms of the earliest change to fetch
5444
+ :param int [limit]: the maximum amount of changes to fetch, default=100, max=100
5445
+ :param dict params: extra parameters specific to the exchange api endpoint
5446
+ :param int [params.until]: timestamp in ms of the latest change to fetch
5447
+ *
5448
+ * EXCHANGE SPECIFIC PARAMETERS
5449
+ :param int [params.offset]: offset
5450
+ :returns dict[]: a list of `margin structures <https://docs.ccxt.com/#/?id=margin-loan-structure>`
5451
+ """
5452
+ await self.load_markets()
5453
+ until = self.safe_integer(params, 'until')
5454
+ params = self.omit(params, 'until')
5455
+ if limit is None:
5456
+ limit = 100
5457
+ request = {
5458
+ 'market': '',
5459
+ 'position_id': 0,
5460
+ 'offset': 0,
5461
+ 'limit': limit,
5462
+ }
5463
+ if symbol is not None:
5464
+ market = self.market(symbol)
5465
+ request['market'] = market['id']
5466
+ if since is not None:
5467
+ request['start_time'] = since
5468
+ if until is not None:
5469
+ request['end_time'] = until
5470
+ response = await self.v1PerpetualPrivateGetPositionMarginHistory(self.extend(request, params))
5471
+ #
5472
+ # {
5473
+ # code: '0',
5474
+ # data: {
5475
+ # limit: '100',
5476
+ # offset: '0',
5477
+ # records: [
5478
+ # {
5479
+ # bkr_price: '0',
5480
+ # leverage: '3',
5481
+ # liq_price: '0',
5482
+ # margin_amount: '5.33236666666666666666',
5483
+ # margin_change: '3',
5484
+ # market: 'XRPUSDT',
5485
+ # position_amount: '11',
5486
+ # position_id: '297155652',
5487
+ # position_type: '2',
5488
+ # settle_price: '0.6361',
5489
+ # time: '1711050906.382891',
5490
+ # type: '1',
5491
+ # user_id: '3685860'
5492
+ # }
5493
+ # ]
5494
+ # },
5495
+ # message: 'OK'
5496
+ # }
5497
+ #
5498
+ data = self.safe_dict(response, 'data', {})
5499
+ records = self.safe_list(data, 'records', [])
5500
+ modifications = self.parse_margin_modifications(records, None, 'market', 'swap')
5501
+ return self.filter_by_symbol_since_limit(modifications, symbol, since, limit)
@@ -7,7 +7,7 @@ from ccxt.async_support.base.exchange import Exchange
7
7
  from ccxt.abstract.coinlist import ImplicitAPI
8
8
  import hashlib
9
9
  import math
10
- from ccxt.base.types import Account, Balances, Currency, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry
10
+ from ccxt.base.types import Account, Balances, Currencies, Currency, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, 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
@@ -336,7 +336,7 @@ class coinlist(Exchange, ImplicitAPI):
336
336
  string = self.safe_string(response, 'iso')
337
337
  return self.parse8601(string)
338
338
 
339
- async def fetch_currencies(self, params={}):
339
+ async def fetch_currencies(self, params={}) -> Currencies:
340
340
  """
341
341
  fetches all available currencies on an exchange
342
342
  :see: https://trade-docs.coinlist.co/?javascript--nodejs#list-supported-assets
@@ -856,7 +856,7 @@ class coinlist(Exchange, ImplicitAPI):
856
856
  'info': trade,
857
857
  }, market)
858
858
 
859
- async def fetch_trading_fees(self, params={}):
859
+ async def fetch_trading_fees(self, params={}) -> TradingFees:
860
860
  """
861
861
  fetch the trading fees for multiple markets
862
862
  :see: https://trade-docs.coinlist.co/?javascript--nodejs#list-fees
@@ -6,7 +6,7 @@
6
6
  from ccxt.async_support.base.exchange import Exchange
7
7
  from ccxt.abstract.coinmate import ImplicitAPI
8
8
  import hashlib
9
- from ccxt.base.types import Balances, Currency, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction
9
+ from ccxt.base.types import Balances, Currency, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, Transaction
10
10
  from typing import List
11
11
  from ccxt.base.errors import ExchangeError
12
12
  from ccxt.base.errors import ArgumentsRequired
@@ -761,7 +761,7 @@ class coinmate(Exchange, ImplicitAPI):
761
761
  data = self.safe_list(response, 'data', [])
762
762
  return self.parse_trades(data, market, since, limit)
763
763
 
764
- async def fetch_trading_fee(self, symbol: str, params={}):
764
+ async def fetch_trading_fee(self, symbol: str, params={}) -> TradingFeeInterface:
765
765
  """
766
766
  fetch the trading fees for a market
767
767
  :see: https://coinmate.docs.apiary.io/#reference/trader-fees/get-trading-fees/post
@@ -5,7 +5,7 @@
5
5
 
6
6
  from ccxt.async_support.base.exchange import Exchange
7
7
  from ccxt.abstract.coinmetro import ImplicitAPI
8
- from ccxt.base.types import Balances, Currency, IndexType, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade
8
+ from ccxt.base.types import Balances, Currencies, Currency, IndexType, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade
9
9
  from typing import List
10
10
  from ccxt.base.errors import ExchangeError
11
11
  from ccxt.base.errors import PermissionDenied
@@ -256,7 +256,7 @@ class coinmetro(Exchange, ImplicitAPI):
256
256
  },
257
257
  })
258
258
 
259
- async def fetch_currencies(self, params={}):
259
+ async def fetch_currencies(self, params={}) -> Currencies:
260
260
  """
261
261
  fetches all available currencies on an exchange
262
262
  :see: https://documenter.getpostman.com/view/3653795/SVfWN6KS#d5876d43-a3fe-4479-8c58-24d0f044edfb
@@ -6,7 +6,7 @@
6
6
  from ccxt.async_support.base.exchange import Exchange
7
7
  from ccxt.abstract.coinone import ImplicitAPI
8
8
  import hashlib
9
- from ccxt.base.types import Balances, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade
9
+ from ccxt.base.types import Balances, Currencies, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade
10
10
  from typing import List
11
11
  from ccxt.base.errors import ExchangeError
12
12
  from ccxt.base.errors import ArgumentsRequired
@@ -205,7 +205,7 @@ class coinone(Exchange, ImplicitAPI):
205
205
  },
206
206
  })
207
207
 
208
- async def fetch_currencies(self, params={}):
208
+ async def fetch_currencies(self, params={}) -> Currencies:
209
209
  """
210
210
  fetches all available currencies on an exchange
211
211
  :see: https://docs.coinone.co.kr/reference/currencies