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
ccxt/kraken.py CHANGED
@@ -468,7 +468,7 @@ class kraken(Exchange, ImplicitAPI):
468
468
  def fetch_markets(self, params={}):
469
469
  """
470
470
  retrieves data on all markets for kraken
471
- :see: https://docs.kraken.com/rest/#tag/Market-Data/operation/getTradableAssetPairs
471
+ :see: https://docs.kraken.com/rest/#tag/Spot-Market-Data/operation/getTradableAssetPairs
472
472
  :param dict [params]: extra parameters specific to the exchange API endpoint
473
473
  :returns dict[]: an array of objects representing market data
474
474
  """
@@ -644,7 +644,7 @@ class kraken(Exchange, ImplicitAPI):
644
644
  def fetch_currencies(self, params={}):
645
645
  """
646
646
  fetches all available currencies on an exchange
647
- :see: https://docs.kraken.com/rest/#tag/Market-Data/operation/getAssetInfo
647
+ :see: https://docs.kraken.com/rest/#tag/Spot-Market-Data/operation/getAssetInfo
648
648
  :param dict [params]: extra parameters specific to the exchange API endpoint
649
649
  :returns dict: an associative dictionary of currencies
650
650
  """
@@ -767,7 +767,7 @@ class kraken(Exchange, ImplicitAPI):
767
767
  def fetch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
768
768
  """
769
769
  fetches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
770
- :see: https://docs.kraken.com/rest/#tag/Market-Data/operation/getOrderBook
770
+ :see: https://docs.kraken.com/rest/#tag/Spot-Market-Data/operation/getOrderBook
771
771
  :param str symbol: unified symbol of the market to fetch the order book for
772
772
  :param int [limit]: the maximum amount of order book entries to return
773
773
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -864,7 +864,7 @@ class kraken(Exchange, ImplicitAPI):
864
864
  def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
865
865
  """
866
866
  fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
867
- :see: https://docs.kraken.com/rest/#tag/Market-Data/operation/getTickerInformation
867
+ :see: https://docs.kraken.com/rest/#tag/Spot-Market-Data/operation/getTickerInformation
868
868
  :param str[]|None symbols: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
869
869
  :param dict [params]: extra parameters specific to the exchange API endpoint
870
870
  :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
@@ -895,7 +895,7 @@ class kraken(Exchange, ImplicitAPI):
895
895
  def fetch_ticker(self, symbol: str, params={}) -> Ticker:
896
896
  """
897
897
  fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
898
- :see: https://docs.kraken.com/rest/#tag/Market-Data/operation/getTickerInformation
898
+ :see: https://docs.kraken.com/rest/#tag/Spot-Market-Data/operation/getTickerInformation
899
899
  :param str symbol: unified symbol of the market to fetch the ticker for
900
900
  :param dict [params]: extra parameters specific to the exchange API endpoint
901
901
  :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
@@ -937,7 +937,7 @@ class kraken(Exchange, ImplicitAPI):
937
937
  def fetch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
938
938
  """
939
939
  fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
940
- :see: https://docs.kraken.com/rest/#tag/Market-Data/operation/getOHLCData
940
+ :see: https://docs.kraken.com/rest/#tag/Spot-Market-Data/operation/getOHLCData
941
941
  :param str symbol: unified symbol of the market to fetch OHLCV data for
942
942
  :param str timeframe: the length of time each candle represents
943
943
  :param int [since]: timestamp in ms of the earliest candle to fetch
@@ -1212,7 +1212,7 @@ class kraken(Exchange, ImplicitAPI):
1212
1212
  def fetch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
1213
1213
  """
1214
1214
  get the list of most recent trades for a particular symbol
1215
- :see: https://docs.kraken.com/rest/#tag/Market-Data/operation/getRecentTrades
1215
+ :see: https://docs.kraken.com/rest/#tag/Spot-Market-Data/operation/getRecentTrades
1216
1216
  :param str symbol: unified symbol of the market to fetch trades for
1217
1217
  :param int [since]: timestamp in ms of the earliest trade to fetch
1218
1218
  :param int [limit]: the maximum amount of trades to fetch
@@ -2264,7 +2264,7 @@ class kraken(Exchange, ImplicitAPI):
2264
2264
  def fetch_time(self, params={}):
2265
2265
  """
2266
2266
  fetches the current integer timestamp in milliseconds from the exchange server
