ccxt 4.4.50__py2.py3-none-any.whl → 4.4.52__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 (59) hide show
  1. ccxt/__init__.py +1 -1
  2. ccxt/alpaca.py +1 -1
  3. ccxt/async_support/__init__.py +1 -1
  4. ccxt/async_support/alpaca.py +1 -1
  5. ccxt/async_support/base/exchange.py +1 -1
  6. ccxt/async_support/binance.py +31 -16
  7. ccxt/async_support/blofin.py +4 -0
  8. ccxt/async_support/coinex.py +1 -1
  9. ccxt/async_support/coinmetro.py +16 -3
  10. ccxt/async_support/deribit.py +18 -3
  11. ccxt/async_support/gate.py +1 -1
  12. ccxt/async_support/hollaex.py +2 -1
  13. ccxt/async_support/htx.py +5 -3
  14. ccxt/async_support/kucoin.py +2 -2
  15. ccxt/async_support/mexc.py +21 -6
  16. ccxt/async_support/onetrading.py +1 -1
  17. ccxt/async_support/paradex.py +1 -1
  18. ccxt/async_support/probit.py +9 -7
  19. ccxt/async_support/vertex.py +65 -2
  20. ccxt/async_support/wavesexchange.py +73 -0
  21. ccxt/async_support/wazirx.py +59 -3
  22. ccxt/async_support/whitebit.py +69 -0
  23. ccxt/async_support/xt.py +112 -0
  24. ccxt/async_support/yobit.py +56 -0
  25. ccxt/async_support/zaif.py +55 -0
  26. ccxt/async_support/zonda.py +58 -0
  27. ccxt/base/exchange.py +32 -4
  28. ccxt/binance.py +31 -16
  29. ccxt/blofin.py +4 -0
  30. ccxt/coinex.py +1 -1
  31. ccxt/coinmetro.py +16 -3
  32. ccxt/deribit.py +18 -3
  33. ccxt/gate.py +1 -1
  34. ccxt/hollaex.py +2 -1
  35. ccxt/htx.py +5 -3
  36. ccxt/kucoin.py +2 -2
  37. ccxt/mexc.py +21 -6
  38. ccxt/onetrading.py +1 -1
  39. ccxt/paradex.py +1 -1
  40. ccxt/pro/__init__.py +1 -1
  41. ccxt/pro/binance.py +2 -0
  42. ccxt/pro/blofin.py +8 -0
  43. ccxt/pro/coinex.py +4 -1
  44. ccxt/probit.py +9 -7
  45. ccxt/test/tests_async.py +0 -1
  46. ccxt/test/tests_sync.py +0 -1
  47. ccxt/vertex.py +65 -2
  48. ccxt/wavesexchange.py +73 -0
  49. ccxt/wazirx.py +59 -3
  50. ccxt/whitebit.py +69 -0
  51. ccxt/xt.py +112 -0
  52. ccxt/yobit.py +56 -0
  53. ccxt/zaif.py +55 -0
  54. ccxt/zonda.py +58 -0
  55. {ccxt-4.4.50.dist-info → ccxt-4.4.52.dist-info}/METADATA +18 -18
  56. {ccxt-4.4.50.dist-info → ccxt-4.4.52.dist-info}/RECORD +59 -59
  57. {ccxt-4.4.50.dist-info → ccxt-4.4.52.dist-info}/WHEEL +1 -1
  58. {ccxt-4.4.50.dist-info → ccxt-4.4.52.dist-info}/LICENSE.txt +0 -0
  59. {ccxt-4.4.50.dist-info → ccxt-4.4.52.dist-info}/top_level.txt +0 -0
ccxt/blofin.py CHANGED
@@ -166,6 +166,9 @@ class blofin(Exchange, ImplicitAPI):
166
166
  'api': {
167
167
  'rest': 'https://openapi.blofin.com',
168
168
  },
