ccxt 4.2.76__py2.py3-none-any.whl → 4.2.78__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 (57) hide show
  1. ccxt/__init__.py +1 -1
  2. ccxt/abstract/kucoin.py +1 -0
  3. ccxt/abstract/kucoinfutures.py +1 -0
  4. ccxt/async_support/__init__.py +1 -1
  5. ccxt/async_support/base/exchange.py +1 -1
  6. ccxt/async_support/binance.py +503 -444
  7. ccxt/async_support/bingx.py +1 -1
  8. ccxt/async_support/bitflyer.py +2 -2
  9. ccxt/async_support/bithumb.py +2 -2
  10. ccxt/async_support/blofin.py +11 -2
  11. ccxt/async_support/bybit.py +88 -52
  12. ccxt/async_support/coinbase.py +21 -10
  13. ccxt/async_support/delta.py +65 -51
  14. ccxt/async_support/deribit.py +2 -2
  15. ccxt/async_support/gate.py +3 -2
  16. ccxt/async_support/htx.py +34 -27
  17. ccxt/async_support/hyperliquid.py +7 -5
  18. ccxt/async_support/kraken.py +8 -8
  19. ccxt/async_support/kucoin.py +192 -5
  20. ccxt/async_support/okcoin.py +27 -1
  21. ccxt/async_support/okx.py +20 -2
  22. ccxt/async_support/woo.py +62 -3
  23. ccxt/base/exchange.py +9 -4
  24. ccxt/binance.py +503 -444
  25. ccxt/bingx.py +1 -1
  26. ccxt/bitflyer.py +2 -2
  27. ccxt/bithumb.py +2 -2
  28. ccxt/blofin.py +11 -2
  29. ccxt/bybit.py +88 -52
  30. ccxt/coinbase.py +21 -10
  31. ccxt/delta.py +65 -51
  32. ccxt/deribit.py +2 -2
  33. ccxt/gate.py +3 -2
  34. ccxt/htx.py +34 -27
  35. ccxt/hyperliquid.py +7 -5
  36. ccxt/kraken.py +8 -8
  37. ccxt/kucoin.py +192 -5
  38. ccxt/okcoin.py +27 -1
  39. ccxt/okx.py +20 -2
  40. ccxt/pro/__init__.py +1 -1
  41. ccxt/pro/ascendex.py +1 -1
  42. ccxt/pro/bitvavo.py +1 -1
  43. ccxt/pro/coinex.py +20 -14
  44. ccxt/pro/deribit.py +1 -1
  45. ccxt/pro/exmo.py +1 -1
  46. ccxt/pro/krakenfutures.py +1 -1
  47. ccxt/pro/phemex.py +1 -1
  48. ccxt/pro/poloniex.py +1 -1
  49. ccxt/pro/probit.py +1 -1
  50. ccxt/pro/woo.py +50 -6
  51. ccxt/test/test_async.py +9 -16
  52. ccxt/test/test_sync.py +9 -16
  53. ccxt/woo.py +62 -3
  54. {ccxt-4.2.76.dist-info → ccxt-4.2.78.dist-info}/METADATA +4 -4
  55. {ccxt-4.2.76.dist-info → ccxt-4.2.78.dist-info}/RECORD +57 -57
  56. {ccxt-4.2.76.dist-info → ccxt-4.2.78.dist-info}/WHEEL +0 -0
  57. {ccxt-4.2.76.dist-info → ccxt-4.2.78.dist-info}/top_level.txt +0 -0
@@ -2324,7 +2324,7 @@ class bingx(Exchange, ImplicitAPI):
2324
2324
  'FILLED': 'closed',
2325
2325
  'CANCELED': 'canceled',
2326
2326
  'CANCELLED': 'canceled',
2327
- 'FAILED': 'failed',
2327
+ 'FAILED': 'canceled',
2328
2328
  }
2329
2329
  return self.safe_string(statuses, status, status)
2330
2330
 
@@ -6,7 +6,7 @@
6
6
  from ccxt.async_support.base.exchange import Exchange
7
7
  from ccxt.abstract.bitflyer import ImplicitAPI
8
8
  import hashlib
9
- from ccxt.base.types import Balances, Currency, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Trade, Transaction
9
+ from ccxt.base.types import Balances, Currency, Int, Market, MarketInterface, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Trade, Transaction
10
10
  from typing import List