2267
- :see: https://docs.kraken.com/rest/#tag/Market-Data/operation/getServerTime
2267
+ :see: https://docs.kraken.com/rest/#tag/Spot-Market-Data/operation/getServerTime
2268
2268
  :param dict [params]: extra parameters specific to the exchange API endpoint
2269
2269
  :returns int: the current integer timestamp in milliseconds from the exchange server
2270
2270
  """
ccxt/kucoin.py CHANGED
@@ -70,8 +70,8 @@ class kucoin(Exchange, ImplicitAPI):
70
70
  'fetchAccounts': True,
71
71
  'fetchBalance': True,
72
72
  'fetchBorrowInterest': True,
73
- 'fetchBorrowRateHistories': False,
74
- 'fetchBorrowRateHistory': False,
73
+ 'fetchBorrowRateHistories': True,
74
+ 'fetchBorrowRateHistory': True,
75
75
  'fetchClosedOrders': True,
76
76
  'fetchCrossBorrowRate': False,
77
77
  'fetchCrossBorrowRates': False,
@@ -245,6 +245,7 @@ class kucoin(Exchange, ImplicitAPI):
245
245
  'isolated/account/{symbol}': 50, # 50SW
246
246
  'margin/borrow': 15, # 15SW
247
247
  'margin/repay': 15, # 15SW
248
+ 'margin/interest': 20, # 20SW
248
249
  'project/list': 10, # 10SW
249
250
  'project/marketInterestRate': 7.5, # 5PW
250
251
  'redeem/orders': 10, # 10SW
@@ -463,6 +464,56 @@ class kucoin(Exchange, ImplicitAPI):
463
464
  '130202': ExchangeError, # The system is renewing the loan automatically. Please try again later
464
465
  '130203': InsufficientFunds, # Insufficient account balance
465
466
  '130204': BadRequest, # As the total lending amount for platform leverage reaches the platform's maximum position limit, the system suspends the borrowing function of leverage
467
+ '130301': InsufficientFunds, # Insufficient account balance
468
+ '130302': PermissionDenied, # Your relevant permission rights have been restricted, you can contact customer service for processing
469
+ '130303': NotSupported, # The current trading pair does not support isolated positions
470
+ '130304': NotSupported, # The trading function of the current trading pair is not enabled
471
+ '130305': NotSupported, # The current trading pair does not support cross position
472
+ '130306': NotSupported, # The account has not opened leveraged trading
473
+ '130307': NotSupported, # Please reopen the leverage agreement
474
+ '130308': InvalidOrder, # Position renewal freeze
475
+ '130309': InvalidOrder, # Position forced liquidation freeze
476
+ '130310': ExchangeError, # Abnormal leverage account status
477
+ '130311': InvalidOrder, # Failed to place an order, triggering buy limit
478
+ '130312': InvalidOrder, # Trigger global position limit, suspend buying
479
+ '130313': InvalidOrder, # Trigger global position limit, suspend selling
480
+ '130314': InvalidOrder, # Trigger the global position limit and prompt the remaining quantity available for purchase
481
+ '130315': NotSupported, # This feature has been suspended due to country restrictions
482
+ '126000': ExchangeError, # Abnormal margin trading
483
+ '126001': NotSupported, # Users currently do not support high frequency
484
+ '126002': ExchangeError, # There is a risk problem in your account and transactions are temporarily not allowed!
485
+ '126003': InvalidOrder, # The commission amount is less than the minimum transaction amount for a single commission
486
+ '126004': ExchangeError, # Trading pair does not exist or is prohibited
487
+ '126005': PermissionDenied, # This trading pair requires advanced KYC certification before trading
488
+ '126006': ExchangeError, # Trading pair is not available
489
+ '126007': ExchangeError, # Trading pair suspended
490
+ '126009': ExchangeError, # Trading pair is suspended from creating orders
491
+ '126010': ExchangeError, # Trading pair suspended order cancellation
492
+ '126011': ExchangeError, # There are too many orders in the order
493
+ '126013': InsufficientFunds, # Insufficient account balance
494
+ '126015': ExchangeError, # It is prohibited to place orders on self trading pair
495
+ '126021': NotSupported, # This digital asset does not support user participation in your region, thank you for your understanding!
496
+ '126022': InvalidOrder, # The final transaction price of your order will trigger the price protection strategy. To protect the price from deviating too much, please place an order again.
497
+ '126027': InvalidOrder, # Only limit orders are supported
498
+ '126028': InvalidOrder, # Only limit orders are supported before the specified time
499
+ '126029': InvalidOrder, # The maximum order price is: xxx
500
+ '126030': InvalidOrder, # The minimum order price is: xxx
501
+ '126033': InvalidOrder, # Duplicate order
502
+ '126034': InvalidOrder, # Failed to create take profit and stop loss order
503
+ '126036': InvalidOrder, # Failed to create margin order
504
+ '126037': ExchangeError, # Due to country and region restrictions, self function has been suspended!
505
+ '126038': ExchangeError, # Third-party service call failed(internal exception)
506
+ '126039': ExchangeError, # Third-party service call failed, reason: xxx
507
+ '126041': ExchangeError, # clientTimestamp parameter error
508
+ '126042': ExchangeError, # Exceeded maximum position limit
509
+ '126043': OrderNotFound, # Order does not exist
510
+ '126044': InvalidOrder, # clientOid duplicate
511
+ '126045': NotSupported, # This digital asset does not support user participation in your region, thank you for your understanding!
512
+ '126046': NotSupported, # This digital asset does not support your IP region, thank you for your understanding!
513
+ '126047': PermissionDenied, # Please complete identity verification
514
+ '126048': PermissionDenied, # Please complete authentication for the master account
515
+ '135005': ExchangeError, # Margin order query business abnormality
516
+ '135018': ExchangeError, # Margin order query service abnormality
466
517
  '200004': InsufficientFunds,
467
518
  '210014': InvalidOrder, # {"code":"210014","msg":"Exceeds the max. borrowing amount, the remaining amount you can borrow: 0USDT"}
468
519
  '210021': InsufficientFunds, # {"code":"210021","msg":"Balance not enough"}
@@ -484,10 +535,12 @@ class kucoin(Exchange, ImplicitAPI):
484
535
  '400350': InvalidOrder, # {"code":"400350","msg":"Upper limit for holding: 10,000USDT, you can still buy 10,000USDT worth of coin."}
485
536
  '400370': InvalidOrder, # {"code":"400370","msg":"Max. price: 0.02500000000000000000"}
486
537
  '400400': BadRequest, # Parameter error
538
+ '400401': AuthenticationError, # User is not logged in
487
539
  '400500': InvalidOrder, # {"code":"400500","msg":"Your located country/region is currently not supported for the trading of self token"}
488
540
  '400600': BadSymbol, # {"code":"400600","msg":"validation.createOrder.symbolNotAvailable"}
489
541
  '400760': InvalidOrder, # {"code":"400760","msg":"order price should be more than XX"}
490
542
  '401000': BadRequest, # {"code":"401000","msg":"The interface has been deprecated"}
543
+ '408000': BadRequest, # Network timeout, please try again later
491
544
  '411100': AccountSuspended,
492
545
  '415000': BadRequest, # {"code":"415000","msg":"Unsupported Media Type"}
493
546
  '400303': PermissionDenied, # {"msg":"To enjoy the full range of our products and services, we kindly request you complete the identity verification process.","code":"400303"}
@@ -606,6 +659,7 @@ class kucoin(Exchange, ImplicitAPI):
606
659
  'margin/currencies': 'v3',
607
660
  'margin/borrow': 'v3',
608
661
  'margin/repay': 'v3',
662
+ 'margin/interest': 'v3',
609
663
  'project/list': 'v3',
610
664
  'project/marketInterestRate': 'v3',
611
665
  'redeem/orders': 'v3',
@@ -3787,12 +3841,19 @@ class kucoin(Exchange, ImplicitAPI):
3787
3841
  # "timestamp": 1658531274508488480
3788
3842
  # },
3789
3843
  #
3790
- timestampId = self.safe_string(info, 'timestamp')
3791
- timestamp = Precise.string_mul(timestampId, '0.000001')
3844
+ # {
3845
+ # "createdAt": 1697783812257,
3846
+ # "currency": "XMR",
3847
+ # "interestAmount": "0.1",
3848
+ # "dayRatio": "0.001"
3849
+ # }
3850
+ #
3851
+ timestampId = self.safe_string_2(info, 'createdAt', 'timestamp')
3852
+ timestamp = self.parse_to_int(timestampId[0:13])
3792
3853
  currencyId = self.safe_string(info, 'currency')
3793
3854
  return {
3794
3855
  'currency': self.safe_currency_code(currencyId, currency),
3795
- 'rate': self.safe_number(info, 'dailyIntRate'),
3856
+ 'rate': self.safe_number_2(info, 'dailyIntRate', 'dayRatio'),
3796
3857
  'period': 86400000,
3797
3858
  'timestamp': timestamp,
3798
3859
  'datetime': self.iso8601(timestamp),
@@ -3968,6 +4029,132 @@ class kucoin(Exchange, ImplicitAPI):
3968
4029
  'info': info,
3969
4030
  }
3970
4031
 
4032
+ def fetch_borrow_rate_histories(self, codes=None, since: Int = None, limit: Int = None, params={}):
4033
+ """
4034
+ retrieves a history of a multiple currencies borrow interest rate at specific time slots, returns all currencies if no symbols passed, default is None
4035
+ :see: https://www.kucoin.com/docs/rest/margin-trading/margin-trading-v3-/get-cross-isolated-margin-interest-records
4036
+ :param str[]|None codes: list of unified currency codes, default is None
4037
+ :param int [since]: timestamp in ms of the earliest borrowRate, default is None
4038
+ :param int [limit]: max number of borrow rate prices to return, default is None
4039
+ :param dict [params]: extra parameters specific to the exchange API endpoint
4040
+ :param str [params.marginMode]: 'cross' or 'isolated' default is 'cross'
4041
+ :param int [params.until]: the latest time in ms to fetch entries for
4042
+ :returns dict: a dictionary of `borrow rate structures <https://docs.ccxt.com/#/?id=borrow-rate-structure>` indexed by the market symbol
4043
+ """
4044
+ self.load_markets()
4045
+ marginResult = self.handle_margin_mode_and_params('fetchBorrowRateHistories', params)
4046
+ marginMode = self.safe_string(marginResult, 0, 'cross')
4047
+ isIsolated = (marginMode == 'isolated') # True-isolated, False-cross
4048
+ request = {
4049
+ 'isIsolated': isIsolated,
4050
+ }
4051
+ if since is not None:
4052
+ request['startTime'] = since
4053
+ request, params = self.handle_until_option('endTime', request, params)
4054
+ if limit is not None:
4055
+ request['pageSize'] = limit # default:50, min:10, max:500
4056
+ response = self.privateGetMarginInterest(self.extend(request, params))
4057
+ #
4058
+ # {
4059
+ # "code": "200000",
4060
+ # "data": {
4061
+ # "timestamp": 1710829939673,
4062
+ # "currentPage": 1,
4063
+ # "pageSize": 50,
4064
+ # "totalNum": 0,
4065
+ # "totalPage": 0,
4066
+ # "items": [
4067
+ # {
4068
+ # "createdAt": 1697783812257,
4069
+ # "currency": "XMR",
4070
+ # "interestAmount": "0.1",
4071
+ # "dayRatio": "0.001"
4072
+ # }
4073
+ # ]
4074
+ # }
4075
+ # }
4076
+ #
4077
+ data = self.safe_dict(response, 'data')
4078
+ rows = self.safe_list(data, 'items')
4079
+ return self.parse_borrow_rate_histories(rows, codes, since, limit)
4080
+
4081
+ def fetch_borrow_rate_history(self, code: str, since: Int = None, limit: Int = None, params={}):
4082
+ """
4083
+ retrieves a history of a currencies borrow interest rate at specific time slots
4084
+ :see: https://www.kucoin.com/docs/rest/margin-trading/margin-trading-v3-/get-cross-isolated-margin-interest-records
4085
+ :param str code: unified currency code
4086
+ :param int [since]: timestamp for the earliest borrow rate
4087
+ :param int [limit]: the maximum number of `borrow rate structures <https://docs.ccxt.com/#/?id=borrow-rate-structure>` to retrieve
4088
+ :param dict [params]: extra parameters specific to the exchange API endpoint
4089
+ :param str [params.marginMode]: 'cross' or 'isolated' default is 'cross'
4090
+ :param int [params.until]: the latest time in ms to fetch entries for
4091
+ :returns dict[]: an array of `borrow rate structures <https://docs.ccxt.com/#/?id=borrow-rate-structure>`
4092
+ """
4093
+ self.load_markets()
4094
+ marginResult = self.handle_margin_mode_and_params('fetchBorrowRateHistories', params)
4095
+ marginMode = self.safe_string(marginResult, 0, 'cross')
4096
+ isIsolated = (marginMode == 'isolated') # True-isolated, False-cross
4097
+ currency = self.currency(code)
4098
+ request = {
4099
+ 'isIsolated': isIsolated,
4100
+ 'currency': currency['id'],
4101
+ }
4102
+ if since is not None:
4103
+ request['startTime'] = since
4104
+ request, params = self.handle_until_option('endTime', request, params)
4105
+ if limit is not None:
4106
+ request['pageSize'] = limit # default:50, min:10, max:500
4107
+ response = self.privateGetMarginInterest(self.extend(request, params))
4108
+ #
4109
+ # {
4110
+ # "code": "200000",
4111
+ # "data": {
4112
+ # "timestamp": 1710829939673,
4113
+ # "currentPage": 1,
4114
+ # "pageSize": 50,
4115
+ # "totalNum": 0,
4116
+ # "totalPage": 0,
4117
+ # "items": [
4118
+ # {
4119
+ # "createdAt": 1697783812257,
4120
+ # "currency": "XMR",
4121
+ # "interestAmount": "0.1",
4122
+ # "dayRatio": "0.001"
4123
+ # }
4124
+ # ]
4125
+ # }
4126
+ # }
4127
+ #
4128
+ data = self.safe_dict(response, 'data')
4129
+ rows = self.safe_list(data, 'items')
4130
+ return self.parse_borrow_rate_history(rows, code, since, limit)
4131
+
4132
+ def parse_borrow_rate_histories(self, response, codes, since, limit):
4133
+ #
4134
+ # [
4135
+ # {
4136
+ # "createdAt": 1697783812257,
4137
+ # "currency": "XMR",
4138
+ # "interestAmount": "0.1",
4139
+ # "dayRatio": "0.001"
4140
+ # }
4141
+ # ]
4142
+ #
4143
+ borrowRateHistories = {}
4144
+ for i in range(0, len(response)):
4145
+ item = response[i]
4146
+ code = self.safe_currency_code(self.safe_string(item, 'currency'))
4147
+ if codes is None or self.in_array(code, codes):
4148
+ if not (code in borrowRateHistories):
4149
+ borrowRateHistories[code] = []
4150
+ borrowRateStructure = self.parse_borrow_rate(item)
4151
+ borrowRateHistories[code].append(borrowRateStructure)
4152
+ keys = list(borrowRateHistories.keys())
4153
+ for i in range(0, len(keys)):
4154
+ code = keys[i]
4155
+ borrowRateHistories[code] = self.filter_by_currency_since_limit(borrowRateHistories[code], code, since, limit)
4156
+ return borrowRateHistories
4157
+
3971
4158
  def borrow_cross_margin(self, code: str, amount: float, params={}):
3972
4159
  """
