ccxt 4.4.38__py2.py3-none-any.whl → 4.4.39__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.
ccxt/async_support/htx.py CHANGED
@@ -1251,6 +1251,128 @@ class htx(Exchange, ImplicitAPI):
1251
1251
  'BIFI': 'BITCOINFILE', # conflict with Beefy.Finance https://github.com/ccxt/ccxt/issues/8706
1252
1252
  'FUD': 'FTX Users Debt',
1253
1253
  },
1254
+ 'features': {
1255
+ 'spot': {
1256
+ 'sandbox': True,
1257
+ 'createOrder': {
1258
+ 'marginMode': True,
1259
+ 'triggerPrice': True,
1260
+ 'triggerDirection': True,
1261
+ 'triggerPriceType': None,
1262
+ 'stopLossPrice': False, # todo: add support by triggerprice
1263
+ 'takeProfitPrice': False,
1264
+ 'attachedStopLossTakeProfit': None,
1265
+ 'timeInForce': {
1266
+ 'IOC': True,
1267
+ 'FOK': True,
1268
+ 'PO': True,
1269
+ 'GTD': False,
1270
+ },
1271
+ 'hedged': False,
1272
+ 'trailing': False,
1273
+ # exchange-specific features
1274
+ 'iceberg': False,
1275
+ 'selfTradePrevention': True,
1276
+ },
1277
+ 'createOrders': {
1278
+ 'max': 10,
1279
+ },
1280
+ 'fetchMyTrades': {
1281
+ 'marginMode': False,
1282
+ 'limit': 500,
1283
+ 'daysBack': 120,
1284
+ 'untilDays': 2,
1285
+ },
1286
+ 'fetchOrder': {
1287
+ 'marginMode': False,
1288
+ 'trigger': False,
1289
+ 'trailing': False,
1290
+ },
1291
+ 'fetchOpenOrders': {
1292
+ 'marginMode': False,
1293
+ 'trigger': True,
1294
+ 'trailing': False,
1295
+ 'limit': 500,
1296
+ },
1297
+ 'fetchOrders': {
1298
+ 'marginMode': False,
1299
+ 'trigger': True,
1300
+ 'trailing': False,
1301
+ 'limit': 500,
1302
+ 'untilDays': 2,
1303
+ 'daysBack': 180,
1304
+ },
1305
+ 'fetchClosedOrders': {
1306
+ 'marginMode': False,
1307
+ 'trigger': True,
1308
+ 'trailing': False,
1309
+ 'untilDays': 2,
1310
+ 'limit': 500,
1311
+ 'daysBackClosed': 180,
1312
+ 'daysBackCanceled': 1 / 12,
1313
+ },
1314
+ 'fetchOHLCV': {
1315
+ 'limit': 1000, # 2000 for non-historical
1316
+ },
1317
+ },
1318
+ 'forDerivatives': {
1319
+ 'extends': 'spot',
1320
+ 'createOrder': {
1321
+ 'stopLossPrice': True,
1322
+ 'takeProfitPrice': True,
1323
+ 'trailing': True,
1324
+ 'hedged': True,
1325
+ # 'leverage': True, # todo
1326
+ },
1327
+ 'createOrders': {
1328
+ 'max': 25,
1329
+ },
1330
+ 'fetchOrder': {
1331
+ 'marginMode': True,
1332
+ },
1333
+ 'fetchOpenOrders': {
1334
+ 'marginMode': True,
1335
+ 'trigger': False,
1336
+ 'trailing': False,
1337
+ 'limit': 50,
1338
+ },
1339
+ 'fetchOrders': {
1340
+ 'marginMode': True,
1341
+ 'trigger': False,
1342
+ 'trailing': False,
1343
+ 'limit': 50,
1344
+ 'daysBack': 90,
1345
+ },
1346
+ 'fetchClosedOrders': {
1347
+ 'marginMode': True,
1348
+ 'trigger': False,
1349
+ 'trailing': False,
1350
+ 'untilDays': 2,
1351
+ 'limit': 50,
1352
+ 'daysBackClosed': 90,
1353
+ 'daysBackCanceled': 1 / 12,
1354
+ },
1355
+ 'fetchOHLCV': {
1356
+ 'limit': 2000,
1357
+ },
1358
+ },
1359
+ 'swap': {
1360
+ 'linear': {
1361
+ 'extends': 'forDerivatives',
1362
+ },
1363
+ 'inverse': {
1364
+ 'extends': 'forDerivatives',
1365
+ },
1366
+ },
1367
+ 'future': {
1368
+ 'linear': {
1369
+ 'extends': 'forDerivatives',
1370
+ },
1371
+ 'inverse': {
1372
+ 'extends': 'forDerivatives',
1373
+ },
1374
+ },
1375
+ },
1254
1376
  })
1255
1377
 
1256
1378
  async def fetch_status(self, params={}):
