ccxt 4.4.90__py2.py3-none-any.whl → 4.4.92__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 (71) hide show
  1. ccxt/__init__.py +1 -3
  2. ccxt/abstract/lbank.py +1 -0
  3. ccxt/async_support/__init__.py +1 -3
  4. ccxt/async_support/base/exchange.py +6 -3
  5. ccxt/async_support/base/ws/client.py +173 -64
  6. ccxt/async_support/base/ws/future.py +23 -50
  7. ccxt/async_support/binance.py +1 -1
  8. ccxt/async_support/bitmart.py +7 -0
  9. ccxt/async_support/bitmex.py +2 -1
  10. ccxt/async_support/bitvavo.py +7 -1
  11. ccxt/async_support/cex.py +61 -0
  12. ccxt/async_support/cryptocom.py +17 -2
  13. ccxt/async_support/cryptomus.py +1 -1
  14. ccxt/async_support/exmo.py +25 -10
  15. ccxt/async_support/gate.py +2 -2
  16. ccxt/async_support/htx.py +1 -1
  17. ccxt/async_support/hyperliquid.py +104 -53
  18. ccxt/async_support/kraken.py +26 -1
  19. ccxt/async_support/krakenfutures.py +1 -1
  20. ccxt/async_support/lbank.py +113 -33
  21. ccxt/async_support/mexc.py +1 -0
  22. ccxt/async_support/modetrade.py +2 -2
  23. ccxt/async_support/okx.py +2 -2
  24. ccxt/async_support/paradex.py +1 -1
  25. ccxt/base/exchange.py +22 -23
  26. ccxt/base/types.py +1 -0
  27. ccxt/binance.py +1 -1
  28. ccxt/bitmart.py +7 -0
  29. ccxt/bitmex.py +2 -1
  30. ccxt/bitvavo.py +7 -1
  31. ccxt/cex.py +61 -0
  32. ccxt/cryptocom.py +17 -2
  33. ccxt/cryptomus.py +1 -1
  34. ccxt/exmo.py +24 -10
  35. ccxt/gate.py +2 -2
  36. ccxt/htx.py +1 -1
  37. ccxt/hyperliquid.py +104 -53
  38. ccxt/kraken.py +26 -1
  39. ccxt/krakenfutures.py +1 -1
  40. ccxt/lbank.py +113 -33
  41. ccxt/mexc.py +1 -0
  42. ccxt/modetrade.py +2 -2
  43. ccxt/okx.py +2 -2
  44. ccxt/paradex.py +1 -1
  45. ccxt/pro/__init__.py +1 -1
  46. ccxt/pro/bitstamp.py +1 -1
  47. ccxt/pro/bybit.py +9 -140
  48. ccxt/pro/kraken.py +246 -258
  49. ccxt/pro/mexc.py +0 -1
  50. {ccxt-4.4.90.dist-info → ccxt-4.4.92.dist-info}/METADATA +6 -7
  51. {ccxt-4.4.90.dist-info → ccxt-4.4.92.dist-info}/RECORD +54 -71
  52. ccxt/abstract/coinlist.py +0 -57
  53. ccxt/async_support/base/ws/aiohttp_client.py +0 -147
  54. ccxt/async_support/bitcoincom.py +0 -18
  55. ccxt/async_support/bitfinex1.py +0 -1711
  56. ccxt/async_support/bitpanda.py +0 -17
  57. ccxt/async_support/coinlist.py +0 -2542
  58. ccxt/async_support/poloniexfutures.py +0 -1875
  59. ccxt/bitcoincom.py +0 -18
  60. ccxt/bitfinex1.py +0 -1710
  61. ccxt/bitpanda.py +0 -17
  62. ccxt/coinlist.py +0 -2542
  63. ccxt/poloniexfutures.py +0 -1875
  64. ccxt/pro/bitcoincom.py +0 -35
  65. ccxt/pro/bitfinex1.py +0 -635
  66. ccxt/pro/bitpanda.py +0 -16
  67. ccxt/pro/poloniexfutures.py +0 -1004
  68. ccxt/pro/wazirx.py +0 -766
  69. {ccxt-4.4.90.dist-info → ccxt-4.4.92.dist-info}/LICENSE.txt +0 -0
  70. {ccxt-4.4.90.dist-info → ccxt-4.4.92.dist-info}/WHEEL +0 -0
  71. {ccxt-4.4.90.dist-info → ccxt-4.4.92.dist-info}/top_level.txt +0 -0
