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
@@ -454,44 +454,44 @@ class ndax(Exchange, ImplicitAPI):
454
454
  }
455
455
  response = await 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
  async def fetch_markets(self, params={}) -> List[Market]:
@@ -840,47 +840,30 @@ class okcoin(Exchange, ImplicitAPI):
840
840
  return None
841
841
  else:
842
842
  response = await 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
  async def fetch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
ccxt/async_support/okx.py CHANGED
@@ -7,7 +7,7 @@ from ccxt.async_support.base.exchange import Exchange
7
7
  from ccxt.abstract.okx import ImplicitAPI
8
8
  import asyncio
9
9
  import hashlib
10
- 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
10
+ 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
11
11
  from typing import List
12
12
  from ccxt.base.errors import ExchangeError
13
13
  from ccxt.base.errors import AuthenticationError
@@ -109,7 +109,7 @@ class okx(Exchange, ImplicitAPI):
109
109
  'fetchFundingIntervals': False,
110
110
  'fetchFundingRate': True,
111
111
  'fetchFundingRateHistory': True,
112
- 'fetchFundingRates': False,
112
+ 'fetchFundingRates': True,
113
113
  'fetchGreeks': True,
114
114
  'fetchIndexOHLCV': True,
115
115
  'fetchIsolatedBorrowRate': False,
@@ -132,6 +132,7 @@ class okx(Exchange, ImplicitAPI):
132
132
  'fetchOHLCV': True,
133
133
  'fetchOpenInterest': True,
134
134
  'fetchOpenInterestHistory': True,
135
+ 'fetchOpenInterests': True,
135
136
  'fetchOpenOrder': None,
136
137
  'fetchOpenOrders': True,
137
138
  'fetchOption': True,
@@ -389,6 +390,7 @@ class okx(Exchange, ImplicitAPI):
389
390
  'account/spot-manual-borrow-repay': 10,
390
391
  'account/set-auto-repay': 4,
391
392
  'account/spot-borrow-repay-history': 4,
393
+ 'account/move-positions-history': 10,
392
394
  # subaccount
393
395
  'users/subaccount/list': 10,
394
396
  'account/subaccount/balances': 10 / 3,
@@ -526,6 +528,7 @@ class okx(Exchange, ImplicitAPI):
526
528
  'account/fixed-loan/manual-reborrow': 5,
527
529
  'account/fixed-loan/repay-borrowing-order': 5,
528
530
  'account/bills-history-archive': 72000, # 12 req/day
531
+ 'account/move-positions': 10,
529
532
  # subaccount
530
533
  'users/subaccount/modify-apikey': 10,
531
534
  'asset/subaccount/transfer': 10,
@@ -992,6 +995,13 @@ class okx(Exchange, ImplicitAPI):
992
995
  '70010': BadRequest, # Timestamp parameters need to be in Unix timestamp format in milliseconds.
993
996
  '70013': BadRequest, # endTs needs to be bigger than or equal to beginTs.
994
997
  '70016': BadRequest, # Please specify your instrument settings for at least one instType.
998
+ '70060': BadRequest, # The account doesn’t exist or the position side is incorrect. To and from accounts must be under the same main account.
999
+ '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.
1000
+ '70062': BadRequest, # account has reached the maximum number of position transfers allowed per day.
1001
+ '70064': BadRequest, # Position does not exist.
1002
+ '70065': BadRequest, # Couldn’t move position. Execution price cannot be determined
1003
+ '70066': BadRequest, # Moving positions isn't supported in spot mode. Switch to any other account mode and try again.
1004
+ '70067': BadRequest, # Moving positions isn't supported in margin trading.
995
1005
  '1009': BadRequest, # Request message exceeds the maximum frame length
996
1006
  '4001': AuthenticationError, # Login Failed
997
1007
  '4002': BadRequest, # Invalid Request
@@ -5976,7 +5986,7 @@ class okx(Exchange, ImplicitAPI):
5976
5986
  nextFundingRate = self.safe_number(contract, 'nextFundingRate')
5977
5987
  fundingTime = self.safe_integer(contract, 'fundingTime')
5978
5988
  fundingTimeString = self.safe_string(contract, 'fundingTime')
5979
- nextFundingTimeString = self.safe_string(contract, 'nextFundingRate')
5989
+ nextFundingTimeString = self.safe_string(contract, 'nextFundingTime')
5980
5990
  millisecondsInterval = Precise.string_sub(nextFundingTimeString, fundingTimeString)