@@ -3865,11 +3987,11 @@ class htx(Exchange, ImplicitAPI):
3865
3987
  'status': '0', # support multiple query seperated by ',',such as '3,4,5', 0: all. 3. Have sumbmitted the orders; 4. Orders partially matched; 5. Orders cancelled with partially matched; 6. Orders fully matched; 7. Orders cancelled
3866
3988
  }
3867
3989
  response = None
3868
- stop = self.safe_bool_2(params, 'stop', 'trigger')
3990
+ trigger = self.safe_bool_2(params, 'stop', 'trigger')
3869
3991
  stopLossTakeProfit = self.safe_value(params, 'stopLossTakeProfit')
3870
3992
  trailing = self.safe_bool(params, 'trailing', False)
3871
3993
  params = self.omit(params, ['stop', 'stopLossTakeProfit', 'trailing', 'trigger'])
3872
- if stop or stopLossTakeProfit or trailing:
3994
+ if trigger or stopLossTakeProfit or trailing:
3873
3995
  if limit is not None:
3874
3996
  request['page_size'] = limit
3875
3997
  request['contract_code'] = market['id']
@@ -3886,7 +4008,7 @@ class htx(Exchange, ImplicitAPI):
3886
4008
  marginMode, params = self.handle_margin_mode_and_params('fetchContractOrders', params)
3887
4009
  marginMode = 'cross' if (marginMode is None) else marginMode
3888
4010
  if marginMode == 'isolated':
3889
- if stop:
4011
+ if trigger:
3890
4012
  response = await self.contractPrivatePostLinearSwapApiV1SwapTriggerHisorders(self.extend(request, params))
3891
4013
  elif stopLossTakeProfit:
3892
4014
  response = await self.contractPrivatePostLinearSwapApiV1SwapTpslHisorders(self.extend(request, params))
@@ -3895,7 +4017,7 @@ class htx(Exchange, ImplicitAPI):
3895
4017
  else:
3896
4018
  response = await self.contractPrivatePostLinearSwapApiV3SwapHisorders(self.extend(request, params))
3897
4019
  elif marginMode == 'cross':
3898
- if stop:
4020
+ if trigger:
3899
4021
  response = await self.contractPrivatePostLinearSwapApiV1SwapCrossTriggerHisorders(self.extend(request, params))
3900
4022
  elif stopLossTakeProfit:
3901
4023
  response = await self.contractPrivatePostLinearSwapApiV1SwapCrossTpslHisorders(self.extend(request, params))
@@ -3905,7 +4027,7 @@ class htx(Exchange, ImplicitAPI):
3905
4027
  response = await self.contractPrivatePostLinearSwapApiV3SwapCrossHisorders(self.extend(request, params))
3906
4028
  elif market['inverse']:
3907
4029
  if market['swap']:
3908
- if stop:
4030
+ if trigger:
3909
4031
  response = await self.contractPrivatePostSwapApiV1SwapTriggerHisorders(self.extend(request, params))
3910
4032
  elif stopLossTakeProfit:
3911
4033
  response = await self.contractPrivatePostSwapApiV1SwapTpslHisorders(self.extend(request, params))
@@ -3915,7 +4037,7 @@ class htx(Exchange, ImplicitAPI):
3915
4037
  response = await self.contractPrivatePostSwapApiV3SwapHisorders(self.extend(request, params))
3916
4038
  elif market['future']:
3917
4039
  request['symbol'] = market['settleId']
3918
- if stop:
4040
+ if trigger:
3919
4041
  response = await self.contractPrivatePostApiV1ContractTriggerHisorders(self.extend(request, params))
3920
4042
  elif stopLossTakeProfit:
3921
4043
  response = await self.contractPrivatePostApiV1ContractTpslHisorders(self.extend(request, params))
@@ -4091,7 +4213,7 @@ class htx(Exchange, ImplicitAPI):
4091
4213
  :param int [since]: the earliest time in ms to fetch orders for
4092
4214
  :param int [limit]: the maximum number of order structures to retrieve
4093
4215
  :param dict [params]: extra parameters specific to the exchange API endpoint
4094
- :param bool [params.stop]: *contract only* if the orders are stop trigger orders or not
4216
+ :param bool [params.trigger]: *contract only* if the orders are trigger trigger orders or not
4095
4217
  :param bool [params.stopLossTakeProfit]: *contract only* if the orders are stop-loss or take-profit orders
4096
4218
  :param int [params.until]: the latest time in ms to fetch entries for
4097
4219
  :param boolean [params.trailing]: *contract only* set to True if you want to fetch trailing stop orders
@@ -4157,7 +4279,7 @@ class htx(Exchange, ImplicitAPI):
4157
4279
  :param int [since]: the earliest time in ms to fetch open orders for
4158
4280
  :param int [limit]: the maximum number of open order structures to retrieve