3973
4160
  create a loan to borrow margin
ccxt/okcoin.py CHANGED
@@ -266,6 +266,16 @@ class okcoin(Exchange, ImplicitAPI):
266
266
  '50026': ExchangeNotAvailable, # System error, please try again later.
267
267
  '50027': PermissionDenied, # The account is restricted from trading
268
268
  '50028': ExchangeError, # Unable to take the order, please reach out to support center for details
269
+ '50029': ExchangeError, # This instrument({0}) is unavailable at present due to risk management. Please contact customer service for help.
270
+ '50030': PermissionDenied, # No permission to use self API
271
+ '50032': AccountSuspended, # This asset is blocked, allow its trading and try again
272
+ '50033': AccountSuspended, # This instrument is blocked, allow its trading and try again
273
+ '50035': BadRequest, # This endpoint requires that APIKey must be bound to IP
274
+ '50036': BadRequest, # Invalid expTime
275
+ '50037': BadRequest, # Order expired
276
+ '50038': ExchangeError, # This feature is temporarily unavailable in demo trading
277
+ '50039': ExchangeError, # The before parameter is not available for implementing timestamp pagination
278
+ '50041': ExchangeError, # You are not currently on the whitelist, please contact customer service
269
279
  '50044': BadRequest, # Must select one broker type
