ccxt 4.4.16__py2.py3-none-any.whl → 4.4.18__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.
@@ -359,11 +359,7 @@ class timex(Exchange, ImplicitAPI):
359
359
  # },
360
360
  # ]
361
361
  #
362
- result = []
363
- for i in range(0, len(response)):
364
- currency = response[i]
365
- result.append(self.parse_currency(currency))
366
- return self.index_by(result, 'code')
362
+ return self.parse_currencies(response)
367
363
 
368
364
  async def fetch_deposits(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
369
365
  """
@@ -1239,7 +1235,7 @@ class timex(Exchange, ImplicitAPI):
1239
1235
  'info': market,
1240
1236
  }
1241
1237
 
1242
- def parse_currency(self, currency: dict):
1238
+ def parse_currency(self, currency: dict) -> Currency:
1243
1239
  #
1244
1240
  # {
1245
1241
  # "symbol": "BTC",
@@ -1300,7 +1296,7 @@ class timex(Exchange, ImplicitAPI):
1300
1296
  for i in range(0, -dotIndex):
1301
1297
  fraction += '0'
1302
1298
  fee = self.parse_number(fraction + feeString)
1303
- return {
1299
+ return self.safe_currency_structure({
1304
1300
  'id': code,
1305
1301
  'code': code,
1306
1302
  'info': currency,
@@ -1316,7 +1312,7 @@ class timex(Exchange, ImplicitAPI):
1316
1312
  'amount': {'min': None, 'max': None},
1317
1313
  },
1318
1314
  'networks': {},
1319
- }
1315
+ })
1320
1316
 
1321
1317
  def parse_ticker(self, ticker: dict, market: Market = None) -> Ticker:
1322
1318
  #
ccxt/base/exchange.py CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # -----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.4.16'
7
+ __version__ = '4.4.18'
8
8
 
9
9
  # -----------------------------------------------------------------------------
10
10
 
@@ -2491,6 +2491,18 @@ class Exchange(object):
2491
2491
  def fetch_trading_limits(self, symbols: Strings = None, params={}):
2492
2492
  raise NotSupported(self.id + ' fetchTradingLimits() is not supported yet')
2493
2493
 
2494
+ def parse_currency(self, rawCurrency: dict):
2495
+ raise NotSupported(self.id + ' parseCurrency() is not supported yet')
2496
+
2497
+ def parse_currencies(self, rawCurrencies):
2498
+ result = {}
2499
+ arr = self.to_array(rawCurrencies)
2500
+ for i in range(0, len(arr)):
2501
+ parsed = self.parse_currency(arr[i])
2502
+ code = parsed['code']
2503
+ result[code] = parsed
2504
+ return result
2505
+
2494
2506
  def parse_market(self, market: dict):
2495
2507
  raise NotSupported(self.id + ' parseMarket() is not supported yet')
2496
2508
 
ccxt/binance.py CHANGED
@@ -2662,11 +2662,16 @@ class binance(Exchange, ImplicitAPI):
2662
2662
  apiBackup = self.safe_value(self.urls, 'apiBackup')
2663
2663
  if apiBackup is not None:
2664
2664
  return None
2665
- promises = [self.sapiGetCapitalConfigGetall(params), self.sapiGetMarginAllAssets(params)]
2665
+ promises = [self.sapiGetCapitalConfigGetall(params)]
2666
+ fetchMargins = self.safe_bool(self.options, 'fetchMargins', False)
2667
+ if fetchMargins:
2668
+ promises.append(self.sapiGetMarginAllPairs(params))
2666
2669
  results = promises
2667
2670
  responseCurrencies = results[0]
2668
- responseMarginables = results[1]
2669
- marginablesById = self.index_by(responseMarginables, 'assetName')
2671
+ marginablesById = None
2672
+ if fetchMargins:
2673
+ responseMarginables = results[1]
2674
+ marginablesById = self.index_by(responseMarginables, 'assetName')
2670
2675
  result: dict = {}
2671
2676
  for i in range(0, len(responseCurrencies)):
2672
2677
  #
@@ -4114,7 +4119,7 @@ class binance(Exchange, ImplicitAPI):
4114
4119
  fetches mark price for the market
4115
4120
  :see: https://binance-docs.github.io/apidocs/futures/en/#mark-price
4116
4121
  :see: https://binance-docs.github.io/apidocs/delivery/en/#index-price-and-mark-price
4117
- :param str[] [symbols]: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
4122
+ :param str symbol: unified symbol of the market to fetch the ticker for
4118
4123
  :param dict [params]: extra parameters specific to the exchange API endpoint
4119
4124
  :param str [params.subType]: "linear" or "inverse"
4120
4125
  :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
ccxt/bingx.py CHANGED
@@ -81,6 +81,7 @@ class bingx(Exchange, ImplicitAPI):
81
81
  'fetchMarginMode': True,
82
82
  'fetchMarkets': True,
83
83
  'fetchMarkOHLCV': True,
84
+ 'fetchMarkPrice': True,
84
85
  'fetchMarkPrices': True,
85
86
  'fetchMyLiquidations': True,
86
87
  'fetchOHLCV': True,
@@ -612,9 +613,10 @@ class bingx(Exchange, ImplicitAPI):
612
613
  'max': self.safe_number(rawNetwork, 'withdrawMax'),
613
614
  },
614
615
  }
616
+ fee = self.safe_number(rawNetwork, 'withdrawFee')
615
617
  if isDefault:
616
- fee = self.safe_number(rawNetwork, 'withdrawFee')
617
618
  defaultLimits = limits
619
+ precision = self.safe_number(rawNetwork, 'withdrawPrecision')
618
620
  networkActive = networkDepositEnabled or networkWithdrawEnabled
619
621
  networks[networkCode] = {
620
622
  'info': rawNetwork,
@@ -624,7 +626,7 @@ class bingx(Exchange, ImplicitAPI):
624
626
  'active': networkActive,
625
627
  'deposit': networkDepositEnabled,
626
628
  'withdraw': networkWithdrawEnabled,
627
- 'precision': None,
629
+ 'precision': precision,
628
630
  'limits': limits,
629
631
  }
630
632
  active = depositEnabled or withdrawEnabled
@@ -1656,6 +1658,59 @@ class bingx(Exchange, ImplicitAPI):
1656
1658
  tickers = self.safe_list(response, 'data')
1657
1659
  return self.parse_tickers(tickers, symbols)
1658
1660
 
1661
+ def fetch_mark_price(self, symbol: str, params={}) -> Ticker:
1662
+ """
1663
+ fetches mark prices for the market
1664
+ :see: https://bingx-api.github.io/docs/#/en-us/swapV2/market-api.html#Mark%20Price%20and%20Funding%20Rate
1665
+ :param str symbol: unified symbol of the market to fetch the ticker for
1666
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1667
+ :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
1668
+ """
1669
+ self.load_markets()
1670
+ market = self.market(symbol)
1671
+ subType = None
1672
+ subType, params = self.handle_sub_type_and_params('fetchMarkPrice', market, params, 'linear')
1673
+ request = {
1674
+ 'symbol': market['id'],
1675
+ }
1676
+ response = None
1677
+ if subType == 'inverse':
1678
+ response = self.cswapV1PublicGetMarketPremiumIndex(self.extend(request, params))
1679
+ #
1680
+ # {
1681
+ # "code": 0,
1682
+ # "msg": "",
1683
+ # "timestamp": 1728577213289,
1684
+ # "data": [
1685
+ # {
1686
+ # "symbol": "ETH-USD",
1687
+ # "lastFundingRate": "0.0001",
1688
+ # "markPrice": "2402.68",
1689
+ # "indexPrice": "2404.92",
1690
+ # "nextFundingTime": 1728604800000
1691
+ # }
1692
+ # ]
1693
+ # }
1694
+ #
1695
+ else:
1696
+ response = self.swapV2PublicGetQuotePremiumIndex(self.extend(request, params))
1697
+ #
1698
+ # {
1699
+ # "code": 0,
1700
+ # "msg": "",
1701
+ # "data": {
1702
+ # "symbol": "ETH-USDT",
1703
+ # "markPrice": "2408.40",
1704
+ # "indexPrice": "2409.62",
1705
+ # "lastFundingRate": "0.00009900",
1706
+ # "nextFundingTime": 1728604800000
1707
+ # }
1708
+ # }
1709
+ #
1710
+ if isinstance(response['data'], list):
1711
+ return self.parse_ticker(self.safe_dict(response['data'], 0, {}), market)
1712
+ return self.parse_ticker(response['data'], market)
1713
+
1659
1714
  def fetch_mark_prices(self, symbols: Strings = None, params={}) -> Tickers:
1660
1715
  """
1661
1716
  fetches mark prices for multiple markets
ccxt/bitmart.py CHANGED
@@ -1287,7 +1287,7 @@ class bitmart(Exchange, ImplicitAPI):
1287
1287
  'close': last,
1288
1288
  'last': last,
1289
1289
  'previousClose': None,
1290
- 'change': change,
1290
+ 'change': None,
1291
1291
  'percentage': percentage,
1292
1292
  'average': average,
1293
1293
  'baseVolume': baseVolume,
ccxt/bitso.py CHANGED
@@ -124,6 +124,12 @@ class bitso(Exchange, ImplicitAPI):
124
124
  'TUSD': 0.01,
125
125
  },
126
126
  'defaultPrecision': 0.00000001,
127
+ 'networks': {
128
+ 'TRC20': 'trx',
129
+ 'ERC20': 'erc20',
130
+ 'BEP20': 'bsc',
131
+ 'BEP2': 'bep2',
132
+ },
127
133
  },
128
134
  'timeframes': {
129
135
  '1m': '60',
@@ -1548,18 +1554,6 @@ class bitso(Exchange, ImplicitAPI):
1548
1554
  first = self.safe_dict(payload, 0)
1549
1555
  return self.parse_transaction(first, currency)
1550
1556
 
1551
- def safe_network(self, networkId):
1552
- if networkId is None:
1553
- return None
1554
- networkId = networkId.upper()
1555
- networksById: dict = {
1556
- 'trx': 'TRC20',
1557
- 'erc20': 'ERC20',
1558
- 'bsc': 'BEP20',
1559
- 'bep2': 'BEP2',
1560
- }
1561
- return self.safe_string(networksById, networkId, networkId)
1562
-
1563
1557
  def parse_transaction(self, transaction: dict, currency: Currency = None) -> Transaction:
1564
1558
  #
1565
1559
  # deposit
@@ -1606,12 +1600,14 @@ class bitso(Exchange, ImplicitAPI):
1606
1600
  networkId = self.safe_string_2(transaction, 'network', 'method')
1607
1601
  status = self.safe_string(transaction, 'status')
1608
1602
  withdrawId = self.safe_string(transaction, 'wid')
1603
+ networkCode = self.network_id_to_code(networkId)
1604
+ networkCodeUpper = networkCode.upper() if (networkCode is not None) else None
1609
1605
  return {
1610
1606
  'id': self.safe_string_2(transaction, 'wid', 'fid'),
1611
1607
  'txid': self.safe_string(details, 'tx_hash'),
1612
1608
  'timestamp': self.parse8601(datetime),
1613
1609
  'datetime': datetime,
1614
- 'network': self.safe_network(networkId),
1610
+ 'network': networkCodeUpper,
1615
1611
  'addressFrom': receivingAddress,
1616
1612
  'address': withdrawalAddress if (withdrawalAddress is not None) else receivingAddress,
1617
1613
  'addressTo': withdrawalAddress,
ccxt/bitvavo.py CHANGED
@@ -458,9 +458,9 @@ class bitvavo(Exchange, ImplicitAPI):
458
458
  # },
459
459
  # ]
460
460
  #
461
- return self.parse_currencies(response)
461
+ return self.parse_currencies_custom(response)
462
462
 
463
- def parse_currencies(self, currencies):
463
+ def parse_currencies_custom(self, currencies):
464
464
  #
465
465
  # [
466
466
  # {
ccxt/bybit.py CHANGED
@@ -4538,7 +4538,7 @@ class bybit(Exchange, ImplicitAPI):
4538
4538
  length = len(result)
4539
4539
  if length == 0:
4540
4540
  isTrigger = self.safe_bool_n(params, ['trigger', 'stop'], False)
4541
- extra = '' if isTrigger else 'If you are trying to fetch SL/TP conditional order, you might try setting params["trigger"] = True'
4541
+ extra = '' if isTrigger else ' If you are trying to fetch SL/TP conditional order, you might try setting params["trigger"] = True'
4542
4542
  raise OrderNotFound('Order ' + str(id) + ' was not found.' + extra)
4543
4543
  if length > 1:
4544
4544
  raise InvalidOrder(self.id + ' returned more than one order')
@@ -4627,6 +4627,9 @@ class bybit(Exchange, ImplicitAPI):
4627
4627
  #
4628
4628
  result = self.safe_dict(response, 'result', {})
4629
4629
  innerList = self.safe_list(result, 'list', [])
4630
+ if len(innerList) == 0:
4631
+ extra = '' if isTrigger else ' If you are trying to fetch SL/TP conditional order, you might try setting params["trigger"] = True'
4632
+ raise OrderNotFound('Order ' + str(id) + ' was not found.' + extra)
4630
4633
  order = self.safe_dict(innerList, 0, {})
4631
4634
  return self.parse_order(order, market)
4632
4635
 
@@ -4777,7 +4780,7 @@ class bybit(Exchange, ImplicitAPI):
4777
4780
  length = len(result)
4778
4781
  if length == 0:
4779
4782
  isTrigger = self.safe_bool_n(params, ['trigger', 'stop'], False)
4780
- extra = '' if isTrigger else 'If you are trying to fetch SL/TP conditional order, you might try setting params["trigger"] = True'
4783
+ extra = '' if isTrigger else ' If you are trying to fetch SL/TP conditional order, you might try setting params["trigger"] = True'
4781
4784
  raise OrderNotFound('Order ' + str(id) + ' was not found.' + extra)
4782
4785
  if length > 1:
4783
4786
  raise InvalidOrder(self.id + ' returned more than one order')
@@ -4806,7 +4809,7 @@ class bybit(Exchange, ImplicitAPI):
4806
4809
  length = len(result)
4807
4810
  if length == 0:
4808
4811
  isTrigger = self.safe_bool_n(params, ['trigger', 'stop'], False)
4809
- extra = '' if isTrigger else 'If you are trying to fetch SL/TP conditional order, you might try setting params["trigger"] = True'
4812
+ extra = '' if isTrigger else ' If you are trying to fetch SL/TP conditional order, you might try setting params["trigger"] = True'
4810
4813
  raise OrderNotFound('Order ' + str(id) + ' was not found.' + extra)
4811
4814
  if length > 1:
4812
4815
  raise InvalidOrder(self.id + ' returned more than one order')
@@ -1315,13 +1315,9 @@ class coinbaseinternational(Exchange, ImplicitAPI):
1315
1315
  # ...
1316
1316
  # ]
1317
1317
  #
1318
- result: dict = {}
1319
- for i in range(0, len(currencies)):
1320
- currency = self.parse_currency(currencies[i])
1321
- result[currency['code']] = currency
1322
- return result
1318
+ return self.parse_currencies(currencies)
1323
1319
 
1324
- def parse_currency(self, currency: dict):
1320
+ def parse_currency(self, currency: dict) -> Currency:
1325
1321
  #
1326
1322
  # {
1327
1323
  # "asset_id":"1",
@@ -1335,7 +1331,7 @@ class coinbaseinternational(Exchange, ImplicitAPI):
1335
1331
  id = self.safe_string(currency, 'asset_name')
1336
1332
  code = self.safe_currency_code(id)
1337
1333
  statusId = self.safe_string(currency, 'status')
1338
- return {
1334
+ return self.safe_currency_structure({
1339
1335
  'id': id,
1340
1336
  'name': code,
1341
1337
  'code': code,
@@ -1348,7 +1344,7 @@ class coinbaseinternational(Exchange, ImplicitAPI):
1348
1344
  'fee': None,
1349
1345
  'fees': None,
1350
1346
  'limits': self.limits,
1351
- }
1347
+ })
1352
1348
 
1353
1349
  def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
1354
1350
  """
ccxt/gate.py CHANGED
@@ -3490,32 +3490,61 @@ class gate(Exchange, ImplicitAPI):
3490
3490
 
3491
3491
  def parse_transaction(self, transaction: dict, currency: Currency = None) -> Transaction:
3492
3492
  #
3493
- # deposits
3493
+ # fetchDeposits
3494
3494
  #
3495
- # {
3496
- # "id": "d33361395",
3497
- # "currency": "USDT_TRX",
3498
- # "address": "TErdnxenuLtXfnMafLbfappYdHtnXQ5U4z",
3499
- # "amount": "100",
3500
- # "txid": "ae9374de34e558562fe18cbb1bf9ab4d9eb8aa7669d65541c9fa2a532c1474a0",
3501
- # "timestamp": "1626345819",
3502
- # "status": "DONE",
3503
- # "memo": ""
3504
- # }
3495
+ # {
3496
+ # "id": "d33361395",
3497
+ # "currency": "USDT_TRX",
3498
+ # "address": "TErdnxenuLtXfnMafLbfappYdHtnXQ5U4z",
3499
+ # "amount": "100",
3500
+ # "txid": "ae9374de34e558562fe18cbb1bf9ab4d9eb8aa7669d65541c9fa2a532c1474a0",
3501
+ # "timestamp": "1626345819",
3502
+ # "status": "DONE",
3503
+ # "memo": ""
3504
+ # }
3505
3505
  #
3506
3506
  # withdraw
3507
3507
  #
3508
- # {
3509
- # "id": "w13389675",
3510
- # "currency": "USDT",
3511
- # "amount": "50",
3512
- # "address": "TUu2rLFrmzUodiWfYki7QCNtv1akL682p1",
3513
- # "memo": null
3514
- # }
3508
+ # {
3509
+ # "id":"w64413318",
3510
+ # "currency":"usdt",
3511
+ # "amount":"10150",
3512
+ # "address":"0x0ab891497116f7f5532a4c2f4f7b1784488628e1",
3513
+ # "memo":null,
3514
+ # "status":"REQUEST",
3515
+ # "chain":"eth",
3516
+ # "withdraw_order_id":"",
3517
+ # "fee_amount":"4.15000000"
3518
+ # }
3519
+ #
3520
+ # fetchWithdrawals
3521
+ #
3522
+ # {
3523
+ # "id": "210496",
3524
+ # "timestamp": "1542000000",
3525
+ # "withdraw_order_id": "order_123456",
3526
+ # "currency": "USDT",
3527
+ # "address": "1HkxtBAMrA3tP5ENnYY2CZortjZvFDH5Cs",
3528
+ # "txid": "128988928203223323290",
3529
+ # "block_number": "41575382",
3530
+ # "amount": "222.61",
3531
+ # "fee": "0.01",
3532
+ # "memo": "",
3533
+ # "status": "DONE",
3534
+ # "chain": "TRX"
3535
+ # }
3536
+ #
3537
+ # {
3538
+ # "id": "w13389675",
3539
+ # "currency": "USDT",
3540
+ # "amount": "50",
3541
+ # "address": "TUu2rLFrmzUodiWfYki7QCNtv1akL682p1",
3542
+ # "memo": null
3543
+ # }
3515
3544
  #
3516
3545
  # {
3517
3546
  # "currency":"usdt",
3518
- # "address":"0x01b0A9b7b4CdE774AF0f3E47CB4f1c2CCdBa0806",
3547
+ # "address":"0x01c0A9b7b4CdE774AF0f3E47CB4f1c2CCdBa0806",
3519
3548
  # "amount":"1880",
3520
3549
  # "chain":"eth"
3521
3550
  # }
@@ -3530,7 +3559,7 @@ class gate(Exchange, ImplicitAPI):
3530
3559
  amountString = Precise.string_abs(amountString)
3531
3560
  else:
3532
3561
  type = self.parse_transaction_type(id[0])
3533
- feeCostString = self.safe_string(transaction, 'fee')
3562
+ feeCostString = self.safe_string_2(transaction, 'fee', 'fee_amount')
3534
3563
  if type == 'withdrawal':
3535
3564
  amountString = Precise.string_sub(amountString, feeCostString)
3536
3565
  networkId = self.safe_string_upper(transaction, 'chain')
ccxt/htx.py CHANGED
@@ -5913,6 +5913,7 @@ class htx(Exchange, ImplicitAPI):
5913
5913
  def fetch_withdrawals(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
5914
5914
  """
5915
5915
  fetch all withdrawals made from an account
5916
+ :see: https://huobiapi.github.io/docs/spot/v1/en/#search-for-existed-withdraws-and-deposits
5916
5917
  :param str code: unified currency code
5917
5918
  :param int [since]: the earliest time in ms to fetch withdrawals for
5918
5919
  :param int [limit]: the maximum number of withdrawals structures to retrieve
@@ -6238,6 +6239,7 @@ class htx(Exchange, ImplicitAPI):
6238
6239
  def fetch_isolated_borrow_rates(self, params={}) -> IsolatedBorrowRates:
6239
6240
  """
6240
6241
  fetch the borrow interest rates of all currencies
6242
+ :see: https://huobiapi.github.io/docs/spot/v1/en/#get-loan-interest-rate-and-quota-isolated
6241
6243
  :param dict [params]: extra parameters specific to the exchange API endpoint
6242
6244
  :returns dict: a list of `isolated borrow rate structures <https://docs.ccxt.com/#/?id=isolated-borrow-rate-structure>`
6243
6245
  """
@@ -6448,6 +6450,8 @@ class htx(Exchange, ImplicitAPI):
6448
6450
  def fetch_funding_rate(self, symbol: str, params={}) -> FundingRate:
6449
6451
  """
6450
6452
  fetch the current funding rate
6453
+ :see: https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-funding-rate
6454
+ :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-query-funding-rate
6451
6455
  :param str symbol: unified market symbol
6452
6456
  :param dict [params]: extra parameters specific to the exchange API endpoint
6453
6457
  :returns dict: a `funding rate structure <https://docs.ccxt.com/#/?id=funding-rate-structure>`
@@ -6485,6 +6489,8 @@ class htx(Exchange, ImplicitAPI):
6485
6489
  def fetch_funding_rates(self, symbols: Strings = None, params={}) -> FundingRates:
6486
6490
  """
6487
6491
  fetch the funding rate for multiple markets
6492
+ :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-query-a-batch-of-funding-rate
6493
+ :see: https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-a-batch-of-funding-rate
6488
6494
  :param str[]|None symbols: list of unified market symbols
6489
6495
  :param dict [params]: extra parameters specific to the exchange API endpoint
6490
6496
  :returns dict[]: a list of `funding rate structures <https://docs.ccxt.com/#/?id=funding-rates-structure>`, indexed by market symbols
ccxt/kucoinfutures.py CHANGED
@@ -52,6 +52,7 @@ class kucoinfutures(kucoin, ImplicitAPI):
52
52
  'createDepositAddress': True,
53
53
  'createOrder': True,
54
54
  'createOrders': True,
55
+ 'createOrderWithTakeProfitAndStopLoss': True,
55
56
  'createReduceOnlyOrder': True,
56
57
  'createStopLimitOrder': True,
57
58
  'createStopLossOrder': True,
@@ -255,6 +256,7 @@ class kucoinfutures(kucoin, ImplicitAPI):
255
256
  '400100': BadRequest, # Parameter Error -- You tried to access the resource with invalid parameters
256
257
  '411100': AccountSuspended, # User is frozen -- Please contact us via support center
257
258
  '500000': ExchangeNotAvailable, # Internal Server Error -- We had a problem with our server. Try again later.
259
+ '300009': InvalidOrder, # {"msg":"No open positions to close.","code":"300009"}
258
260
  },
259
261
  'broad': {
260
262
  'Position does not exist': OrderNotFound, # {"code":"200000", "msg":"Position does not exist"}
@@ -1372,12 +1374,15 @@ class kucoinfutures(kucoin, ImplicitAPI):
1372
1374
  """
1373
1375
  Create an order on the exchange
1374
1376
  :see: https://docs.kucoin.com/futures/#place-an-order
1377
+ :see: https://www.kucoin.com/docs/rest/futures-trading/orders/place-take-profit-and-stop-loss-order#http-request
1375
1378
  :param str symbol: Unified CCXT market symbol
1376
1379
  :param str type: 'limit' or 'market'
1377
1380
  :param str side: 'buy' or 'sell'
1378
1381
  :param float amount: the amount of currency to trade
1379
1382
  :param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
1380
1383
  :param dict [params]: extra parameters specific to the exchange API endpoint
1384
+ :param dict [params.takeProfit]: *takeProfit object in params* containing the triggerPrice at which the attached take profit order will be triggered
1385
+ :param dict [params.stopLoss]: *stopLoss object in params* containing the triggerPrice at which the attached stop loss order will be triggered
1381
1386
  :param float [params.triggerPrice]: The price a trigger order is triggered at
1382
1387
  :param float [params.stopLossPrice]: price to trigger stop-loss orders
1383
1388
  :param float [params.takeProfitPrice]: price to trigger take-profit orders
@@ -1399,12 +1404,16 @@ class kucoinfutures(kucoin, ImplicitAPI):
1399
1404
  market = self.market(symbol)
1400
1405
  testOrder = self.safe_bool(params, 'test', False)
1401
1406
  params = self.omit(params, 'test')
1407
+ isTpAndSlOrder = (self.safe_value(params, 'stopLoss') is not None) or (self.safe_value(params, 'takeProfit') is not None)
1402
1408
  orderRequest = self.create_contract_order_request(symbol, type, side, amount, price, params)
1403
1409
  response = None
1404
1410
  if testOrder:
1405
1411
  response = self.futuresPrivatePostOrdersTest(orderRequest)
1406
1412
  else:
1407
- response = self.futuresPrivatePostOrders(orderRequest)
1413
+ if isTpAndSlOrder:
1414
+ response = self.futuresPrivatePostStOrders(orderRequest)
1415
+ else:
1416
+ response = self.futuresPrivatePostOrders(orderRequest)
1408
1417
  #
1409
1418
  # {
1410
1419
  # "code": "200000",
@@ -1479,6 +1488,9 @@ class kucoinfutures(kucoin, ImplicitAPI):
1479
1488
  'leverage': 1,
1480
1489
  }
1481
1490
  triggerPrice, stopLossPrice, takeProfitPrice = self.handle_trigger_prices(params)
1491
+ stopLoss = self.safe_dict(params, 'stopLoss')
1492
+ takeProfit = self.safe_dict(params, 'takeProfit')
1493
+ # isTpAndSl = stopLossPrice and takeProfitPrice
1482
1494
  triggerPriceTypes: dict = {
1483
1495
  'mark': 'MP',
1484
1496
  'last': 'TP',
@@ -1486,11 +1498,22 @@ class kucoinfutures(kucoin, ImplicitAPI):
1486
1498
  }
1487
1499
  triggerPriceType = self.safe_string(params, 'triggerPriceType', 'mark')
1488
1500
  triggerPriceTypeValue = self.safe_string(triggerPriceTypes, triggerPriceType, triggerPriceType)
1489
- params = self.omit(params, ['stopLossPrice', 'takeProfitPrice', 'triggerPrice', 'stopPrice'])
1501
+ params = self.omit(params, ['stopLossPrice', 'takeProfitPrice', 'triggerPrice', 'stopPrice', 'takeProfit', 'stopLoss'])
1490
1502
  if triggerPrice:
1491
1503
  request['stop'] = 'up' if (side == 'buy') else 'down'
1492
1504
  request['stopPrice'] = self.price_to_precision(symbol, triggerPrice)
1493
1505
  request['stopPriceType'] = triggerPriceTypeValue
1506
+ elif stopLoss is not None or takeProfit is not None:
1507
+ priceType = triggerPriceTypeValue
1508
+ if stopLoss is not None:
1509
+ slPrice = self.safe_string_2(stopLoss, 'triggerPrice', 'stopPrice')
1510
+ request['triggerStopDownPrice'] = self.price_to_precision(symbol, slPrice)
1511
+ priceType = self.safe_string(stopLoss, 'triggerPriceType', triggerPriceTypeValue)
1512
+ if takeProfit is not None:
1513
+ tpPrice = self.safe_string_2(takeProfit, 'triggerPrice', 'takeProfitPrice')
1514
+ request['triggerStopUpPrice'] = self.price_to_precision(symbol, tpPrice)
1515
+ priceType = self.safe_string(stopLoss, 'triggerPriceType', triggerPriceTypeValue)
1516
+ request['stopPriceType'] = priceType
1494
1517
  elif stopLossPrice or takeProfitPrice:
1495
1518
  if stopLossPrice:
1496
1519
  request['stop'] = 'up' if (side == 'buy') else 'down'
ccxt/kuna.py CHANGED
@@ -462,15 +462,7 @@ class kuna(Exchange, ImplicitAPI):
462
462
  data = self.safe_value(response, 'data', [])
463
463
  return self.parse_currencies(data)
464
464
 
465
- def parse_currencies(self, currencies, params={}):
466
- currencies = self.to_array(currencies)
467
- result: dict = {}
468
- for i in range(0, len(currencies)):
469
- currency = self.parse_currency(currencies[i])
470
- result[currency['code']] = currency
471
- return result
472
-
473
- def parse_currency(self, currency: dict):
465
+ def parse_currency(self, currency: dict) -> Currency:
474
466
  #
475
467
  # {
476
468
  # "code": "BTC",
@@ -494,7 +486,7 @@ class kuna(Exchange, ImplicitAPI):
494
486
  currencyId = self.safe_string(currency, 'code')
495
487
  precision = self.safe_string(currency, 'precision')
496
488
  tradePrecision = self.safe_string(currency, 'tradePrecision')
497
- return {
489
+ return self.safe_currency_structure({
498
490
  'info': currency,
499
491
  'id': currencyId,
500
492
  'code': self.safe_currency_code(currencyId),
@@ -505,7 +497,7 @@ class kuna(Exchange, ImplicitAPI):
505
497
  'deposit': None,
506
498
  'withdraw': None,
507
499
  'fee': None,
508
- 'precision': Precise.string_min(precision, tradePrecision),
500
+ 'precision': self.parse_number(Precise.string_min(precision, tradePrecision)),
509
501
  'limits': {
510
502
  'amount': {
511
503
  'min': None,
@@ -517,7 +509,7 @@ class kuna(Exchange, ImplicitAPI):
517
509
  },
518
510
  },
519
511
  'networks': {},
520
- }
512
+ })
521
513
 
522
514
  def fetch_markets(self, params={}) -> List[Market]:
523
515
  """
ccxt/mexc.py CHANGED
@@ -242,6 +242,7 @@ class mexc(Exchange, ImplicitAPI):
242
242
  'rebate/affiliate/commission/detail': 1,
243
243
  'mxDeduct/enable': 1,
244
244
  'userDataStream': 1,
245
+ 'selfSymbols': 1,
245
246
  },
246
247
  'post': {
247
248
  'order': 1,
@@ -2161,8 +2162,10 @@ class mexc(Exchange, ImplicitAPI):
2161
2162
  order = self.parse_order(response, market)
2162
2163
  order['side'] = side
2163
2164
  order['type'] = type
2164
- order['price'] = price
2165
- order['amount'] = amount
2165
+ if self.safe_string(order, 'price') is None:
2166
+ order['price'] = price
2167
+ if self.safe_string(order, 'amount') is None:
2168
+ order['amount'] = amount
2166
2169
  return order
2167
2170
 
2168
2171
  def create_swap_order(self, market, type, side, amount, price=None, marginMode=None, params={}):