ccxt 4.4.32__py2.py3-none-any.whl → 4.4.34__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.
Files changed (95) hide show
  1. ccxt/__init__.py +3 -1
  2. ccxt/abstract/bingx.py +16 -0
  3. ccxt/abstract/bitbank.py +5 -0
  4. ccxt/abstract/bitfinex2.py +1 -0
  5. ccxt/abstract/coinbaseexchange.py +1 -0
  6. ccxt/abstract/ellipx.py +25 -0
  7. ccxt/abstract/kraken.py +1 -0
  8. ccxt/alpaca.py +2 -0
  9. ccxt/async_support/__init__.py +3 -1
  10. ccxt/async_support/alpaca.py +2 -0
  11. ccxt/async_support/base/exchange.py +1 -1
  12. ccxt/async_support/binance.py +164 -7
  13. ccxt/async_support/bingx.py +155 -8
  14. ccxt/async_support/bitbank.py +5 -0
  15. ccxt/async_support/bitbns.py +2 -0
  16. ccxt/async_support/bitfinex2.py +1 -0
  17. ccxt/async_support/bitget.py +174 -40
  18. ccxt/async_support/bitmex.py +2 -0
  19. ccxt/async_support/bitopro.py +3 -0
  20. ccxt/async_support/bitrue.py +1 -0
  21. ccxt/async_support/btcmarkets.py +2 -0
  22. ccxt/async_support/bybit.py +143 -12
  23. ccxt/async_support/cex.py +16 -5
  24. ccxt/async_support/coinbase.py +5 -24
  25. ccxt/async_support/coinbaseexchange.py +2 -1
  26. ccxt/async_support/coinex.py +2 -0
  27. ccxt/async_support/coinone.py +7 -7
  28. ccxt/async_support/coinsph.py +7 -7
  29. ccxt/async_support/coinspot.py +39 -39
  30. ccxt/async_support/cryptocom.py +36 -34
  31. ccxt/async_support/ellipx.py +1828 -0
  32. ccxt/async_support/gate.py +1 -0
  33. ccxt/async_support/hyperliquid.py +13 -2
  34. ccxt/async_support/kraken.py +1 -0
  35. ccxt/async_support/krakenfutures.py +3 -1
  36. ccxt/async_support/kucoinfutures.py +1 -1
  37. ccxt/async_support/lbank.py +1 -0
  38. ccxt/async_support/okcoin.py +2 -0
  39. ccxt/async_support/okx.py +103 -8
  40. ccxt/async_support/onetrading.py +20 -1
  41. ccxt/async_support/paradex.py +2 -0
  42. ccxt/async_support/phemex.py +33 -6
  43. ccxt/async_support/poloniex.py +3 -1
  44. ccxt/async_support/poloniexfutures.py +3 -1
  45. ccxt/async_support/vertex.py +2 -0
  46. ccxt/async_support/woo.py +69 -69
  47. ccxt/base/exchange.py +100 -2
  48. ccxt/binance.py +164 -7
  49. ccxt/bingx.py +155 -8
  50. ccxt/bitbank.py +5 -0
  51. ccxt/bitbns.py +2 -0
  52. ccxt/bitfinex2.py +1 -0
  53. ccxt/bitget.py +174 -40
  54. ccxt/bitmex.py +2 -0
  55. ccxt/bitopro.py +3 -0
  56. ccxt/bitrue.py +1 -0
  57. ccxt/btcmarkets.py +2 -0
  58. ccxt/bybit.py +143 -12
  59. ccxt/cex.py +16 -5
  60. ccxt/coinbase.py +5 -24
  61. ccxt/coinbaseexchange.py +2 -1
  62. ccxt/coinex.py +2 -0
  63. ccxt/coinone.py +7 -7
  64. ccxt/coinsph.py +7 -7
  65. ccxt/coinspot.py +39 -39
  66. ccxt/cryptocom.py +36 -34
  67. ccxt/ellipx.py +1828 -0
  68. ccxt/gate.py +1 -0
  69. ccxt/hyperliquid.py +13 -2
  70. ccxt/kraken.py +1 -0
  71. ccxt/krakenfutures.py +3 -1
  72. ccxt/kucoinfutures.py +1 -1
  73. ccxt/lbank.py +1 -0
  74. ccxt/okcoin.py +2 -0
  75. ccxt/okx.py +103 -8
  76. ccxt/onetrading.py +20 -1
  77. ccxt/paradex.py +2 -0
  78. ccxt/phemex.py +33 -6
  79. ccxt/poloniex.py +3 -1
  80. ccxt/poloniexfutures.py +3 -1
  81. ccxt/pro/__init__.py +1 -1
  82. ccxt/pro/idex.py +15 -0
  83. ccxt/pro/okx.py +8 -0
  84. ccxt/pro/probit.py +4 -2
  85. ccxt/pro/woo.py +15 -15
  86. ccxt/test/tests_async.py +3 -1
  87. ccxt/test/tests_helpers.py +1 -3
  88. ccxt/test/tests_sync.py +3 -1
  89. ccxt/vertex.py +2 -0
  90. ccxt/woo.py +69 -69
  91. {ccxt-4.4.32.dist-info → ccxt-4.4.34.dist-info}/METADATA +9 -8
  92. {ccxt-4.4.32.dist-info → ccxt-4.4.34.dist-info}/RECORD +95 -92
  93. {ccxt-4.4.32.dist-info → ccxt-4.4.34.dist-info}/LICENSE.txt +0 -0
  94. {ccxt-4.4.32.dist-info → ccxt-4.4.34.dist-info}/WHEEL +0 -0
  95. {ccxt-4.4.32.dist-info → ccxt-4.4.34.dist-info}/top_level.txt +0 -0