270
280
  # API Class
271
281
  '50100': ExchangeError, # API frozen, please contact customer service
@@ -309,9 +319,25 @@ class okcoin(Exchange, ImplicitAPI):
309
319
  '51024': AccountSuspended, # Unified accountblocked
310
320
  '51025': ExchangeError, # Order count exceeds the limit
311
321
  '51026': BadSymbol, # Instrument type does not match underlying index
322
+ '51030': InvalidOrder, # Funding fee is being settled.
323
+ '51031': InvalidOrder, # This order price is not within the closing price range
324
+ '51032': InvalidOrder, # Closing all positions at market price.
325
+ '51033': InvalidOrder, # The total amount per order for self pair has reached the upper limit.
326
+ '51037': InvalidOrder, # The current account risk status only supports you to place IOC orders that can reduce the risk of your account.
327
+ '51038': InvalidOrder, # There is already an IOC order under the current risk module that reduces the risk of the account.
328
+ '51044': InvalidOrder, # The order type {0}, {1} is not allowed to set stop loss and take profit
312
329
  '51046': InvalidOrder, # The take profit trigger price must be higher than the order price
313
330
  '51047': InvalidOrder, # The stop loss trigger price must be lower than the order price
314
- '51031': InvalidOrder, # This order price is not within the closing price range
331
+ '51048': InvalidOrder, # The take profit trigger price should be lower than the order price
332
+ '51049': InvalidOrder, # The stop loss trigger price should be higher than the order price
333
+ '51050': InvalidOrder, # The take profit trigger price should be higher than the best ask price
334
+ '51051': InvalidOrder, # The stop loss trigger price should be lower than the best ask price
335
+ '51052': InvalidOrder, # The take profit trigger price should be lower than the best bid price
336
+ '51053': InvalidOrder, # The stop loss trigger price should be higher than the best bid price
337
+ '51054': BadRequest, # Getting information timed out, please try again later
338
+ '51056': InvalidOrder, # Action not allowed
339
+ '51058': InvalidOrder, # No available position for self algo order
340
+ '51059': InvalidOrder, # Strategy for the current state does not support self operation
315
341
  '51100': InvalidOrder, # Trading amount does not meet the min tradable amount
