ccxt 4.3.76__py2.py3-none-any.whl → 4.3.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 (45) hide show
  1. ccxt/__init__.py +1 -1
  2. ccxt/async_support/__init__.py +1 -1
  3. ccxt/async_support/base/exchange.py +1 -1
  4. ccxt/async_support/binance.py +2 -2
  5. ccxt/async_support/bingx.py +0 -1
  6. ccxt/async_support/bitget.py +1 -0
  7. ccxt/async_support/bithumb.py +14 -14
  8. ccxt/async_support/bitmart.py +3 -0
  9. ccxt/async_support/bitteam.py +0 -1
  10. ccxt/async_support/bybit.py +4 -1
  11. ccxt/async_support/gate.py +2 -2
  12. ccxt/async_support/kraken.py +10 -8
  13. ccxt/async_support/kuna.py +0 -1
  14. ccxt/async_support/vertex.py +6 -4
  15. ccxt/async_support/woo.py +3 -0
  16. ccxt/async_support/woofipro.py +3 -0
  17. ccxt/async_support/xt.py +0 -1
  18. ccxt/base/exchange.py +65 -37
  19. ccxt/binance.py +2 -2
  20. ccxt/bingx.py +0 -1
  21. ccxt/bitget.py +1 -0
  22. ccxt/bithumb.py +14 -14
  23. ccxt/bitmart.py +3 -0
  24. ccxt/bitteam.py +0 -1
  25. ccxt/bybit.py +4 -1
  26. ccxt/gate.py +2 -2
  27. ccxt/kraken.py +10 -8
  28. ccxt/kuna.py +0 -1
  29. ccxt/pro/__init__.py +1 -1
  30. ccxt/pro/binance.py +1 -1
  31. ccxt/pro/bybit.py +19 -0
  32. ccxt/pro/paradex.py +2 -0
  33. ccxt/pro/woo.py +1 -1
  34. ccxt/static_dependencies/starkware/crypto/utils.py +6 -1
  35. ccxt/vertex.py +6 -4
  36. ccxt/woo.py +3 -0
  37. ccxt/woofipro.py +3 -0
  38. ccxt/xt.py +0 -1
  39. {ccxt-4.3.76.dist-info → ccxt-4.3.78.dist-info}/METADATA +4 -4
  40. {ccxt-4.3.76.dist-info → ccxt-4.3.78.dist-info}/RECORD +43 -45
  41. ccxt/static_dependencies/typing_extensions/__init__.py +0 -0
  42. ccxt/static_dependencies/typing_extensions/typing_extensions.py +0 -3839
  43. {ccxt-4.3.76.dist-info → ccxt-4.3.78.dist-info}/LICENSE.txt +0 -0
  44. {ccxt-4.3.76.dist-info → ccxt-4.3.78.dist-info}/WHEEL +0 -0
  45. {ccxt-4.3.76.dist-info → ccxt-4.3.78.dist-info}/top_level.txt +0 -0
ccxt/__init__.py CHANGED
@@ -22,7 +22,7 @@
22
22
 
23
23
  # ----------------------------------------------------------------------------
24
24
 
25
- __version__ = '4.3.76'
25
+ __version__ = '4.3.78'
26
26
 
27
27
  # ----------------------------------------------------------------------------
28
28
 
@@ -4,7 +4,7 @@
4
4
 
5
5
  # -----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.3.76'
7
+ __version__ = '4.3.78'
8
8
 
9
9
  # -----------------------------------------------------------------------------
10
10
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  # -----------------------------------------------------------------------------
4
4
 
5
- __version__ = '4.3.76'
5
+ __version__ = '4.3.78'
6
6
 
7
7
  # -----------------------------------------------------------------------------
8
8
 
@@ -2785,7 +2785,7 @@ class binance(Exchange, ImplicitAPI):
2785
2785
  'active': depositEnable and withdrawEnable,
2786
2786
  'deposit': depositEnable,
2787
2787
  'withdraw': withdrawEnable,
2788
- 'fee': self.parse_number(fee),
2788
+ 'fee': withdrawFee,
2789
2789
  'precision': self.parse_number(precisionTick),
2790
2790
  'limits': {
2791
2791
  'withdraw': {
@@ -2793,7 +2793,7 @@ class binance(Exchange, ImplicitAPI):
2793
2793
  'max': self.safe_number(networkItem, 'withdrawMax'),
2794
2794
  },
2795
2795
  'deposit': {
2796
- 'min': None,
2796
+ 'min': self.safe_number(networkItem, 'depositDust'),
2797
2797
  'max': None,
2798
2798
  },
2799
2799
  },