ccxt/bybit.py CHANGED
@@ -11,6 +11,7 @@ from typing import List
11
11
  from ccxt.base.errors import ExchangeError
12
12
  from ccxt.base.errors import AuthenticationError
13
13
  from ccxt.base.errors import PermissionDenied
14
+ from ccxt.base.errors import AccountSuspended
14
15
  from ccxt.base.errors import ArgumentsRequired
15
16
  from ccxt.base.errors import BadRequest
16
17
  from ccxt.base.errors import BadSymbol
@@ -567,7 +568,7 @@ class bybit(Exchange, ImplicitAPI):
567
568
  '10005': PermissionDenied, # permission denied for current apikey
568
569
  '10006': RateLimitExceeded, # too many requests
569
570
  '10007': AuthenticationError, # api_key not found in your request parameters
570
- '10008': AuthenticationError, # User had been banned
571
+ '10008': AccountSuspended, # User had been banned
571
572
  '10009': AuthenticationError, # IP had been banned
572
573
  '10010': PermissionDenied, # request ip mismatch
573
574
  '10014': BadRequest, # Request is duplicate
@@ -1011,7 +1012,7 @@ class bybit(Exchange, ImplicitAPI):
1011
1012
  'enableUnifiedMargin': None,
1012
1013
  'enableUnifiedAccount': None,
1013
1014
  'unifiedMarginStatus': None,
1014
- 'createMarketBuyOrderRequiresPrice': True, # only True for classic accounts
1015
+ 'createMarketBuyOrderRequiresPrice': False, # only True for classic accounts
1015
1016
  'createUnifiedMarginAccount': False,
1016
1017
  'defaultType': 'swap', # 'swap', 'future', 'option', 'spot'
1017
1018
  'defaultSubType': 'linear', # 'linear', 'inverse'
@@ -1071,6 +1072,123 @@ class bybit(Exchange, ImplicitAPI):
1071
1072
  '1d': '1d',
1072
1073
  },
1073
1074
  },