169
+ 'test': {
170
+ 'rest': 'https://demo-trading-openapi.blofin.com',
171
+ },
169
172
  'referral': {
170
173
  'url': 'https://blofin.com/register?referral_code=f79EsS',
171
174
  'discount': 0.05,
@@ -323,6 +326,7 @@ class blofin(Exchange, ImplicitAPI):
323
326
  'attachedStopLossTakeProfit': {
324
327
  'triggerPriceType': None,
325
328
  'limit': True,
329
+ 'price': None,
326
330
  },
327
331
  'hedged': True,
328
332
  },
ccxt/coinex.py CHANGED
@@ -3766,7 +3766,7 @@ class coinex(Exchange, ImplicitAPI):
3766
3766
  'currency': self.safe_currency_code(None, currency),
3767
3767
  'network': None,
3768
3768
  'address': address,
3769
- 'tag': tag,
3769
+ 'tag': self.safe_string(depositAddress, 'memo', tag),
3770
3770
  }
3771
3771
 
3772
3772
  def fetch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
ccxt/coinmetro.py CHANGED
@@ -219,7 +219,7 @@ class coinmetro(Exchange, ImplicitAPI):
219
219
  # exchange-specific options
220
220
  'options': {
221
221
  'currenciesByIdForParseMarket': None,
222
- 'currencyIdsListForParseMarket': None,
222
+ 'currencyIdsListForParseMarket': ['QRDO'],
223
223
  },