4159
4281
  :param dict [params]: extra parameters specific to the exchange API endpoint
4160
- :param bool [params.stop]: *contract only* if the orders are stop trigger orders or not
4282
+ :param bool [params.trigger]: *contract only* if the orders are trigger trigger orders or not
4161
4283
  :param bool [params.stopLossTakeProfit]: *contract only* if the orders are stop-loss or take-profit orders
4162
4284
  :param boolean [params.trailing]: *contract only* set to True if you want to fetch trailing stop orders
4163
4285
  :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
@@ -4195,7 +4317,7 @@ class htx(Exchange, ImplicitAPI):
4195
4317
  if limit is not None:
4196
4318
  request['page_size'] = limit
4197
4319
  request['contract_code'] = market['id']
4198
- stop = self.safe_bool_2(params, 'stop', 'trigger')
4320
+ trigger = self.safe_bool_2(params, 'stop', 'trigger')
4199
4321
  stopLossTakeProfit = self.safe_value(params, 'stopLossTakeProfit')
4200
4322
  trailing = self.safe_bool(params, 'trailing', False)
4201
4323
  params = self.omit(params, ['stop', 'stopLossTakeProfit', 'trailing', 'trigger'])
@@ -4204,7 +4326,7 @@ class htx(Exchange, ImplicitAPI):
4204
4326
  marginMode, params = self.handle_margin_mode_and_params('fetchOpenOrders', params)
4205
4327
  marginMode = 'cross' if (marginMode is None) else marginMode
4206
4328
  if marginMode == 'isolated':
4207
- if stop:
4329
+ if trigger:
4208
4330
  response = await self.contractPrivatePostLinearSwapApiV1SwapTriggerOpenorders(self.extend(request, params))
4209
4331
  elif stopLossTakeProfit:
4210
4332
  response = await self.contractPrivatePostLinearSwapApiV1SwapTpslOpenorders(self.extend(request, params))
@@ -4213,7 +4335,7 @@ class htx(Exchange, ImplicitAPI):
4213
4335
  else:
4214
4336
  response = await self.contractPrivatePostLinearSwapApiV1SwapOpenorders(self.extend(request, params))
4215
4337
  elif marginMode == 'cross':
4216
- if stop:
4338
+ if trigger:
4217
4339
  response = await self.contractPrivatePostLinearSwapApiV1SwapCrossTriggerOpenorders(self.extend(request, params))
4218
4340
  elif stopLossTakeProfit:
4219
4341
  response = await self.contractPrivatePostLinearSwapApiV1SwapCrossTpslOpenorders(self.extend(request, params))
@@ -4223,7 +4345,7 @@ class htx(Exchange, ImplicitAPI):
4223
4345
  response = await self.contractPrivatePostLinearSwapApiV1SwapCrossOpenorders(self.extend(request, params))
4224
4346
  elif market['inverse']:
4225
4347
  if market['swap']:
4226
- if stop:
4348
+ if trigger:
4227
4349
  response = await self.contractPrivatePostSwapApiV1SwapTriggerOpenorders(self.extend(request, params))
4228
4350
  elif stopLossTakeProfit:
4229
4351
  response = await self.contractPrivatePostSwapApiV1SwapTpslOpenorders(self.extend(request, params))
@@ -4233,7 +4355,7 @@ class htx(Exchange, ImplicitAPI):
4233
4355
  response = await self.contractPrivatePostSwapApiV1SwapOpenorders(self.extend(request, params))
4234
4356
  elif market['future']:
4235
4357
  request['symbol'] = market['settleId']
4236
- if stop:
4358
+ if trigger:
4237
4359
  response = await self.contractPrivatePostApiV1ContractTriggerOpenorders(self.extend(request, params))
4238
4360
  elif stopLossTakeProfit:
4239
4361
  response = await self.contractPrivatePostApiV1ContractTpslOpenorders(self.extend(request, params))
@@ -4959,7 +5081,7 @@ class htx(Exchange, ImplicitAPI):
4959
5081
  if triggerPrice is None:
4960
5082
  stopOrderTypes = self.safe_value(options, 'stopOrderTypes', {})
4961
5083
  if orderType in stopOrderTypes:
4962
- raise ArgumentsRequired(self.id + ' createOrder() requires a triggerPrice for a stop order')
5084
+ raise ArgumentsRequired(self.id + ' createOrder() requires a triggerPrice for a trigger order')
4963
5085
  else:
4964
5086
  defaultOperator = 'lte' if (side == 'sell') else 'gte'
4965
5087
  stopOperator = self.safe_string(params, 'operator', defaultOperator)
@@ -5395,7 +5517,7 @@ class htx(Exchange, ImplicitAPI):
5395
5517
  :param str id: order id
5396
5518
  :param str symbol: unified symbol of the market the order was made in
5397
5519
  :param dict [params]: extra parameters specific to the exchange API endpoint