11
11
  from ccxt.base.errors import ExchangeError
12
12
  from ccxt.base.errors import ArgumentsRequired
@@ -141,7 +141,7 @@ class bitflyer(Exchange, ImplicitAPI):
141
141
  month = self.safe_string(months, monthName)
142
142
  return self.parse8601(year + '-' + month + '-' + day + 'T00:00:00Z')
143
143
 
144
- def safe_market(self, marketId=None, market=None, delimiter=None, marketType=None):
144
+ def safe_market(self, marketId: Str = None, market: Market = None, delimiter: Str = None, marketType: Str = None) -> MarketInterface:
145
145
  # Bitflyer has a different type of conflict in markets, because
146
146
  # some of their ids(ETH/BTC and BTC/JPY) are duplicated in US, EU and JP.
147
147
  # Since they're the same we just need to return one
@@ -6,7 +6,7 @@
6
6
  from ccxt.async_support.base.exchange import Exchange
7
7
  from ccxt.abstract.bithumb 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, MarketInterface, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction
10
10
  from typing import List
11
11
  from ccxt.base.errors import ExchangeError
12
12
  from ccxt.base.errors import PermissionDenied
@@ -189,7 +189,7 @@ class bithumb(Exchange, ImplicitAPI):
189
189
  },
190
190
  })
191
191
 
192
- def safe_market(self, marketId=None, market=None, delimiter=None, marketType=None):
192
+ def safe_market(self, marketId: Str = None, market: Market = None, delimiter: Str = None, marketType: Str = None) -> MarketInterface:
193
193
  # bithumb has a different type of conflict in markets, because
194
194
  # their ids are the base currency(BTC for instance), so we can have
195
195
  # multiple "BTC" ids representing the different markets(BTC/ETH, "BTC/DOGE", etc)
@@ -1194,6 +1194,7 @@ class blofin(Exchange, ImplicitAPI):
1194
1194
  :param str id: order id
1195
1195
  :param str symbol: unified symbol of the market the order was made in
1196
1196
  :param dict [params]: extra parameters specific to the exchange API endpoint
1197
+ :param boolean [params.trigger]: True if cancelling a trigger/conditional order/tp sl orders
1197
1198
  :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1198