@@ -1180,7 +1180,6 @@ class bingx(Exchange, ImplicitAPI):
1180
1180
  'fee': {
1181
1181
  'cost': self.parse_number(Precise.string_abs(self.safe_string_2(trade, 'commission', 'n'))),
1182
1182
  'currency': currencyCode,
1183
- 'rate': None,
1184
1183
  },
1185
1184
  }, market)
1186
1185
 
@@ -1331,6 +1331,7 @@ class bitget(Exchange, ImplicitAPI):
1331
1331
  'JADE': 'Jade Protocol',
1332
1332
  'DEGEN': 'DegenReborn',
1333
1333
  'TONCOIN': 'TON',
1334
+ 'OMNI': 'omni', # conflict with Omni Network
1334
1335
  },
1335
1336
  'options': {
1336
1337
  'timeframes': {
@@ -208,7 +208,7 @@ class bithumb(Exchange, ImplicitAPI):
208
208
  async def fetch_markets(self, params={}) -> List[Market]:
209
209
  """
210
210
  retrieves data on all markets for bithumb
211
- :see: https://apidocs.bithumb.com/reference/%ED%98%84%EC%9E%AC%EA%B0%80-%EC%A0%95%EB%B3%B4-%EC%A1%B0%ED%9A%8C-all
211
+ :see: https://apidocs.bithumb.com/v1.2.0/reference/%ED%98%84%EC%9E%AC%EA%B0%80-%EC%A0%95%EB%B3%B4-%EC%A1%B0%ED%9A%8C-all
212
212
  :param dict [params]: extra parameters specific to the exchange API endpoint
213
213
  :returns dict[]: an array of objects representing market data
214
214
  """
@@ -342,7 +342,7 @@ class bithumb(Exchange, ImplicitAPI):
342
342
  async def fetch_balance(self, params={}) -> Balances:
343
343
  """
344
344
  query for balance and get the amount of funds available for trading or funds locked in orders
345
- :see: https://apidocs.bithumb.com/reference/%EB%B3%B4%EC%9C%A0%EC%9E%90%EC%82%B0-%EC%A1%B0%ED%9A%8C
345
+ :see: https://apidocs.bithumb.com/v1.2.0/reference/%EB%B3%B4%EC%9C%A0%EC%9E%90%EC%82%B0-%EC%A1%B0%ED%9A%8C
346
346
  :param dict [params]: extra parameters specific to the exchange API endpoint
347
347
  :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
348
348
  """
@@ -356,7 +356,7 @@ class bithumb(Exchange, ImplicitAPI):
356
356
  async def fetch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
357
357
  """
358
358
  fetches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
359
- :see: https://apidocs.bithumb.com/reference/%ED%98%B8%EA%B0%80-%EC%A0%95%EB%B3%B4-%EC%A1%B0%ED%9A%8C
359
+ :see: https://apidocs.bithumb.com/v1.2.0/reference/%ED%98%B8%EA%B0%80-%EC%A0%95%EB%B3%B4-%EC%A1%B0%ED%9A%8C
360
360
  :param str symbol: unified symbol of the market to fetch the order book for
361
361
  :param int [limit]: the maximum amount of order book entries to return
362
362
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -446,7 +446,7 @@ class bithumb(Exchange, ImplicitAPI):
446
446
  async def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
447
447
  """
448
448
  fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
449
- :see: https://apidocs.bithumb.com/reference/%ED%98%84%EC%9E%AC%EA%B0%80-%EC%A0%95%EB%B3%B4-%EC%A1%B0%ED%9A%8C-all
449
+ :see: https://apidocs.bithumb.com/v1.2.0/reference/%ED%98%84%EC%9E%AC%EA%B0%80-%EC%A0%95%EB%B3%B4-%EC%A1%B0%ED%9A%8C-all
450
450
  :param str[]|None symbols: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
451
451
  :param dict [params]: extra parameters specific to the exchange API endpoint
452
452
  :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
@@ -503,7 +503,7 @@ class bithumb(Exchange, ImplicitAPI):
503
503
  async def fetch_ticker(self, symbol: str, params={}) -> Ticker:
504
504
  """
505
505
  fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
506
- :see: https://apidocs.bithumb.com/reference/%ED%98%84%EC%9E%AC%EA%B0%80-%EC%A0%95%EB%B3%B4-%EC%A1%B0%ED%9A%8C
506
+ :see: https://apidocs.bithumb.com/v1.2.0/reference/%ED%98%84%EC%9E%AC%EA%B0%80-%EC%A0%95%EB%B3%B4-%EC%A1%B0%ED%9A%8C
507
507
  :param str symbol: unified symbol of the market to fetch the ticker for
508
508
  :param dict [params]: extra parameters specific to the exchange API endpoint
509
509
  :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
@@ -560,7 +560,7 @@ class bithumb(Exchange, ImplicitAPI):
560
560
  async def fetch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
561
561
  """
562
562
  fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
563
- :see: https://apidocs.bithumb.com/reference/candlestick-rest-api
563
+ :see: https://apidocs.bithumb.com/v1.2.0/reference/candlestick-rest-api
564
564
  :param str symbol: unified symbol of the market to fetch OHLCV data for
565
565
  :param str timeframe: the length of time each candle represents
566
566
  :param int [since]: timestamp in ms of the earliest candle to fetch
@@ -677,7 +677,7 @@ class bithumb(Exchange, ImplicitAPI):
677
677
  async def fetch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
678
678
  """
679
679
  get the list of most recent trades for a particular symbol
680
- :see: https://apidocs.bithumb.com/reference/%EC%B5%9C%EA%B7%BC-%EC%B2%B4%EA%B2%B0-%EB%82%B4%EC%97%AD
680
+ :see: https://apidocs.bithumb.com/v1.2.0/reference/%EC%B5%9C%EA%B7%BC-%EC%B2%B4%EA%B2%B0-%EB%82%B4%EC%97%AD
681
681
  :param str symbol: unified symbol of the market to fetch trades for
682
682
  :param int [since]: timestamp in ms of the earliest trade to fetch
683
683
  :param int [limit]: the maximum amount of trades to fetch
@@ -713,9 +713,9 @@ class bithumb(Exchange, ImplicitAPI):
713
713
  async def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
714
714
  """
715
715
  create a trade order
716
- :see: https://apidocs.bithumb.com/reference/%EC%A7%80%EC%A0%95%EA%B0%80-%EC%A3%BC%EB%AC%B8%ED%95%98%EA%B8%B0
717
- :see: https://apidocs.bithumb.com/reference/%EC%8B%9C%EC%9E%A5%EA%B0%80-%EB%A7%A4%EC%88%98%ED%95%98%EA%B8%B0
718
- :see: https://apidocs.bithumb.com/reference/%EC%8B%9C%EC%9E%A5%EA%B0%80-%EB%A7%A4%EB%8F%84%ED%95%98%EA%B8%B0
716
+ :see: https://apidocs.bithumb.com/v1.2.0/reference/%EC%A7%80%EC%A0%95%EA%B0%80-%EC%A3%BC%EB%AC%B8%ED%95%98%EA%B8%B0
717
+ :see: https://apidocs.bithumb.com/v1.2.0/reference/%EC%8B%9C%EC%9E%A5%EA%B0%80-%EB%A7%A4%EC%88%98%ED%95%98%EA%B8%B0
718
+ :see: https://apidocs.bithumb.com/v1.2.0/reference/%EC%8B%9C%EC%9E%A5%EA%B0%80-%EB%A7%A4%EB%8F%84%ED%95%98%EA%B8%B0
719
719
  :param str symbol: unified symbol of the market to create an order in
720
720
  :param str type: 'market' or 'limit'
721
721
  :param str side: 'buy' or 'sell'
@@ -752,7 +752,7 @@ class bithumb(Exchange, ImplicitAPI):
752
752
  async def fetch_order(self, id: str, symbol: Str = None, params={}):
753
753
  """
754
754
  fetches information on an order made by the user
755
- :see: https://apidocs.bithumb.com/reference/%EA%B1%B0%EB%9E%98-%EC%A3%BC%EB%AC%B8%EB%82%B4%EC%97%AD-%EC%83%81%EC%84%B8-%EC%A1%B0%ED%9A%8C
755
+ :see: https://apidocs.bithumb.com/v1.2.0/reference/%EA%B1%B0%EB%9E%98-%EC%A3%BC%EB%AC%B8%EB%82%B4%EC%97%AD-%EC%83%81%EC%84%B8-%EC%A1%B0%ED%9A%8C
756
756
  :param str symbol: unified symbol of the market the order was made in
757
757
  :param dict [params]: extra parameters specific to the exchange API endpoint
758
758
  :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
@@ -902,7 +902,7 @@ class bithumb(Exchange, ImplicitAPI):
902
902
  async def fetch_open_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
903
903
  """
904
904
  fetch all unfilled currently open orders
905
- :see: https://apidocs.bithumb.com/reference/%EA%B1%B0%EB%9E%98-%EC%A3%BC%EB%AC%B8%EB%82%B4%EC%97%AD-%EC%A1%B0%ED%9A%8C
905
+ :see: https://apidocs.bithumb.com/v1.2.0/reference/%EA%B1%B0%EB%9E%98-%EC%A3%BC%EB%AC%B8%EB%82%B4%EC%97%AD-%EC%A1%B0%ED%9A%8C
906
906
  :param str symbol: unified market symbol
907
907
  :param int [since]: the earliest time in ms to fetch open orders for
908
908
  :param int [limit]: the maximum number of open order structures to retrieve
@@ -946,7 +946,7 @@ class bithumb(Exchange, ImplicitAPI):
946
946
  async def cancel_order(self, id: str, symbol: Str = None, params={}):
947
947
  """
948
948
  cancels an open order
949
- :see: https://apidocs.bithumb.com/reference/%EC%A3%BC%EB%AC%B8-%EC%B7%A8%EC%86%8C%ED%95%98%EA%B8%B0
949
+ :see: https://apidocs.bithumb.com/v1.2.0/reference/%EC%A3%BC%EB%AC%B8-%EC%B7%A8%EC%86%8C%ED%95%98%EA%B8%B0
950
950
  :param str id: order id
951
951
  :param str symbol: unified symbol of the market the order was made in
952
952
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -986,7 +986,7 @@ class bithumb(Exchange, ImplicitAPI):
986
986
  async def withdraw(self, code: str, amount: float, address: str, tag=None, params={}):
987
987
  """
988
988
  make a withdrawal
989
- :see: https://apidocs.bithumb.com/reference/%EC%BD%94%EC%9D%B8-%EC%B6%9C%EA%B8%88%ED%95%98%EA%B8%B0-%EA%B0%9C%EC%9D%B8
989
+ :see: https://apidocs.bithumb.com/v1.2.0/reference/%EC%BD%94%EC%9D%B8-%EC%B6%9C%EA%B8%88%ED%95%98%EA%B8%B0-%EA%B0%9C%EC%9D%B8
990
990
  :param str code: unified currency code
991
991
  :param float amount: the amount to withdraw
992
992
  :param str address: the address to withdraw to
@@ -2366,6 +2366,7 @@ class bitmart(Exchange, ImplicitAPI):
2366
2366
  :see: https://developer-pro.bitmart.com/en/futures/#submit-plan-order-signed
2367
2367
  :see: https://developer-pro.bitmart.com/en/futures/#submit-order-signed
2368
2368
  :see: https://developer-pro.bitmart.com/en/futures/#submit-plan-order-signed
2369
+ :see: https://developer-pro.bitmart.com/en/futuresv2/#submit-plan-order-signed
2369
2370
  :param str symbol: unified symbol of the market to create an order in
2370
2371
  :param str type: 'market', 'limit' or 'trailing' for swap markets only
2371
2372
  :param str side: 'buy' or 'sell'
@@ -2582,6 +2583,8 @@ class bitmart(Exchange, ImplicitAPI):
2582
2583
  params = self.omit(params, ['timeInForce', 'postOnly', 'reduceOnly', 'leverage', 'trailingTriggerPrice', 'trailingPercent', 'triggerPrice', 'stopPrice'])
2583
2584
  if leverage is not None:
2584
2585
  request['leverage'] = self.number_to_string(leverage)
2586
+ elif isTriggerOrder:
2587
+ request['leverage'] = '1' # for plan orders leverage is required, if not available default to 1
2585
2588
  return self.extend(request, params)
2586
2589
 
2587
2590
  def create_spot_order_request(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
@@ -1886,7 +1886,6 @@ class bitteam(Exchange, ImplicitAPI):
1886
1886
  fee = {
1887
1887
  'currency': self.safe_currency_code(feeCurrencyId),
1888
1888
  'cost': feeCost,
1889
- 'rate': None,
1890
1889
  }
1891
1890
  intTs = self.parse_to_int(timestamp)
1892
1891
  return self.safe_trade({
@@ -3566,7 +3566,10 @@ class bybit(Exchange, ImplicitAPI):
3566
3566
  request['qty'] = self.cost_to_precision(symbol, amount)
3567
3567
  else:
3568
3568
  if not isTrailingAmountOrder and not isAlternativeEndpoint:
3569
- request['qty'] = self.amount_to_precision(symbol, amount)
3569
+ if market['option']:
3570
+ request['qty'] = self.number_to_string(amount)
3571
+ else:
3572
+ request['qty'] = self.amount_to_precision(symbol, amount)
3570
3573
  if isTrailingAmountOrder:
3571
3574
  if trailingTriggerPrice is not None:
3572
3575
  request['activePrice'] = self.price_to_precision(symbol, trailingTriggerPrice)
@@ -3294,8 +3294,8 @@ class gate(Exchange, ImplicitAPI):
3294
3294
  side = self.safe_string_2(trade, 'side', 'type', contractSide)
3295
3295
  orderId = self.safe_string(trade, 'order_id')
3296
3296
  feeAmount = self.safe_string(trade, 'fee')
3297
- gtFee = self.safe_string(trade, 'gt_fee')
3298
- pointFee = self.safe_string(trade, 'point_fee')
3297
+ gtFee = self.omit_zero(self.safe_string(trade, 'gt_fee'))
3298
+ pointFee = self.omit_zero(self.safe_string(trade, 'point_fee'))
3299
3299
  fees = []
3300
3300
  if feeAmount is not None:
3301
3301
  feeCurrencyId = self.safe_string(trade, 'fee_currency')
@@ -1336,7 +1336,7 @@ class kraken(Exchange, ImplicitAPI):
1336
1336
  async def create_market_order_with_cost(self, symbol: str, side: OrderSide, cost: float, params={}):
1337
1337
  """
1338
1338
  create a market order by providing the symbol, side and cost
1339
- :see: https://docs.kraken.com/rest/#tag/Trading/operation/addOrder
1339
+ :see: https://docs.kraken.com/rest/#tag/Spot-Trading/operation/addOrder
1340
1340
  :param str symbol: unified symbol of the market to create an order in(only USD markets are supported)
1341
1341
  :param str side: 'buy' or 'sell'
1342
1342
  :param float cost: how much you want to trade in units of the quote currency
@@ -1351,7 +1351,7 @@ class kraken(Exchange, ImplicitAPI):
1351
1351
  async def create_market_buy_order_with_cost(self, symbol: str, cost: float, params={}):
1352
1352
  """
1353
1353
  create a market buy order by providing the symbol, side and cost
1354
- :see: https://docs.kraken.com/rest/#tag/Trading/operation/addOrder
1354
+ :see: https://docs.kraken.com/rest/#tag/Spot-Trading/operation/addOrder
1355
1355
  :param str symbol: unified symbol of the market to create an order in
1356
1356
  :param float cost: how much you want to trade in units of the quote currency
1357
1357
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -1362,7 +1362,7 @@ class kraken(Exchange, ImplicitAPI):
1362
1362
 
1363
1363
  async def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
1364
1364
  """
1365
- :see: https://docs.kraken.com/rest/#tag/Trading/operation/addOrder
1365
+ :see: https://docs.kraken.com/rest/#tag/Spot-Trading/operation/addOrder
1366
1366
  create a trade order
1367
1367
  :param str symbol: unified symbol of the market to create an order in
1368
1368
  :param str type: 'market' or 'limit'
@@ -1495,6 +1495,8 @@ class kraken(Exchange, ImplicitAPI):
1495
1495
  # "status": "ok",
1496
1496
  # "txid": "OAW2BO-7RWEK-PZY5UO",
1497
1497
  # "originaltxid": "OXL6SS-UPNMC-26WBE7",
1498
+ # "newuserref": 1234,
1499
+ # "olduserref": 123,
1498
1500
  # "volume": "0.00075000",
1499
1501
  # "price": "13500.0",
1500
1502
  # "orders_cancelled": 1,
@@ -1623,7 +1625,7 @@ class kraken(Exchange, ImplicitAPI):
1623
1625
  if (id is None) or (id.startswith('[')):
1624
1626
  txid = self.safe_list(order, 'txid')
1625
1627
  id = self.safe_string(txid, 0)
1626
- clientOrderId = self.safe_string(order, 'userref')
1628
+ clientOrderId = self.safe_string_2(order, 'userref', 'newuserref')
1627
1629
  rawTrades = self.safe_value(order, 'trades', [])
1628
1630
  trades = []
1629
1631
  for i in range(0, len(rawTrades)):
@@ -1750,13 +1752,15 @@ class kraken(Exchange, ImplicitAPI):
1750
1752
  if postOnly:
1751
1753
  extendedPostFlags = flags + ',post' if (flags is not None) else 'post'
1752
1754
  request['oflags'] = extendedPostFlags
1755
+ if (flags is not None) and not ('oflags' in request):
1756
+ request['oflags'] = flags
1753
1757
  params = self.omit(params, ['timeInForce', 'reduceOnly', 'stopLossPrice', 'takeProfitPrice', 'trailingAmount', 'trailingLimitAmount', 'offset'])
1754
1758
  return [request, params]
1755
1759
 
1756
1760
  async def edit_order(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: Num = None, price: Num = None, params={}):
1757
1761
  """
1758
1762
  edit a trade order
1759
- :see: https://docs.kraken.com/rest/#tag/Trading/operation/editOrder
1763
+ :see: https://docs.kraken.com/rest/#tag/Spot-Trading/operation/editOrder
1760
1764
  :param str id: order id
1761
1765
  :param str symbol: unified symbol of the market to create an order in
1762
1766
  :param str type: 'market' or 'limit'
@@ -1815,15 +1819,13 @@ class kraken(Exchange, ImplicitAPI):
1815
1819
  clientOrderId = self.safe_value_2(params, 'userref', 'clientOrderId')
1816
1820
  request: dict = {
1817
1821
  'trades': True, # whether or not to include trades in output(optional, default False)
1818
- # 'txid': id, # do not comma separate a list of ids - use fetchOrdersByIds instead
1822
+ 'txid': id, # do not comma separate a list of ids - use fetchOrdersByIds instead
1819
1823
  # 'userref': 'optional', # restrict results to given user reference id(optional)
1820
1824
  }
1821
1825
  query = params
1822
1826
  if clientOrderId is not None:
1823
1827
  request['userref'] = clientOrderId
1824
1828
  query = self.omit(params, ['userref', 'clientOrderId'])
1825
- else:
1826
- request['txid'] = id
1827
1829
  response = await self.privatePostQueryOrders(self.extend(request, query))
1828
1830
  #
1829
1831
  # {
@@ -870,7 +870,6 @@ class kuna(Exchange, ImplicitAPI):
870
870
  'fee': {
871
871
  'cost': self.safe_string(trade, 'fee'),
872
872
  'currency': self.safe_currency_code(self.safe_string(trade, 'feeCurrency')),
873
- 'rate': None,
874
873
  },
875
874
  }, market)
876
875
 
@@ -658,6 +658,12 @@ class vertex(Exchange, ImplicitAPI):
658
658
  amount = None
659
659
  side = None
660
660
  fee = None
661
+ feeCost = self.convert_from_x18(self.safe_string(trade, 'fee'))
662
+ if feeCost is not None:
663
+ fee = {
664
+ 'cost': feeCost,
665
+ 'currency': None,
666
+ }
661
667
  id = self.safe_string_2(trade, 'trade_id', 'submission_idx')
662
668
  order = self.safe_string(trade, 'digest')
663
669
  timestamp = self.safe_timestamp(trade, 'timestamp')
@@ -673,10 +679,6 @@ class vertex(Exchange, ImplicitAPI):
673
679
  subOrder = self.safe_dict(trade, 'order', {})
674
680
  price = self.convert_from_x18(self.safe_string(subOrder, 'priceX18'))
675
681
  amount = self.convert_from_x18(self.safe_string(trade, 'base_filled'))
676
- fee = {
677
- 'cost': self.convert_from_x18(self.safe_string(trade, 'fee')),
678
- 'currency': None,
679
- }
680
682
  if Precise.string_lt(amount, '0'):
681
683
  side = 'sell'
682
684
  else:
ccxt/async_support/woo.py CHANGED
@@ -603,6 +603,9 @@ class woo(Exchange, ImplicitAPI):
603
603
  amount = self.safe_string(trade, 'executed_quantity')
604
604
  order_id = self.safe_string(trade, 'order_id')
605
605
  fee = self.parse_token_and_fee_temp(trade, 'fee_asset', 'fee')
606
+ feeCost = self.safe_string(fee, 'cost')
607
+ if feeCost is not None:
608
+ fee['cost'] = feeCost
606
609
  cost = Precise.string_mul(price, amount)
607
610
  side = self.safe_string_lower(trade, 'side')
608
611
  id = self.safe_string(trade, 'id')
@@ -673,6 +673,9 @@ class woofipro(Exchange, ImplicitAPI):
673
673
  amount = self.safe_string(trade, 'executed_quantity')
674
674
  order_id = self.safe_string(trade, 'order_id')
675
675
  fee = self.parse_token_and_fee_temp(trade, 'fee_asset', 'fee')
676
+ feeCost = self.safe_string(fee, 'cost')
677
+ if feeCost is not None:
678
+ fee['cost'] = feeCost
676
679
  cost = Precise.string_mul(price, amount)
677
680
  side = self.safe_string_lower(trade, 'side')
678
681
  id = self.safe_string(trade, 'id')
ccxt/async_support/xt.py CHANGED
@@ -2035,7 +2035,6 @@ class xt(Exchange, ImplicitAPI):
2035
2035
  'fee': {
2036
2036
  'currency': self.safe_currency_code(self.safe_string_2(trade, 'feeCurrency', 'feeCoin')),
2037
2037
  'cost': self.safe_string(trade, 'fee'),
2038
- 'rate': None,
2039
2038
  },
2040
2039
  }, market)
2041
2040
 
ccxt/base/exchange.py CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # -----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.3.76'
7
+ __version__ = '4.3.78'
8
8
 
9
9
  # -----------------------------------------------------------------------------
10
10
 
@@ -110,6 +110,14 @@ from ccxt.base.types import Int
110
110
 
111
111
  # -----------------------------------------------------------------------------
112
112
 
113
+ class SafeJSONEncoder(json.JSONEncoder):
114
+ def default(self, obj):
115
+ if isinstance(obj, Exception):
116
+ return {"name": obj.__class__.__name__}
117
+ try:
118
+ return super().default(obj)
119
+ except TypeError:
120
+ return f"TypeError: Object of type {type(obj).__name__} is not JSON serializable"
113
121
 
114
122
  class Exchange(object):
115
123
  """Base exchange class"""
@@ -1419,7 +1427,7 @@ class Exchange(object):
1419
1427
 
1420
1428
  @staticmethod
1421
1429
  def json(data, params=None):
1422
- return json.dumps(data, separators=(',', ':'))
1430
+ return json.dumps(data, separators=(',', ':'), cls=SafeJSONEncoder)
1423
1431
 
1424
1432
  @staticmethod
1425
1433
  def is_json_encoded_object(input):
@@ -3268,40 +3276,53 @@ class Exchange(object):
3268
3276
  multiplyPrice = Precise.string_div('1', price)
3269
3277
  multiplyPrice = Precise.string_mul(multiplyPrice, contractSize)
3270
3278
  cost = Precise.string_mul(multiplyPrice, amount)
3271
- parseFee = self.safe_value(trade, 'fee') is None
3272
- parseFees = self.safe_value(trade, 'fees') is None
3273
- shouldParseFees = parseFee or parseFees
3274
- fees = []
3275
- fee = self.safe_value(trade, 'fee')
3276
- if shouldParseFees:
3277
- reducedFees = self.reduce_fees_by_currency(fees) if self.reduceFees else fees
3278
- reducedLength = len(reducedFees)
3279
- for i in range(0, reducedLength):
3280
- reducedFees[i]['cost'] = self.safe_number(reducedFees[i], 'cost')
3281
- if 'rate' in reducedFees[i]:
3282
- reducedFees[i]['rate'] = self.safe_number(reducedFees[i], 'rate')
3283
- if not parseFee and (reducedLength == 0):
3284
- # copy fee to avoid modification by reference
3285
- feeCopy = self.deep_extend(fee)
3286
- feeCopy['cost'] = self.safe_number(feeCopy, 'cost')
3287
- if 'rate' in feeCopy:
3288
- feeCopy['rate'] = self.safe_number(feeCopy, 'rate')
3289
- reducedFees.append(feeCopy)
3290
- if parseFees:
3291
- trade['fees'] = reducedFees
3292
- if parseFee and (reducedLength == 1):
3293
- trade['fee'] = reducedFees[0]
3294
- tradeFee = self.safe_value(trade, 'fee')
3295
- if tradeFee is not None:
3296
- tradeFee['cost'] = self.safe_number(tradeFee, 'cost')
3297
- if 'rate' in tradeFee:
3298
- tradeFee['rate'] = self.safe_number(tradeFee, 'rate')
3299
- trade['fee'] = tradeFee
3279
+ resultFee, resultFees = self.parsed_fee_and_fees(trade)
3280
+ trade['fee'] = resultFee
3281
+ trade['fees'] = resultFees
3300
3282
  trade['amount'] = self.parse_number(amount)
3301
3283
  trade['price'] = self.parse_number(price)
3302
3284
  trade['cost'] = self.parse_number(cost)
3303
3285
  return trade
3304
3286
 
3287
+ def parsed_fee_and_fees(self, container: Any):
3288
+ fee = self.safe_dict(container, 'fee')
3289
+ fees = self.safe_list(container, 'fees')
3290
+ feeDefined = fee is not None
3291
+ feesDefined = fees is not None
3292
+ # parsing only if at least one of them is defined
3293
+ shouldParseFees = (feeDefined or feesDefined)
3294
+ if shouldParseFees:
3295
+ if feeDefined:
3296
+ fee = self.parse_fee_numeric(fee)
3297
+ if not feesDefined:
3298
+ # just set it directly, no further processing needed
3299
+ fees = [fee]
3300
+ # 'fees' were set, so reparse them
3301
+ reducedFees = self.reduce_fees_by_currency(fees) if self.reduceFees else fees
3302
+ reducedLength = len(reducedFees)
3303
+ for i in range(0, reducedLength):
3304
+ reducedFees[i] = self.parse_fee_numeric(reducedFees[i])
3305
+ fees = reducedFees
3306
+ if reducedLength == 1:
3307
+ fee = reducedFees[0]
3308
+ elif reducedLength == 0:
3309
+ fee = None
3310
+ # in case `fee & fees` are None, set `fees` array
3311
+ if fee is None:
3312
+ fee = {
3313
+ 'cost': None,
3314
+ 'currency': None,
3315
+ }
3316
+ if fees is None:
3317
+ fees = []
3318
+ return [fee, fees]
3319
+
3320
+ def parse_fee_numeric(self, fee: Any):
3321
+ fee['cost'] = self.safe_number(fee, 'cost') # ensure numeric
3322
+ if 'rate' in fee:
3323
+ fee['rate'] = self.safe_number(fee, 'rate')
3324
+ return fee
3325
+
3305
3326
  def find_nearest_ceiling(self, arr: List[float], providedValue: float):
3306
3327
  # i.e. findNearestCeiling([10, 30, 50], 23) returns 30
3307
3328
  length = len(arr)
@@ -3370,12 +3391,13 @@ class Exchange(object):
3370
3391
  reduced = {}
3371
3392
  for i in range(0, len(fees)):
3372
3393
  fee = fees[i]
3373
- feeCurrencyCode = self.safe_string(fee, 'currency')
3394
+ code = self.safe_string(fee, 'currency')
3395
+ feeCurrencyCode = code is not code if None else str(i)
3374
3396
  if feeCurrencyCode is not None:
3375
3397
  rate = self.safe_string(fee, 'rate')
3376
- cost = self.safe_value(fee, 'cost')
3377
- if Precise.string_eq(cost, '0'):
3378
- # omit zero cost fees
3398
+ cost = self.safe_string(fee, 'cost')
3399
+ if cost is None:
3400
+ # omit None cost, does not make sense, however, don't omit '0' costs, still make sense
3379
3401
  continue
3380
3402
  if not (feeCurrencyCode in reduced):
3381
3403
  reduced[feeCurrencyCode] = {}
@@ -3384,7 +3406,7 @@ class Exchange(object):
3384
3406
  reduced[feeCurrencyCode][rateKey]['cost'] = Precise.string_add(reduced[feeCurrencyCode][rateKey]['cost'], cost)
3385
3407
  else:
3386
3408
  reduced[feeCurrencyCode][rateKey] = {
3387
- 'currency': feeCurrencyCode,
3409
+ 'currency': code,
3388
3410
  'cost': cost,
3389
3411
  }
3390
3412
  if rate is not None:
@@ -3416,7 +3438,13 @@ class Exchange(object):
3416
3438
  if change is None:
3417
3439
  change = Precise.string_sub(last, open)
3418
3440
  if average is None:
3419
- average = Precise.string_div(Precise.string_add(last, open), '2')
3441
+ precision = 18
3442
+ if market is not None and self.is_tick_precision():
3443
+ marketPrecision = self.safe_dict(market, 'precision')
3444
+ precisionPrice = self.safe_string(marketPrecision, 'price')
3445
+ if precisionPrice is not None:
3446
+ precision = self.precision_from_string(precisionPrice)
3447
+ average = Precise.string_div(Precise.string_add(last, open), '2', precision)
3420
3448
  if (percentage is None) and (change is not None) and (open is not None) and Precise.string_gt(open, '0'):
3421
3449
  percentage = Precise.string_mul(Precise.string_div(change, open), '100')
3422
3450
  if (change is None) and (percentage is not None) and (open is not None):
ccxt/binance.py CHANGED
@@ -2784,7 +2784,7 @@ class binance(Exchange, ImplicitAPI):
2784
2784
  'active': depositEnable and withdrawEnable,
2785
2785
  'deposit': depositEnable,
2786
2786
  'withdraw': withdrawEnable,
2787
- 'fee': self.parse_number(fee),
2787
+ 'fee': withdrawFee,
2788
2788
  'precision': self.parse_number(precisionTick),
2789
2789
  'limits': {
2790
2790
  'withdraw': {
@@ -2792,7 +2792,7 @@ class binance(Exchange, ImplicitAPI):
2792
2792
  'max': self.safe_number(networkItem, 'withdrawMax'),
2793
2793
  },
2794
2794
  'deposit': {
2795
- 'min': None,
2795
+ 'min': self.safe_number(networkItem, 'depositDust'),
2796
2796
  'max': None,
2797
2797
  },
2798
2798
  },
ccxt/bingx.py CHANGED
@@ -1179,7 +1179,6 @@ class bingx(Exchange, ImplicitAPI):
1179
1179
  'fee': {
1180
1180
  'cost': self.parse_number(Precise.string_abs(self.safe_string_2(trade, 'commission', 'n'))),
1181
1181
  'currency': currencyCode,
1182
- 'rate': None,
1183
1182
  },
1184
1183
  }, market)
1185
1184
 
ccxt/bitget.py CHANGED
@@ -1330,6 +1330,7 @@ class bitget(Exchange, ImplicitAPI):
1330
1330
  'JADE': 'Jade Protocol',
1331
1331
  'DEGEN': 'DegenReborn',
1332
1332
  'TONCOIN': 'TON',
1333
+ 'OMNI': 'omni', # conflict with Omni Network
1333
1334
  },
1334
1335
  'options': {
1335
1336
  'timeframes': {