5398
- :param boolean [params.stop]: *contract only* if the order is a stop trigger order or not
5520
+ :param boolean [params.trigger]: *contract only* if the order is a trigger trigger order or not
5399
5521
  :param boolean [params.stopLossTakeProfit]: *contract only* if the order is a stop-loss or take-profit order
5400
5522
  :param boolean [params.trailing]: *contract only* set to True if you want to cancel a trailing order
5401
5523
  :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
@@ -5441,7 +5563,7 @@ class htx(Exchange, ImplicitAPI):
5441
5563
  request['symbol'] = market['settleId']
5442
5564
  else:
5443
5565
  request['contract_code'] = market['id']
5444
- stop = self.safe_bool_2(params, 'stop', 'trigger')
5566
+ trigger = self.safe_bool_2(params, 'stop', 'trigger')
5445
5567
  stopLossTakeProfit = self.safe_value(params, 'stopLossTakeProfit')
5446
5568
  trailing = self.safe_bool(params, 'trailing', False)
5447
5569
  params = self.omit(params, ['stop', 'stopLossTakeProfit', 'trailing', 'trigger'])
@@ -5450,7 +5572,7 @@ class htx(Exchange, ImplicitAPI):
5450
5572
  marginMode, params = self.handle_margin_mode_and_params('cancelOrder', params)
5451
5573
  marginMode = 'cross' if (marginMode is None) else marginMode
5452
5574
  if marginMode == 'isolated':
5453
- if stop:
5575
+ if trigger:
5454
5576
  response = await self.contractPrivatePostLinearSwapApiV1SwapTriggerCancel(self.extend(request, params))
5455
5577
  elif stopLossTakeProfit:
5456
5578
  response = await self.contractPrivatePostLinearSwapApiV1SwapTpslCancel(self.extend(request, params))
@@ -5459,7 +5581,7 @@ class htx(Exchange, ImplicitAPI):
5459
5581
  else:
5460
5582
  response = await self.contractPrivatePostLinearSwapApiV1SwapCancel(self.extend(request, params))
5461
5583
  elif marginMode == 'cross':
5462
- if stop:
5584
+ if trigger:
5463
5585
  response = await self.contractPrivatePostLinearSwapApiV1SwapCrossTriggerCancel(self.extend(request, params))
5464
5586
  elif stopLossTakeProfit:
5465
5587
  response = await self.contractPrivatePostLinearSwapApiV1SwapCrossTpslCancel(self.extend(request, params))
@@ -5469,7 +5591,7 @@ class htx(Exchange, ImplicitAPI):
5469
5591
  response = await self.contractPrivatePostLinearSwapApiV1SwapCrossCancel(self.extend(request, params))
5470
5592
  elif market['inverse']:
5471
5593
  if market['swap']:
5472
- if stop:
5594
+ if trigger:
5473
5595
  response = await self.contractPrivatePostSwapApiV1SwapTriggerCancel(self.extend(request, params))
5474
5596
  elif stopLossTakeProfit:
5475
5597
  response = await self.contractPrivatePostSwapApiV1SwapTpslCancel(self.extend(request, params))
@@ -5478,7 +5600,7 @@ class htx(Exchange, ImplicitAPI):
5478
5600
  else:
5479
5601
  response = await self.contractPrivatePostSwapApiV1SwapCancel(self.extend(request, params))
5480
5602
  elif market['future']:
5481
- if stop:
5603
+ if trigger:
5482
5604
  response = await self.contractPrivatePostApiV1ContractTriggerCancel(self.extend(request, params))
5483
5605
  elif stopLossTakeProfit:
5484
5606
  response = await self.contractPrivatePostApiV1ContractTpslCancel(self.extend(request, params))
@@ -5518,7 +5640,7 @@ class htx(Exchange, ImplicitAPI):
5518
5640
  :param str[] ids: order ids
5519
5641
  :param str symbol: unified market symbol, default is None
5520
5642
  :param dict [params]: extra parameters specific to the exchange API endpoint
5521
- :param bool [params.stop]: *contract only* if the orders are stop trigger orders or not
5643
+ :param bool [params.trigger]: *contract only* if the orders are trigger trigger orders or not
5522
5644
  :param bool [params.stopLossTakeProfit]: *contract only* if the orders are stop-loss or take-profit orders
5523
5645
  :returns dict: an list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