ccxt/cryptocom.py CHANGED
@@ -548,7 +548,22 @@ class cryptocom(Exchange, ImplicitAPI):
548
548
  # self endpoint requires authentication
549
549
  if not self.check_required_credentials(False):
550
550
  return None
551
- response = self.v1PrivatePostPrivateGetCurrencyNetworks(params)
551
+ skipFetchCurrencies = False
552
+ skipFetchCurrencies, params = self.handle_option_and_params(params, 'fetchCurrencies', 'skipFetchCurrencies', False)
553
+ if skipFetchCurrencies:
554
+ # sub-accounts can't access self endpoint
555
+ return None
556
+ response = {}
557
+ try:
558
+ response = self.v1PrivatePostPrivateGetCurrencyNetworks(params)
559
+ except Exception as e:
560
+ if isinstance(e, ExchangeError):
561
+ # sub-accounts can't access self endpoint
562
+ # {"code":"10001","msg":"SYS_ERROR"}
563
+ return None
564
+ raise e
565
+ # do nothing
566
+ # sub-accounts can't access self endpoint
552
567
  #
553
568
  # {
554
569
  # "id": "1747502328559",
@@ -573,7 +588,7 @@ class cryptocom(Exchange, ImplicitAPI):
573
588
  # "network_id": "CRONOS",
574
589
  # "withdrawal_fee": "0.18000000",
575
590
  # "withdraw_enabled": True,
576
- # "min_withdrawal_amount": "0.36",
591
+ # "min_withdrawal_amount": "0.35",
577
592
  # "deposit_enabled": True,
578
593
  # "confirmation_required": "15"
579
594
  # },
ccxt/cryptomus.py CHANGED
@@ -461,7 +461,7 @@ class cryptomus(Exchange, ImplicitAPI):
461
461
  #
462
462
  # {
463
463
  # "currency_pair": "XMR_USDT",
464
- # "last_price": "158.04829771",
464
+ # "last_price": "158.04829772",
465
465
  # "base_volume": "0.35185785",
466
466
  # "quote_volume": "55.523761128544"
467
467
  # }
ccxt/exmo.py CHANGED
@@ -666,8 +666,9 @@ class exmo(Exchange, ImplicitAPI):
666
666
  :param dict [params]: extra parameters specific to the exchange API endpoint
667
667
  :returns dict: an associative dictionary of currencies
668
668
  """
669
+ promises = []
669
670
  #
670
- currencyList = self.publicGetCurrencyListExtended(params)
671
+ promises.append(self.publicGetCurrencyListExtended(params))
671
672
  #
672
673
  # [
673
674
  # {"name":"VLX","description":"Velas"},
@@ -676,7 +677,7 @@ class exmo(Exchange, ImplicitAPI):
676
677
  # {"name":"USD","description":"US Dollar"}
677
678
  # ]
678
679
  #
679
- cryptoList = self.publicGetPaymentsProvidersCryptoList(params)
680
+ promises.append(self.publicGetPaymentsProvidersCryptoList(params))
680
681
  #
681
682
  # {
682
683
  # "BTC":[
@@ -701,6 +702,9 @@ class exmo(Exchange, ImplicitAPI):
701
702
  # ],
702
703
  # }
703
704
  #
705
+ responses = promises
706
+ currencyList = responses[0]
707
+ cryptoList = responses[1]
704
708
  result: dict = {}
705
709
  for i in range(0, len(currencyList)):
706
710
  currency = currencyList[i]
@@ -754,6 +758,10 @@ class exmo(Exchange, ImplicitAPI):
754
758
  commissionDesc = self.safe_string(provider, 'commission_desc')
755
759
  fee = self.parse_fixed_float_value(commissionDesc)
756
760
  code = self.safe_currency_code(currencyId)
761
+ info = {
762
+ 'currency': currency,
763
+ 'providers': providers,
764
+ }
757
765
  result[code] = {
758
766
  'id': currencyId,
759
767
  'code': code,
@@ -765,7 +773,7 @@ class exmo(Exchange, ImplicitAPI):
765
773
  'fee': fee,
766
774
  'precision': self.parse_number('1e-8'),
767
775
  'limits': limits,
768
- 'info': providers,
776
+ 'info': info,
769
777
  'networks': {},
770
778
  }
771
779
  return result
@@ -779,7 +787,8 @@ class exmo(Exchange, ImplicitAPI):
779
787
  :param dict [params]: extra parameters specific to the exchange API endpoint
780
788
  :returns dict[]: an array of objects representing market data
781
789
  """
