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.
- ccxt/__init__.py +1 -3
- ccxt/abstract/lbank.py +1 -0
- ccxt/async_support/__init__.py +1 -3
- ccxt/async_support/base/exchange.py +6 -3
- ccxt/async_support/base/ws/client.py +173 -64
- ccxt/async_support/base/ws/future.py +23 -50
- ccxt/async_support/binance.py +1 -1
- ccxt/async_support/bitmart.py +7 -0
- ccxt/async_support/bitmex.py +2 -1
- ccxt/async_support/bitvavo.py +7 -1
- ccxt/async_support/cex.py +61 -0
- ccxt/async_support/cryptocom.py +17 -2
- ccxt/async_support/cryptomus.py +1 -1
- ccxt/async_support/exmo.py +25 -10
- ccxt/async_support/gate.py +2 -2
- ccxt/async_support/htx.py +1 -1
- ccxt/async_support/hyperliquid.py +104 -53
- ccxt/async_support/kraken.py +26 -1
- ccxt/async_support/krakenfutures.py +1 -1
- ccxt/async_support/lbank.py +113 -33
- ccxt/async_support/mexc.py +1 -0
- ccxt/async_support/modetrade.py +2 -2
- ccxt/async_support/okx.py +2 -2
- ccxt/async_support/paradex.py +1 -1
- ccxt/base/exchange.py +22 -23
- ccxt/base/types.py +1 -0
- ccxt/binance.py +1 -1
- ccxt/bitmart.py +7 -0
- ccxt/bitmex.py +2 -1
- ccxt/bitvavo.py +7 -1
- ccxt/cex.py +61 -0
- ccxt/cryptocom.py +17 -2
- ccxt/cryptomus.py +1 -1
- ccxt/exmo.py +24 -10
- ccxt/gate.py +2 -2
- ccxt/htx.py +1 -1
- ccxt/hyperliquid.py +104 -53
- ccxt/kraken.py +26 -1
- ccxt/krakenfutures.py +1 -1
- ccxt/lbank.py +113 -33
- ccxt/mexc.py +1 -0
- ccxt/modetrade.py +2 -2
- ccxt/okx.py +2 -2
- ccxt/paradex.py +1 -1
- ccxt/pro/__init__.py +1 -1
- ccxt/pro/bitstamp.py +1 -1
- ccxt/pro/bybit.py +9 -140
- ccxt/pro/kraken.py +246 -258
- ccxt/pro/mexc.py +0 -1
- {ccxt-4.4.90.dist-info → ccxt-4.4.92.dist-info}/METADATA +6 -7
- {ccxt-4.4.90.dist-info → ccxt-4.4.92.dist-info}/RECORD +54 -71
- ccxt/abstract/coinlist.py +0 -57
- ccxt/async_support/base/ws/aiohttp_client.py +0 -147
- ccxt/async_support/bitcoincom.py +0 -18
- ccxt/async_support/bitfinex1.py +0 -1711
- ccxt/async_support/bitpanda.py +0 -17
- ccxt/async_support/coinlist.py +0 -2542
- ccxt/async_support/poloniexfutures.py +0 -1875
- ccxt/bitcoincom.py +0 -18
- ccxt/bitfinex1.py +0 -1710
- ccxt/bitpanda.py +0 -17
- ccxt/coinlist.py +0 -2542
- ccxt/poloniexfutures.py +0 -1875
- ccxt/pro/bitcoincom.py +0 -35
- ccxt/pro/bitfinex1.py +0 -635
- ccxt/pro/bitpanda.py +0 -16
- ccxt/pro/poloniexfutures.py +0 -1004
- ccxt/pro/wazirx.py +0 -766
- {ccxt-4.4.90.dist-info → ccxt-4.4.92.dist-info}/LICENSE.txt +0 -0
- {ccxt-4.4.90.dist-info → ccxt-4.4.92.dist-info}/WHEEL +0 -0
- {ccxt-4.4.90.dist-info → ccxt-4.4.92.dist-info}/top_level.txt +0 -0
ccxt/async_support/cex.py
CHANGED
@@ -36,34 +36,95 @@ class cex(Exchange, ImplicitAPI):
|
|
36
36
|
'swap': False,
|
37
37
|
'future': False,
|
38
38
|
'option': False,
|
39
|
+
'addMargin': False,
|
40
|
+
'borrowCrossMargin': False,
|
41
|
+
'borrowIsolatedMargin': False,
|
42
|
+
'borrowMargin': False,
|
39
43
|
'cancelAllOrders': True,
|
40
44
|
'cancelOrder': True,
|
45
|
+
'closeAllPositions': False,
|
46
|
+
'closePosition': False,
|
41
47
|
'createOrder': True,
|
48
|
+
'createOrderWithTakeProfitAndStopLoss': False,
|
49
|
+
'createOrderWithTakeProfitAndStopLossWs': False,
|
50
|
+
'createPostOnlyOrder': False,
|
42
51
|
'createReduceOnlyOrder': False,
|
43
52
|
'createStopOrder': True,
|
44
53
|
'createTriggerOrder': True,
|
45
54
|
'fetchAccounts': True,
|
46
55
|
'fetchBalance': True,
|
56
|
+
'fetchBorrowInterest': False,
|
57
|
+
'fetchBorrowRate': False,
|
58
|
+
'fetchBorrowRateHistories': False,
|
59
|
+
'fetchBorrowRateHistory': False,
|
60
|
+
'fetchBorrowRates': False,
|
61
|
+
'fetchBorrowRatesPerSymbol': False,
|
47
62
|
'fetchClosedOrder': True,
|
48
63
|
'fetchClosedOrders': True,
|
64
|
+
'fetchCrossBorrowRate': False,
|
65
|
+
'fetchCrossBorrowRates': False,
|
49
66
|
'fetchCurrencies': True,
|
50
67
|
'fetchDepositAddress': True,
|
51
68
|
'fetchDepositsWithdrawals': True,
|
52
69
|
'fetchFundingHistory': False,
|
70
|
+
'fetchFundingInterval': False,
|
71
|
+
'fetchFundingIntervals': False,
|
53
72
|
'fetchFundingRate': False,
|
54
73
|
'fetchFundingRateHistory': False,
|
55
74
|
'fetchFundingRates': False,
|
75
|
+
'fetchGreeks': False,
|
76
|
+
'fetchIndexOHLCV': False,
|
77
|
+
'fetchIsolatedBorrowRate': False,
|
78
|
+
'fetchIsolatedBorrowRates': False,
|
79
|
+
'fetchIsolatedPositions': False,
|
56
80
|
'fetchLedger': True,
|
81
|
+
'fetchLeverage': False,
|
82
|
+
'fetchLeverages': False,
|
83
|
+
'fetchLeverageTiers': False,
|
84
|
+
'fetchLiquidations': False,
|
85
|
+
'fetchLongShortRatio': False,
|
86
|
+
'fetchLongShortRatioHistory': False,
|
87
|
+
'fetchMarginAdjustmentHistory': False,
|
88
|
+
'fetchMarginMode': False,
|
89
|
+
'fetchMarginModes': False,
|
90
|
+
'fetchMarketLeverageTiers': False,
|
57
91
|
'fetchMarkets': True,
|
92
|
+
'fetchMarkOHLCV': False,
|
93
|
+
'fetchMarkPrices': False,
|
94
|
+
'fetchMyLiquidations': False,
|
95
|
+
'fetchMySettlementHistory': False,
|
58
96
|
'fetchOHLCV': True,
|
97
|
+
'fetchOpenInterest': False,
|
98
|
+
'fetchOpenInterestHistory': False,
|
99
|
+
'fetchOpenInterests': False,
|
59
100
|
'fetchOpenOrder': True,
|
60
101
|
'fetchOpenOrders': True,
|
102
|
+
'fetchOption': False,
|
103
|
+
'fetchOptionChain': False,
|
61
104
|
'fetchOrderBook': True,
|
105
|
+
'fetchPosition': False,
|
106
|
+
'fetchPositionHistory': False,
|
107
|
+
'fetchPositionMode': False,
|
108
|
+
'fetchPositions': False,
|
109
|
+
'fetchPositionsForSymbol': False,
|
110
|
+
'fetchPositionsHistory': False,
|
111
|
+
'fetchPositionsRisk': False,
|
112
|
+
'fetchPremiumIndexOHLCV': False,
|
113
|
+
'fetchSettlementHistory': False,
|
62
114
|
'fetchTicker': True,
|
63
115
|
'fetchTickers': True,
|
64
116
|
'fetchTime': True,
|
65
117
|
'fetchTrades': True,
|
66
118
|
'fetchTradingFees': True,
|
119
|
+
'fetchVolatilityHistory': False,
|
120
|
+
'reduceMargin': False,
|
121
|
+
'repayCrossMargin': False,
|
122
|
+
'repayIsolatedMargin': False,
|
123
|
+
'repayMargin': False,
|
124
|
+
'setLeverage': False,
|
125
|
+
'setMargin': False,
|
126
|
+
'setMarginMode': False,
|
127
|
+
'setPositionMode': False,
|
67
128
|
'transfer': True,
|
68
129
|
},
|
69
130
|
'urls': {
|
ccxt/async_support/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
|
-
|
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 = await 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.
|
591
|
+
# "min_withdrawal_amount": "0.35",
|
577
592
|
# "deposit_enabled": True,
|
578
593
|
# "confirmation_required": "15"
|
579
594
|
# },
|
ccxt/async_support/cryptomus.py
CHANGED
ccxt/async_support/exmo.py
CHANGED
@@ -5,6 +5,7 @@
|
|
5
5
|
|
6
6
|
from ccxt.async_support.base.exchange import Exchange
|
7
7
|
from ccxt.abstract.exmo import ImplicitAPI
|
8
|
+
import asyncio
|
8
9
|
import hashlib
|
9
10
|
from ccxt.base.types import Any, Balances, Currencies, Currency, DepositAddress, Int, MarginModification, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, OrderBooks, Trade, TradingFees, Transaction
|
10
11
|
from typing import List
|
@@ -666,8 +667,9 @@ class exmo(Exchange, ImplicitAPI):
|
|
666
667
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
667
668
|
:returns dict: an associative dictionary of currencies
|
668
669
|
"""
|
670
|
+
promises = []
|
669
671
|
#
|
670
|
-
|
672
|
+
promises.append(self.publicGetCurrencyListExtended(params))
|
671
673
|
#
|
672
674
|
# [
|
673
675
|
# {"name":"VLX","description":"Velas"},
|
@@ -676,7 +678,7 @@ class exmo(Exchange, ImplicitAPI):
|
|
676
678
|
# {"name":"USD","description":"US Dollar"}
|
677
679
|
# ]
|
678
680
|
#
|
679
|
-
|
681
|
+
promises.append(self.publicGetPaymentsProvidersCryptoList(params))
|
680
682
|
#
|
681
683
|
# {
|
682
684
|
# "BTC":[
|
@@ -701,6 +703,9 @@ class exmo(Exchange, ImplicitAPI):
|
|
701
703
|
# ],
|
702
704
|
# }
|
703
705
|
#
|
706
|
+
responses = await asyncio.gather(*promises)
|
707
|
+
currencyList = responses[0]
|
708
|
+
cryptoList = responses[1]
|
704
709
|
result: dict = {}
|
705
710
|
for i in range(0, len(currencyList)):
|
706
711
|
currency = currencyList[i]
|
@@ -754,6 +759,10 @@ class exmo(Exchange, ImplicitAPI):
|
|
754
759
|
commissionDesc = self.safe_string(provider, 'commission_desc')
|
755
760
|
fee = self.parse_fixed_float_value(commissionDesc)
|
756
761
|
code = self.safe_currency_code(currencyId)
|
762
|
+
info = {
|
763
|
+
'currency': currency,
|
764
|
+
'providers': providers,
|
765
|
+
}
|
757
766
|
result[code] = {
|
758
767
|
'id': currencyId,
|
759
768
|
'code': code,
|
@@ -765,7 +774,7 @@ class exmo(Exchange, ImplicitAPI):
|
|
765
774
|
'fee': fee,
|
766
775
|
'precision': self.parse_number('1e-8'),
|
767
776
|
'limits': limits,
|
768
|
-
'info':
|
777
|
+
'info': info,
|
769
778
|
'networks': {},
|
770
779
|
}
|
771
780
|
return result
|
@@ -779,7 +788,8 @@ class exmo(Exchange, ImplicitAPI):
|
|
779
788
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
780
789
|
:returns dict[]: an array of objects representing market data
|
781
790
|
"""
|
782
|
-
|
791
|
+
promises = []
|
792
|
+
promises.append(self.publicGetPairSettings(params))
|
783
793
|
#
|
784
794
|
# {
|
785
795
|
# "BTC_USD":{
|
@@ -796,8 +806,9 @@ class exmo(Exchange, ImplicitAPI):
|
|
796
806
|
# }
|
797
807
|
#
|
798
808
|
marginPairsDict: dict = {}
|
799
|
-
|
800
|
-
|
809
|
+
fetchMargin = self.check_required_credentials(False)
|
810
|
+
if fetchMargin:
|
811
|
+
promises.append(self.privatePostMarginPairList(params))
|
801
812
|
#
|
802
813
|
# {
|
803
814
|
# "pairs": [
|
@@ -827,14 +838,18 @@ class exmo(Exchange, ImplicitAPI):
|
|
827
838
|
# ]
|
828
839
|
# }
|
829
840
|
#
|
830
|
-
|
841
|
+
responses = await asyncio.gather(*promises)
|
842
|
+
spotResponse = responses[0]
|
843
|
+
if fetchMargin:
|
844
|
+
marginPairs = responses[1]
|
845
|
+
pairs = self.safe_list(marginPairs, 'pairs')
|
831
846
|
marginPairsDict = self.index_by(pairs, 'name')
|
832
|
-
keys = list(
|
847
|
+
keys = list(spotResponse.keys())
|
833
848
|
result = []
|
834
849
|
for i in range(0, len(keys)):
|
835
850
|
id = keys[i]
|
836
|
-
market =
|
837
|
-
marginMarket = self.
|
851
|
+
market = spotResponse[id]
|
852
|
+
marginMarket = self.safe_dict(marginPairsDict, id)
|
838
853
|
symbol = id.replace('_', '/')
|
839
854
|
baseId, quoteId = symbol.split('/')
|
840
855
|
base = self.safe_currency_code(baseId)
|
ccxt/async_support/gate.py
CHANGED
@@ -1242,7 +1242,7 @@ class gate(Exchange, ImplicitAPI):
|
|
1242
1242
|
self.fetch_option_markets(params),
|
1243
1243
|
]
|
1244
1244
|
if not sandboxMode:
|
1245
|
-
# gate
|
1245
|
+
# gate doesn't have a sandbox for spot markets
|
1246
1246
|
mainnetOnly = [self.fetch_spot_markets(params)]
|
1247
1247
|
rawPromises = self.array_concat(rawPromises, mainnetOnly)
|
1248
1248
|
promises = await asyncio.gather(*rawPromises)
|
@@ -1653,7 +1653,7 @@ class gate(Exchange, ImplicitAPI):
|
|
1653
1653
|
'contractSize': self.parse_number('1'),
|
1654
1654
|
'expiry': expiry,
|
1655
1655
|
'expiryDatetime': self.iso8601(expiry),
|
1656
|
-
'strike': strike,
|
1656
|
+
'strike': self.parse_number(strike),
|
1657
1657
|
'optionType': optionType,
|
1658
1658
|
'precision': {
|
1659
1659
|
'amount': self.parse_number('1'), # all options have self step size
|
ccxt/async_support/htx.py
CHANGED
@@ -6342,7 +6342,7 @@ class htx(Exchange, ImplicitAPI):
|
|
6342
6342
|
fee = self.safe_number(params, 'fee')
|
6343
6343
|
if fee is None:
|
6344
6344
|
currencies = await self.fetch_currencies()
|
6345
|
-
self.currencies = self.deep_extend(self.currencies, currencies)
|
6345
|
+
self.currencies = self.map_to_safe_map(self.deep_extend(self.currencies, currencies))
|
6346
6346
|
targetNetwork = self.safe_value(currency['networks'], networkCode, {})
|
6347
6347
|
fee = self.safe_number(targetNetwork, 'fee')
|
6348
6348
|
if fee is None:
|
@@ -57,6 +57,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
57
57
|
'createMarketSellOrderWithCost': False,
|
58
58
|
'createOrder': True,
|
59
59
|
'createOrders': True,
|
60
|
+
'createOrderWithTakeProfitAndStopLoss': True,
|
60
61
|
'createReduceOnlyOrder': True,
|
61
62
|
'createStopOrder': True,
|
62
63
|
'createTriggerOrder': True,
|
@@ -240,7 +241,16 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
240
241
|
'triggerDirection': False,
|
241
242
|
'stopLossPrice': False,
|
242
243
|
'takeProfitPrice': False,
|
243
|
-
'attachedStopLossTakeProfit':
|
244
|
+
'attachedStopLossTakeProfit': {
|
245
|
+
'triggerPriceType': {
|
246
|
+
'last': False,
|
247
|
+
'mark': False,
|
248
|
+
'index': False,
|
249
|
+
},
|
250
|
+
'triggerPrice': True,
|
251
|
+
'type': True,
|
252
|
+
'price': True,
|
253
|
+
},
|
244
254
|
'timeInForce': {
|
245
255
|
'IOC': True,
|
246
256
|
'FOK': False,
|
@@ -1404,6 +1414,65 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
1404
1414
|
statuses = self.safe_list(data, 'statuses', [])
|
1405
1415
|
return self.parse_orders(statuses, None)
|
1406
1416
|
|
1417
|
+
def create_order_request(self, symbol: str, type: OrderType, side: OrderSide, amount: str, price: Str = None, params={}):
|
1418
|
+
market = self.market(symbol)
|
1419
|
+
type = type.upper()
|
1420
|
+
side = side.upper()
|
1421
|
+
isMarket = (type == 'MARKET')
|
1422
|
+
isBuy = (side == 'BUY')
|
1423
|
+
clientOrderId = self.safe_string_2(params, 'clientOrderId', 'client_id')
|
1424
|
+
slippage = self.safe_string(params, 'slippage')
|
1425
|
+
defaultTimeInForce = 'ioc' if (isMarket) else 'gtc'
|
1426
|
+
postOnly = self.safe_bool(params, 'postOnly', False)
|
1427
|
+
if postOnly:
|
1428
|
+
defaultTimeInForce = 'alo'
|
1429
|
+
timeInForce = self.safe_string_lower(params, 'timeInForce', defaultTimeInForce)
|
1430
|
+
timeInForce = self.capitalize(timeInForce)
|
1431
|
+
triggerPrice = self.safe_string_2(params, 'triggerPrice', 'stopPrice')
|
1432
|
+
stopLossPrice = self.safe_string(params, 'stopLossPrice', triggerPrice)
|
1433
|
+
takeProfitPrice = self.safe_string(params, 'takeProfitPrice')
|
1434
|
+
isTrigger = (stopLossPrice or takeProfitPrice)
|
1435
|
+
px = None
|
1436
|
+
if isMarket:
|
1437
|
+
if price is None:
|
1438
|
+
raise ArgumentsRequired(self.id + ' market orders require price to calculate the max slippage price. Default slippage can be set in options(default is 5%).')
|
1439
|
+
px = Precise.string_mul(price, Precise.string_add('1', slippage)) if (isBuy) else Precise.string_mul(price, Precise.string_sub('1', slippage))
|
1440
|
+
px = self.price_to_precision(symbol, px) # round after adding slippage
|
1441
|
+
else:
|
1442
|
+
px = self.price_to_precision(symbol, price)
|
1443
|
+
sz = self.amount_to_precision(symbol, amount)
|
1444
|
+
reduceOnly = self.safe_bool(params, 'reduceOnly', False)
|
1445
|
+
orderType: dict = {}
|
1446
|
+
if isTrigger:
|
1447
|
+
isTp = False
|
1448
|
+
if takeProfitPrice is not None:
|
1449
|
+
triggerPrice = self.price_to_precision(symbol, takeProfitPrice)
|
1450
|
+
isTp = True
|
1451
|
+
else:
|
1452
|
+
triggerPrice = self.price_to_precision(symbol, stopLossPrice)
|
1453
|
+
orderType['trigger'] = {
|
1454
|
+
'isMarket': isMarket,
|
1455
|
+
'triggerPx': triggerPrice,
|
1456
|
+
'tpsl': 'tp' if (isTp) else 'sl',
|
1457
|
+
}
|
1458
|
+
else:
|
1459
|
+
orderType['limit'] = {
|
1460
|
+
'tif': timeInForce,
|
1461
|
+
}
|
1462
|
+
params = self.omit(params, ['clientOrderId', 'slippage', 'triggerPrice', 'stopPrice', 'stopLossPrice', 'takeProfitPrice', 'timeInForce', 'client_id', 'reduceOnly', 'postOnly'])
|
1463
|
+
orderObj: dict = {
|
1464
|
+
'a': self.parse_to_int(market['baseId']),
|
1465
|
+
'b': isBuy,
|
1466
|
+
'p': px,
|
1467
|
+
's': sz,
|
1468
|
+
'r': reduceOnly,
|
1469
|
+
't': orderType,
|
1470
|
+
# 'c': clientOrderId,
|
1471
|
+
}
|
1472
|
+
if clientOrderId is not None:
|
1473
|
+
orderObj['c'] = clientOrderId
|
1474
|
+
return orderObj
|
1475
|
+
|
1407
1476
|
def create_orders_request(self, orders, params={}) -> dict:
|
1408
1477
|
"""
|
1409
1478
|
create a list of trade orders
|
@@ -1431,77 +1500,59 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
1431
1500
|
params = self.omit(params, ['slippage', 'clientOrderId', 'client_id', 'slippage', 'triggerPrice', 'stopPrice', 'stopLossPrice', 'takeProfitPrice', 'timeInForce'])
|
1432
1501
|
nonce = self.milliseconds()
|
1433
1502
|
orderReq = []
|
1503
|
+
grouping = 'na'
|
1434
1504
|
for i in range(0, len(orders)):
|
1435
1505
|
rawOrder = orders[i]
|
1436
1506
|
marketId = self.safe_string(rawOrder, 'symbol')
|
1437
1507
|
market = self.market(marketId)
|
1438
1508
|
symbol = market['symbol']
|
1439
1509
|
type = self.safe_string_upper(rawOrder, 'type')
|
1440
|
-
isMarket = (type == 'MARKET')
|
1441
1510
|
side = self.safe_string_upper(rawOrder, 'side')
|
1442
|
-
isBuy = (side == 'BUY')
|
1443
1511
|
amount = self.safe_string(rawOrder, 'amount')
|
1444
1512
|
price = self.safe_string(rawOrder, 'price')
|
1445
1513
|
orderParams = self.safe_dict(rawOrder, 'params', {})
|
1446
|
-
clientOrderId = self.safe_string_2(orderParams, 'clientOrderId', 'client_id')
|
1447
1514
|
slippage = self.safe_string(orderParams, 'slippage', defaultSlippage)
|
1448
|
-
|
1449
|
-
|
1450
|
-
|
1451
|
-
|
1452
|
-
|
1453
|
-
|
1454
|
-
|
1455
|
-
stopLossPrice = self.safe_string(orderParams, 'stopLossPrice', triggerPrice)
|
1456
|
-
takeProfitPrice = self.safe_string(orderParams, 'takeProfitPrice')
|
1457
|
-
isTrigger = (stopLossPrice or takeProfitPrice)
|
1458
|
-
px = None
|
1459
|
-
if isMarket:
|
1460
|
-
if price is None:
|
1461
|
-
raise ArgumentsRequired(self.id + ' market orders require price to calculate the max slippage price. Default slippage can be set in options(default is 5%).')
|
1462
|
-
px = Precise.string_mul(price, Precise.string_add('1', slippage)) if (isBuy) else Precise.string_mul(price, Precise.string_sub('1', slippage))
|
1463
|
-
px = self.price_to_precision(symbol, px) # round after adding slippage
|
1464
|
-
else:
|
1465
|
-
px = self.price_to_precision(symbol, price)
|
1466
|
-
sz = self.amount_to_precision(symbol, amount)
|
1467
|
-
reduceOnly = self.safe_bool(orderParams, 'reduceOnly', False)
|
1468
|
-
orderType: dict = {}
|
1515
|
+
orderParams['slippage'] = slippage
|
1516
|
+
stopLoss = self.safe_value(orderParams, 'stopLoss')
|
1517
|
+
takeProfit = self.safe_value(orderParams, 'takeProfit')
|
1518
|
+
isTrigger = (stopLoss or takeProfit)
|
1519
|
+
orderParams = self.omit(orderParams, ['stopLoss', 'takeProfit'])
|
1520
|
+
mainOrderObj: dict = self.create_order_request(symbol, type, side, amount, price, orderParams)
|
1521
|
+
orderReq.append(mainOrderObj)
|
1469
1522
|
if isTrigger:
|
1470
|
-
|
1471
|
-
|
1472
|
-
|
1473
|
-
|
1523
|
+
# grouping opposed orders for sl/tp
|
1524
|
+
stopLossOrderTriggerPrice = self.safe_string_n(stopLoss, ['triggerPrice', 'stopPrice'])
|
1525
|
+
stopLossOrderType = self.safe_string(stopLoss, 'type')
|
1526
|
+
stopLossOrderLimitPrice = self.safe_string_n(stopLoss, ['price', 'stopLossPrice'], stopLossOrderTriggerPrice)
|
1527
|
+
takeProfitOrderTriggerPrice = self.safe_string_n(takeProfit, ['triggerPrice', 'stopPrice'])
|
1528
|
+
takeProfitOrderType = self.safe_string(takeProfit, 'type')
|
1529
|
+
takeProfitOrderLimitPrice = self.safe_string_n(takeProfit, ['price', 'takeProfitPrice'], takeProfitOrderTriggerPrice)
|
1530
|
+
grouping = 'normalTpsl'
|
1531
|
+
orderParams = self.omit(orderParams, ['stopLoss', 'takeProfit'])
|
1532
|
+
triggerOrderSide = ''
|
1533
|
+
if side == 'BUY':
|
1534
|
+
triggerOrderSide = 'sell'
|
1474
1535
|
else:
|
1475
|
-
|
1476
|
-
|
1477
|
-
|
1478
|
-
|
1479
|
-
|
1480
|
-
|
1481
|
-
|
1482
|
-
|
1483
|
-
|
1484
|
-
|
1485
|
-
|
1486
|
-
|
1487
|
-
|
1488
|
-
'b': isBuy,
|
1489
|
-
'p': px,
|
1490
|
-
's': sz,
|
1491
|
-
'r': reduceOnly,
|
1492
|
-
't': orderType,
|
1493
|
-
# 'c': clientOrderId,
|
1494
|
-
}
|
1495
|
-
if clientOrderId is not None:
|
1496
|
-
orderObj['c'] = clientOrderId
|
1497
|
-
orderReq.append(orderObj)
|
1536
|
+
triggerOrderSide = 'buy'
|
1537
|
+
if takeProfit is not None:
|
1538
|
+
orderObj: dict = self.create_order_request(symbol, takeProfitOrderType, triggerOrderSide, amount, takeProfitOrderLimitPrice, self.extend(orderParams, {
|
1539
|
+
'takeProfitPrice': takeProfitOrderTriggerPrice,
|
1540
|
+
'reduceOnly': True,
|
1541
|
+
}))
|
1542
|
+
orderReq.append(orderObj)
|
1543
|
+
if stopLoss is not None:
|
1544
|
+
orderObj: dict = self.create_order_request(symbol, stopLossOrderType, triggerOrderSide, amount, stopLossOrderLimitPrice, self.extend(orderParams, {
|
1545
|
+
'stopLossPrice': stopLossOrderTriggerPrice,
|
1546
|
+
'reduceOnly': True,
|
1547
|
+
}))
|
1548
|
+
orderReq.append(orderObj)
|
1498
1549
|
vaultAddress = None
|
1499
1550
|
vaultAddress, params = self.handle_option_and_params(params, 'createOrder', 'vaultAddress')
|
1500
1551
|
vaultAddress = self.format_vault_address(vaultAddress)
|
1501
1552
|
orderAction: dict = {
|
1502
1553
|
'type': 'order',
|
1503
1554
|
'orders': orderReq,
|
1504
|
-
'grouping':
|
1555
|
+
'grouping': grouping,
|
1505
1556
|
# 'brokerCode': 1, # cant
|
1506
1557
|
}
|
1507
1558
|
if vaultAddress is None:
|
ccxt/async_support/kraken.py
CHANGED
@@ -1366,7 +1366,20 @@ class kraken(Exchange, ImplicitAPI):
|
|
1366
1366
|
# "maker": False
|
1367
1367
|
# }
|
1368
1368
|
#
|
1369
|
+
# watchTrades
|
1370
|
+
#
|
1371
|
+
# {
|
1372
|
+
# "symbol": "BTC/USD",
|
1373
|
+
# "side": "buy",
|
1374
|
+
# "price": 109601.2,
|
1375
|
+
# "qty": 0.04561994,
|
1376
|
+
# "ord_type": "market",
|
1377
|
+
# "trade_id": 83449369,
|
1378
|
+
# "timestamp": "2025-05-27T11:24:03.847761Z"
|
1379
|
+
# }
|
1380
|
+
#
|
1369
1381
|
timestamp = None
|
1382
|
+
datetime = None
|
1370
1383
|
side = None
|
1371
1384
|
type = None
|
1372
1385
|
price = None
|
@@ -1409,6 +1422,14 @@ class kraken(Exchange, ImplicitAPI):
|
|
1409
1422
|
'cost': self.safe_string(trade, 'fee'),
|
1410
1423
|
'currency': currency,
|
1411
1424
|
}
|
1425
|
+
else:
|
1426
|
+
symbol = self.safe_string(trade, 'symbol')
|
1427
|
+
datetime = self.safe_string(trade, 'timestamp')
|
1428
|
+
id = self.safe_string(trade, 'trade_id')
|
1429
|
+
side = self.safe_string(trade, 'side')
|
1430
|
+
type = self.safe_string(trade, 'ord_type')
|
1431
|
+
price = self.safe_string(trade, 'price')
|
1432
|
+
amount = self.safe_string(trade, 'qty')
|
1412
1433
|
if market is not None:
|
1413
1434
|
symbol = market['symbol']
|
1414
1435
|
cost = self.safe_string(trade, 'cost')
|
@@ -1416,12 +1437,16 @@ class kraken(Exchange, ImplicitAPI):
|
|
1416
1437
|
takerOrMaker = None
|
1417
1438
|
if maker is not None:
|
1418
1439
|
takerOrMaker = 'maker' if maker else 'taker'
|
1440
|
+
if datetime is None:
|
1441
|
+
datetime = self.iso8601(timestamp)
|
1442
|
+
else:
|
1443
|
+
timestamp = self.parse8601(datetime)
|
1419
1444
|
return self.safe_trade({
|
1420
1445
|
'id': id,
|
1421
1446
|
'order': orderId,
|
1422
1447
|
'info': trade,
|
1423
1448
|
'timestamp': timestamp,
|
1424
|
-
'datetime':
|
1449
|
+
'datetime': datetime,
|
1425
1450
|
'symbol': symbol,
|
1426
1451
|
'type': type,
|
1427
1452
|
'side': side,
|
@@ -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
|
async def fetch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
|