316
342
  '51102': InvalidOrder, # Entered amount exceeds the max pending count
317
343
  '51103': InvalidOrder, # Entered amount exceeds the max pending order count of the underlying asset
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, Balances, Currency, Greeks, Int, Leverage, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry
9
+ from ccxt.base.types import Account, Balances, Currency, Greeks, Int, Leverage, Market, MarketInterface, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry
10
10
  from typing import List
11
11
  from ccxt.base.errors import ExchangeError
12
12
  from ccxt.base.errors import PermissionDenied
@@ -595,6 +595,7 @@ class okx(Exchange, ImplicitAPI):
595
595
  '50027': PermissionDenied, # The account is restricted from trading
596
596
  '50028': ExchangeError, # Unable to take the order, please reach out to support center for details
597
597
  '50044': BadRequest, # Must select one broker type
598
+ '50061': ExchangeError, # You've reached the maximum order rate limit for self account.
598
599
  '50062': ExchangeError, # This feature is currently unavailable.
599
600
  # API Class
600
601
  '50100': ExchangeError, # API frozen, please contact customer service
@@ -782,6 +783,15 @@ class okx(Exchange, ImplicitAPI):
782
783
  # SPOT/MARGIN error codes 54000-54999
783
784
  '54000': ExchangeError, # Margin transactions unavailable