224
224
  'features': {
225
225
  'spot': {
@@ -407,7 +407,11 @@ class coinmetro(Exchange, ImplicitAPI):
407
407
  if self.safe_value(self.options, 'currenciesByIdForParseMarket') is None:
408
408
  currenciesById = self.index_by(result, 'id')
409
409
  self.options['currenciesByIdForParseMarket'] = currenciesById
410
- self.options['currencyIdsListForParseMarket'] = list(currenciesById.keys())
410
+ currentCurrencyIdsList = self.safe_list(self.options, 'currencyIdsListForParseMarket', [])
411
+ currencyIdsList = list(currenciesById.keys())
412
+ for i in range(0, len(currencyIdsList)):
413
+ currentCurrencyIdsList.append(currencyIdsList[i])
414
+ self.options['currencyIdsListForParseMarket'] = currentCurrencyIdsList
411
415
  return result
412
416
 
413
417
  def fetch_markets(self, params={}) -> List[Market]:
@@ -506,10 +510,19 @@ class coinmetro(Exchange, ImplicitAPI):
506
510
  baseId = None
507
511
  quoteId = None
508
512
  currencyIds = self.safe_value(self.options, 'currencyIdsListForParseMarket', [])
513
+ # Bubble sort by length(longest first)
514
+ currencyIdsLength = len(currencyIds)
515
+ for i in range(0, currencyIdsLength):
516
+ for j in range(0, currencyIdsLength - i - 1):
517
+ a = currencyIds[j]
518
+ b = currencyIds[j + 1]
519
+ if len(a) < len(b):
520
+ currencyIds[j] = b
521
+ currencyIds[j + 1] = a
509
522
  for i in range(0, len(currencyIds)):
510
523
  currencyId = currencyIds[i]
511
524
  entryIndex = marketId.find(currencyId)
512
- if entryIndex != -1:
525
+ if entryIndex == 0:
513
526
  restId = marketId.replace(currencyId, '')
514
527
  if self.in_array(restId, currencyIds):
515
528
  if entryIndex == 0:
ccxt/deribit.py CHANGED
@@ -3063,7 +3063,7 @@ class deribit(Exchange, ImplicitAPI):
3063
3063
  :param int [since]: the earliest time in ms to fetch funding rate history for
3064
3064
  :param int [limit]: the maximum number of entries to retrieve
3065
3065
  :param dict [params]: extra parameters specific to the exchange API endpoint
3066
- :param int [params.end_timestamp]: fetch funding rate ending at self timestamp
3066
+ :param int [params.until]: fetch funding rate ending at self timestamp
3067
3067
  :param boolean [params.paginate]: default False, when True will automatically paginate by calling self endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
3068
3068
  :returns dict: a `funding rate structure <https://docs.ccxt.com/#/?id=funding-rate-structure>`
3069
3069
  """
@@ -3071,17 +3071,32 @@ class deribit(Exchange, ImplicitAPI):
3071
3071
  market = self.market(symbol)
3072
3072
  paginate = False
3073
3073
  paginate, params = self.handle_option_and_params(params, 'fetchFundingRateHistory', 'paginate')
3074
+ maxEntriesPerRequest = 744 # seems exchange returns max 744 items per request
3075
+ eachItemDuration = '1h'
3074
3076
  if paginate:
3075
- return self.fetch_paginated_call_deterministic('fetchFundingRateHistory', symbol, since, limit, '8h', params, 720)
3077
+ # fix for: https://github.com/ccxt/ccxt/issues/25040
3078
+ return self.fetch_paginated_call_deterministic('fetchFundingRateHistory', symbol, since, limit, eachItemDuration, self.extend(params, {'isDeribitPaginationCall': True}), maxEntriesPerRequest)
3079
+ duration = self.parse_timeframe(eachItemDuration) * 1000
3076
3080
  time = self.milliseconds()
3077
3081
  month = 30 * 24 * 60 * 60 * 1000
3078
3082
  if since is None:
3079
3083
  since = time - month
3084
+ else:
3085
+ time = since + month
3080
3086
  request: dict = {
3081
3087
  'instrument_name': market['id'],
3082
3088
  'start_timestamp': since - 1,
3083
- 'end_timestamp': time,
3084
3089
  }
3090
+ until = self.safe_integer_2(params, 'until', 'end_timestamp')
3091
+ if until is not None:
3092
+ params = self.omit(params, ['until'])
3093
+ request['end_timestamp'] = until
3094
+ else:
3095
+ request['end_timestamp'] = time
3096
+ if 'isDeribitPaginationCall' in params:
3097
+ params = self.omit(params, 'isDeribitPaginationCall')
3098
+ maxUntil = self.sum(since, limit * duration)
3099
+ request['end_timestamp'] = min(request['end_timestamp'], maxUntil)
3085
3100
  response = self.publicGetGetFundingRateHistory(self.extend(request, params))
3086
3101
  #
3087
3102
  # {
ccxt/gate.py CHANGED
@@ -1791,7 +1791,7 @@ class gate(Exchange, ImplicitAPI):
1791
1791
  active = listed and tradeEnabled and withdrawEnabled and depositEnabled
1792
1792
  if self.safe_value(result, code) is None:
1793
1793
  result[code] = {
1794
- 'id': code.lower(),
1794
+ 'id': currency,
1795
1795
  'code': code,
1796
1796
  'info': None,
1797
1797
  'name': None,
ccxt/hollaex.py CHANGED
@@ -1912,13 +1912,14 @@ class hollaex(Exchange, ImplicitAPI):
1912
1912
  return {'url': url, 'method': method, 'body': body, 'headers': headers}
1913
1913
 
1914
1914
  def handle_errors(self, code: int, reason: str, url: str, method: str, headers: dict, body: str, response, requestHeaders, requestBody):
1915
+ # {"message": "Invalid token"}
1915
1916
  if response is None:
1916
1917
  return None
1917
1918
  if (code >= 400) and (code <= 503):
1918
1919
  #
1919
1920
  # {"message": "Invalid token"}
1920
1921
  #
1921
- # different errors return the same code eg:
1922
+ # different errors return the same code eg
1922
1923
  #
1923
1924
  # {"message":"Error 1001 - Order rejected. Order could not be submitted order was set to a post only order."}
1924
1925
  #
ccxt/htx.py CHANGED
@@ -6991,10 +6991,12 @@ class htx(Exchange, ImplicitAPI):
6991
6991
  'AccessKeyId': self.apiKey,
6992
6992
  'Timestamp': timestamp,
6993
6993
  }
6994
- if method != 'POST':
6995
- request = self.extend(request, query)
6994
+ # sorting needs such flow exactly, before urlencoding(more at: https://github.com/ccxt/ccxt/issues/24930 )
6996
6995
  request = self.keysort(request)
6997
- auth = self.urlencode(request)
6996
+ if method != 'POST':
6997
+ sortedQuery = self.keysort(query)
6998
+ request = self.extend(request, sortedQuery)
6999
+ auth = self.urlencode(request).replace('%2c', '%2C') # in c# it manually needs to be uppercased
6998
7000
  # unfortunately, PHP demands double quotes for the escaped newline symbol
6999
7001
  payload = "\n".join([method, hostname, url, auth]) # eslint-disable-line quotes
7000
7002
  signature = self.hmac(self.encode(payload), self.encode(self.secret), hashlib.sha256, 'base64')
ccxt/kucoin.py CHANGED
@@ -3100,14 +3100,14 @@ class kucoin(Exchange, ImplicitAPI):
3100
3100
  if symbol is not None:
3101
3101
  market = self.market(symbol)
3102
3102
  request['symbol'] = market['id']
3103
- if limit is not None:
3104
- request['pageSize'] = limit
3105
3103
  method = self.options['fetchMyTradesMethod']
3106
3104
  parseResponseData = False
3107
3105
  response = None
3108
3106
  request, params = self.handle_until_option('endAt', request, params)
3109
3107
  if hf:
3110
3108
  # does not return trades earlier than 2019-02-18T00:00:00Z
3109
+ if limit is not None:
3110
+ request['limit'] = limit
3111
3111
  if since is not None:
3112
3112
  # only returns trades up to one week after the since param
3113
3113
  request['startAt'] = since
ccxt/mexc.py CHANGED
@@ -2234,7 +2234,7 @@ class mexc(Exchange, ImplicitAPI):
2234
2234
  :param bool [params.postOnly]: if True, the order will only be posted if it will be a maker order
2235
2235
  :param bool [params.reduceOnly]: *contract only* indicates if self order is to reduce the size of a position
2236
2236
  :param bool [params.hedged]: *swap only* True for hedged mode, False for one way mode, default is False
2237
-
2237
+ :param str [params.timeInForce]: 'IOC' or 'FOK', default is 'GTC'
2238
2238
  EXCHANGE SPECIFIC PARAMETERS
2239
2239
  :param int [params.leverage]: *contract only* leverage is necessary on isolated margin
2240
2240
  :param long [params.positionId]: *contract only* it is recommended to hasattr(self, fill) parameter when closing a position
@@ -2289,6 +2289,13 @@ class mexc(Exchange, ImplicitAPI):
2289
2289
  postOnly, params = self.handle_post_only(type == 'market', type == 'LIMIT_MAKER', params)
2290
2290
  if postOnly:
2291
2291
  request['type'] = 'LIMIT_MAKER'
2292
+ tif = self.safe_string(params, 'timeInForce')
2293
+ if tif is not None:
2294
+ params = self.omit(params, 'timeInForce')
2295
+ if tif == 'IOC':
2296
+ request['type'] = 'IMMEDIATE_OR_CANCEL'
2297
+ elif tif == 'FOK':
2298
+ request['type'] = 'FILL_OR_KILL'
2292
2299
  return self.extend(request, params)
2293
2300
 
2294
2301
  def create_spot_order(self, market, type, side, amount, price=None, marginMode=None, params={}):
@@ -5708,12 +5715,20 @@ class mexc(Exchange, ImplicitAPI):
5708
5715
  url = self.urls['api'][section][access] + '/' + path
5709
5716
  else:
5710
5717
  url = self.urls['api'][section][access] + '/api/' + self.version + '/' + path
5711
- paramsEncoded = ''
5718
+ urlParams = params
5712
5719
  if access == 'private':
5713
- params['timestamp'] = self.nonce()
5714
- params['recvWindow'] = self.safe_integer(self.options, 'recvWindow', 5000)
5715
- if params:
5716
- paramsEncoded = self.urlencode(params)
5720
+ if section == 'broker' and ((method == 'POST') or (method == 'PUT') or (method == 'DELETE')):
5721
+ urlParams = {
5722
+ 'timestamp': self.nonce(),
5723
+ 'recvWindow': self.safe_integer(self.options, 'recvWindow', 5000),
5724
+ }
5725
+ body = self.json(params)
5726
+ else:
5727
+ urlParams['timestamp'] = self.nonce()
5728
+ urlParams['recvWindow'] = self.safe_integer(self.options, 'recvWindow', 5000)
5729
+ paramsEncoded = ''
5730
+ if urlParams:
5731
+ paramsEncoded = self.urlencode(urlParams)
5717
5732
  url += '?' + paramsEncoded
5718
5733
  if access == 'private':
5719
5734
  self.check_required_credentials()
ccxt/onetrading.py CHANGED
@@ -1200,7 +1200,7 @@ class onetrading(Exchange, ImplicitAPI):
1200
1200
  https://docs.onetrading.com/#create-order
1201
1201
 
1202
1202
  :param str symbol: unified symbol of the market to create an order in
1203
- :param str type: 'market' or 'limit'
1203
+ :param str type: 'limit'
1204
1204
  :param str side: 'buy' or 'sell'
1205
1205
  :param float amount: how much of currency you want to trade in units of base currency
1206
1206
  :param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
ccxt/paradex.py CHANGED
@@ -943,7 +943,7 @@ class paradex(Exchange, ImplicitAPI):
943
943
  #
944
944
  # {
945
945
  # "symbol": "BTC-USD-PERP",
946
- # "oracle_price": "68465.17449906",
946
+ # "oracle_price": "68465.17449904",
947
947
  # "mark_price": "68465.17449906",
948
948
  # "last_traded_price": "68495.1",
949
949
  # "bid": "68477.6",
ccxt/pro/__init__.py CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # ----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.4.50'
7
+ __version__ = '4.4.52'
8
8
 
9
9
  # ----------------------------------------------------------------------------
10
10
 
ccxt/pro/binance.py CHANGED
@@ -2215,6 +2215,7 @@ class binance(ccxt.async_support.binance):
2215
2215
  response = None
2216
2216
  if isPortfolioMargin:
2217
2217
  response = await self.papiPostListenKey(params)
2218
+ params = self.extend(params, {'portfolioMargin': True})
2218
2219
  elif type == 'future':
2219
2220
  response = await self.fapiPrivatePostListenKey(params)
2220
2221
  elif type == 'delivery':
@@ -2259,6 +2260,7 @@ class binance(ccxt.async_support.binance):
2259
2260
  try:
2260
2261
  if isPortfolioMargin:
2261
2262
  await self.papiPutListenKey(self.extend(request, params))
2263
+ params = self.extend(params, {'portfolioMargin': True})
2262
2264
  elif type == 'future':
2263
2265
  await self.fapiPrivatePutListenKey(self.extend(request, params))
2264
2266
  elif type == 'delivery':
ccxt/pro/blofin.py CHANGED
@@ -42,6 +42,14 @@ class blofin(ccxt.async_support.blofin):
42
42
  },
43
43
  },
44
44
  },
45
+ 'test': {
46
+ 'ws': {
47
+ 'swap': {
48
+ 'public': 'wss://demo-trading-openapi.blofin.com/ws/public',
49
+ 'private': 'wss://demo-trading-openapi.blofin.com/ws/private',
50
+ },
51
+ },
52
+ },
45
53
  },
46
54
  'options': {
47
55
  'defaultType': 'swap',
ccxt/pro/coinex.py CHANGED
@@ -263,7 +263,10 @@ class coinex(ccxt.async_support.coinex):
263
263
  type, params = self.handle_market_type_and_params('watchBalance', None, params, 'spot')
264
264
  await self.authenticate(type)
265
265
  url = self.urls['api']['ws'][type]
266
- currencies = list(self.currencies_by_id.keys())
266
+ # coinex throws a closes the websocket when subscribing over 1422 currencies, therefore we filter out inactive currencies
267
+ activeCurrencies = self.filter_by(self.currencies_by_id, 'active', True)
268
+ activeCurrenciesById = self.index_by(activeCurrencies, 'id')
269
+ currencies = list(activeCurrenciesById.keys())
267
270
  if currencies is None:
268
271
  currencies = []
269
272
  messageHash = 'balances'
ccxt/probit.py CHANGED
@@ -990,6 +990,7 @@ class probit(Exchange, ImplicitAPI):
990
990
  :param int [since]: timestamp in ms of the earliest candle to fetch
991
991
  :param int [limit]: the maximum amount of candles to fetch
992
992
  :param dict [params]: extra parameters specific to the exchange API endpoint
993
+ :param str [params.until]: timestamp in ms of the earliest candle to fetch
993
994
  :returns int[][]: A list of candles ordered, open, high, low, close, volume
994
995
  """
995
996
  self.load_markets()
@@ -1005,18 +1006,19 @@ class probit(Exchange, ImplicitAPI):
1005
1006
  'limit': requestLimit, # max 1000
1006
1007
  }
1007
1008
  now = self.milliseconds()
1008
- duration = self.parse_timeframe(timeframe)
1009
+ until = self.safe_integer(params, 'until')
1010
+ durationMilliseconds = self.parse_timeframe(timeframe) * 1000
1009
1011
  startTime = since
1010
- endTime = now
1012
+ endTime = until - durationMilliseconds if (until is not None) else now
1011
1013
  if since is None:
1012
1014
  if limit is None:
1013
1015
  limit = requestLimit
1014
- startTime = now - limit * duration * 1000
1016
+ startLimit = limit - 1
1017
+ startTime = endTime - startLimit * durationMilliseconds
1015
1018
  else:
1016
- if limit is None:
1017
- endTime = now
1018
- else:
1019
- endTime = self.sum(since, self.sum(limit, 1) * duration * 1000)
1019
+ if limit is not None:
1020
+ endByLimit = self.sum(since, limit * durationMilliseconds)
1021
+ endTime = min(endTime, endByLimit)
1020
1022
  startTimeNormalized = self.normalize_ohlcv_timestamp(startTime, timeframe)
1021
1023
  endTimeNormalized = self.normalize_ohlcv_timestamp(endTime, timeframe, True)
1022
1024
  request['start_time'] = startTimeNormalized
ccxt/test/tests_async.py CHANGED
@@ -12,7 +12,6 @@ class testMainClass:
12
12
  request_tests = False
13
13
  ws_tests = False
14
14
  response_tests = False
15
- static_tests = False
16
15
  info = False
17
16
  verbose = False
18
17
  debug = False
ccxt/test/tests_sync.py CHANGED
@@ -9,7 +9,6 @@ class testMainClass:
9
9
  request_tests = False
10
10
  ws_tests = False
11
11
  response_tests = False
12
- static_tests = False
13
12
  info = False
14
13
  verbose = False
15
14
  debug = False
ccxt/vertex.py CHANGED
@@ -330,6 +330,69 @@ class vertex(Exchange, ImplicitAPI):
330
330
  'timeDifference': 0, # the difference between system clock and exchange server clock
331
331
  'brokerId': 5930043274845996,
332
332
  },