5524
5646
  """
@@ -5568,7 +5690,7 @@ class htx(Exchange, ImplicitAPI):
5568
5690
  request['symbol'] = market['settleId']
5569
5691
  else:
5570
5692
  request['contract_code'] = market['id']
5571
- stop = self.safe_bool_2(params, 'stop', 'trigger')
5693
+ trigger = self.safe_bool_2(params, 'stop', 'trigger')
5572
5694
  stopLossTakeProfit = self.safe_value(params, 'stopLossTakeProfit')
5573
5695
  params = self.omit(params, ['stop', 'stopLossTakeProfit', 'trigger'])
5574
5696
  if market['linear']:
@@ -5576,14 +5698,14 @@ class htx(Exchange, ImplicitAPI):
5576
5698
  marginMode, params = self.handle_margin_mode_and_params('cancelOrders', params)
5577
5699
  marginMode = 'cross' if (marginMode is None) else marginMode
5578
5700
  if marginMode == 'isolated':
5579
- if stop:
5701
+ if trigger:
5580
5702
  response = await self.contractPrivatePostLinearSwapApiV1SwapTriggerCancel(self.extend(request, params))
5581
5703
  elif stopLossTakeProfit:
5582
5704
  response = await self.contractPrivatePostLinearSwapApiV1SwapTpslCancel(self.extend(request, params))
5583
5705
  else:
5584
5706
  response = await self.contractPrivatePostLinearSwapApiV1SwapCancel(self.extend(request, params))
5585
5707
  elif marginMode == 'cross':
5586
- if stop:
5708
+ if trigger:
5587
5709
  response = await self.contractPrivatePostLinearSwapApiV1SwapCrossTriggerCancel(self.extend(request, params))
5588
5710
  elif stopLossTakeProfit:
5589
5711
  response = await self.contractPrivatePostLinearSwapApiV1SwapCrossTpslCancel(self.extend(request, params))
@@ -5591,14 +5713,14 @@ class htx(Exchange, ImplicitAPI):
5591
5713
  response = await self.contractPrivatePostLinearSwapApiV1SwapCrossCancel(self.extend(request, params))
5592
5714
  elif market['inverse']:
5593
5715
  if market['swap']:
5594
- if stop:
5716
+ if trigger:
5595
5717
  response = await self.contractPrivatePostSwapApiV1SwapTriggerCancel(self.extend(request, params))
5596
5718
  elif stopLossTakeProfit:
5597
5719
  response = await self.contractPrivatePostSwapApiV1SwapTpslCancel(self.extend(request, params))
5598
5720
  else:
5599
5721
  response = await self.contractPrivatePostSwapApiV1SwapCancel(self.extend(request, params))
5600
5722
  elif market['future']:
5601
- if stop:
5723
+ if trigger:
5602
5724
  response = await self.contractPrivatePostApiV1ContractTriggerCancel(self.extend(request, params))
5603
5725
  elif stopLossTakeProfit:
5604
5726
  response = await self.contractPrivatePostApiV1ContractTpslCancel(self.extend(request, params))
@@ -5719,7 +5841,7 @@ class htx(Exchange, ImplicitAPI):
5719
5841
  cancel all open orders
5720
5842
  :param str symbol: unified market symbol, only orders in the market of self symbol are cancelled when symbol is not None
5721
5843
  :param dict [params]: extra parameters specific to the exchange API endpoint
5722
- :param boolean [params.stop]: *contract only* if the orders are stop trigger orders or not
5844
+ :param boolean [params.trigger]: *contract only* if the orders are trigger trigger orders or not
5723
5845
  :param boolean [params.stopLossTakeProfit]: *contract only* if the orders are stop-loss or take-profit orders
5724
5846
  :param boolean [params.trailing]: *contract only* set to True if you want to cancel all trailing orders
5725
5847
  :returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
@@ -5771,7 +5893,7 @@ class htx(Exchange, ImplicitAPI):
5771
5893
  if market['future']:
5772
5894
  request['symbol'] = market['settleId']
5773
5895
  request['contract_code'] = market['id']
5774
- stop = self.safe_bool_2(params, 'stop', 'trigger')
5896
+ trigger = self.safe_bool_2(params, 'stop', 'trigger')
5775
5897
  stopLossTakeProfit = self.safe_value(params, 'stopLossTakeProfit')
5776
5898
  trailing = self.safe_bool(params, 'trailing', False)
5777
5899
  params = self.omit(params, ['stop', 'stopLossTakeProfit', 'trailing', 'trigger'])
@@ -5780,7 +5902,7 @@ class htx(Exchange, ImplicitAPI):
5780
5902
  marginMode, params = self.handle_margin_mode_and_params('cancelAllOrders', params)
5781
5903
  marginMode = 'cross' if (marginMode is None) else marginMode
5782
5904
  if marginMode == 'isolated':
5783
- if stop:
5905
+ if trigger:
5784
5906
  response = await self.contractPrivatePostLinearSwapApiV1SwapTriggerCancelall(self.extend(request, params))
5785
5907
  elif stopLossTakeProfit:
5786
5908
  response = await self.contractPrivatePostLinearSwapApiV1SwapTpslCancelall(self.extend(request, params))
@@ -5789,7 +5911,7 @@ class htx(Exchange, ImplicitAPI):
5789
5911
  else:
5790
5912
  response = await self.contractPrivatePostLinearSwapApiV1SwapCancelall(self.extend(request, params))
5791
5913
  elif marginMode == 'cross':
5792
- if stop:
5914
+ if trigger:
5793
5915
  response = await self.contractPrivatePostLinearSwapApiV1SwapCrossTriggerCancelall(self.extend(request, params))
5794
5916
  elif stopLossTakeProfit:
5795
5917
  response = await self.contractPrivatePostLinearSwapApiV1SwapCrossTpslCancelall(self.extend(request, params))
@@ -5799,7 +5921,7 @@ class htx(Exchange, ImplicitAPI):
5799
5921
  response = await self.contractPrivatePostLinearSwapApiV1SwapCrossCancelall(self.extend(request, params))
5800
5922
  elif market['inverse']:
5801
5923
  if market['swap']:
5802
- if stop:
5924
+ if trigger:
5803
5925
  response = await self.contractPrivatePostSwapApiV1SwapTriggerCancelall(self.extend(request, params))
5804
5926
  elif stopLossTakeProfit:
5805
5927
  response = await self.contractPrivatePostSwapApiV1SwapTpslCancelall(self.extend(request, params))
@@ -5808,7 +5930,7 @@ class htx(Exchange, ImplicitAPI):
5808
5930
  else:
5809
5931
  response = await self.contractPrivatePostSwapApiV1SwapCancelall(self.extend(request, params))
5810
5932
  elif market['future']:
5811
- if stop:
5933
+ if trigger:
5812
5934
  response = await self.contractPrivatePostApiV1ContractTriggerCancelall(self.extend(request, params))
5813
5935
  elif stopLossTakeProfit:
5814
5936
  response = await self.contractPrivatePostApiV1ContractTpslCancelall(self.extend(request, params))
@@ -577,6 +577,7 @@ class kucoin(Exchange, ImplicitAPI):
577
577
  '400008': NotSupported,
578
578
  '400100': InsufficientFunds, # {"msg":"account.available.amount","code":"400100"} or {"msg":"Withdrawal amount is below the minimum requirement.","code":"400100"}
579
579
  '400200': InvalidOrder, # {"code":"400200","msg":"Forbidden to place an order"}
580
+ '400330': InvalidOrder, # {"msg":"Order price can't deviate from NAV by 50%","code":"400330"}
580
581
  '400350': InvalidOrder, # {"code":"400350","msg":"Upper limit for holding: 10,000USDT, you can still buy 10,000USDT worth of coin."}
581
582
  '400370': InvalidOrder, # {"code":"400370","msg":"Max. price: 0.02500000000000000000"}
582
583
  '400400': BadRequest, # Parameter error
@@ -7,7 +7,7 @@ from ccxt.async_support.base.exchange import Exchange
7
7
  from ccxt.abstract.mexc import ImplicitAPI
8
8
  import asyncio
9
9
  import hashlib
10
- from ccxt.base.types import Account, Balances, Currencies, Currency, DepositAddress, IndexType, Int, Leverage, LeverageTier, LeverageTiers, MarginModification, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, FundingRate, Trade, TradingFees, Transaction, TransferEntry
10
+ from ccxt.base.types import Account, Balances, Currencies, Currency, DepositAddress, IndexType, Int, Leverage, LeverageTier, LeverageTiers, MarginModification, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, FundingRate, Trade, TradingFeeInterface, Transaction, TransferEntry
11
11
  from typing import List
12
12
  from ccxt.base.errors import ExchangeError
13
13
  from ccxt.base.errors import AuthenticationError
@@ -133,8 +133,8 @@ class mexc(Exchange, ImplicitAPI):
133
133
  'fetchTickers': True,
134
134
  'fetchTime': True,
135
135
  'fetchTrades': True,
136
- 'fetchTradingFee': None,
137
- 'fetchTradingFees': True,
136
+ 'fetchTradingFee': True,
137
+ 'fetchTradingFees': False,
138
138
  'fetchTradingLimits': None,
139
139
  'fetchTransactionFee': 'emulated',
140
140
  'fetchTransactionFees': True,
@@ -207,6 +207,7 @@ class mexc(Exchange, ImplicitAPI):
207
207
  'allOrders': 10,
208
208
  'account': 10,
209
209
  'myTrades': 10,
210
+ 'tradeFee': 10,
210
211
  'sub-account/list': 1,
211
212
  'sub-account/apiKey': 1,
212
213
  'capital/config/getall': 10,
@@ -3426,34 +3427,44 @@ class mexc(Exchange, ImplicitAPI):
3426
3427
  })
3427
3428
  return result
3428
3429
 
3429
- async def fetch_trading_fees(self, params={}) -> TradingFees:
3430
+ async def fetch_trading_fee(self, symbol: str, params={}) -> TradingFeeInterface:
3430
3431
  """