784
785
  '54001': ExchangeError, # Only Multi-currency margin account can be set to borrow coins automatically
786
+ # Trading bot Error Code from 55100 to 55999
787
+ '55100': InvalidOrder, # Take profit % should be within the range of {parameter1}-{parameter2}
788
+ '55101': InvalidOrder, # Stop loss % should be within the range of {parameter1}-{parameter2}
789
+ '55102': InvalidOrder, # Take profit % should be greater than the current bot’s PnL%
790
+ '55103': InvalidOrder, # Stop loss % should be less than the current bot’s PnL%
791
+ '55104': InvalidOrder, # Only futures grid supports take profit or stop loss based on profit percentage
792
+ '55111': InvalidOrder, # This signal name is in use, please try a new name
793
+ '55112': InvalidOrder, # This signal does not exist
794
+ '55113': InvalidOrder, # Create signal strategies with leverage greater than the maximum leverage of the instruments
785
795
  # FUNDING error codes 58000-58999
786
796
  '58000': ExchangeError, # Account type {0} does not supported when getting the sub-account balance
787
797
  '58001': AuthenticationError, # Incorrect trade password
@@ -1195,7 +1205,7 @@ class okx(Exchange, ImplicitAPI):
1195
1205
  'info': None,
1196
1206
  }