333
+ 'features': {
334
+ 'default': {
335
+ 'sandbox': True,
336
+ 'createOrder': {
337
+ 'marginMode': False,
338
+ 'triggerPrice': True, # todo
339
+ 'triggerDirection': False,
340
+ 'triggerPriceType': None,
341
+ 'stopLossPrice': True, # todo
342
+ 'takeProfitPrice': True, # todo
343
+ 'attachedStopLossTakeProfit': None,
344
+ 'timeInForce': {
345
+ 'IOC': False,
346
+ 'FOK': False,
347
+ 'PO': True,
348
+ 'GTD': True,
349
+ },
350
+ 'hedged': False,
351
+ 'trailing': False,
352
+ 'leverage': False,
353
+ 'marketBuyByCost': True, # todo
354
+ 'marketBuyRequiresPrice': True, # todo fix implementation
355
+ 'selfTradePrevention': False,
356
+ 'iceberg': False,
357
+ },
358
+ 'createOrders': None,
359
+ 'fetchMyTrades': {
360
+ 'marginMode': False,
361
+ 'limit': 500,
362
+ 'daysBack': 100000, # todo
363
+ 'untilDays': None,
364
+ },
365
+ 'fetchOrder': {
366
+ 'marginMode': False,
367
+ 'trigger': False,
368
+ 'trailing': False,
369
+ },
370
+ 'fetchOpenOrders': {
371
+ 'marginMode': False,
372
+ 'limit': 500,
373
+ 'trigger': True,
374
+ 'trailing': False,
375
+ },
376
+ 'fetchOrders': None, # todo, only for trigger
377
+ 'fetchClosedOrders': None, # todo through fetchOrders
378
+ 'fetchOHLCV': {
379
+ 'limit': 1000,
380
+ },
381
+ },
382
+ 'spot': {
383
+ 'extends': 'default',
384
+ },
385
+ 'swap': {
386
+ 'linear': {
387
+ 'extends': 'default',
388
+ },
389
+ 'inverse': None,
390
+ },
391
+ 'future': {
392
+ 'linear': None,
393
+ 'inverse': None,
394
+ },
395
+ },
333
396
  })