1199
  """
1199
1200
  if symbol is None:
@@ -1203,12 +1204,20 @@ class blofin(Exchange, ImplicitAPI):
1203
1204
  request = {
1204
1205
  'instId': market['id'],
1205
1206
  }
1207
+ isTrigger = self.safe_bool_n(params, ['stop', 'trigger', 'tpsl'], False)
1206
1208
  clientOrderId = self.safe_string(params, 'clientOrderId')
1207
1209
  if clientOrderId is not None:
1208
1210
  request['clientOrderId'] = clientOrderId
1209
1211
  else:
1210
- request['orderId'] = id
1211
- query = self.omit(params, ['orderId', 'clientOrderId'])
1212
+ if not isTrigger:
1213
+ request['orderId'] = str(id)
1214
+ else:
1215
+ request['tpslId'] = str(id)
1216
+ query = self.omit(params, ['orderId', 'clientOrderId', 'stop', 'trigger', 'tpsl'])
1217
+ if isTrigger:
1218
+ tpslResponse = await self.cancel_orders([id], symbol, params)
1219
+ first = self.safe_dict(tpslResponse, 0)
1220
+ return first
1212
1221
  response = await self.privatePostTradeCancelOrder(self.extend(request, query))
1213
1222
  data = self.safe_list(response, 'data', [])
1214
1223
  order = self.safe_dict(data, 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, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry
10
+ from ccxt.base.types import Balances, Currency, Greeks, Int, Leverage, Market, MarketInterface, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry
11
11
  from typing import List
12
12
  from ccxt.base.errors import ExchangeError
13
13
  from ccxt.base.errors import PermissionDenied
@@ -978,6 +978,9 @@ class bybit(Exchange, ImplicitAPI):
978
978
  'precisionMode': TICK_SIZE,
979
979
  'options': {
980
980
  'fetchMarkets': ['spot', 'linear', 'inverse', 'option'],
981
+ 'createOrder': {
982
+ 'method': 'privatePostV5OrderCreate', # 'privatePostV5PositionTradingStop'
983
+ },
981
984
  'enableUnifiedMargin': None,
982
985
  'enableUnifiedAccount': None,
983
986
  'createMarketBuyOrderRequiresPrice': True, # only True for classic accounts
@@ -1254,7 +1257,7 @@ class bybit(Exchange, ImplicitAPI):
1254
1257
  'info': None,
1255
1258
  }
1256
1259
 
1257
- def safe_market(self, marketId=None, market=None, delimiter=None, marketType=None):
1260
+ def safe_market(self, marketId: Str = None, market: Market = None, delimiter: Str = None, marketType: Str = None) -> MarketInterface:
1258
1261
  isOption = (marketId is not None) and ((marketId.find('-C') > -1) or (marketId.find('-P') > -1))
1259
1262
  if isOption and not (marketId in self.markets_by_id):
1260
1263
  # handle expired option contracts
@@ -3357,8 +3360,10 @@ class bybit(Exchange, ImplicitAPI):
3357
3360
  trailingAmount = self.safe_string_2(params, 'trailingAmount', 'trailingStop')
3358
3361
  isTrailingAmountOrder = trailingAmount is not None
3359
3362
  orderRequest = self.create_order_request(symbol, type, side, amount, price, params, enableUnifiedAccount)
3363
+ options = self.safe_value(self.options, 'createOrder', {})
3364
+ defaultMethod = self.safe_string(options, 'method', 'privatePostV5OrderCreate')
3360
3365
  response = None
3361
- if isTrailingAmountOrder:
3366
+ if isTrailingAmountOrder or (defaultMethod == 'privatePostV5PositionTradingStop'):
3362
3367
  response = await self.privatePostV5PositionTradingStop(orderRequest)
3363
3368
  else:
3364
3369
  response = await self.privatePostV5OrderCreate(orderRequest) # already extended inside createOrderRequest
@@ -3383,10 +3388,12 @@ class bybit(Exchange, ImplicitAPI):
3383
3388
  lowerCaseType = type.lower()
3384
3389
  if (price is None) and (lowerCaseType == 'limit'):
3385
3390
  raise ArgumentsRequired(self.id + ' createOrder requires a price argument for limit orders')
3391
+ defaultMethod = None
3392
+ defaultMethod, params = self.handle_option_and_params(params, 'createOrder', 'method', 'privatePostV5OrderCreate')
3386
3393
  request = {
3387
3394
  'symbol': market['id'],
3388
- 'side': self.capitalize(side),
3389
- 'orderType': self.capitalize(lowerCaseType), # limit or market
3395
+ # 'side': self.capitalize(side),
3396
+ # 'orderType': self.capitalize(lowerCaseType), # limit or market
3390
3397
  # 'timeInForce': 'GTC', # IOC, FOK, PostOnly
3391
3398
  # 'takeProfit': 123.45, # take profit price, only take effect upon opening the position
3392
3399
  # 'stopLoss': 123.45, # stop loss price, only take effect upon opening the position
@@ -3408,6 +3415,69 @@ class bybit(Exchange, ImplicitAPI):
3408
3415
  # Valid for option only.
3409
3416
  # 'orderIv': '0', # Implied volatility; parameters are passed according to the real value; for example, for 10%, 0.1 is passed
3410
3417
  }
3418
+ triggerPrice = self.safe_value_2(params, 'triggerPrice', 'stopPrice')
3419
+ stopLossTriggerPrice = self.safe_value(params, 'stopLossPrice')
3420
+ takeProfitTriggerPrice = self.safe_value(params, 'takeProfitPrice')
3421
+ stopLoss = self.safe_value(params, 'stopLoss')
3422
+ takeProfit = self.safe_value(params, 'takeProfit')
3423
+ trailingTriggerPrice = self.safe_string_2(params, 'trailingTriggerPrice', 'activePrice', self.number_to_string(price))
3424
+ trailingAmount = self.safe_string_2(params, 'trailingAmount', 'trailingStop')
3425
+ isTrailingAmountOrder = trailingAmount is not None
3426
+ isTriggerOrder = triggerPrice is not None
3427
+ isStopLossTriggerOrder = stopLossTriggerPrice is not None
3428
+ isTakeProfitTriggerOrder = takeProfitTriggerPrice is not None
3429
+ isStopLoss = stopLoss is not None
3430
+ isTakeProfit = takeProfit is not None
3431
+ isMarket = lowerCaseType == 'market'
3432
+ isLimit = lowerCaseType == 'limit'
3433
+ isBuy = side == 'buy'
3434
+ isAlternativeEndpoint = defaultMethod == 'privatePostV5PositionTradingStop'
3435
+ if isTrailingAmountOrder or isAlternativeEndpoint:
3436
+ if isStopLoss or isTakeProfit or isTriggerOrder or market['spot']:
3437
+ raise InvalidOrder(self.id + ' the API endpoint used only supports contract trailingAmount, stopLossPrice and takeProfitPrice orders')
3438
+ if isStopLossTriggerOrder or isTakeProfitTriggerOrder:
3439
+ if isStopLossTriggerOrder:
3440
+ request['stopLoss'] = self.price_to_precision(symbol, stopLossTriggerPrice)
3441
+ if isLimit:
3442
+ request['tpslMode'] = 'Partial'
3443
+ request['slOrderType'] = 'Limit'
3444
+ request['slLimitPrice'] = self.price_to_precision(symbol, price)
3445
+ request['slSize'] = self.amount_to_precision(symbol, amount)
3446
+ elif isTakeProfitTriggerOrder:
3447
+ request['takeProfit'] = self.price_to_precision(symbol, takeProfitTriggerPrice)
3448
+ if isLimit:
3449
+ request['tpslMode'] = 'Partial'
3450
+ request['tpOrderType'] = 'Limit'
3451
+ request['tpLimitPrice'] = self.price_to_precision(symbol, price)
3452
+ request['tpSize'] = self.amount_to_precision(symbol, amount)
3453
+ else:
3454
+ request['side'] = self.capitalize(side)
3455
+ request['orderType'] = self.capitalize(lowerCaseType)
3456
+ timeInForce = self.safe_string_lower(params, 'timeInForce') # self is same specific param
3457
+ postOnly = None
3458
+ postOnly, params = self.handle_post_only(isMarket, timeInForce == 'postonly', params)
3459
+ if postOnly:
3460
+ request['timeInForce'] = 'PostOnly'
3461
+ elif timeInForce == 'gtc':
3462
+ request['timeInForce'] = 'GTC'
3463
+ elif timeInForce == 'fok':
3464
+ request['timeInForce'] = 'FOK'
3465
+ elif timeInForce == 'ioc':
3466
+ request['timeInForce'] = 'IOC'
3467
+ if market['spot']:
3468
+ # only works for spot market
3469
+ if triggerPrice is not None:
3470
+ request['orderFilter'] = 'StopOrder'
3471
+ elif stopLossTriggerPrice is not None or takeProfitTriggerPrice is not None or isStopLoss or isTakeProfit:
3472
+ request['orderFilter'] = 'tpslOrder'
3473
+ clientOrderId = self.safe_string(params, 'clientOrderId')
3474
+ if clientOrderId is not None:
3475
+ request['orderLinkId'] = clientOrderId
3476
+ elif market['option']:
3477
+ # mandatory field for options
3478
+ request['orderLinkId'] = self.uuid16()
3479
+ if isLimit:
3480
+ request['price'] = self.price_to_precision(symbol, price)
3411
3481
  if market['spot']:
3412
3482
  request['category'] = 'spot'
3413
3483
  elif market['linear']:
@@ -3453,40 +3523,13 @@ class bybit(Exchange, ImplicitAPI):
3453
3523
  else:
3454
3524
  request['qty'] = self.cost_to_precision(symbol, amount)
3455
3525
  else:
3456
- request['qty'] = self.amount_to_precision(symbol, amount)
3457
- isMarket = lowerCaseType == 'market'
3458
- isLimit = lowerCaseType == 'limit'
3459
- if isLimit:
3460
- request['price'] = self.price_to_precision(symbol, price)
3461
- timeInForce = self.safe_string_lower(params, 'timeInForce') # self is same specific param
3462
- postOnly = None
3463
- postOnly, params = self.handle_post_only(isMarket, timeInForce == 'postonly', params)
3464
- if postOnly:
3465
- request['timeInForce'] = 'PostOnly'
3466
- elif timeInForce == 'gtc':
3467
- request['timeInForce'] = 'GTC'
3468
- elif timeInForce == 'fok':
3469
- request['timeInForce'] = 'FOK'
3470
- elif timeInForce == 'ioc':
3471
- request['timeInForce'] = 'IOC'
3472
- triggerPrice = self.safe_value_2(params, 'triggerPrice', 'stopPrice')
3473
- stopLossTriggerPrice = self.safe_value(params, 'stopLossPrice')
3474
- takeProfitTriggerPrice = self.safe_value(params, 'takeProfitPrice')
3475
- stopLoss = self.safe_value(params, 'stopLoss')
3476
- takeProfit = self.safe_value(params, 'takeProfit')
3477
- trailingTriggerPrice = self.safe_string_2(params, 'trailingTriggerPrice', 'activePrice', self.number_to_string(price))
3478
- trailingAmount = self.safe_string_2(params, 'trailingAmount', 'trailingStop')
3479
- isTrailingAmountOrder = trailingAmount is not None
3480
- isStopLossTriggerOrder = stopLossTriggerPrice is not None
3481
- isTakeProfitTriggerOrder = takeProfitTriggerPrice is not None
3482
- isStopLoss = stopLoss is not None
3483
- isTakeProfit = takeProfit is not None
3484
- isBuy = side == 'buy'
3526
+ if not isTrailingAmountOrder and not isAlternativeEndpoint:
3527
+ request['qty'] = self.amount_to_precision(symbol, amount)
3485
3528
  if isTrailingAmountOrder:
3486
3529
  if trailingTriggerPrice is not None:
3487
3530
  request['activePrice'] = self.price_to_precision(symbol, trailingTriggerPrice)
3488
3531
  request['trailingStop'] = trailingAmount
3489
- elif triggerPrice is not None:
3532
+ elif isTriggerOrder and not isAlternativeEndpoint:
3490
3533
  triggerDirection = self.safe_string(params, 'triggerDirection')
3491
3534
  params = self.omit(params, ['triggerPrice', 'stopPrice', 'triggerDirection'])
3492
3535
  if market['spot']:
@@ -3498,7 +3541,7 @@ class bybit(Exchange, ImplicitAPI):
3498
3541
  isAsending = ((triggerDirection == 'above') or (triggerDirection == '1'))
3499
3542
  request['triggerDirection'] = 1 if isAsending else 2
3500
3543
  request['triggerPrice'] = self.price_to_precision(symbol, triggerPrice)
3501
- elif isStopLossTriggerOrder or isTakeProfitTriggerOrder:
3544
+ elif (isStopLossTriggerOrder or isTakeProfitTriggerOrder) and not isAlternativeEndpoint:
3502
3545
  if isBuy:
3503
3546
  request['triggerDirection'] = 1 if isStopLossTriggerOrder else 2
3504
3547
  else:
@@ -3506,7 +3549,7 @@ class bybit(Exchange, ImplicitAPI):
3506
3549
  triggerPrice = stopLossTriggerPrice if isStopLossTriggerOrder else takeProfitTriggerPrice
3507
3550
  request['triggerPrice'] = self.price_to_precision(symbol, triggerPrice)
3508
3551
  request['reduceOnly'] = True
3509
- if isStopLoss or isTakeProfit:
3552
+ if (isStopLoss or isTakeProfit) and not isAlternativeEndpoint:
3510
3553
  if isStopLoss:
3511
3554
  slTriggerPrice = self.safe_value_2(stopLoss, 'triggerPrice', 'stopPrice', stopLoss)
3512
3555
  request['stopLoss'] = self.price_to_precision(symbol, slTriggerPrice)
@@ -3523,18 +3566,6 @@ class bybit(Exchange, ImplicitAPI):
3523
3566
  request['tpslMode'] = 'Partial'
3524
3567
  request['tpOrderType'] = 'Limit'
3525
3568
  request['tpLimitPrice'] = self.price_to_precision(symbol, tpLimitPrice)
3526
- if market['spot']:
3527
- # only works for spot market
3528
- if triggerPrice is not None:
3529
- request['orderFilter'] = 'StopOrder'
3530
- elif stopLossTriggerPrice is not None or takeProfitTriggerPrice is not None or isStopLoss or isTakeProfit:
3531
- request['orderFilter'] = 'tpslOrder'
3532
- clientOrderId = self.safe_string(params, 'clientOrderId')
3533
- if clientOrderId is not None:
3534
- request['orderLinkId'] = clientOrderId
3535
- elif market['option']:
3536
- # mandatory field for options
3537
- request['orderLinkId'] = self.uuid16()
3538
3569
  params = self.omit(params, ['stopPrice', 'timeInForce', 'stopLossPrice', 'takeProfitPrice', 'postOnly', 'clientOrderId', 'triggerPrice', 'stopLoss', 'takeProfit', 'trailingAmount', 'trailingTriggerPrice'])
3539
3570
  return self.extend(request, params)
3540
3571
 
@@ -4848,7 +4879,9 @@ class bybit(Exchange, ImplicitAPI):
4848
4879
  return await self.fetch_paginated_call_cursor('fetchMyTrades', symbol, since, limit, params, 'nextPageCursor', 'cursor', None, 100)
4849
4880
  enableUnifiedMargin, enableUnifiedAccount = await self.is_unified_enabled()
4850
4881
  isUnifiedAccount = (enableUnifiedMargin or enableUnifiedAccount)
4851
- request = {}
4882
+ request = {
4883
+ 'execType': 'Trade',
4884
+ }
4852
4885
  market = None
4853
4886
  isUsdcSettled = False
4854
4887
  if symbol is not None:
@@ -7493,11 +7526,14 @@ class bybit(Exchange, ImplicitAPI):
7493
7526
  tier = info[i]
7494
7527
  marketId = self.safe_string(info, 'symbol')
7495
7528
  market = self.safe_market(marketId)
7529
+ minNotional = self.parse_number('0')
7530
+ if i != 0:
7531
+ minNotional = self.safe_number(info[i - 1], 'riskLimitValue')
7496
7532
  tiers.append({
7497
7533
  'tier': self.safe_integer(tier, 'id'),
7498
7534
  'currency': market['settle'],
7499
- 'minNotional': None,
7500
- 'maxNotional': None,
7535
+ 'minNotional': minNotional,
7536
+ 'maxNotional': self.safe_number(tier, 'riskLimitValue'),
7501
7537
  'maintenanceMarginRate': self.safe_number(tier, 'maintenanceMargin'),
7502
7538
  'maxLeverage': self.safe_number(tier, 'maxLeverage'),
7503
7539
  'info': tier,
@@ -1041,7 +1041,9 @@ class coinbase(Exchange, ImplicitAPI):
1041
1041
  :returns dict[]: an array of objects representing market data
1042
1042
  """