1197
1207
 
1198
- def safe_market(self, marketId=None, market=None, delimiter=None, marketType=None):
1208
+ def safe_market(self, marketId: Str = None, market: Market = None, delimiter: Str = None, marketType: Str = None) -> MarketInterface:
1199
1209
  isOption = (marketId is not None) and ((marketId.find('-C') > -1) or (marketId.find('-P') > -1))
1200
1210
  if isOption and not (marketId in self.markets_by_id):
1201
1211
  # handle expired option contracts
@@ -4699,6 +4709,14 @@ class okx(Exchange, ImplicitAPI):
4699
4709
  '3': 'pending',
4700
4710
  '4': 'pending',
4701
4711
  '5': 'pending',
4712
+ '6': 'pending',
4713
+ '7': 'pending',
4714
+ '8': 'pending',
4715
+ '9': 'pending',
4716
+ '10': 'pending',
4717
+ '12': 'pending',
4718
+ '15': 'pending',
4719
+ '16': 'pending',
4702
4720
  }
4703
4721
  return self.safe_string(statuses, status, status)
4704
4722
 
ccxt/pro/__init__.py CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # ----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.2.76'
7
+ __version__ = '4.2.78'
8
8
 
9
9
  # ----------------------------------------------------------------------------
10
10
 
ccxt/pro/ascendex.py CHANGED
@@ -911,6 +911,6 @@ class ascendex(ccxt.async_support.ascendex):
911
911
  'key': self.apiKey,
912
912
  'sig': signature,
913
913
  }
914
- future = self.watch(url, messageHash, self.extend(request, params))
914
+ future = await self.watch(url, messageHash, self.extend(request, params), messageHash)
915
915
  client.subscriptions[messageHash] = future
916
916
  return future
ccxt/pro/bitvavo.py CHANGED
@@ -1140,7 +1140,7 @@ class bitvavo(ccxt.async_support.bitvavo):
1140
1140
  'timestamp': timestamp,
1141
1141
  }
1142
1142
  message = self.extend(request, params)
1143
- future = self.watch(url, messageHash, message)
1143
+ future = await self.watch(url, messageHash, message, messageHash)
1144
1144
  client.subscriptions[messageHash] = future
1145
1145
  return future
1146
1146
 
ccxt/pro/coinex.py CHANGED
@@ -981,8 +981,12 @@ class coinex(ccxt.async_support.coinex):
981
981
  #
982
982
  messageHashSpot = 'authenticated:spot'
983
983
  messageHashSwap = 'authenticated:swap'
984
- client.resolve(message, messageHashSpot)
985
- client.resolve(message, messageHashSwap)
984
+ # client.resolve(message, messageHashSpot)
985
+ # client.resolve(message, messageHashSwap)
986
+ spotFuture = self.safe_value(client.futures, messageHashSpot)
987
+ spotFuture.resolve(True)
988
+ swapFutures = self.safe_value(client.futures, messageHashSwap)
989
+ swapFutures.resolve(True)
986
990
  return message
987
991
 
988
992
  def handle_subscription_status(self, client: Client, message):
@@ -1004,15 +1008,19 @@ class coinex(ccxt.async_support.coinex):
1004
1008
  url = self.urls['api']['ws'][type]
1005
1009
  client = self.client(url)
1006
1010
  time = self.milliseconds()
1011
+ isSpot = (type == 'spot')
1012
+ spotMessageHash = 'authenticated:spot'
1013
+ swapMessageHash = 'authenticated:swap'
1014
+ messageHash = spotMessageHash if isSpot else swapMessageHash
1015
+ future = client.future(messageHash)
1016
+ authenticated = self.safe_value(client.subscriptions, messageHash)
1007
1017
  if type == 'spot':
1008
- messageHash = 'authenticated:spot'
1009
- future = self.safe_value(client.subscriptions, messageHash)
1010
- if future is not None:
1018
+ if authenticated is not None:
1011
1019
  return await future
1012
1020
  requestId = self.request_id()
1013
1021
  subscribe = {
1014
1022
  'id': requestId,
1015
- 'future': 'authenticated:spot',
1023
+ 'future': spotMessageHash,
1016
1024
  }
1017
1025
  signData = 'access_id=' + self.apiKey + '&tonce=' + self.number_to_string(time) + '&secret_key=' + self.secret
