ccxt 4.4.85__py2.py3-none-any.whl → 4.4.87__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 (92) hide show
  1. ccxt/__init__.py +7 -5
  2. ccxt/abstract/modetrade.py +119 -0
  3. ccxt/abstract/myokx.py +2 -0
  4. ccxt/abstract/okx.py +2 -0
  5. ccxt/abstract/okxus.py +349 -0
  6. ccxt/ascendex.py +187 -151
  7. ccxt/async_support/__init__.py +7 -5
  8. ccxt/async_support/ascendex.py +187 -151
  9. ccxt/async_support/base/exchange.py +30 -26
  10. ccxt/async_support/bequant.py +1 -1
  11. ccxt/async_support/binance.py +1 -1
  12. ccxt/async_support/bitget.py +4 -4
  13. ccxt/async_support/bitmart.py +1 -1
  14. ccxt/async_support/bitteam.py +31 -0
  15. ccxt/async_support/{huobijp.py → bittrade.py} +11 -11
  16. ccxt/async_support/coinbase.py +2 -5
  17. ccxt/async_support/coinmetro.py +3 -0
  18. ccxt/async_support/deribit.py +4 -5
  19. ccxt/async_support/gate.py +91 -73
  20. ccxt/async_support/hollaex.py +106 -49
  21. ccxt/async_support/htx.py +30 -51
  22. ccxt/async_support/hyperliquid.py +36 -20
  23. ccxt/async_support/kraken.py +5 -8
  24. ccxt/async_support/mexc.py +2 -2
  25. ccxt/async_support/modetrade.py +2727 -0
  26. ccxt/async_support/ndax.py +25 -24
  27. ccxt/async_support/okcoin.py +12 -29
  28. ccxt/async_support/okx.py +99 -3
  29. ccxt/async_support/okxus.py +54 -0
  30. ccxt/async_support/onetrading.py +10 -7
  31. ccxt/async_support/oxfun.py +40 -110
  32. ccxt/async_support/paradex.py +6 -0
  33. ccxt/async_support/phemex.py +4 -6
  34. ccxt/async_support/poloniex.py +172 -159
  35. ccxt/async_support/probit.py +18 -47
  36. ccxt/async_support/timex.py +5 -10
  37. ccxt/async_support/vertex.py +3 -4
  38. ccxt/async_support/whitebit.py +41 -11
  39. ccxt/async_support/woo.py +101 -75
  40. ccxt/async_support/woofipro.py +25 -20
  41. ccxt/async_support/xt.py +31 -41
  42. ccxt/base/exchange.py +12 -9
  43. ccxt/bequant.py +1 -1
  44. ccxt/binance.py +1 -1
  45. ccxt/bitget.py +4 -4
  46. ccxt/bitmart.py +1 -1
  47. ccxt/bitteam.py +31 -0
  48. ccxt/{huobijp.py → bittrade.py} +11 -11
  49. ccxt/coinbase.py +2 -5
  50. ccxt/coinmetro.py +3 -0
  51. ccxt/deribit.py +4 -5
  52. ccxt/gate.py +91 -73
  53. ccxt/hollaex.py +106 -49
  54. ccxt/htx.py +30 -51
  55. ccxt/hyperliquid.py +36 -20
  56. ccxt/kraken.py +5 -8
  57. ccxt/mexc.py +2 -2
  58. ccxt/modetrade.py +2727 -0
  59. ccxt/ndax.py +25 -24
  60. ccxt/okcoin.py +12 -29
  61. ccxt/okx.py +99 -3
  62. ccxt/okxus.py +54 -0
  63. ccxt/onetrading.py +10 -7
  64. ccxt/oxfun.py +40 -110
  65. ccxt/paradex.py +6 -0
  66. ccxt/phemex.py +4 -6
  67. ccxt/poloniex.py +172 -159
  68. ccxt/pro/__init__.py +101 -3
  69. ccxt/pro/binance.py +1 -0
  70. ccxt/pro/{huobijp.py → bittrade.py} +3 -3
  71. ccxt/pro/luno.py +6 -5
  72. ccxt/pro/mexc.py +2 -0
  73. ccxt/pro/modetrade.py +1271 -0
  74. ccxt/pro/okxus.py +38 -0
  75. ccxt/probit.py +18 -47
  76. ccxt/test/tests_async.py +17 -1
  77. ccxt/test/tests_sync.py +17 -1
  78. ccxt/timex.py +5 -10
  79. ccxt/vertex.py +3 -4
  80. ccxt/whitebit.py +41 -11
  81. ccxt/woo.py +100 -75
  82. ccxt/woofipro.py +24 -20
  83. ccxt/xt.py +31 -41
  84. {ccxt-4.4.85.dist-info → ccxt-4.4.87.dist-info}/METADATA +19 -8
  85. {ccxt-4.4.85.dist-info → ccxt-4.4.87.dist-info}/RECORD +89 -84
  86. ccxt/abstract/kuna.py +0 -182
  87. ccxt/async_support/kuna.py +0 -1935
  88. ccxt/kuna.py +0 -1935
  89. /ccxt/abstract/{huobijp.py → bittrade.py} +0 -0
  90. {ccxt-4.4.85.dist-info → ccxt-4.4.87.dist-info}/LICENSE.txt +0 -0
  91. {ccxt-4.4.85.dist-info → ccxt-4.4.87.dist-info}/WHEEL +0 -0
  92. {ccxt-4.4.85.dist-info → ccxt-4.4.87.dist-info}/top_level.txt +0 -0