3431
- fetch the trading fees for multiple markets
3432
+ fetch the trading fees for a market
3432
3433
 
3433
- https://mexcdevelop.github.io/apidocs/spot_v3_en/#account-information
3434
- https://mexcdevelop.github.io/apidocs/contract_v1_en/#get-all-informations-of-user-39-s-asset
3434
+ https://mexcdevelop.github.io/apidocs/spot_v3_en/#query-mx-deduct-status
3435
3435
 
3436
+ :param str symbol: unified market symbol
3436
3437
  :param dict [params]: extra parameters specific to the exchange API endpoint
3437
- :returns dict: a dictionary of `fee structures <https://docs.ccxt.com/#/?id=fee-structure>` indexed by market symbols
3438
+ :returns dict: a `fee structure <https://docs.ccxt.com/#/?id=fee-structure>`
3438
3439
  """
3439
3440
  await self.load_markets()
3440
- response = await self.fetch_account_helper('spot', params)
3441
- makerFee = self.safe_string(response, 'makerCommission')
3442
- takerFee = self.safe_string(response, 'takerCommission')
3443
- makerFee = Precise.string_div(makerFee, '1000')
3444
- takerFee = Precise.string_div(takerFee, '1000')
3445
- result: dict = {}
3446
- for i in range(0, len(self.symbols)):
3447
- symbol = self.symbols[i]
3448
- result[symbol] = {
3449
- 'symbol': symbol,
3450
- 'maker': self.parse_number(makerFee),
3451
- 'taker': self.parse_number(takerFee),
3452
- 'percentage': True,
3453
- 'tierBased': False,
3454
- 'info': response,
3455
- }
3456
- return result
3441
+ market = self.market(symbol)
3442
+ if not market['spot']:
3443
+ raise BadRequest(self.id + ' fetchTradingFee() supports spot markets only')
3444
+ request: dict = {
3445
+ 'symbol': market['id'],
3446
+ }
3447
+ response = await self.spotPrivateGetTradeFee(self.extend(request, params))
3448
+ #
3449
+ # {
3450
+ # "data":{
3451
+ # "makerCommission":0.003000000000000000,
3452
+ # "takerCommission":0.003000000000000000
3453
+ # },
3454
+ # "code":0,
3455
+ # "msg":"success",
3456
+ # "timestamp":1669109672717
3457
+ # }
3458
+ #
3459
+ data = self.safe_dict(response, 'data', {})
3460
+ return {
3461
+ 'info': data,
3462
+ 'symbol': symbol,
3463
+ 'maker': self.safe_number(data, 'makerCommission'),
3464
+ 'taker': self.safe_number(data, 'takerCommission'),
3465
+ 'percentage': None,
3466
+ 'tierBased': None,
3467
+ }
3457
3468
 
3458
3469
  def custom_parse_balance(self, response, marketType) -> Balances:
3459
3470
  #
ccxt/async_support/okx.py CHANGED
@@ -2243,6 +2243,7 @@ class okx(Exchange, ImplicitAPI):
2243
2243
  :param int [since]: timestamp in ms of the earliest trade to fetch
2244
2244
  :param int [limit]: the maximum amount of trades to fetch
2245
2245
  :param dict [params]: extra parameters specific to the exchange API endpoint
2246
+ :param str [params.method]: 'publicGetMarketTrades' or 'publicGetMarketHistoryTrades' default is 'publicGetMarketTrades'
2246
2247
  :param boolean [params.paginate]: *only applies to publicGetMarketHistoryTrades* default False, when True will automatically paginate by calling self endpoint multiple times
2247
2248
  :returns Trade[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
2248
2249
  """