1018
1026
  hash = self.hash(self.encode(signData), 'md5')
@@ -1025,18 +1033,16 @@ class coinex(ccxt.async_support.coinex):
1025
1033
  ],
1026
1034
  'id': requestId,
1027
1035
  }
1028
- future = self.watch(url, messageHash, request, requestId, subscribe)
1029
- client.subscriptions[messageHash] = future
1036
+ self.watch(url, messageHash, request, requestId, subscribe)
1037
+ client.subscriptions[messageHash] = True
1030
1038
  return await future
1031
1039
  else:
1032
- messageHash = 'authenticated:swap'
1033
- future = self.safe_value(client.subscriptions, messageHash)
1034
- if future is not None:
1040
+ if authenticated is not None:
1035
1041
  return await future
1036
1042
  requestId = self.request_id()
1037
1043
  subscribe = {
1038
1044
  'id': requestId,
1039
- 'future': 'authenticated:swap',
1045
+ 'future': swapMessageHash,
1040
1046
  }
1041
1047
  signData = 'access_id=' + self.apiKey + '&timestamp=' + self.number_to_string(time) + '&secret_key=' + self.secret
1042
1048
  hash = self.hash(self.encode(signData), 'sha256', 'hex')
@@ -1049,6 +1055,6 @@ class coinex(ccxt.async_support.coinex):
1049
1055
  ],
1050
1056
  'id': requestId,
1051
1057
  }
1052
- future = self.watch(url, messageHash, request, requestId, subscribe)
1053
- client.subscriptions[messageHash] = future
1058
+ self.watch(url, messageHash, request, requestId, subscribe)
1059
+ client.subscriptions[messageHash] = True
1054
1060
  return await future
ccxt/pro/deribit.py CHANGED
@@ -887,6 +887,6 @@ class deribit(ccxt.async_support.deribit):
887
887
  'data': '',
888
888
  },
889
889
  }
890
- future = self.watch(url, messageHash, self.extend(request, params))
890
+ future = await self.watch(url, messageHash, self.extend(request, params), messageHash)
891
891
  client.subscriptions[messageHash] = future
892
892
  return future
ccxt/pro/exmo.py CHANGED
@@ -625,6 +625,6 @@ class exmo(ccxt.async_support.exmo):
625
625
  'nonce': time,
626
626
  }
627
627
  message = self.extend(request, query)
628
- future = self.watch(url, messageHash, message)
628
+ future = await self.watch(url, messageHash, message, messageHash)
629
629
  client.subscriptions[messageHash] = future
630
630
  return future
ccxt/pro/krakenfutures.py CHANGED
@@ -92,7 +92,7 @@ class krakenfutures(ccxt.async_support.krakenfutures):
92
92
  'api_key': self.apiKey,
93
93
  }
94
94
  message = self.extend(request, params)
95
- future = await self.watch(url, messageHash, message)
95
+ future = await self.watch(url, messageHash, message, messageHash)
96
96
  client.subscriptions[messageHash] = future
97
97
  return future
98
98
 
ccxt/pro/phemex.py CHANGED
@@ -1431,6 +1431,6 @@ class phemex(ccxt.async_support.phemex):
1431
1431
  message = self.extend(request, params)
1432
1432
  if not (messageHash in client.subscriptions):
1433
1433
  client.subscriptions[subscriptionHash] = self.handle_authenticate
1434
- future = self.watch(url, messageHash, message)
1434
+ future = await self.watch(url, messageHash, message, messageHash)
1435
1435
  client.subscriptions[messageHash] = future
1436
1436
  return future
ccxt/pro/poloniex.py CHANGED
@@ -111,7 +111,7 @@ class poloniex(ccxt.async_support.poloniex):
111
111
  },
112
112
  }
113
113
  message = self.extend(request, params)
114
- future = await self.watch(url, messageHash, message)
114
+ future = await self.watch(url, messageHash, message, messageHash)
115
115
  #
116
116
  # {
117
117
  # "data": {
ccxt/pro/probit.py CHANGED
@@ -546,6 +546,6 @@ class probit(ccxt.async_support.probit):
546
546
  'type': 'authorization',
547
547
  'token': accessToken,
548
548
  }
549
- future = self.watch(url, messageHash, self.extend(request, params))
549
+ future = await self.watch(url, messageHash, self.extend(request, params), messageHash)
550
550
  client.subscriptions[messageHash] = future
551
551
  return future