5981
5991
  # https://www.okx.com/support/hc/en-us/articles/360053909272-Ⅸ-Introduction-to-perpetual-swap-funding-fee
5982
5992
  # > The current interest is 0.
@@ -6061,6 +6071,39 @@ class okx(Exchange, ImplicitAPI):
6061
6071
  entry = self.safe_dict(data, 0, {})
6062
6072
  return self.parse_funding_rate(entry, market)
6063
6073
 
6074
+ async def fetch_funding_rates(self, symbols: Strings = None, params={}) -> FundingRates:
6075
+ """
6076
+ fetches the current funding rates for multiple symbols
6077
+
6078
+ https://www.okx.com/docs-v5/en/#public-data-rest-api-get-funding-rate
6079
+
6080
+ :param str[] symbols: unified market symbols
6081
+ :param dict [params]: extra parameters specific to the exchange API endpoint
6082
+ :returns dict: a dictionary of `funding rates structure <https://docs.ccxt.com/#/?id=funding-rates-structure>`
6083
+ """
6084
+ await self.load_markets()
6085
+ symbols = self.market_symbols(symbols, 'swap', True)
6086
+ request: dict = {'instId': 'ANY'}
6087
+ response = await self.publicGetPublicFundingRate(self.extend(request, params))
6088
+ #
6089
+ # {
6090
+ # "code": "0",
6091
+ # "data": [
6092
+ # {
6093
+ # "fundingRate": "0.00027815",
6094
+ # "fundingTime": "1634256000000",
6095
+ # "instId": "BTC-USD-SWAP",
6096
+ # "instType": "SWAP",
6097
+ # "nextFundingRate": "0.00017",
6098
+ # "nextFundingTime": "1634284800000"
6099
+ # }
6100
+ # ],
6101
+ # "msg": ""
6102
+ # }
6103
+ #
6104
+ data = self.safe_list(response, 'data', [])
6105
+ return self.parse_funding_rates(data, symbols)
6106
+
6064
6107
  async def fetch_funding_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
6065
6108
  """
6066
6109
  fetch the history of funding payments paid and received on self account
@@ -7018,6 +7061,59 @@ class okx(Exchange, ImplicitAPI):
7018
7061
  data = self.safe_list(response, 'data', [])
7019
7062
  return self.parse_open_interest(data[0], market)
7020
7063
 
7064
+ async def fetch_open_interests(self, symbols: Strings = None, params={}) -> OpenInterests:
7065
+ """
7066
+ Retrieves the open interests of some currencies
7067
+
7068
+ https://www.okx.com/docs-v5/en/#rest-api-public-data-get-open-interest
7069
+
7070
+ :param str[] symbols: Unified CCXT market symbols
7071
+ :param dict [params]: exchange specific parameters
7072
+ :param str params['instType']: Instrument type, options: 'SWAP', 'FUTURES', 'OPTION', default to 'SWAP'
7073
+ :param str params['uly']: Underlying, Applicable to FUTURES/SWAP/OPTION, if instType is 'OPTION', either uly or instFamily is required
7074
+ :param str params['instFamily']: Instrument family, Applicable to FUTURES/SWAP/OPTION, if instType is 'OPTION', either uly or instFamily is required
7075
+ :returns dict: an dictionary of `open interest structures <https://docs.ccxt.com/#/?id=open-interest-structure>`
7076
+ """
7077
+ await self.load_markets()
7078
+ symbols = self.market_symbols(symbols, None, True, True)
7079
+ market = None
7080
+ if symbols is not None:
7081
+ market = self.market(symbols[0])
7082
+ marketType = None
7083
+ marketType, params = self.handle_sub_type_and_params('fetchOpenInterests', market, params, 'swap')
7084
+ instType = 'SWAP'
7085
+ if marketType == 'future':
7086
+ instType = 'FUTURES'
7087
+ elif instType == 'option':
7088
+ instType = 'OPTION'
7089
+ request: dict = {'instType': instType}
7090
+ uly = self.safe_string(params, 'uly')
7091
+ if uly is not None:
7092
+ request['uly'] = uly
7093
+ instFamily = self.safe_string(params, 'instFamily')
7094
+ if instFamily is not None:
7095
+ request['instFamily'] = instFamily
7096
+ if instType == 'OPTION' and uly is None and instFamily is None:
7097
+ raise BadRequest(self.id + ' fetchOpenInterests() requires either uly or instFamily parameter for OPTION markets')
7098
+ response = await self.publicGetPublicOpenInterest(self.extend(request, params))
7099
+ #
7100
+ # {
7101
+ # "code": "0",
7102
+ # "data": [
7103
+ # {
7104
+ # "instId": "BTC-USDT-SWAP",
7105
+ # "instType": "SWAP",
7106
+ # "oi": "2125419",
7107
+ # "oiCcy": "21254.19",
7108
+ # "ts": "1664005108969"
7109
+ # }
7110
+ # ],
7111
+ # "msg": ""
7112
+ # }
7113
+ #
7114
+ data = self.safe_list(response, 'data', [])
7115
+ return self.parse_open_interests(data, symbols)
7116
+
7021
7117
  async def fetch_open_interest_history(self, symbol: str, timeframe='1d', since: Int = None, limit: Int = None, params={}):
7022
7118
  """