334
397
 
335
398
  def set_sandbox_mode(self, enabled):
@@ -2104,7 +2167,7 @@ class vertex(Exchange, ImplicitAPI):
2104
2167
  # "product_id": 1,
2105
2168
  # "orders": [
2106
2169
  # {
2107
- # "product_id": 1,
2170
+ # "product_id": 2,
2108
2171
  # "sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43000000000000000000000000",
2109
2172
  # "price_x18": "1000000000000000000",
2110
2173
  # "amount": "1000000000000000000",
@@ -2113,7 +2176,7 @@ class vertex(Exchange, ImplicitAPI):
2113
2176
  # "order_type": "default",
2114
2177
  # "unfilled_amount": "1000000000000000000",
2115
2178
  # "digest": "0x0000000000000000000000000000000000000000000000000000000000000000",
2116
- # "placed_at": 1682437739,
2179
+ # "placed_at": 1682437737,
2117
2180
  # "order_type": "ioc"
2118
2181
  # }
2119
2182
  # ]
ccxt/wavesexchange.py CHANGED
@@ -357,6 +357,79 @@ class wavesexchange(Exchange, ImplicitAPI):
357
357
  'BEP20': 'BSC',
358
358
  },
359
359
  },
360
+ 'features': {
361
+ 'spot': {
362
+ 'sandbox': True,
363
+ 'createOrder': {
364
+ 'marginMode': False,
365
+ 'triggerPrice': True, # todo
366
+ 'triggerDirection': False,
367
+ 'triggerPriceType': None,
368
+ 'stopLossPrice': False, # todo
369
+ 'takeProfitPrice': False, # todo
370
+ 'attachedStopLossTakeProfit': None,
371
+ 'timeInForce': {
372
+ 'IOC': False,
373
+ 'FOK': False,
374
+ 'PO': False,
375
+ 'GTD': True, # todo
376
+ },
377
+ 'hedged': False,
378
+ 'trailing': False,
379
+ 'leverage': False,
380
+ 'marketBuyByCost': False, # todo
381
+ 'marketBuyRequiresPrice': True,
382
+ 'selfTradePrevention': False,
383
+ 'iceberg': False,
384
+ },
385
+ 'createOrders': None,
386
+ 'fetchMyTrades': {
387
+ 'marginMode': False,
388
+ 'limit': 100, # todo
389
+ 'daysBack': 100000, # todo
390
+ 'untilDays': 100000, # todo
391
+ },
392
+ 'fetchOrder': {
393
+ 'marginMode': False,
394
+ 'trigger': False,
395
+ 'trailing': False,
396
+ },
397
+ 'fetchOpenOrders': {
398
+ 'marginMode': False,
399
+ 'limit': 100, # todo
400
+ 'trigger': False,
401
+ 'trailing': False,
402
+ },
403
+ 'fetchOrders': {
404
+ 'marginMode': False,
405
+ 'limit': 100, # todo
406
+ 'daysBack': None,
407
+ 'untilDays': None,
408
+ 'trigger': False,
409
+ 'trailing': False,
410
+ }, # todo
411
+ 'fetchClosedOrders': {
412
+ 'marginMode': False,
413
+ 'limit': 100,
414
+ 'daysBack': 100000, # todo
415
+ 'daysBackCanceled': 1, # todo
416
+ 'untilDays': 100000, # todo
417
+ 'trigger': False,
418
+ 'trailing': False,
419
+ },
420
+ 'fetchOHLCV': {
421
+ 'limit': None, # todo
422
+ },
423
+ },
424
+ 'swap': {
425
+ 'linear': None,
426
+ 'inverse': None,
427
+ },
428
+ 'future': {
429
+ 'linear': None,
430
+ 'inverse': None,
431
+ },
432
+ },
360
433
  'commonCurrencies': {
361
434
  'EGG': 'Waves Ducks',
362
435
  },