1043
1043
  method = self.safe_string(self.options, 'fetchMarkets', 'fetchMarketsV3')
1044
- return await getattr(self, method)(params)
1044
+ if method == 'fetchMarketsV3':
1045
+ return await self.fetch_markets_v3(params)
1046
+ return await self.fetch_markets_v2(params)
1045
1047
 
1046
1048
  async def fetch_markets_v2(self, params={}):
1047
1049
  response = await self.fetch_currencies_from_cache(params)
@@ -1113,7 +1115,13 @@ class coinbase(Exchange, ImplicitAPI):
1113
1115
  return result
1114
1116
 
1115
1117
  async def fetch_markets_v3(self, params={}):
1116
- response = await self.v3PrivateGetBrokerageProducts(params)
1118
+ promisesUnresolved = [
1119
+ self.v3PrivateGetBrokerageProducts(params),
1120
+ self.v3PrivateGetBrokerageTransactionSummary(params),
1121
+ ]
1122
+ # response = await self.v3PrivateGetBrokerageProducts(params)
1123
+ promises = await asyncio.gather(*promisesUnresolved)
1124
+ response = self.safe_dict(promises, 0, {})
1117
1125
  #
1118
1126
  # [
1119
1127
  # {
@@ -1148,7 +1156,8 @@ class coinbase(Exchange, ImplicitAPI):
1148
1156
  # ...