7023
7119
  Retrieves the open interest history of a currency
@@ -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.async_support.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
+ })
@@ -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
  async def fetch_markets(self, params={}) -> List[Market]:
@@ -25,7 +25,6 @@ from ccxt.base.errors import NetworkError
25
25
  from ccxt.base.errors import RateLimitExceeded
26
26
  from ccxt.base.errors import RequestTimeout
27
27
  from ccxt.base.decimal_to_precision import TICK_SIZE
28
- from ccxt.base.precise import Precise
29
28
 
30
29
 
31
30
  class oxfun(Exchange, ImplicitAPI):
@@ -613,66 +612,7 @@ class oxfun(Exchange, ImplicitAPI):
613
612
  # "minDeposit": "0.00010",
614
613
  # "minWithdrawal": "0.00010"
615
614
  # },
616
- # {
617
- # "network": "Arbitrum",
618
- # "tokenId": "0xba0Dda8762C24dA9487f5FA026a9B64b695A07Ea",
619
- # "transactionPrecision": "18",
620
- # "isWithdrawalFeeChargedToUser": True,
621
- # "canDeposit": True,
622
- # "canWithdraw": True,
623
- # "minDeposit": "0.00010",
624
- # "minWithdrawal": "0.00010"
625
- # },
626
- # {
627
- # "network": "Ethereum",
628
- # "tokenId": "0xba0Dda8762C24dA9487f5FA026a9B64b695A07Ea",
629
- # "transactionPrecision": "18",
630
- # "isWithdrawalFeeChargedToUser": True,
631
- # "canDeposit": True,
632
- # "canWithdraw": True,
633
- # "minDeposit": "0.00010",
634
- # "minWithdrawal": "0.00010"
635
- # },
636
- # {
637
- # "network": "Arbitrum",
638
- # "tokenId": "0x78a0A62Fba6Fb21A83FE8a3433d44C73a4017A6f",
639
- # "transactionPrecision": "18",
640
- # "isWithdrawalFeeChargedToUser": True,
641
- # "canDeposit": True,
642
- # "canWithdraw": False,
643
- # "minDeposit": "0.00010",
644
- # "minWithdrawal": "0.00010"
645
- # },
646
- # {
647
- # "network": "Avalanche",
648
- # "tokenId": "0x78a0A62Fba6Fb21A83FE8a3433d44C73a4017A6f",
649
- # "transactionPrecision": "18",
650
- # "isWithdrawalFeeChargedToUser": True,
651
- # "canDeposit": True,
652
- # "canWithdraw": False,
653
- # "minDeposit": "0.00010",
654
- # "minWithdrawal": "0.00010"
655
- # },
656
- # {
657
- # "network": "Solana",
658
- # "tokenId": "DV3845GEAVXfwpyVGGgWbqBVCtzHdCXNCGfcdboSEuZz",
659
- # "transactionPrecision": "8",
660
- # "isWithdrawalFeeChargedToUser": True,
661
- # "canDeposit": True,
662
- # "canWithdraw": True,
663
- # "minDeposit": "0.00010",
664
- # "minWithdrawal": "0.00010"
665
- # },
666
- # {
667
- # "network": "Ethereum",
668
- # "tokenId": "0x78a0A62Fba6Fb21A83FE8a3433d44C73a4017A6f",
669
- # "transactionPrecision": "18",
670
- # "isWithdrawalFeeChargedToUser": True,
671
- # "canDeposit": True,
672
- # "canWithdraw": False,
673
- # "minDeposit": "0.00010",
674
- # "minWithdrawal": "0.00010"
675
- # }
615
+ # ...
676
616
  # ]
677
617
  # },
678
618
  # {