ccxt/wazirx.py CHANGED
@@ -217,6 +217,62 @@ class wazirx(Exchange, ImplicitAPI):
217
217
  # You can get network from fetchCurrencies
218
218
  },
219
219
  },
220
+ 'features': {
221
+ 'spot': {
222
+ 'sandbox': False,
223
+ 'createOrder': {
224
+ 'marginMode': False,
225
+ 'triggerPrice': True,
226
+ 'triggerDirection': False,
227
+ 'triggerPriceType': None,
228
+ 'stopLossPrice': False, # todo
229
+ 'takeProfitPrice': False, # todo
230
+ 'attachedStopLossTakeProfit': None,
231
+ 'timeInForce': {
232
+ 'IOC': False,
233
+ 'FOK': False,
234
+ 'PO': False,
235
+ 'GTD': False,
236
+ },
237
+ 'hedged': False,
238
+ 'trailing': False,
239
+ 'leverage': False,
240
+ 'marketBuyByCost': False,
241
+ 'marketBuyRequiresPrice': False,
242
+ 'selfTradePrevention': False,
243
+ 'iceberg': False,
244
+ },
245
+ 'createOrders': None,
246
+ 'fetchMyTrades': None,
247
+ 'fetchOrder': None, # todo
248
+ 'fetchOpenOrders': {
249
+ 'marginMode': False,
250
+ 'limit': None,
251
+ 'trigger': False,
252
+ 'trailing': False,
253
+ },
254
+ 'fetchOrders': {
255
+ 'marginMode': False,
256
+ 'limit': 1000,
257
+ 'daysBack': 100000, # todo
258
+ 'untilDays': 100000, # todo
259
+ 'trigger': False,
260
+ 'trailing': False,
261
+ },
262
+ 'fetchClosedOrders': None,
263
+ 'fetchOHLCV': {
264
+ 'limit': 2000,
265
+ },
266
+ },
267
+ 'swap': {
268
+ 'linear': None,
269
+ 'inverse': None,
270
+ },
271
+ 'future': {
272
+ 'linear': None,
273
+ 'inverse': None,
274
+ },
275
+ },
220
276
  })
221
277
 
222
278
  def fetch_markets(self, params={}) -> List[Market]:
@@ -878,10 +934,10 @@ class wazirx(Exchange, ImplicitAPI):
878
934
  'type': 'limit',
879
935
  }
880
936
  request['price'] = self.price_to_precision(symbol, price)
881
- stopPrice = self.safe_string(params, 'stopPrice')
882
- if stopPrice is not None:
937
+ triggerPrice = self.safe_string_2(params, 'triggerPrice', 'stopPrice')
938
+ if triggerPrice is not None:
883
939
  request['type'] = 'stop_limit'
884
- request['stopPrice'] = self.price_to_precision(symbol, stopPrice)
940
+ request['stopPrice'] = self.price_to_precision(symbol, triggerPrice)
885
941
  response = self.privatePostOrder(self.extend(request, params))
886
942
  # {
887
943
  # "id": 28,