1149
1157
  # ]
1150
1158
  #
1151
- fees = await self.v3PrivateGetBrokerageTransactionSummary(params)
1159
+ # fees = await self.v3PrivateGetBrokerageTransactionSummary(params)
1160
+ fees = self.safe_dict(promises, 1, {})
1152
1161
  #
1153
1162
  # {
1154
1163
  # "total_volume": 0,
@@ -1832,6 +1841,8 @@ class coinbase(Exchange, ImplicitAPI):
1832
1841
  response = await self.v2PrivateGetAccountsAccountIdTransactions(self.extend(request, params))
1833
1842
  ledger = self.parse_ledger(response['data'], currency, since, limit)
1834
1843
  length = len(ledger)
1844
+ if length == 0:
1845
+ return ledger
1835
1846
  lastIndex = length - 1
1836
1847
  last = self.safe_dict(ledger, lastIndex)
1837
1848
  pagination = self.safe_dict(response, 'pagination', {})
@@ -2165,9 +2176,9 @@ class coinbase(Exchange, ImplicitAPI):
2165
2176
  'fee': fee,
2166
2177
  }
2167
2178
 
2168
- async def find_account_id(self, code):
2179
+ async def find_account_id(self, code, params={}):
2169
2180
  await self.load_markets()
2170
- await self.load_accounts()
2181
+ await self.load_accounts(False, params)
2171
2182
  for i in range(0, len(self.accounts)):