ccxt/ndax.py CHANGED
@@ -454,44 +454,44 @@ class ndax(Exchange, ImplicitAPI):
454
454
  }
455
455
  response = self.publicGetGetProducts(self.extend(request, params))
456
456
  #
457
- # [
458
- # {
459
- # "OMSId":1,
460
- # "ProductId":1,
461
- # "Product":"BTC",
462
- # "ProductFullName":"Bitcoin",
463
- # "ProductType":"CryptoCurrency",
464
- # "DecimalPlaces":8,
465
- # "TickSize":0.0000000100000000000000000000,
466
- # "NoFees":false,
467
- # "IsDisabled":false,
468
- # "MarginEnabled":false
469
- # },
470
- # ]
457
+ # [
458
+ # {
459
+ # "OMSId": "1",
460
+ # "ProductId": "1",
461
+ # "Product": "BTC",
462
+ # "ProductFullName": "Bitcoin",
463
+ # "MasterDataUniqueProductSymbol": "",
464
+ # "ProductType": "CryptoCurrency",
465
+ # "DecimalPlaces": "8",
466
+ # "TickSize": "0.0000000100000000000000000000",
467
+ # "DepositEnabled": True,
468
+ # "WithdrawEnabled": True,
469
+ # "NoFees": False,
470
+ # "IsDisabled": False,
471
+ # "MarginEnabled": False
472
+ # },
473
+ # ...
471
474
  #
472
475
  result: dict = {}
473
476
  for i in range(0, len(response)):
474
477
  currency = response[i]
475
478
  id = self.safe_string(currency, 'ProductId')
476
- name = self.safe_string(currency, 'ProductFullName')
479
+ code = self.safe_currency_code(self.safe_string(currency, 'Product'))
477
480
  ProductType = self.safe_string(currency, 'ProductType')
478
481
  type = 'fiat' if (ProductType == 'NationalCurrency') else 'crypto'
479
482
  if ProductType == 'Unknown':
480
483
  # such currency is just a blanket entry
481
484
  type = 'other'
482
- code = self.safe_currency_code(self.safe_string(currency, 'Product'))
483
- isDisabled = self.safe_value(currency, 'IsDisabled')
484
- active = not isDisabled
485
- result[code] = {
485
+ result[code] = self.safe_currency_structure({
486
486
  'id': id,
487
- 'name': name,
487
+ 'name': self.safe_string(currency, 'ProductFullName'),
488
488
  'code': code,
489
489
  'type': type,
490
490
  'precision': self.safe_number(currency, 'TickSize'),
491
491
  'info': currency,
492
- 'active': active,
493
- 'deposit': None,
494
- 'withdraw': None,
492
+ 'active': not self.safe_bool(currency, 'IsDisabled'),
493
+ 'deposit': self.safe_bool(currency, 'DepositEnabled'),
494
+ 'withdraw': self.safe_bool(currency, 'WithdrawEnabled'),
495
495
  'fee': None,
496
496
  'limits': {
497
497
  'amount': {
@@ -504,7 +504,8 @@ class ndax(Exchange, ImplicitAPI):
504
504
  },
505
505
  },
506
506
  'networks': {},
507
- }
507
+ 'margin': self.safe_bool(currency, 'MarginEnabled'),
508
+ })
508
509
  return result
509
510
 
510
511
  def fetch_markets(self, params={}) -> List[Market]:
ccxt/okcoin.py CHANGED
@@ -840,47 +840,30 @@ class okcoin(Exchange, ImplicitAPI):
840
840
  return None
841
841
  else:
842
842
  response = self.privateGetAssetCurrencies(params)
843
- data = self.safe_value(response, 'data', [])
843
+ data = self.safe_list(response, 'data', [])
844
844
  result: dict = {}
845
845
  dataByCurrencyId = self.group_by(data, 'ccy')
846
846
  currencyIds = list(dataByCurrencyId.keys())
847
847
  for i in range(0, len(currencyIds)):
848
848
  currencyId = currencyIds[i]
849
- currency = self.safe_currency(currencyId)
850
- code = currency['code']
849
+ code = self.safe_currency_code(currencyId)
851
850
  chains = dataByCurrencyId[currencyId]
852
851
  networks: dict = {}
853
- currencyActive = False
854
- depositEnabled = False
855
- withdrawEnabled = False
856
- maxPrecision = None
857
852
  for j in range(0, len(chains)):
858
853
  chain = chains[j]
859
- canDeposit = self.safe_value(chain, 'canDep')
860
- depositEnabled = canDeposit if (canDeposit) else depositEnabled
861
- canWithdraw = self.safe_value(chain, 'canWd')
862
- withdrawEnabled = canWithdraw if (canWithdraw) else withdrawEnabled
863
- canInternal = self.safe_value(chain, 'canInternal')
864
- active = True if (canDeposit and canWithdraw and canInternal) else False
865
- currencyActive = active if (active) else currencyActive
866
854
  networkId = self.safe_string(chain, 'chain')
867
855
  if (networkId is not None) and (networkId.find('-') >= 0):
868
856
  parts = networkId.split('-')
869
857
  chainPart = self.safe_string(parts, 1, networkId)
870
858
  networkCode = self.network_id_to_code(chainPart)
871
- precision = self.parse_precision(self.safe_string(chain, 'wdTickSz'))
872
- if maxPrecision is None:
873
- maxPrecision = precision
874
- else:
875
- maxPrecision = Precise.string_min(maxPrecision, precision)
876
859
  networks[networkCode] = {
877
860
  'id': networkId,
878
861
  'network': networkCode,
879
- 'active': active,
880
- 'deposit': canDeposit,
881
- 'withdraw': canWithdraw,
862
+ 'active': None,
863
+ 'deposit': self.safe_bool(chain, 'canDep'),
864
+ 'withdraw': self.safe_bool(chain, 'canWd'),
882
865
  'fee': self.safe_number(chain, 'minFee'),
883
- 'precision': self.parse_number(precision),
866
+ 'precision': self.parse_number(self.parse_precision(self.safe_string(chain, 'wdTickSz'))),
884
867
  'limits': {
885
868
  'withdraw': {
886
869
  'min': self.safe_number(chain, 'minWd'),
@@ -890,16 +873,16 @@ class okcoin(Exchange, ImplicitAPI):
890
873
  'info': chain,
891
874
  }
892
875
  firstChain = self.safe_value(chains, 0)
893
- result[code] = {
876
+ result[code] = self.safe_currency_structure({
894
877
  'info': chains,
895
878
  'code': code,
896
879
  'id': currencyId,
897
880
  'name': self.safe_string(firstChain, 'name'),
898
- 'active': currencyActive,
899
- 'deposit': depositEnabled,
900
- 'withdraw': withdrawEnabled,
881
+ 'active': None,
882
+ 'deposit': None,
883
+ 'withdraw': None,
901
884
  'fee': None,
902
- 'precision': self.parse_number(maxPrecision),
885
+ 'precision': None,
903
886
  'limits': {
904
887
  'amount': {
905
888
  'min': None,
@@ -907,7 +890,7 @@ class okcoin(Exchange, ImplicitAPI):
907
890
  },
908
891
  },
909
892
  'networks': networks,
910
- }
893
+ })
911
894
  return result
912
895
 
913
896
  def fetch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
ccxt/okx.py CHANGED
@@ -6,7 +6,7 @@
6
6
  from ccxt.base.exchange import Exchange
7
7
  from ccxt.abstract.okx import ImplicitAPI
8
8
  import hashlib
9
- from ccxt.base.types import Account, Any, Balances, BorrowInterest, Conversion, CrossBorrowRate, CrossBorrowRates, Currencies, Currency, DepositAddress, Greeks, Int, LedgerEntry, Leverage, LeverageTier, LongShortRatio, MarginModification, Market, Num, Option, OptionChain, Order, OrderBook, OrderRequest, CancellationRequest, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, FundingRate, Trade, TradingFeeInterface, Transaction, MarketInterface, TransferEntry
9
+ from ccxt.base.types import Account, Any, Balances, BorrowInterest, Conversion, CrossBorrowRate, CrossBorrowRates, Currencies, Currency, DepositAddress, Greeks, Int, LedgerEntry, Leverage, LeverageTier, LongShortRatio, MarginModification, Market, Num, Option, OptionChain, Order, OrderBook, OrderRequest, CancellationRequest, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, FundingRate, FundingRates, OpenInterests, Trade, TradingFeeInterface, Transaction, MarketInterface, TransferEntry
10
10
  from typing import List
11
11
  from ccxt.base.errors import ExchangeError
12
12
  from ccxt.base.errors import AuthenticationError
@@ -108,7 +108,7 @@ class okx(Exchange, ImplicitAPI):
108
108
  'fetchFundingIntervals': False,
109
109
  'fetchFundingRate': True,
110
110
  'fetchFundingRateHistory': True,
111
- 'fetchFundingRates': False,
111
+ 'fetchFundingRates': True,
112
112
  'fetchGreeks': True,
113
113
  'fetchIndexOHLCV': True,
114
114
  'fetchIsolatedBorrowRate': False,
@@ -131,6 +131,7 @@ class okx(Exchange, ImplicitAPI):
131
131
  'fetchOHLCV': True,
132
132
  'fetchOpenInterest': True,
133
133
  'fetchOpenInterestHistory': True,
134
+ 'fetchOpenInterests': True,
134
135
  'fetchOpenOrder': None,
135
136
  'fetchOpenOrders': True,
136
137
  'fetchOption': True,
@@ -388,6 +389,7 @@ class okx(Exchange, ImplicitAPI):
388
389
  'account/spot-manual-borrow-repay': 10,
389
390
  'account/set-auto-repay': 4,
390
391
  'account/spot-borrow-repay-history': 4,
392
+ 'account/move-positions-history': 10,
391
393
  # subaccount
392
394
  'users/subaccount/list': 10,
393
395
  'account/subaccount/balances': 10 / 3,
@@ -525,6 +527,7 @@ class okx(Exchange, ImplicitAPI):
525
527
  'account/fixed-loan/manual-reborrow': 5,
526
528
  'account/fixed-loan/repay-borrowing-order': 5,
527
529
  'account/bills-history-archive': 72000, # 12 req/day
530
+ 'account/move-positions': 10,
528
531
  # subaccount
529
532
  'users/subaccount/modify-apikey': 10,
530
533
  'asset/subaccount/transfer': 10,
@@ -991,6 +994,13 @@ class okx(Exchange, ImplicitAPI):
991
994
  '70010': BadRequest, # Timestamp parameters need to be in Unix timestamp format in milliseconds.
992
995
  '70013': BadRequest, # endTs needs to be bigger than or equal to beginTs.
993
996
  '70016': BadRequest, # Please specify your instrument settings for at least one instType.
997
+ '70060': BadRequest, # The account doesn’t exist or the position side is incorrect. To and from accounts must be under the same main account.
998
+ '70061': BadRequest, # To move position, please enter a position that’s opposite to your current side and is smaller than or equal to your current size.
999
+ '70062': BadRequest, # account has reached the maximum number of position transfers allowed per day.
1000
+ '70064': BadRequest, # Position does not exist.
1001
+ '70065': BadRequest, # Couldn’t move position. Execution price cannot be determined
1002
+ '70066': BadRequest, # Moving positions isn't supported in spot mode. Switch to any other account mode and try again.
1003
+ '70067': BadRequest, # Moving positions isn't supported in margin trading.
994
1004
  '1009': BadRequest, # Request message exceeds the maximum frame length
995
1005
  '4001': AuthenticationError, # Login Failed
996
1006
  '4002': BadRequest, # Invalid Request
@@ -5975,7 +5985,7 @@ class okx(Exchange, ImplicitAPI):
5975
5985
  nextFundingRate = self.safe_number(contract, 'nextFundingRate')
5976
5986
  fundingTime = self.safe_integer(contract, 'fundingTime')
5977
5987
  fundingTimeString = self.safe_string(contract, 'fundingTime')
5978
- nextFundingTimeString = self.safe_string(contract, 'nextFundingRate')
5988
+ nextFundingTimeString = self.safe_string(contract, 'nextFundingTime')
5979
5989
  millisecondsInterval = Precise.string_sub(nextFundingTimeString, fundingTimeString)
5980
5990
  # https://www.okx.com/support/hc/en-us/articles/360053909272-Ⅸ-Introduction-to-perpetual-swap-funding-fee
5981
5991
  # > The current interest is 0.
@@ -6060,6 +6070,39 @@ class okx(Exchange, ImplicitAPI):
6060
6070
  entry = self.safe_dict(data, 0, {})
6061
6071
  return self.parse_funding_rate(entry, market)
6062
6072
 
6073
+ def fetch_funding_rates(self, symbols: Strings = None, params={}) -> FundingRates:
6074
+ """
6075
+ fetches the current funding rates for multiple symbols
6076
+
6077
+ https://www.okx.com/docs-v5/en/#public-data-rest-api-get-funding-rate
6078
+
6079
+ :param str[] symbols: unified market symbols
6080
+ :param dict [params]: extra parameters specific to the exchange API endpoint
6081
+ :returns dict: a dictionary of `funding rates structure <https://docs.ccxt.com/#/?id=funding-rates-structure>`
6082
+ """
6083
+ self.load_markets()
6084
+ symbols = self.market_symbols(symbols, 'swap', True)
6085
+ request: dict = {'instId': 'ANY'}
6086
+ response = self.publicGetPublicFundingRate(self.extend(request, params))
6087
+ #
6088
+ # {
6089
+ # "code": "0",
6090
+ # "data": [
6091
+ # {
6092
+ # "fundingRate": "0.00027815",
6093
+ # "fundingTime": "1634256000000",
6094
+ # "instId": "BTC-USD-SWAP",
6095
+ # "instType": "SWAP",
6096
+ # "nextFundingRate": "0.00017",
6097
+ # "nextFundingTime": "1634284800000"
6098
+ # }
6099
+ # ],
6100
+ # "msg": ""
6101
+ # }
6102
+ #
6103
+ data = self.safe_list(response, 'data', [])
6104
+ return self.parse_funding_rates(data, symbols)
6105
+
6063
6106
  def fetch_funding_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
6064
6107
  """
6065
6108
  fetch the history of funding payments paid and received on self account
@@ -7017,6 +7060,59 @@ class okx(Exchange, ImplicitAPI):
7017
7060
  data = self.safe_list(response, 'data', [])
7018
7061
  return self.parse_open_interest(data[0], market)
7019
7062
 
7063
+ def fetch_open_interests(self, symbols: Strings = None, params={}) -> OpenInterests:
7064
+ """
7065
+ Retrieves the open interests of some currencies
7066
+
7067
+ https://www.okx.com/docs-v5/en/#rest-api-public-data-get-open-interest
7068
+
7069
+ :param str[] symbols: Unified CCXT market symbols
7070
+ :param dict [params]: exchange specific parameters
7071
+ :param str params['instType']: Instrument type, options: 'SWAP', 'FUTURES', 'OPTION', default to 'SWAP'
7072
+ :param str params['uly']: Underlying, Applicable to FUTURES/SWAP/OPTION, if instType is 'OPTION', either uly or instFamily is required
7073
+ :param str params['instFamily']: Instrument family, Applicable to FUTURES/SWAP/OPTION, if instType is 'OPTION', either uly or instFamily is required
7074
+ :returns dict: an dictionary of `open interest structures <https://docs.ccxt.com/#/?id=open-interest-structure>`
7075
+ """
7076
+ self.load_markets()
7077
+ symbols = self.market_symbols(symbols, None, True, True)
7078
+ market = None
7079
+ if symbols is not None:
7080
+ market = self.market(symbols[0])
7081
+ marketType = None
7082
+ marketType, params = self.handle_sub_type_and_params('fetchOpenInterests', market, params, 'swap')
7083
+ instType = 'SWAP'
7084
+ if marketType == 'future':
7085
+ instType = 'FUTURES'
7086
+ elif instType == 'option':
7087
+ instType = 'OPTION'
7088
+ request: dict = {'instType': instType}
7089
+ uly = self.safe_string(params, 'uly')
7090
+ if uly is not None:
7091
+ request['uly'] = uly
7092
+ instFamily = self.safe_string(params, 'instFamily')
7093
+ if instFamily is not None:
7094
+ request['instFamily'] = instFamily
7095
+ if instType == 'OPTION' and uly is None and instFamily is None:
7096
+ raise BadRequest(self.id + ' fetchOpenInterests() requires either uly or instFamily parameter for OPTION markets')
7097
+ response = self.publicGetPublicOpenInterest(self.extend(request, params))
7098
+ #
7099
+ # {
7100
+ # "code": "0",
7101
+ # "data": [
7102
+ # {
7103
+ # "instId": "BTC-USDT-SWAP",
7104
+ # "instType": "SWAP",
7105
+ # "oi": "2125419",
7106
+ # "oiCcy": "21254.19",
7107
+ # "ts": "1664005108969"
7108
+ # }
7109
+ # ],
7110
+ # "msg": ""
7111
+ # }
7112
+ #
7113
+ data = self.safe_list(response, 'data', [])
7114
+ return self.parse_open_interests(data, symbols)
7115
+
7020
7116
  def fetch_open_interest_history(self, symbol: str, timeframe='1d', since: Int = None, limit: Int = None, params={}):
7021
7117
  """
7022
7118
  Retrieves the open interest history of a currency
ccxt/okxus.py ADDED
@@ -0,0 +1,54 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ # PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
4
+ # https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
5
+
6
+ from ccxt.okx import okx
7
+ from ccxt.abstract.okxus import ImplicitAPI
8
+ from ccxt.base.types import Any
9
+
10
+
11
+ class okxus(okx, ImplicitAPI):
12
+
13
+ def describe(self) -> Any:
14
+ return self.deep_extend(super(okxus, self).describe(), {
15
+ 'id': 'okxus',
16
+ 'name': 'OKX(US)',
17
+ 'certified': False,
18
+ 'pro': True,
19
+ 'hostname': 'us.okx.com',
20
+ 'urls': {
21
+ 'logo': 'https://user-images.githubusercontent.com/1294454/152485636-38b19e4a-bece-4dec-979a-5982859ffc04.jpg',
22
+ 'api': {
23
+ 'rest': 'https://{hostname}',
24
+ },
25
+ 'www': 'https://app.okx.com',
26
+ 'doc': 'https://app.okx.com/docs-v5/en/#overview',
27
+ 'fees': 'https://app.okx.com/pages/products/fees.html',
28
+ 'referral': {
29
+ 'url': 'https://www.app.okx.com/join/CCXT2023',
30
+ 'discount': 0.2,
31
+ },
32
+ 'test': {
33
+ 'rest': 'https://{hostname}',
34
+ },
35
+ },
36
+ 'has': {
37
+ 'CORS': None,
38
+ 'spot': True,
39
+ 'margin': None,
40
+ 'swap': False,
41
+ 'future': False,
42
+ 'option': False,
43
+ },
44
+ 'features': {
45
+ 'swap': {
46
+ 'linear': None,
47
+ 'inverse': None,
48
+ },
49
+ 'future': {
50
+ 'linear': None,
51
+ 'inverse': None,
52
+ },
53
+ },
54
+ })
ccxt/onetrading.py CHANGED
@@ -405,9 +405,12 @@ class onetrading(Exchange, ImplicitAPI):
405
405
  #
406
406
  # [
407
407
  # {
408
- # "code":"BEST",
409
- # "precision":8
410
- # }
408
+ # "code": "USDT",
409
+ # "precision": 6,
410
+ # "unified_cryptoasset_id": 825,
411
+ # "name": "Tether USDt",
412
+ # "collateral_percentage": 0
413
+ # },
411
414
  # ]
412
415
  #
413
416
  result: dict = {}
@@ -415,11 +418,11 @@ class onetrading(Exchange, ImplicitAPI):
415
418
  currency = response[i]
416
419
  id = self.safe_string(currency, 'code')
417
420
  code = self.safe_currency_code(id)
418
- result[code] = {
421
+ result[code] = self.safe_currency_structure({
419
422
  'id': id,
420
423
  'code': code,
421
- 'name': None,
422
- 'info': currency, # the original payload
424
+ 'name': self.safe_string(currency, 'name'),
425
+ 'info': currency,
423
426
  'active': None,
424
427
  'fee': None,
425
428
  'precision': self.parse_number(self.parse_precision(self.safe_string(currency, 'precision'))),
@@ -430,7 +433,7 @@ class onetrading(Exchange, ImplicitAPI):
430
433
  'withdraw': {'min': None, 'max': None},
431
434
  },
432
435
  'networks': {},
433
- }
436
+ })
434
437
  return result
435
438
 
436
439
  def fetch_markets(self, params={}) -> List[Market]:
ccxt/oxfun.py CHANGED
@@ -24,7 +24,6 @@ from ccxt.base.errors import NetworkError
24
24
  from ccxt.base.errors import RateLimitExceeded
25
25
  from ccxt.base.errors import RequestTimeout
26
26
  from ccxt.base.decimal_to_precision import TICK_SIZE
27
- from ccxt.base.precise import Precise
28
27
 
29
28
 
30
29
  class oxfun(Exchange, ImplicitAPI):
@@ -612,66 +611,7 @@ class oxfun(Exchange, ImplicitAPI):
612
611
  # "minDeposit": "0.00010",
613
612
  # "minWithdrawal": "0.00010"
614
613
  # },
615
- # {
616
- # "network": "Arbitrum",
617
- # "tokenId": "0xba0Dda8762C24dA9487f5FA026a9B64b695A07Ea",
618
- # "transactionPrecision": "18",
619
- # "isWithdrawalFeeChargedToUser": True,
620
- # "canDeposit": True,
621
- # "canWithdraw": True,
622
- # "minDeposit": "0.00010",
623
- # "minWithdrawal": "0.00010"
624
- # },
625
- # {
626
- # "network": "Ethereum",
627
- # "tokenId": "0xba0Dda8762C24dA9487f5FA026a9B64b695A07Ea",
628
- # "transactionPrecision": "18",
629
- # "isWithdrawalFeeChargedToUser": True,
630
- # "canDeposit": True,
631
- # "canWithdraw": True,
632
- # "minDeposit": "0.00010",
633
- # "minWithdrawal": "0.00010"
634
- # },
635
- # {
636
- # "network": "Arbitrum",
637
- # "tokenId": "0x78a0A62Fba6Fb21A83FE8a3433d44C73a4017A6f",
638
- # "transactionPrecision": "18",
639
- # "isWithdrawalFeeChargedToUser": True,
640
- # "canDeposit": True,
641
- # "canWithdraw": False,
642
- # "minDeposit": "0.00010",
643
- # "minWithdrawal": "0.00010"
644
- # },
645
- # {
646
- # "network": "Avalanche",
647
- # "tokenId": "0x78a0A62Fba6Fb21A83FE8a3433d44C73a4017A6f",
648
- # "transactionPrecision": "18",
649
- # "isWithdrawalFeeChargedToUser": True,
650
- # "canDeposit": True,
651
- # "canWithdraw": False,
652
- # "minDeposit": "0.00010",
653
- # "minWithdrawal": "0.00010"
654
- # },
655
- # {
656
- # "network": "Solana",
657
- # "tokenId": "DV3845GEAVXfwpyVGGgWbqBVCtzHdCXNCGfcdboSEuZz",
658
- # "transactionPrecision": "8",
659
- # "isWithdrawalFeeChargedToUser": True,
660
- # "canDeposit": True,
661
- # "canWithdraw": True,
662
- # "minDeposit": "0.00010",
663
- # "minWithdrawal": "0.00010"
664
- # },
665
- # {
666
- # "network": "Ethereum",
667
- # "tokenId": "0x78a0A62Fba6Fb21A83FE8a3433d44C73a4017A6f",
668
- # "transactionPrecision": "18",
669
- # "isWithdrawalFeeChargedToUser": True,
670
- # "canDeposit": True,
671
- # "canWithdraw": False,
672
- # "minDeposit": "0.00010",
673
- # "minWithdrawal": "0.00010"
674
- # }
614
+ # ...
675
615
  # ]
676
616
  # },
677
617
  # {
@@ -721,74 +661,64 @@ class oxfun(Exchange, ImplicitAPI):
721
661
  parts = fullId.split('.')
722
662
  id = parts[0]
723
663
  code = self.safe_currency_code(id)
724
- networks: dict = {}
664
+ if not (code in result):
665
+ result[code] = {
666
+ 'id': id,
667
+ 'code': code,
668
+ 'precision': None,
669
+ 'type': None,
670
+ 'name': None,
671
+ 'active': None,
672
+ 'deposit': None,
673
+ 'withdraw': None,
674
+ 'fee': None,
675
+ 'limits': {
676
+ 'withdraw': {
677
+ 'min': None,
678
+ 'max': None,
679
+ },
680
+ 'deposit': {
681
+ 'min': None,
682
+ 'max': None,
683
+ },
684
+ },
685
+ 'networks': {},
686
+ 'info': [],
687
+ }
725
688
  chains = self.safe_list(currency, 'networkList', [])
726
- currencyMaxPrecision: Str = None
727
- currencyDepositEnabled: Bool = None
728
- currencyWithdrawEnabled: Bool = None
729
689
  for j in range(0, len(chains)):
730
690
  chain = chains[j]
731
691
  networkId = self.safe_string(chain, 'network')
732
692
  networkCode = self.network_id_to_code(networkId)
733
- deposit = self.safe_bool(chain, 'canDeposit')
734
- withdraw = self.safe_bool(chain, 'canWithdraw')
735
- active = (deposit and withdraw)
736
- minDeposit = self.safe_string(chain, 'minDeposit')
737
- minWithdrawal = self.safe_string(chain, 'minWithdrawal')
738
- precision = self.parse_precision(self.safe_string(chain, 'transactionPrecision'))
739
- networks[networkCode] = {
693
+ result[code]['networks'][networkCode] = {
740
694
  'id': networkId,
741
695
  'network': networkCode,
742
696
  'margin': None,
743
- 'deposit': deposit,
744
- 'withdraw': withdraw,
745
- 'active': active,
697
+ 'deposit': self.safe_bool(chain, 'canDeposit'),
698
+ 'withdraw': self.safe_bool(chain, 'canWithdraw'),
699
+ 'active': None,
746
700
  'fee': None,
747
- 'precision': self.parse_number(precision),
701
+ 'precision': self.parse_number(self.parse_precision(self.safe_string(chain, 'transactionPrecision'))),
748
702
  'limits': {
749
703
  'deposit': {
750
- 'min': minDeposit,
704
+ 'min': self.safe_number(chain, 'minDeposit'),
751
705
  'max': None,
752
706
  },
753
707
  'withdraw': {
754
- 'min': minWithdrawal,
708
+ 'min': self.safe_number(chain, 'minWithdrawal'),
755
709
  'max': None,
756
710
  },
757
711
  },
758
712
  'info': chain,
759
713
  }
760
- if (currencyDepositEnabled is None) or deposit:
761
- currencyDepositEnabled = deposit
762
- if (currencyWithdrawEnabled is None) or withdraw:
763
- currencyWithdrawEnabled = withdraw
764
- if (currencyMaxPrecision is None) or Precise.string_gt(currencyMaxPrecision, precision):
765
- currencyMaxPrecision = precision
766
- if code in result:
767
- # checking for specific ids.ARB
768
- networks = self.extend(result[code]['networks'], networks)
769
- result[code] = {
770
- 'id': id,
771
- 'code': code,
772
- 'name': None,
773
- 'type': None,
774
- 'active': None,
775
- 'deposit': currencyDepositEnabled,
776
- 'withdraw': currencyWithdrawEnabled,
777
- 'fee': None,
778
- 'precision': self.parse_number(currencyMaxPrecision),
779
- 'limits': {
780
- 'amount': {
781
- 'min': None,
782
- 'max': None,
783
- },
784
- 'withdraw': {
785
- 'min': None,
786
- 'max': None,
787
- },
788
- },
789
- 'networks': networks,
790
- 'info': currency,
791
- }
714
+ infos = self.safe_list(result[code], 'info', [])
715
+ infos.append(currency)
716
+ result[code]['info'] = infos
717
+ # only after all entries are formed in currencies, restructure each entry
718
+ allKeys = list(result.keys())
719
+ for i in range(0, len(allKeys)):
720
+ code = allKeys[i]
721
+ result[code] = self.safe_currency_structure(result[code]) # self is needed after adding network entry
792
722
  return result
793
723
 
794
724
  def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
ccxt/paradex.py CHANGED
@@ -1245,7 +1245,13 @@ class paradex(Exchange, ImplicitAPI):
1245
1245
  price = self.safe_string(order, 'price')
1246
1246
  amount = self.safe_string(order, 'size')
1247
1247
  orderType = self.safe_string(order, 'type')
1248
+ cancelReason = self.safe_string(order, 'cancel_reason')
1248
1249
  status = self.safe_string(order, 'status')
1250
+ if cancelReason is not None:
1251
+ if cancelReason == 'NOT_ENOUGH_MARGIN':
1252
+ status = 'rejected'
1253
+ else:
1254
+ status = 'canceled'
1249
1255
  side = self.safe_string_lower(order, 'side')
1250
1256
  average = self.omit_zero(self.safe_string(order, 'avg_fill_price'))
1251
1257
  remaining = self.omit_zero(self.safe_string(order, 'remaining_size'))