ccxt/async_support/woo.py CHANGED
@@ -45,7 +45,7 @@ class woo(Exchange, ImplicitAPI):
45
45
  'cancelAllOrders': True,
46
46
  'cancelAllOrdersAfter': True,
47
47
  'cancelOrder': True,
48
- 'cancelWithdraw': False, # exchange have that endpoint disabled atm, but was once implemented in ccxt per old docs: https://kronosresearch.github.io/wootrade-documents/#cancel-withdraw-request
48
+ 'cancelWithdraw': False, # exchange have that endpoint disabled atm, but was once implemented in ccxt per old docs: https://docx.woo.io/wootrade-documents/#cancel-withdraw-request
49
49
  'closeAllPositions': False,
50
50
  'closePosition': False,
51
51
  'createConvertTrade': True,
@@ -124,7 +124,7 @@ class woo(Exchange, ImplicitAPI):
124
124
  'setMargin': False,
125
125
  'setPositionMode': True,
126
126
  'transfer': True,
127
- 'withdraw': True, # exchange have that endpoint disabled atm, but was once implemented in ccxt per old docs: https://kronosresearch.github.io/wootrade-documents/#token-withdraw
127
+ 'withdraw': True, # exchange have that endpoint disabled atm, but was once implemented in ccxt per old docs: https://docx.woo.io/wootrade-documents/#token-withdraw
128
128
  },
129
129
  'timeframes': {
130
130
  '1m': '1m',
@@ -168,7 +168,7 @@ class woo(Exchange, ImplicitAPI):
168
168
  'pub': {
169
169
  'get': {
170
170
  'hist/kline': 10,
171
- 'hist/trades': 1,
171
+ 'hist/trades': 10,
172
172
  },
173
173
  },
174
174
  'public': {
@@ -218,11 +218,11 @@ class woo(Exchange, ImplicitAPI):
218
218
  'client/futures_leverage': 60,
219
219
  },
220
220
  'post': {
221
- 'order': 5, # 2 requests per 1 second per symbol
221
+ 'order': 1, # 10 requests per 1 second per symbol
222
222
  'order/cancel_all_after': 1,
223
223
  'asset/main_sub_transfer': 30, # 20 requests per 60 seconds
224
224
  'asset/ltv': 30,
225
- 'asset/withdraw': 30, # implemented in ccxt, disabled on the exchange side https://kronosresearch.github.io/wootrade-documents/#token-withdraw
225
+ 'asset/withdraw': 30, # implemented in ccxt, disabled on the exchange side https://docx.woo.io/wootrade-documents/#token-withdraw
226
226
  'asset/internal_withdraw': 30,
227
227
  'interest/repay': 60,
228
228
  'client/account_mode': 120,
@@ -235,7 +235,7 @@ class woo(Exchange, ImplicitAPI):
235
235
  'order': 1,
236
236
  'client/order': 1,
237
237
  'orders': 1,
238
- 'asset/withdraw': 120, # implemented in ccxt, disabled on the exchange side https://kronosresearch.github.io/wootrade-documents/#cancel-withdraw-request
238
+ 'asset/withdraw': 120, # implemented in ccxt, disabled on the exchange side https://docx.woo.io/wootrade-documents/#cancel-withdraw-request
239
239
  },
240
240
  },
241
241
  },
ccxt/base/exchange.py CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # -----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.4.38'
7
+ __version__ = '4.4.39'
8
8
 
9
9
  # -----------------------------------------------------------------------------
10
10
 
@@ -6537,29 +6537,39 @@ class Exchange(object):
6537
6537
  symbolAndTimeFrame = symbolsAndTimeFrames[i]
6538
6538
  symbol = self.safe_string(symbolAndTimeFrame, 0)
6539
6539
  timeframe = self.safe_string(symbolAndTimeFrame, 1)
6540
- if timeframe in self.ohlcvs[symbol]:
6541
- del self.ohlcvs[symbol][timeframe]
6540
+ if symbol in self.ohlcvs:
6541
+ if timeframe in self.ohlcvs[symbol]:
6542
+ del self.ohlcvs[symbol][timeframe]
6542
6543
  elif symbolsLength > 0:
6543
6544
  for i in range(0, len(symbols)):
6544
6545
  symbol = symbols[i]
6545
6546
  if topic == 'trades':
6546
- del self.trades[symbol]
6547
+ if symbol in self.trades:
6548
+ del self.trades[symbol]
6547
6549
  elif topic == 'orderbook':
6548
- del self.orderbooks[symbol]
6550
+ if symbol in self.orderbooks:
6551
+ del self.orderbooks[symbol]
6549
6552
  elif topic == 'ticker':
6550
- del self.tickers[symbol]
6553
+ if symbol in self.tickers:
6554
+ del self.tickers[symbol]
6551
6555
  else:
6552
6556
  if topic == 'myTrades':
6553
6557
  # don't reset self.myTrades directly here
6554
- # because in c# we need to use a different object
6558
+ # because in c# we need to use a different object(thread-safe dict)
6555
6559
  keys = list(self.myTrades.keys())
6556
6560
  for i in range(0, len(keys)):
6557
- del self.myTrades[keys[i]]
6561
+ key = keys[i]
6562
+ if key in self.myTrades:
6563
+ del self.myTrades[key]
6558
6564
  elif topic == 'orders':
6559
6565
  orderSymbols = list(self.orders.keys())
6560
6566
  for i in range(0, len(orderSymbols)):
6561
- del self.orders[orderSymbols[i]]
6567
+ orderSymbol = orderSymbols[i]
6568
+ if orderSymbol in self.orders:
6569
+ del self.orders[orderSymbol]
6562
6570
  elif topic == 'ticker':
6563
6571
  tickerSymbols = list(self.tickers.keys())
6564
6572
  for i in range(0, len(tickerSymbols)):
6565
- del self.tickers[tickerSymbols[i]]
6573
+ tickerSymbol = tickerSymbols[i]
6574
+ if tickerSymbol in self.tickers:
6575
+ del self.tickers[tickerSymbol]