2172
2183
  account = self.accounts[i]
2173
2184
  if account['code'] == code:
@@ -2191,7 +2202,7 @@ class coinbase(Exchange, ImplicitAPI):
2191
2202
  if accountId is None:
2192
2203
  if code is None:
2193
2204
  raise ArgumentsRequired(self.id + ' prepareAccountRequestWithCurrencyCode() method requires an account_id(or accountId) parameter OR a currency code argument')
2194
- accountId = await self.find_account_id(code)
2205
+ accountId = await self.find_account_id(code, params)
2195
2206
  if accountId is None:
2196
2207
  raise ExchangeError(self.id + ' prepareAccountRequestWithCurrencyCode() could not find account id for ' + code)
2197
2208
  request = {
@@ -2744,7 +2755,7 @@ class coinbase(Exchange, ImplicitAPI):
2744
2755
  paginate = False
2745
2756
  paginate, params = self.handle_option_and_params(params, 'fetchOrders', 'paginate')
2746
2757
  if paginate:
2747
- return await self.fetch_paginated_call_cursor('fetchOrders', symbol, since, limit, params, 'cursor', 'cursor', None, 100)
2758
+ return await self.fetch_paginated_call_cursor('fetchOrders', symbol, since, limit, params, 'cursor', 'cursor', None, 1000)
2748
2759
  market = None
2749
2760
  if symbol is not None:
2750
2761
  market = self.market(symbol)
@@ -3220,7 +3231,7 @@ class coinbase(Exchange, ImplicitAPI):
3220
3231
  if accountId is None:
3221
3232
  if code is None:
3222
3233
  raise ArgumentsRequired(self.id + ' withdraw() requires an account_id(or accountId) parameter OR a currency code argument')
3223
- accountId = await self.find_account_id(code)
3234
+ accountId = await self.find_account_id(code, params)
3224
3235
  if accountId is None:
3225
3236
  raise ExchangeError(self.id + ' withdraw() could not find account id for ' + code)
3226
3237
  request = {
@@ -3437,7 +3448,7 @@ class coinbase(Exchange, ImplicitAPI):
3437
3448
  if accountId is None:
3438
3449
  if code is None:
3439
3450
  raise ArgumentsRequired(self.id + ' deposit() requires an account_id(or accountId) parameter OR a currency code argument')
3440
- accountId = await self.find_account_id(code)
3451
+ accountId = await self.find_account_id(code, params)
3441
3452
  if accountId is None:
3442
3453
  raise ExchangeError(self.id + ' deposit() could not find account id for ' + code)
3443
3454
  request = {
@@ -3502,7 +3513,7 @@ class coinbase(Exchange, ImplicitAPI):
3502
3513
  if accountId is None:
3503
3514
  if code is None:
3504
3515
  raise ArgumentsRequired(self.id + ' fetchDeposit() requires an account_id(or accountId) parameter OR a currency code argument')
3505
- accountId = await self.find_account_id(code)
3516
+ accountId = await self.find_account_id(code, params)
3506
3517
  if accountId is None:
3507
3518
  raise ExchangeError(self.id + ' fetchDeposit() could not find account id for ' + code)
3508
3519
  request = {