1075
+ 'features': {
1076
+ 'default': {
1077
+ 'sandbox': True,
1078
+ 'createOrder': {
1079
+ 'marginMode': False,
1080
+ 'triggerPrice': True,
1081
+ 'triggerPriceType': {
1082
+ 'last': True,
1083
+ 'mark': True,
1084
+ 'index': True,
1085
+ },
1086
+ 'triggerDirection': True,
1087
+ 'stopLossPrice': True,
1088
+ 'takeProfitPrice': True,
1089
+ 'attachedStopLossTakeProfit': {
1090
+ 'triggerPriceType': {
1091
+ 'last': True,
1092
+ 'mark': True,
1093
+ 'index': True,
1094
+ },
1095
+ 'limitPrice': True,
1096
+ },
1097
+ 'timeInForce': {
1098
+ 'GTC': True,
1099
+ 'IOC': True,
1100
+ 'FOK': True,
1101
+ 'PO': True,
1102
+ 'GTD': False,
1103
+ },
1104
+ 'hedged': True,
1105
+ # exchange-supported features
1106
+ 'selfTradePrevention': True,
1107
+ 'trailing': True,
1108
+ 'twap': False,
1109
+ 'iceberg': False,
1110
+ 'oco': False,
1111
+ },
1112
+ 'createOrders': {
1113
+ 'max': 10,
1114
+ },
1115
+ 'fetchMyTrades': {
1116
+ 'marginMode': False,
1117
+ 'limit': 100,
1118
+ 'daysBack': 365 * 2, # 2 years
1119
+ 'untilDays': 7, # days between start-end
1120
+ },
1121
+ 'fetchOrder': {
1122
+ 'marginMode': False,
1123
+ 'trigger': True,
1124
+ 'trailing': False,
1125
+ },
1126
+ 'fetchOpenOrders': {
1127
+ 'marginMode': False,
1128
+ 'limit': 50,
1129
+ 'trigger': True,
1130
+ 'trailing': False,
1131
+ },
1132
+ 'fetchOrders': None,
1133
+ 'fetchClosedOrders': {
1134
+ 'marginMode': False,
1135
+ 'limit': 50,
1136
+ 'daysBackClosed': 365 * 2, # 2 years
1137
+ 'daysBackCanceled': 1,
1138
+ 'untilDays': 7,
1139
+ 'trigger': True,
1140
+ 'trailing': False,
1141
+ },
1142
+ 'fetchOHLCV': {
1143
+ 'limit': 1000,
1144
+ },
1145
+ },
1146
+ 'spot': {
1147
+ 'extends': 'default',
1148
+ 'createOrder': {
1149
+ 'marginMode': False,
1150
+ 'triggerPrice': True,
1151
+ 'triggerPriceType': None,
1152
+ 'triggerDirection': False,
1153
+ 'stopLossPrice': True,
1154
+ 'takeProfitPrice': True,
1155
+ 'attachedStopLossTakeProfit': {
1156
+ 'triggerPriceType': None,
1157
+ 'limitPrice': True,
1158
+ },
1159
+ 'timeInForce': {
1160
+ 'GTC': True,
1161
+ 'IOC': True,
1162
+ 'FOK': True,
1163
+ 'PO': True,
1164
+ 'GTD': False,
1165
+ },
1166
+ 'hedged': True,
1167
+ # exchange-supported features
1168
+ 'selfTradePrevention': True,
1169
+ 'trailing': True,
1170
+ 'twap': False,
1171
+ 'iceberg': False,
1172
+ 'oco': False,
1173
+ },
1174
+ },
1175
+ 'swap': {
1176
+ 'linear': {
1177
+ 'extends': 'default',
1178
+ },
1179
+ 'inverse': {
1180
+ 'extends': 'default',
1181
+ },
1182
+ },
1183
+ 'future': {
1184
+ 'linear': {
1185
+ 'extends': 'default',
1186
+ },
1187
+ 'inverse': {
1188
+ 'extends': 'default',
1189
+ },
1190
+ },
1191
+ },
1074
1192
  'fees': {
1075
1193
  'trading': {
1076
1194
  'feeSide': 'get',
@@ -1111,7 +1229,7 @@ class bybit(Exchange, ImplicitAPI):
1111
1229
 
1112
1230
  def add_pagination_cursor_to_result(self, response):
1113
1231
  result = self.safe_dict(response, 'result', {})
1114
- data = self.safe_value_n(result, ['list', 'rows', 'data', 'dataList'], [])
1232
+ data = self.safe_list_n(result, ['list', 'rows', 'data', 'dataList'], [])
1115
1233
  paginationCursor = self.safe_string_2(result, 'nextPageCursor', 'cursor')
1116
1234
  dataLength = len(data)
1117
1235
  if (paginationCursor is not None) and (dataLength > 0):
@@ -1122,12 +1240,12 @@ class bybit(Exchange, ImplicitAPI):
1122
1240
 
1123
1241
  def is_unified_enabled(self, params={}):
1124
1242
  """
1125
- :param dict [params]: extra parameters specific to the exchange API endpoint
1126
1243
 
1127
1244
  https://bybit-exchange.github.io/docs/v5/user/apikey-info#http-request
1128
1245
  https://bybit-exchange.github.io/docs/v5/account/account-info
1129
1246
 
1130
1247
  returns [enableUnifiedMargin, enableUnifiedAccount] so the user can check if unified account is enabled
1248
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1131
1249
  :returns any: [enableUnifiedMargin, enableUnifiedAccount]
1132
1250
  """
1133
1251
  # The API key of user id must own one of permissions will be allowed to call following API endpoints.
@@ -2160,6 +2278,7 @@ class bybit(Exchange, ImplicitAPI):
2160
2278
  :param str[] symbols: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
2161
2279
  :param dict [params]: extra parameters specific to the exchange API endpoint
2162
2280
  :param str [params.subType]: *contract only* 'linear', 'inverse'
2281
+ :param str [params.baseCoin]: *option only* base coin, default is 'BTC'
2163
2282
  :returns dict: an array of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
2164
2283
  """
2165
2284
  self.load_markets()
@@ -2201,10 +2320,11 @@ class bybit(Exchange, ImplicitAPI):
2201
2320
  # only if passedSubType is None, then use spot
2202
2321
  if type == 'spot' and passedSubType is None:
2203
2322
  request['category'] = 'spot'
2204
- elif type == 'swap' or type == 'future' or subType is not None:
2205
- request['category'] = subType
2206
2323
  elif type == 'option':
2207
2324
  request['category'] = 'option'
2325
+ request['baseCoin'] = self.safe_string(params, 'baseCoin', 'BTC')
2326
+ elif type == 'swap' or type == 'future' or subType is not None:
2327
+ request['category'] = subType
2208
2328
  response = self.publicGetV5MarketTickers(self.extend(request, params))
2209
2329
  #
2210
2330
  # {
@@ -2991,7 +3111,7 @@ class bybit(Exchange, ImplicitAPI):
2991
3111
  'datetime': self.iso8601(timestamp),
2992
3112
  }
2993
3113
  responseResult = self.safe_dict(response, 'result', {})
2994
- currencyList = self.safe_value_n(responseResult, ['loanAccountList', 'list', 'balance'])
3114
+ currencyList = self.safe_list_n(responseResult, ['loanAccountList', 'list', 'balance'])
2995
3115
  if currencyList is None:
2996
3116
  # usdc wallet
2997
3117
  code = 'USDC'
@@ -3345,11 +3465,17 @@ class bybit(Exchange, ImplicitAPI):
3345
3465
  market = self.safe_market(marketId, market, None, marketType)
3346
3466
  symbol = market['symbol']
3347
3467
  timestamp = self.safe_integer_2(order, 'createdTime', 'createdAt')
3468
+ marketUnit = self.safe_string(order, 'marketUnit', 'baseCoin')
3348
3469
  id = self.safe_string(order, 'orderId')
3349
3470
  type = self.safe_string_lower(order, 'orderType')
3350
3471
  price = self.safe_string(order, 'price')
3351
- amount = self.safe_string(order, 'qty')
3352
- cost = self.safe_string(order, 'cumExecValue')
3472
+ amount: Str = None
3473
+ cost: Str = None
3474
+ if marketUnit == 'baseCoin':
3475
+ amount = self.safe_string(order, 'qty')
3476
+ cost = self.safe_string(order, 'cumExecValue')
3477
+ else:
3478
+ cost = self.safe_string(order, 'cumExecValue')
3353
3479
  filled = self.safe_string(order, 'cumExecQty')
3354
3480
  remaining = self.safe_string(order, 'leavesQty')
3355
3481
  lastTradeTimestamp = self.safe_integer_2(order, 'updatedTime', 'updatedAt')
@@ -3665,7 +3791,7 @@ class bybit(Exchange, ImplicitAPI):
3665
3791
  # classic accounts
3666
3792
  # for market buy it requires the amount of quote currency to spend
3667
3793
  createMarketBuyOrderRequiresPrice = True
3668
- createMarketBuyOrderRequiresPrice, params = self.handle_option_and_params(params, 'createOrder', 'createMarketBuyOrderRequiresPrice', True)
3794
+ createMarketBuyOrderRequiresPrice, params = self.handle_option_and_params(params, 'createOrder', 'createMarketBuyOrderRequiresPrice')
3669
3795
  if createMarketBuyOrderRequiresPrice:
3670
3796
  if (price is None) and (cost is None):
3671
3797
  raise InvalidOrder(self.id + ' createOrder() requires the price argument for market buy orders to calculate the total cost to spend(amount * price), alternatively set the createMarketBuyOrderRequiresPrice option or param to False and pass the cost to spend in the amount argument')
@@ -3674,7 +3800,12 @@ class bybit(Exchange, ImplicitAPI):
3674
3800
  costRequest = cost if (cost is not None) else quoteAmount
3675
3801
  request['qty'] = self.get_cost(symbol, costRequest)
3676
3802
  else:
3677
- request['qty'] = self.get_cost(symbol, self.number_to_string(amount))
3803
+ if cost is not None:
3804
+ request['qty'] = self.get_cost(symbol, self.number_to_string(cost))
3805
+ elif price is not None:
3806
+ request['qty'] = self.get_cost(symbol, Precise.string_mul(amountString, priceString))
3807
+ else:
3808
+ request['qty'] = self.get_cost(symbol, self.number_to_string(amount))
3678
3809
  else:
3679
3810
  if not isTrailingAmountOrder and not isAlternativeEndpoint:
3680
3811
  request['qty'] = amountString
@@ -3750,7 +3881,7 @@ class bybit(Exchange, ImplicitAPI):
3750
3881
  side = self.safe_string(rawOrder, 'side')
3751
3882
  amount = self.safe_value(rawOrder, 'amount')
3752
3883
  price = self.safe_value(rawOrder, 'price')
3753
- orderParams = self.safe_value(rawOrder, 'params', {})
3884
+ orderParams = self.safe_dict(rawOrder, 'params', {})
3754
3885
  orderRequest = self.create_order_request(marketId, type, side, amount, price, orderParams, isUta)
3755
3886
  ordersRequests.append(orderRequest)
3756
3887
  symbols = self.market_symbols(orderSymbols, None, False, True, True)
ccxt/cex.py CHANGED
@@ -9,6 +9,7 @@ import hashlib
9
9
  from ccxt.base.types import Account, Balances, Currencies, Currency, DepositAddress, Int, LedgerEntry, Market, Num, Order, OrderBook, 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
+ from ccxt.base.errors import AuthenticationError
12
13
  from ccxt.base.errors import PermissionDenied
13
14
  from ccxt.base.errors import ArgumentsRequired
14
15
  from ccxt.base.errors import BadRequest
@@ -25,7 +26,7 @@ class cex(Exchange, ImplicitAPI):
25
26
  'id': 'cex',
26
27
  'name': 'CEX.IO',
27
28
  'countries': ['GB', 'EU', 'CY', 'RU'],
28
- 'rateLimit': 1667, # 100 req/min
29
+ 'rateLimit': 300, # 200 req/min
29
30
  'pro': True,
30
31
  'has': {
31
32
  'CORS': None,
@@ -37,6 +38,8 @@ class cex(Exchange, ImplicitAPI):
37
38
  'cancelAllOrders': True,
38
39
  'cancelOrder': True,
39
40
  'createOrder': True,
41
+ 'createStopOrder': True,
42
+ 'createTriggerOrder': True,
40
43
  'fetchAccounts': True,
41
44
  'fetchBalance': True,
42
45
  'fetchClosedOrder': True,
@@ -126,6 +129,7 @@ class cex(Exchange, ImplicitAPI):
126
129
  'Insufficient funds': InsufficientFunds,
127
130
  'Get deposit address for main account is not allowed': PermissionDenied,
128
131
  'Market Trigger orders are not allowed': BadRequest, # for some reason, triggerPrice does not work for market orders
132
+ 'key not passed or incorrect': AuthenticationError,
129
133
  },
130
134
  },
131
135
  'timeframes': {
@@ -836,7 +840,7 @@ class cex(Exchange, ImplicitAPI):
836
840
  code = self.safe_currency_code(key)
837
841
  account: dict = {
838
842
  'used': self.safe_string(balance, 'balanceOnHold'),
839
- 'free': self.safe_string(balance, 'balance'),
843
+ 'total': self.safe_string(balance, 'balance'),
840
844
  }
841
845
  result[code] = account
842
846
  return self.safe_balance(result)
@@ -916,7 +920,7 @@ class cex(Exchange, ImplicitAPI):
916
920
  # },
917
921
  # ...
918
922
  #
919
- data = self.safe_value(response, 'data', [])
923
+ data = self.safe_list(response, 'data', [])
920
924
  return self.parse_orders(data, market, since, limit)
921
925
 
922
926
  def fetch_closed_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
@@ -985,10 +989,16 @@ class cex(Exchange, ImplicitAPI):
985
989
 
986
990
  def parse_order_status(self, status: Str):
987
991
  statuses: dict = {
992
+ 'PENDING_NEW': 'open',
993
+ 'NEW': 'open',
994
+ 'PARTIALLY_FILLED': 'open',
988
995
  'FILLED': 'closed',
996
+ 'EXPIRED': 'expired',
997
+ 'REJECTED': 'rejected',
998
+ 'PENDING_CANCEL': 'canceling',
989
999
  'CANCELLED': 'canceled',
990
1000
  }
991
- return self.safe_string(statuses, status, None)
1001
+ return self.safe_string(statuses, status, status)
992
1002
 
993
1003
  def parse_order(self, order: dict, market: Market = None) -> Order:
994
1004
  #
@@ -1037,7 +1047,7 @@ class cex(Exchange, ImplicitAPI):
1037
1047
  currencyId = self.safe_string(order, 'feeCurrency')
1038
1048
  feeCode = self.safe_currency_code(currencyId)
1039
1049
  fee['currency'] = feeCode
1040
- fee['fee'] = feeAmount
1050
+ fee['cost'] = feeAmount
1041
1051
  timestamp = self.safe_integer(order, 'serverCreateTimestamp')
1042
1052
  requestedBase = self.safe_number(order, 'requestedAmountCcy1')
1043
1053
  executedBase = self.safe_number(order, 'executedAmountCcy1')
@@ -1081,6 +1091,7 @@ class cex(Exchange, ImplicitAPI):
1081
1091
  :param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
1082
1092
  :param dict [params]: extra parameters specific to the exchange API endpoint
1083
1093
  :param str [params.accountId]: account-id to use(default is empty string)
1094
+ :param float [params.triggerPrice]: the price at which a trigger order is triggered at
1084
1095
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1085
1096
  """
1086
1097
  accountId = None
ccxt/coinbase.py CHANGED
@@ -2181,7 +2181,8 @@ class coinbase(Exchange, ImplicitAPI):
2181
2181
 
2182
2182
  :param dict [params]: extra parameters specific to the exchange API endpoint
2183
2183
  :param boolean [params.v3]: default False, set True to use v3 api endpoint
2184
- :param dict [params.type]: "spot"(default) or "swap" or "future"
2184
+ :param str [params.type]: "spot"(default) or "swap" or "future"
2185
+ :param int [params.limit]: default 250, maximum number of accounts to return
2185
2186
  :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
2186
2187
  """
2187
2188
  self.load_markets()
@@ -2198,7 +2199,7 @@ class coinbase(Exchange, ImplicitAPI):
2198
2199
  request['limit'] = 250
2199
2200
  response = self.v3PrivateGetBrokerageAccounts(self.extend(request, params))
2200
2201
  else:
2201
- request['limit'] = 100
2202
+ request['limit'] = 250
2202
2203
  response = self.v2PrivateGetAccounts(self.extend(request, params))
2203
2204
  #
2204
2205
  # v2PrivateGetAccounts
@@ -2310,28 +2311,8 @@ class coinbase(Exchange, ImplicitAPI):
2310
2311
  pagination = self.safe_dict(response, 'pagination', {})
2311
2312
  cursor = self.safe_string(pagination, 'next_starting_after')
2312
2313
  if (cursor is not None) and (cursor != ''):
2313
- lastFee = self.safe_dict(last, 'fee')
2314
- last['next_starting_after'] = cursor
2315
- ledger[lastIndex] = {
2316
- 'info': self.safe_dict(last, 'info'),
2317
- 'id': self.safe_string(last, 'id'),
2318
- 'timestamp': self.safe_integer(last, 'timestamp'),
2319
- 'datetime': self.safe_string(last, 'datetime'),
2320
- 'direction': self.safe_string(last, 'direction'),
2321
- 'account': self.safe_string(last, 'account'),
2322
- 'referenceId': None,
2323
- 'referenceAccount': None,
2324
- 'type': self.safe_string(last, 'type'),
2325
- 'currency': self.safe_string(last, 'currency'),
2326
- 'amount': self.safe_number(last, 'amount'),
2327
- 'before': None,
2328
- 'after': None,
2329
- 'status': self.safe_string(last, 'status'),
2330
- 'fee': {
2331
- 'cost': self.safe_number(lastFee, 'cost'),
2332
- 'currency': self.safe_string(lastFee, 'currency'),
2333
- },
2334
- }
2314
+ last['info']['next_starting_after'] = cursor
2315
+ ledger[lastIndex] = last
2335
2316
  return ledger
2336
2317
 
2337
2318
  def parse_ledger_entry_status(self, status):
ccxt/coinbaseexchange.py CHANGED
@@ -127,7 +127,8 @@ class coinbaseexchange(Exchange, ImplicitAPI):
127
127
  'products/{id}/ticker',
128
128
  'products/{id}/trades',
129
129
  'time',
130
- 'products/spark-lines', # experimental
130
+ 'products/spark-lines', # experimental,
131
+ 'products/volume-summary',
131
132
  ],
132
133
  },
133
134
  'private': {
ccxt/coinex.py CHANGED
@@ -68,6 +68,7 @@ class coinex(Exchange, ImplicitAPI):
68
68
  'createOrders': True,
69
69
  'createReduceOnlyOrder': True,
70
70
  'createStopLossOrder': True,
71
+ 'createStopOrder': True,
71
72
  'createTakeProfitOrder': True,
72
73
  'createTriggerOrder': True,
73
74
  'editOrder': True,
@@ -4574,6 +4575,7 @@ class coinex(Exchange, ImplicitAPI):
4574
4575
  'not_pass': 'failed',
4575
4576
  'cancel': 'canceled',
4576
4577
  'finish': 'ok',
4578
+ 'finished': 'ok',
4577
4579
  'fail': 'failed',
4578
4580
  }
4579
4581
  return self.safe_string(statuses, status, status)
ccxt/coinone.py CHANGED
@@ -240,7 +240,7 @@ class coinone(Exchange, ImplicitAPI):
240
240
  # }
241
241
  #
242
242
  result: dict = {}
243
- currencies = self.safe_value(response, 'currencies', [])
243
+ currencies = self.safe_list(response, 'currencies', [])
244
244
  for i in range(0, len(currencies)):
245
245
  entry = currencies[i]
246
246
  id = self.safe_string(entry, 'symbol')
@@ -320,7 +320,7 @@ class coinone(Exchange, ImplicitAPI):
320
320
  # ]
321
321
  # }
322
322
  #
323
- tickers = self.safe_value(response, 'tickers', [])
323
+ tickers = self.safe_list(response, 'tickers', [])
324
324
  result = []
325
325
  for i in range(0, len(tickers)):
326
326
  entry = self.safe_value(tickers, i)
@@ -570,7 +570,7 @@ class coinone(Exchange, ImplicitAPI):
570
570
  # ]
571
571
  # }
572
572
  #
573
- data = self.safe_value(response, 'tickers', [])
573
+ data = self.safe_list(response, 'tickers', [])
574
574
  ticker = self.safe_dict(data, 0, {})
575
575
  return self.parse_ticker(ticker, market)
576
576
 
@@ -603,8 +603,8 @@ class coinone(Exchange, ImplicitAPI):
603
603
  #
604
604
  timestamp = self.safe_integer(ticker, 'timestamp')
605
605
  last = self.safe_string(ticker, 'last')
606
- asks = self.safe_value(ticker, 'best_asks')
607
- bids = self.safe_value(ticker, 'best_bids')
606
+ asks = self.safe_list(ticker, 'best_asks', [])
607
+ bids = self.safe_list(ticker, 'best_bids', [])
608
608
  baseId = self.safe_string(ticker, 'target_currency')
609
609
  quoteId = self.safe_string(ticker, 'quote_currency')
610
610
  base = self.safe_currency_code(baseId)
@@ -658,7 +658,7 @@ class coinone(Exchange, ImplicitAPI):
658
658
  #
659
659
  timestamp = self.safe_integer(trade, 'timestamp')
660
660
  market = self.safe_market(None, market)
661
- isSellerMaker = self.safe_value(trade, 'is_seller_maker')
661
+ isSellerMaker = self.safe_bool(trade, 'is_seller_maker')
662
662
  side = None
663
663
  if isSellerMaker is not None:
664
664
  side = 'sell' if isSellerMaker else 'buy'
@@ -1063,7 +1063,7 @@ class coinone(Exchange, ImplicitAPI):
1063
1063
  # }
1064
1064
  # }
1065
1065
  #
1066
- walletAddress = self.safe_value(response, 'walletAddress', {})
1066
+ walletAddress = self.safe_dict(response, 'walletAddress', {})
1067
1067
  keys = list(walletAddress.keys())
1068
1068
  result: dict = {}
1069
1069
  for i in range(0, len(keys)):
ccxt/coinsph.py CHANGED
@@ -555,7 +555,7 @@ class coinsph(Exchange, ImplicitAPI):
555
555
  # ]
556
556
  # }
557
557
  #
558
- markets = self.safe_value(response, 'symbols')
558
+ markets = self.safe_list(response, 'symbols', [])
559
559
  result = []
560
560
  for i in range(0, len(markets)):
561
561
  market = markets[i]
@@ -564,7 +564,7 @@ class coinsph(Exchange, ImplicitAPI):
564
564
  quoteId = self.safe_string(market, 'quoteAsset')
565
565
  base = self.safe_currency_code(baseId)
566
566
  quote = self.safe_currency_code(quoteId)
567
- limits = self.index_by(self.safe_value(market, 'filters'), 'filterType')
567
+ limits = self.index_by(self.safe_list(market, 'filters', []), 'filterType')
568
568
  amountLimits = self.safe_value(limits, 'LOT_SIZE', {})
569
569
  priceLimits = self.safe_value(limits, 'PRICE_FILTER', {})
570
570
  costLimits = self.safe_value(limits, 'NOTIONAL', {})
@@ -644,7 +644,7 @@ class coinsph(Exchange, ImplicitAPI):
644
644
  ids.append(id)
645
645
  request['symbols'] = ids
646
646
  defaultMethod = 'publicGetOpenapiQuoteV1Ticker24hr'
647
- options = self.safe_value(self.options, 'fetchTickers', {})
647
+ options = self.safe_dict(self.options, 'fetchTickers', {})
648
648
  method = self.safe_string(options, 'method', defaultMethod)
649
649
  tickers = None
650
650
  if method == 'publicGetOpenapiQuoteV1TickerPrice':
@@ -673,7 +673,7 @@ class coinsph(Exchange, ImplicitAPI):
673
673
  'symbol': market['id'],
674
674
  }
675
675
  defaultMethod = 'publicGetOpenapiQuoteV1Ticker24hr'
676
- options = self.safe_value(self.options, 'fetchTicker', {})
676
+ options = self.safe_dict(self.options, 'fetchTicker', {})
677
677
  method = self.safe_string(options, 'method', defaultMethod)
678
678
  ticker = None
679
679
  if method == 'publicGetOpenapiQuoteV1TickerPrice':
@@ -1002,7 +1002,7 @@ class coinsph(Exchange, ImplicitAPI):
1002
1002
  'cost': feeCost,
1003
1003
  'currency': self.safe_currency_code(feeCurrencyId),
1004
1004
  }
1005
- isBuyer = self.safe_value_2(trade, 'isBuyer', 'isBuyerMaker', None)
1005
+ isBuyer = self.safe_bool_2(trade, 'isBuyer', 'isBuyerMaker', None)
1006
1006
  side = None
1007
1007
  if isBuyer is not None:
1008
1008
  side = 'buy' if (isBuyer is True) else 'sell'
@@ -1064,7 +1064,7 @@ class coinsph(Exchange, ImplicitAPI):
1064
1064
  return self.parse_balance(response)
1065
1065
 
1066
1066
  def parse_balance(self, response) -> Balances:
1067
- balances = self.safe_value(response, 'balances', [])
1067
+ balances = self.safe_list(response, 'balances', [])
1068
1068
  result: dict = {
1069
1069
  'info': response,
1070
1070
  'timestamp': None,
@@ -1484,7 +1484,7 @@ class coinsph(Exchange, ImplicitAPI):
1484
1484
  # }
1485
1485
  # ]
1486
1486
  #
1487
- tradingFee = self.safe_value(response, 0, {})
1487
+ tradingFee = self.safe_dict(response, 0, {})
1488
1488
  return self.parse_trading_fee(tradingFee, market)
1489
1489
 
1490
1490
  def fetch_trading_fees(self, params={}) -> TradingFees:
ccxt/coinspot.py CHANGED
@@ -270,7 +270,7 @@ class coinspot(Exchange, ImplicitAPI):
270
270
  response = self.publicGetLatest(params)
271
271
  id = market['id']
272
272
  id = id.lower()
273
- prices = self.safe_value(response, 'prices')
273
+ prices = self.safe_dict(response, 'prices', {})
274
274
  #
275
275
  # {
276
276
  # "status":"ok",
@@ -301,22 +301,22 @@ class coinspot(Exchange, ImplicitAPI):
301
301
  #
302
302
  # {
303
303
  # "status": "ok",
304
- # "prices": {
305
- # "btc": {
306
- # "bid": "25050",
307
- # "ask": "25370",
308
- # "last": "25234"
309
- # },
310
- # "ltc": {
311
- # "bid": "79.39192993",
312
- # "ask": "87.98",
313
- # "last": "87.95"
304
+ # "prices": {
305
+ # "btc": {
306
+ # "bid": "25050",
307
+ # "ask": "25370",
308
+ # "last": "25234"
309
+ # },
310
+ # "ltc": {
311
+ # "bid": "79.39192993",
312
+ # "ask": "87.98",
313
+ # "last": "87.95"
314
+ # }
314
315
  # }
315
- # }
316
316
  # }
317
317
  #
318
318
  result: dict = {}
319
- prices = self.safe_value(response, 'prices')
319
+ prices = self.safe_dict(response, 'prices', {})
320
320
  ids = list(prices.keys())
321
321
  for i in range(0, len(ids)):
322
322
  id = ids[i]
@@ -377,35 +377,35 @@ class coinspot(Exchange, ImplicitAPI):
377
377
  request['startdate'] = self.yyyymmdd(since)
378
378
  response = self.privatePostRoMyTransactions(self.extend(request, params))
379
379
  # {
380
- # "status": "ok",
381
- # "buyorders": [
382
- # {
383
- # "otc": False,
384
- # "market": "ALGO/AUD",
385
- # "amount": 386.95197925,
386
- # "created": "2022-10-20T09:56:44.502Z",
387
- # "audfeeExGst": 1.80018002,
388
- # "audGst": 0.180018,
389
- # "audtotal": 200
390
- # },
391
- # ],
392
- # "sellorders": [
393
- # {
394
- # "otc": False,
395
- # "market": "SOLO/ALGO",
396
- # "amount": 154.52345614,
397
- # "total": 115.78858204658796,
398
- # "created": "2022-04-16T09:36:43.698Z",
399
- # "audfeeExGst": 1.08995731,
400
- # "audGst": 0.10899573,
401
- # "audtotal": 118.7
402
- # },
403
- # ]
380
+ # "status": "ok",
381
+ # "buyorders": [
382
+ # {
383
+ # "otc": False,
384
+ # "market": "ALGO/AUD",
385
+ # "amount": 386.95197925,
386
+ # "created": "2022-10-20T09:56:44.502Z",
387
+ # "audfeeExGst": 1.80018002,
388
+ # "audGst": 0.180018,
389
+ # "audtotal": 200
390
+ # },
391
+ # ],
392
+ # "sellorders": [
393
+ # {
394
+ # "otc": False,
395
+ # "market": "SOLO/ALGO",
396
+ # "amount": 154.52345614,
397
+ # "total": 115.78858204658796,
398
+ # "created": "2022-04-16T09:36:43.698Z",
399
+ # "audfeeExGst": 1.08995731,
400
+ # "audGst": 0.10899573,
401
+ # "audtotal": 118.7
402
+ # },
403
+ # ]
404
404
  # }
405
- buyTrades = self.safe_value(response, 'buyorders', [])
405
+ buyTrades = self.safe_list(response, 'buyorders', [])
406
406
  for i in range(0, len(buyTrades)):
407
407
  buyTrades[i]['side'] = 'buy'
408
- sellTrades = self.safe_value(response, 'sellorders', [])
408
+ sellTrades = self.safe_list(response, 'sellorders', [])
409
409
  for i in range(0, len(sellTrades)):
410
410
  sellTrades[i]['side'] = 'sell'
411
411
  trades = self.array_concat(buyTrades, sellTrades)