782
- response = self.publicGetPairSettings(params)
790
+ promises = []
791
+ promises.append(self.publicGetPairSettings(params))
783
792
  #
784
793
  # {
785
794
  # "BTC_USD":{
@@ -796,8 +805,9 @@ class exmo(Exchange, ImplicitAPI):
796
805
  # }
797
806
  #
798
807
  marginPairsDict: dict = {}
799
- if self.check_required_credentials(False):
800
- marginPairs = self.privatePostMarginPairList(params)
808
+ fetchMargin = self.check_required_credentials(False)
809
+ if fetchMargin:
810
+ promises.append(self.privatePostMarginPairList(params))
801
811
  #
802
812
  # {
803
813
  # "pairs": [
@@ -827,14 +837,18 @@ class exmo(Exchange, ImplicitAPI):
827
837
  # ]
828
838
  # }
829
839
  #
830
- pairs = self.safe_value(marginPairs, 'pairs')
840
+ responses = promises
841
+ spotResponse = responses[0]
842
+ if fetchMargin:
843
+ marginPairs = responses[1]
844
+ pairs = self.safe_list(marginPairs, 'pairs')
831
845
  marginPairsDict = self.index_by(pairs, 'name')
832
- keys = list(response.keys())
846
+ keys = list(spotResponse.keys())
833
847
  result = []
834
848
  for i in range(0, len(keys)):
835
849
  id = keys[i]
836
- market = response[id]
837
- marginMarket = self.safe_value(marginPairsDict, id)
850
+ market = spotResponse[id]
851
+ marginMarket = self.safe_dict(marginPairsDict, id)
838
852
  symbol = id.replace('_', '/')
839
853
  baseId, quoteId = symbol.split('/')
840
854
  base = self.safe_currency_code(baseId)
ccxt/gate.py CHANGED
@@ -1241,7 +1241,7 @@ class gate(Exchange, ImplicitAPI):
1241
1241
  self.fetch_option_markets(params),
1242
1242
  ]
1243
1243
  if not sandboxMode:
1244
- # gate does not have a sandbox for spot markets
1244
+ # gate doesn't have a sandbox for spot markets
1245
1245
  mainnetOnly = [self.fetch_spot_markets(params)]
1246
1246
  rawPromises = self.array_concat(rawPromises, mainnetOnly)
1247
1247
  promises = rawPromises
@@ -1652,7 +1652,7 @@ class gate(Exchange, ImplicitAPI):
1652
1652
  'contractSize': self.parse_number('1'),
1653
1653
  'expiry': expiry,
1654
1654
  'expiryDatetime': self.iso8601(expiry),
1655
- 'strike': strike,
1655
+ 'strike': self.parse_number(strike),
1656
1656
  'optionType': optionType,