@@ -722,74 +662,64 @@ class oxfun(Exchange, ImplicitAPI):
722
662
  parts = fullId.split('.')
723
663
  id = parts[0]
724
664
  code = self.safe_currency_code(id)
725
- networks: dict = {}
665
+ if not (code in result):
666
+ result[code] = {
667
+ 'id': id,
668
+ 'code': code,
669
+ 'precision': None,
670
+ 'type': None,
671
+ 'name': None,
672
+ 'active': None,
673
+ 'deposit': None,
674
+ 'withdraw': None,
675
+ 'fee': None,
676
+ 'limits': {
677
+ 'withdraw': {
678
+ 'min': None,
679
+ 'max': None,
680
+ },
681
+ 'deposit': {
682
+ 'min': None,
683
+ 'max': None,
684
+ },
685
+ },
686
+ 'networks': {},
687
+ 'info': [],
688
+ }
726
689
  chains = self.safe_list(currency, 'networkList', [])
727
- currencyMaxPrecision: Str = None
728
- currencyDepositEnabled: Bool = None
729
- currencyWithdrawEnabled: Bool = None
730
690
  for j in range(0, len(chains)):
731
691
  chain = chains[j]
732
692
  networkId = self.safe_string(chain, 'network')
733
693
  networkCode = self.network_id_to_code(networkId)
734
- deposit = self.safe_bool(chain, 'canDeposit')
735
- withdraw = self.safe_bool(chain, 'canWithdraw')
736
- active = (deposit and withdraw)
737
- minDeposit = self.safe_string(chain, 'minDeposit')
738
- minWithdrawal = self.safe_string(chain, 'minWithdrawal')
739
- precision = self.parse_precision(self.safe_string(chain, 'transactionPrecision'))
740
- networks[networkCode] = {
694
+ result[code]['networks'][networkCode] = {
741
695
  'id': networkId,
742
696
  'network': networkCode,
743
697
  'margin': None,
744
- 'deposit': deposit,
745
- 'withdraw': withdraw,
746
- 'active': active,
698
+ 'deposit': self.safe_bool(chain, 'canDeposit'),
699
+ 'withdraw': self.safe_bool(chain, 'canWithdraw'),
700
+ 'active': None,
747
701
  'fee': None,
748
- 'precision': self.parse_number(precision),
702
+ 'precision': self.parse_number(self.parse_precision(self.safe_string(chain, 'transactionPrecision'))),
749
703
  'limits': {
750
704
  'deposit': {
751
- 'min': minDeposit,
705
+ 'min': self.safe_number(chain, 'minDeposit'),
752
706
  'max': None,
753
707
  },
754
708
  'withdraw': {
755
- 'min': minWithdrawal,
709
+ 'min': self.safe_number(chain, 'minWithdrawal'),
756
710
  'max': None,
757
711
  },
758
712
  },
759
713
  'info': chain,
760
714
  }
761
- if (currencyDepositEnabled is None) or deposit:
762
- currencyDepositEnabled = deposit
763
- if (currencyWithdrawEnabled is None) or withdraw:
764
- currencyWithdrawEnabled = withdraw
765
- if (currencyMaxPrecision is None) or Precise.string_gt(currencyMaxPrecision, precision):
766
- currencyMaxPrecision = precision
767
- if code in result:
768
- # checking for specific ids.ARB
769
- networks = self.extend(result[code]['networks'], networks)
770
- result[code] = {
771
- 'id': id,
772
- 'code': code,
773
- 'name': None,
774
- 'type': None,
775
- 'active': None,
776
- 'deposit': currencyDepositEnabled,
777
- 'withdraw': currencyWithdrawEnabled,
778
- 'fee': None,
779
- 'precision': self.parse_number(currencyMaxPrecision),
780
- 'limits': {
781
- 'amount': {
782
- 'min': None,
783
- 'max': None,
784
- },
785
- 'withdraw': {
786
- 'min': None,
787
- 'max': None,
788
- },
789
- },
790
- 'networks': networks,
791
- 'info': currency,
792
- }
715
+ infos = self.safe_list(result[code], 'info', [])
716
+ infos.append(currency)
717
+ result[code]['info'] = infos
718
+ # only after all entries are formed in currencies, restructure each entry
719
+ allKeys = list(result.keys())
720
+ for i in range(0, len(allKeys)):
721
+ code = allKeys[i]
722
+ result[code] = self.safe_currency_structure(result[code]) # self is needed after adding network entry
793
723
  return result
794
724
 
795
725
  async def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
@@ -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'))