1657
1657
  'precision': {
1658
1658
  'amount': self.parse_number('1'), # all options have self step size
ccxt/htx.py CHANGED
@@ -6341,7 +6341,7 @@ class htx(Exchange, ImplicitAPI):
6341
6341
  fee = self.safe_number(params, 'fee')
6342
6342
  if fee is None:
6343
6343
  currencies = self.fetch_currencies()
6344
- self.currencies = self.deep_extend(self.currencies, currencies)
6344
+ self.currencies = self.map_to_safe_map(self.deep_extend(self.currencies, currencies))
6345
6345
  targetNetwork = self.safe_value(currency['networks'], networkCode, {})
6346
6346
  fee = self.safe_number(targetNetwork, 'fee')
6347
6347
  if fee is None:
ccxt/hyperliquid.py CHANGED
@@ -56,6 +56,7 @@ class hyperliquid(Exchange, ImplicitAPI):
56
56
  'createMarketSellOrderWithCost': False,
57
57
  'createOrder': True,
58
58
  'createOrders': True,
59
+ 'createOrderWithTakeProfitAndStopLoss': True,
59
60
  'createReduceOnlyOrder': True,
60
61
  'createStopOrder': True,
61
62
  'createTriggerOrder': True,
@@ -239,7 +240,16 @@ class hyperliquid(Exchange, ImplicitAPI):
239
240
  'triggerDirection': False,
240
241
  'stopLossPrice': False,
241
242
  'takeProfitPrice': False,
242
- 'attachedStopLossTakeProfit': None,
243
+ 'attachedStopLossTakeProfit': {
244
+ 'triggerPriceType': {
245
+ 'last': False,
246
+ 'mark': False,
247
+ 'index': False,
248
+ },
249
+ 'triggerPrice': True,
250
+ 'type': True,
251
+ 'price': True,
252
+ },
243
253
  'timeInForce': {
244
254
  'IOC': True,
245
255
  'FOK': False,
@@ -1403,6 +1413,65 @@ class hyperliquid(Exchange, ImplicitAPI):
1403
1413
  statuses = self.safe_list(data, 'statuses', [])
1404
1414
  return self.parse_orders(statuses, None)
1405
1415
 
1416
+ def create_order_request(self, symbol: str, type: OrderType, side: OrderSide, amount: str, price: Str = None, params={}):
1417
+ market = self.market(symbol)
1418
+ type = type.upper()
1419
+ side = side.upper()
1420
+ isMarket = (type == 'MARKET')
1421
+ isBuy = (side == 'BUY')
1422
+ clientOrderId = self.safe_string_2(params, 'clientOrderId', 'client_id')
1423
+ slippage = self.safe_string(params, 'slippage')
1424
+ defaultTimeInForce = 'ioc' if (isMarket) else 'gtc'
1425
+ postOnly = self.safe_bool(params, 'postOnly', False)
1426
+ if postOnly:
1427
+ defaultTimeInForce = 'alo'
1428
+ timeInForce = self.safe_string_lower(params, 'timeInForce', defaultTimeInForce)
1429
+ timeInForce = self.capitalize(timeInForce)
1430
+ triggerPrice = self.safe_string_2(params, 'triggerPrice', 'stopPrice')
1431
+ stopLossPrice = self.safe_string(params, 'stopLossPrice', triggerPrice)
1432
+ takeProfitPrice = self.safe_string(params, 'takeProfitPrice')
1433
+ isTrigger = (stopLossPrice or takeProfitPrice)
1434
+ px = None
1435
+ if isMarket:
1436
+ if price is None:
1437
+ raise ArgumentsRequired(self.id + ' market orders require price to calculate the max slippage price. Default slippage can be set in options(default is 5%).')
1438
+ px = Precise.string_mul(price, Precise.string_add('1', slippage)) if (isBuy) else Precise.string_mul(price, Precise.string_sub('1', slippage))
1439
+ px = self.price_to_precision(symbol, px) # round after adding slippage
1440
+ else:
1441
+ px = self.price_to_precision(symbol, price)
1442
+ sz = self.amount_to_precision(symbol, amount)
1443
+ reduceOnly = self.safe_bool(params, 'reduceOnly', False)
1444
+ orderType: dict = {}
1445
+ if isTrigger:
1446
+ isTp = False
1447
+ if takeProfitPrice is not None:
1448
+ triggerPrice = self.price_to_precision(symbol, takeProfitPrice)
1449
+ isTp = True
1450
+ else:
1451
+ triggerPrice = self.price_to_precision(symbol, stopLossPrice)
1452
+ orderType['trigger'] = {
1453
+ 'isMarket': isMarket,
1454
+ 'triggerPx': triggerPrice,
1455
+ 'tpsl': 'tp' if (isTp) else 'sl',
1456
+ }
1457
+ else:
1458
+ orderType['limit'] = {
1459
+ 'tif': timeInForce,
1460
+ }
1461
+ params = self.omit(params, ['clientOrderId', 'slippage', 'triggerPrice', 'stopPrice', 'stopLossPrice', 'takeProfitPrice', 'timeInForce', 'client_id', 'reduceOnly', 'postOnly'])
1462
+ orderObj: dict = {
1463
+ 'a': self.parse_to_int(market['baseId']),
1464
+ 'b': isBuy,
1465
+ 'p': px,
1466
+ 's': sz,
1467
+ 'r': reduceOnly,
1468
+ 't': orderType,
1469
+ # 'c': clientOrderId,
1470
+ }
1471
+ if clientOrderId is not None:
1472
+ orderObj['c'] = clientOrderId
1473
+ return orderObj
1474
+
1406
1475
  def create_orders_request(self, orders, params={}) -> dict:
1407
1476
  """
1408
1477
  create a list of trade orders
@@ -1430,77 +1499,59 @@ class hyperliquid(Exchange, ImplicitAPI):
1430
1499
  params = self.omit(params, ['slippage', 'clientOrderId', 'client_id', 'slippage', 'triggerPrice', 'stopPrice', 'stopLossPrice', 'takeProfitPrice', 'timeInForce'])
1431
1500
  nonce = self.milliseconds()
1432
1501
  orderReq = []
1502
+ grouping = 'na'
1433
1503
  for i in range(0, len(orders)):
1434
1504
  rawOrder = orders[i]
1435
1505
  marketId = self.safe_string(rawOrder, 'symbol')
1436
1506
  market = self.market(marketId)
1437
1507
  symbol = market['symbol']
1438
1508
  type = self.safe_string_upper(rawOrder, 'type')
1439
- isMarket = (type == 'MARKET')
1440
1509
  side = self.safe_string_upper(rawOrder, 'side')
1441
- isBuy = (side == 'BUY')
1442
1510
  amount = self.safe_string(rawOrder, 'amount')
1443
1511
  price = self.safe_string(rawOrder, 'price')
1444
1512
  orderParams = self.safe_dict(rawOrder, 'params', {})
1445
- clientOrderId = self.safe_string_2(orderParams, 'clientOrderId', 'client_id')
1446
1513
  slippage = self.safe_string(orderParams, 'slippage', defaultSlippage)
1447
- defaultTimeInForce = 'ioc' if (isMarket) else 'gtc'
1448
- postOnly = self.safe_bool(orderParams, 'postOnly', False)
1449
- if postOnly:
1450
- defaultTimeInForce = 'alo'
1451
- timeInForce = self.safe_string_lower(orderParams, 'timeInForce', defaultTimeInForce)
1452
- timeInForce = self.capitalize(timeInForce)
1453
- triggerPrice = self.safe_string_2(orderParams, 'triggerPrice', 'stopPrice')
1454
- stopLossPrice = self.safe_string(orderParams, 'stopLossPrice', triggerPrice)
1455
- takeProfitPrice = self.safe_string(orderParams, 'takeProfitPrice')
1456
- isTrigger = (stopLossPrice or takeProfitPrice)
1457
- px = None
1458
- if isMarket:
1459
- if price is None:
1460
- raise ArgumentsRequired(self.id + ' market orders require price to calculate the max slippage price. Default slippage can be set in options(default is 5%).')
1461
- px = Precise.string_mul(price, Precise.string_add('1', slippage)) if (isBuy) else Precise.string_mul(price, Precise.string_sub('1', slippage))
1462
- px = self.price_to_precision(symbol, px) # round after adding slippage
1463
- else:
1464
- px = self.price_to_precision(symbol, price)
1465
- sz = self.amount_to_precision(symbol, amount)
1466
- reduceOnly = self.safe_bool(orderParams, 'reduceOnly', False)
1467
- orderType: dict = {}
1514
+ orderParams['slippage'] = slippage
1515
+ stopLoss = self.safe_value(orderParams, 'stopLoss')
1516
+ takeProfit = self.safe_value(orderParams, 'takeProfit')
1517
+ isTrigger = (stopLoss or takeProfit)
1518
+ orderParams = self.omit(orderParams, ['stopLoss', 'takeProfit'])
1519
+ mainOrderObj: dict = self.create_order_request(symbol, type, side, amount, price, orderParams)
1520
+ orderReq.append(mainOrderObj)
1468
1521
  if isTrigger:
1469
- isTp = False
1470
- if takeProfitPrice is not None:
1471
- triggerPrice = self.price_to_precision(symbol, takeProfitPrice)
1472
- isTp = True
1522
+ # grouping opposed orders for sl/tp
1523
+ stopLossOrderTriggerPrice = self.safe_string_n(stopLoss, ['triggerPrice', 'stopPrice'])
1524
+ stopLossOrderType = self.safe_string(stopLoss, 'type')
1525
+ stopLossOrderLimitPrice = self.safe_string_n(stopLoss, ['price', 'stopLossPrice'], stopLossOrderTriggerPrice)
1526
+ takeProfitOrderTriggerPrice = self.safe_string_n(takeProfit, ['triggerPrice', 'stopPrice'])
1527
+ takeProfitOrderType = self.safe_string(takeProfit, 'type')
1528
+ takeProfitOrderLimitPrice = self.safe_string_n(takeProfit, ['price', 'takeProfitPrice'], takeProfitOrderTriggerPrice)
1529
+ grouping = 'normalTpsl'
1530
+ orderParams = self.omit(orderParams, ['stopLoss', 'takeProfit'])
1531
+ triggerOrderSide = ''
1532
+ if side == 'BUY':
1533
+ triggerOrderSide = 'sell'
1473
1534
  else:
1474
- triggerPrice = self.price_to_precision(symbol, stopLossPrice)
1475
- orderType['trigger'] = {
1476
- 'isMarket': isMarket,
1477
- 'triggerPx': triggerPrice,
1478
- 'tpsl': 'tp' if (isTp) else 'sl',
1479
- }
1480
- else:
1481
- orderType['limit'] = {
1482
- 'tif': timeInForce,
1483
- }
1484
- orderParams = self.omit(orderParams, ['clientOrderId', 'slippage', 'triggerPrice', 'stopPrice', 'stopLossPrice', 'takeProfitPrice', 'timeInForce', 'client_id', 'reduceOnly', 'postOnly'])
1485
- orderObj: dict = {
1486
- 'a': self.parse_to_int(market['baseId']),
1487
- 'b': isBuy,
1488
- 'p': px,
1489
- 's': sz,
1490
- 'r': reduceOnly,
1491
- 't': orderType,
1492
- # 'c': clientOrderId,
1493
- }
1494
- if clientOrderId is not None:
1495
- orderObj['c'] = clientOrderId
1496
- orderReq.append(orderObj)
1535
+ triggerOrderSide = 'buy'
1536
+ if takeProfit is not None:
1537
+ orderObj: dict = self.create_order_request(symbol, takeProfitOrderType, triggerOrderSide, amount, takeProfitOrderLimitPrice, self.extend(orderParams, {
1538
+ 'takeProfitPrice': takeProfitOrderTriggerPrice,
1539
+ 'reduceOnly': True,
1540
+ }))
1541
+ orderReq.append(orderObj)
1542
+ if stopLoss is not None:
1543
+ orderObj: dict = self.create_order_request(symbol, stopLossOrderType, triggerOrderSide, amount, stopLossOrderLimitPrice, self.extend(orderParams, {
1544
+ 'stopLossPrice': stopLossOrderTriggerPrice,
1545
+ 'reduceOnly': True,
1546
+ }))
1547
+ orderReq.append(orderObj)
1497
1548
  vaultAddress = None
1498
1549
  vaultAddress, params = self.handle_option_and_params(params, 'createOrder', 'vaultAddress')
1499
1550
  vaultAddress = self.format_vault_address(vaultAddress)
1500
1551
  orderAction: dict = {
1501
1552
  'type': 'order',
1502
1553
  'orders': orderReq,
1503
- 'grouping': 'na',
1554
+ 'grouping': grouping,
1504
1555
  # 'brokerCode': 1, # cant
1505
1556
  }
1506
1557
  if vaultAddress is None:
ccxt/kraken.py CHANGED
@@ -1365,7 +1365,20 @@ class kraken(Exchange, ImplicitAPI):
1365
1365
  # "maker": False
1366
1366
  # }
1367
1367
  #
1368
+ # watchTrades
1369
+ #
1370
+ # {
1371
+ # "symbol": "BTC/USD",
1372
+ # "side": "buy",
1373
+ # "price": 109601.2,
1374
+ # "qty": 0.04561994,
1375
+ # "ord_type": "market",
1376
+ # "trade_id": 83449369,
1377
+ # "timestamp": "2025-05-27T11:24:03.847761Z"
1378
+ # }
1379
+ #
1368
1380
  timestamp = None
1381
+ datetime = None
1369
1382
  side = None
1370
1383
  type = None
1371
1384
  price = None
@@ -1408,6 +1421,14 @@ class kraken(Exchange, ImplicitAPI):
1408
1421
  'cost': self.safe_string(trade, 'fee'),
1409
1422
  'currency': currency,
1410
1423
  }
1424
+ else:
1425
+ symbol = self.safe_string(trade, 'symbol')
1426
+ datetime = self.safe_string(trade, 'timestamp')
1427
+ id = self.safe_string(trade, 'trade_id')
1428
+ side = self.safe_string(trade, 'side')
1429
+ type = self.safe_string(trade, 'ord_type')
1430
+ price = self.safe_string(trade, 'price')
1431
+ amount = self.safe_string(trade, 'qty')
1411
1432
  if market is not None:
1412
1433
  symbol = market['symbol']
1413
1434
  cost = self.safe_string(trade, 'cost')
@@ -1415,12 +1436,16 @@ class kraken(Exchange, ImplicitAPI):
1415
1436
  takerOrMaker = None
1416
1437
  if maker is not None:
1417
1438
  takerOrMaker = 'maker' if maker else 'taker'
1439
+ if datetime is None:
1440
+ datetime = self.iso8601(timestamp)
1441
+ else:
1442
+ timestamp = self.parse8601(datetime)
1418
1443
  return self.safe_trade({
1419
1444
  'id': id,
1420
1445
  'order': orderId,
1421
1446
  'info': trade,
1422
1447
  'timestamp': timestamp,
1423
- 'datetime': self.iso8601(timestamp),
1448
+ 'datetime': datetime,
1424
1449
  'symbol': symbol,
1425
1450
  'type': type,
1426
1451
  'side': side,
ccxt/krakenfutures.py CHANGED
@@ -538,7 +538,7 @@ class krakenfutures(Exchange, ImplicitAPI):
538
538
  'code': code,
539
539
  'precision': None,
540
540
  })
541
- self.currencies = self.deep_extend(currencies, self.currencies)
541
+ self.currencies = self.map_to_safe_map(self.deep_extend(currencies, self.currencies))
542
542
  return result
543
543
 
544
544
  def fetch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook: