ccxt 4.4.69__py2.py3-none-any.whl → 4.4.71__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/bingx.py +1 -0
- ccxt/abstract/bitmart.py +1 -0
- ccxt/abstract/bybit.py +4 -0
- ccxt/abstract/myokx.py +3 -0
- ccxt/abstract/okx.py +3 -0
- ccxt/abstract/poloniex.py +36 -0
- ccxt/abstract/tradeogre.py +1 -1
- ccxt/async_support/__init__.py +1 -3
- ccxt/async_support/base/exchange.py +3 -3
- ccxt/async_support/binance.py +107 -102
- ccxt/async_support/bingx.py +64 -42
- ccxt/async_support/bitget.py +47 -265
- ccxt/async_support/bitmart.py +12 -1
- ccxt/async_support/bitopro.py +1 -0
- ccxt/async_support/bitrue.py +1 -0
- ccxt/async_support/bybit.py +7 -0
- ccxt/async_support/cex.py +1 -0
- ccxt/async_support/coinbase.py +23 -4
- ccxt/async_support/coinbaseexchange.py +1 -0
- ccxt/async_support/deribit.py +1 -0
- ccxt/async_support/hashkey.py +4 -2
- ccxt/async_support/hyperliquid.py +16 -7
- ccxt/async_support/kraken.py +77 -5
- ccxt/async_support/kucoin.py +4 -2
- ccxt/async_support/mexc.py +8 -4
- ccxt/async_support/okx.py +62 -46
- ccxt/async_support/poloniex.py +1263 -85
- ccxt/async_support/tradeogre.py +20 -4
- ccxt/async_support/whitebit.py +4 -2
- ccxt/base/exchange.py +23 -4
- ccxt/base/types.py +28 -0
- ccxt/binance.py +107 -102
- ccxt/bingx.py +64 -42
- ccxt/bitget.py +47 -265
- ccxt/bitmart.py +12 -1
- ccxt/bitopro.py +1 -0
- ccxt/bitrue.py +1 -0
- ccxt/bybit.py +7 -0
- ccxt/cex.py +1 -0
- ccxt/coinbase.py +23 -4
- ccxt/coinbaseexchange.py +1 -0
- ccxt/deribit.py +1 -0
- ccxt/hashkey.py +4 -2
- ccxt/hyperliquid.py +16 -7
- ccxt/kraken.py +77 -5
- ccxt/kucoin.py +4 -2
- ccxt/mexc.py +8 -4
- ccxt/okx.py +62 -46
- ccxt/poloniex.py +1262 -85
- ccxt/pro/__init__.py +1 -3
- ccxt/pro/binance.py +102 -102
- ccxt/pro/bingx.py +62 -51
- ccxt/pro/bitget.py +28 -3
- ccxt/pro/bybit.py +81 -37
- ccxt/test/tests_async.py +4 -3
- ccxt/test/tests_sync.py +4 -3
- ccxt/tradeogre.py +20 -4
- ccxt/whitebit.py +4 -2
- {ccxt-4.4.69.dist-info → ccxt-4.4.71.dist-info}/METADATA +6 -9
- {ccxt-4.4.69.dist-info → ccxt-4.4.71.dist-info}/RECORD +64 -65
- ccxt/abstract/poloniexfutures.py +0 -48
- {ccxt-4.4.69.dist-info → ccxt-4.4.71.dist-info}/LICENSE.txt +0 -0
- {ccxt-4.4.69.dist-info → ccxt-4.4.71.dist-info}/WHEEL +0 -0
- {ccxt-4.4.69.dist-info → ccxt-4.4.71.dist-info}/top_level.txt +0 -0
ccxt/async_support/poloniex.py
CHANGED
@@ -5,8 +5,9 @@
|
|
5
5
|
|
6
6
|
from ccxt.async_support.base.exchange import Exchange
|
7
7
|
from ccxt.abstract.poloniex import ImplicitAPI
|
8
|
+
import asyncio
|
8
9
|
import hashlib
|
9
|
-
from ccxt.base.types import Any, Balances, Currencies, Currency, DepositAddress, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFees, Transaction, TransferEntry
|
10
|
+
from ccxt.base.types import Any, Balances, Bool, Currencies, Currency, DepositAddress, Int, Leverage, MarginModification, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFees, Transaction, TransferEntry
|
10
11
|
from typing import List
|
11
12
|
from ccxt.base.errors import ExchangeError
|
12
13
|
from ccxt.base.errors import AuthenticationError
|
@@ -41,21 +42,25 @@ class poloniex(Exchange, ImplicitAPI):
|
|
41
42
|
'CORS': None,
|
42
43
|
'spot': True,
|
43
44
|
'margin': None, # has but not fully implemented
|
44
|
-
'swap':
|
45
|
-
'future':
|
45
|
+
'swap': True,
|
46
|
+
'future': True,
|
46
47
|
'option': False,
|
48
|
+
'addMargin': True,
|
47
49
|
'cancelAllOrders': True,
|
48
50
|
'cancelOrder': True,
|
51
|
+
'cancelOrders': None, # not yet implemented, because RL is worse than cancelOrder
|
49
52
|
'createDepositAddress': True,
|
50
53
|
'createMarketBuyOrderWithCost': True,
|
51
54
|
'createMarketOrderWithCost': False,
|
52
55
|
'createMarketSellOrderWithCost': False,
|
53
56
|
'createOrder': True,
|
57
|
+
'createOrders': None, # not yet implemented, because RL is worse than createOrder
|
54
58
|
'createStopOrder': True,
|
55
59
|
'createTriggerOrder': True,
|
56
60
|
'editOrder': True,
|
57
61
|
'fetchBalance': True,
|
58
62
|
'fetchClosedOrder': False,
|
63
|
+
'fetchClosedOrders': True,
|
59
64
|
'fetchCurrencies': True,
|
60
65
|
'fetchDepositAddress': True,
|
61
66
|
'fetchDepositAddresses': False,
|
@@ -69,20 +74,24 @@ class poloniex(Exchange, ImplicitAPI):
|
|
69
74
|
'fetchFundingIntervals': False,
|
70
75
|
'fetchFundingRate': False,
|
71
76
|
'fetchFundingRateHistory': False,
|
72
|
-
'fetchFundingRates':
|
77
|
+
'fetchFundingRates': None, # has but not implemented
|
78
|
+
'fetchLedger': None, # has but not implemented
|
79
|
+
'fetchLeverage': True,
|
80
|
+
'fetchLiquidations': None, # has but not implemented
|
73
81
|
'fetchMarginMode': False,
|
74
82
|
'fetchMarkets': True,
|
75
83
|
'fetchMyTrades': True,
|
76
84
|
'fetchOHLCV': True,
|
77
85
|
'fetchOpenInterestHistory': False,
|
78
86
|
'fetchOpenOrder': False,
|
79
|
-
'fetchOpenOrders': True,
|
87
|
+
'fetchOpenOrders': True,
|
80
88
|
'fetchOrder': True,
|
81
89
|
'fetchOrderBook': True,
|
82
90
|
'fetchOrderBooks': False,
|
83
|
-
'fetchOrderTrades': True,
|
91
|
+
'fetchOrderTrades': True,
|
84
92
|
'fetchPosition': False,
|
85
|
-
'fetchPositionMode':
|
93
|
+
'fetchPositionMode': True,
|
94
|
+
'fetchPositions': True,
|
86
95
|
'fetchTicker': True,
|
87
96
|
'fetchTickers': True,
|
88
97
|
'fetchTime': True,
|
@@ -93,33 +102,37 @@ class poloniex(Exchange, ImplicitAPI):
|
|
93
102
|
'fetchTransfer': False,
|
94
103
|
'fetchTransfers': False,
|
95
104
|
'fetchWithdrawals': True,
|
105
|
+
'reduceMargin': True,
|
96
106
|
'sandbox': True,
|
107
|
+
'setLeverage': True,
|
108
|
+
'setPositionMode': True,
|
97
109
|
'transfer': True,
|
98
110
|
'withdraw': True,
|
99
111
|
},
|
100
112
|
'timeframes': {
|
101
113
|
'1m': 'MINUTE_1',
|
102
114
|
'5m': 'MINUTE_5',
|
103
|
-
'10m': 'MINUTE_10',
|
115
|
+
'10m': 'MINUTE_10', # not in swap
|
104
116
|
'15m': 'MINUTE_15',
|
105
117
|
'30m': 'MINUTE_30',
|
106
118
|
'1h': 'HOUR_1',
|
107
119
|
'2h': 'HOUR_2',
|
108
120
|
'4h': 'HOUR_4',
|
109
|
-
'6h': 'HOUR_6',
|
121
|
+
'6h': 'HOUR_6', # not in swap
|
110
122
|
'12h': 'HOUR_12',
|
111
123
|
'1d': 'DAY_1',
|
112
124
|
'3d': 'DAY_3',
|
113
125
|
'1w': 'WEEK_1',
|
114
|
-
'1M': 'MONTH_1',
|
126
|
+
'1M': 'MONTH_1', # not in swap
|
115
127
|
},
|
116
128
|
'urls': {
|
117
129
|
'logo': 'https://user-images.githubusercontent.com/1294454/27766817-e9456312-5ee6-11e7-9b3c-b628ca5626a5.jpg',
|
118
130
|
'api': {
|
119
|
-
'
|
131
|
+
'spot': 'https://api.poloniex.com',
|
132
|
+
'swap': 'https://api.poloniex.com',
|
120
133
|
},
|
121
134
|
'test': {
|
122
|
-
'
|
135
|
+
'spot': 'https://sand-spot-api-gateway.poloniex.com',
|
123
136
|
},
|
124
137
|
'www': 'https://www.poloniex.com',
|
125
138
|
'doc': 'https://api-docs.poloniex.com/spot/',
|
@@ -206,6 +219,55 @@ class poloniex(Exchange, ImplicitAPI):
|
|
206
219
|
'smartorders/{id}': 20,
|
207
220
|
},
|
208
221
|
},
|
222
|
+
'swapPublic': {
|
223
|
+
'get': {
|
224
|
+
# 300 calls / second
|
225
|
+
'v3/market/allInstruments': 2 / 3,
|
226
|
+
'v3/market/instruments': 2 / 3,
|
227
|
+
'v3/market/orderBook': 2 / 3,
|
228
|
+
'v3/market/candles': 10, # candles have differnt RL
|
229
|
+
'v3/market/indexPriceCandlesticks': 10,
|
230
|
+
'v3/market/premiumIndexCandlesticks': 10,
|
231
|
+
'v3/market/markPriceCandlesticks': 10,
|
232
|
+
'v3/market/trades': 2 / 3,
|
233
|
+
'v3/market/liquidationOrder': 2 / 3,
|
234
|
+
'v3/market/tickers': 2 / 3,
|
235
|
+
'v3/market/markPrice': 2 / 3,
|
236
|
+
'v3/market/indexPrice': 2 / 3,
|
237
|
+
'v3/market/indexPriceComponents': 2 / 3,
|
238
|
+
'v3/market/fundingRate': 2 / 3,
|
239
|
+
'v3/market/openInterest': 2 / 3,
|
240
|
+
'v3/market/insurance': 2 / 3,
|
241
|
+
'v3/market/riskLimit': 2 / 3,
|
242
|
+
},
|
243
|
+
},
|
244
|
+
'swapPrivate': {
|
245
|
+
'get': {
|
246
|
+
'v3/account/balance': 4,
|
247
|
+
'v3/account/bills': 20,
|
248
|
+
'v3/trade/order/opens': 20,
|
249
|
+
'v3/trade/order/trades': 20,
|
250
|
+
'v3/trade/order/history': 20,
|
251
|
+
'v3/trade/position/opens': 20,
|
252
|
+
'v3/trade/position/history': 20, # todo: method for self
|
253
|
+
'v3/position/leverages': 20,
|
254
|
+
'v3/position/mode': 20,
|
255
|
+
},
|
256
|
+
'post': {
|
257
|
+
'v3/trade/order': 4,
|
258
|
+
'v3/trade/orders': 40,
|
259
|
+
'v3/trade/position': 20,
|
260
|
+
'v3/trade/positionAll': 100,
|
261
|
+
'v3/position/leverage': 20,
|
262
|
+
'v3/position/mode': 20,
|
263
|
+
'v3/trade/position/margin': 20,
|
264
|
+
},
|
265
|
+
'delete': {
|
266
|
+
'v3/trade/order': 2,
|
267
|
+
'v3/trade/batchOrders': 20,
|
268
|
+
'v3/trade/allOrders': 20,
|
269
|
+
},
|
270
|
+
},
|
209
271
|
},
|
210
272
|
'fees': {
|
211
273
|
'trading': {
|
@@ -254,6 +316,7 @@ class poloniex(Exchange, ImplicitAPI):
|
|
254
316
|
'UST': 'USTC',
|
255
317
|
},
|
256
318
|
'options': {
|
319
|
+
'defaultType': 'spot',
|
257
320
|
'createMarketBuyOrderRequiresPrice': True,
|
258
321
|
'networks': {
|
259
322
|
'BEP20': 'BSC',
|
@@ -300,7 +363,7 @@ class poloniex(Exchange, ImplicitAPI):
|
|
300
363
|
'timeInForce': {
|
301
364
|
'IOC': True,
|
302
365
|
'FOK': True,
|
303
|
-
'PO':
|
366
|
+
'PO': True,
|
304
367
|
'GTD': False,
|
305
368
|
},
|
306
369
|
'hedged': False,
|
@@ -311,7 +374,9 @@ class poloniex(Exchange, ImplicitAPI):
|
|
311
374
|
'trailing': False,
|
312
375
|
'iceberg': False,
|
313
376
|
},
|
314
|
-
'createOrders':
|
377
|
+
'createOrders': {
|
378
|
+
'max': 20,
|
379
|
+
},
|
315
380
|
'fetchMyTrades': {
|
316
381
|
'marginMode': False,
|
317
382
|
'limit': 1000,
|
@@ -341,13 +406,50 @@ class poloniex(Exchange, ImplicitAPI):
|
|
341
406
|
'spot': {
|
342
407
|
'extends': 'default',
|
343
408
|
},
|
409
|
+
'forContracts': {
|
410
|
+
'extends': 'default',
|
411
|
+
'createOrder': {
|
412
|
+
'marginMode': True,
|
413
|
+
'triggerPrice': False,
|
414
|
+
'hedged': True,
|
415
|
+
'stpMode': True, # todo
|
416
|
+
'marketBuyByCost': False,
|
417
|
+
},
|
418
|
+
'createOrders': {
|
419
|
+
'max': 10,
|
420
|
+
},
|
421
|
+
'fetchOpenOrders': {
|
422
|
+
'limit': 100,
|
423
|
+
},
|
424
|
+
'fetchClosedOrders': {
|
425
|
+
'marginMode': False,
|
426
|
+
'limit': 100,
|
427
|
+
'daysBack': None,
|
428
|
+
'daysBackCanceled': 1 / 6,
|
429
|
+
'untilDays': None,
|
430
|
+
'trigger': False,
|
431
|
+
'trailing': False,
|
432
|
+
},
|
433
|
+
'fetchMyTrades': {
|
434
|
+
'limit': 100,
|
435
|
+
'untilDays': 90,
|
436
|
+
},
|
437
|
+
},
|
344
438
|
'swap': {
|
345
|
-
'linear':
|
346
|
-
|
439
|
+
'linear': {
|
440
|
+
'extends': 'forContracts',
|
441
|
+
},
|
442
|
+
'inverse': {
|
443
|
+
'extends': 'forContracts',
|
444
|
+
},
|
347
445
|
},
|
348
446
|
'future': {
|
349
|
-
'linear':
|
350
|
-
|
447
|
+
'linear': {
|
448
|
+
'extends': 'forContracts',
|
449
|
+
},
|
450
|
+
'inverse': {
|
451
|
+
'extends': 'forContracts',
|
452
|
+
},
|
351
453
|
},
|
352
454
|
},
|
353
455
|
'precisionMode': TICK_SIZE,
|
@@ -467,6 +569,8 @@ class poloniex(Exchange, ImplicitAPI):
|
|
467
569
|
})
|
468
570
|
|
469
571
|
def parse_ohlcv(self, ohlcv, market: Market = None) -> list:
|
572
|
+
#
|
573
|
+
# spot:
|
470
574
|
#
|
471
575
|
# [
|
472
576
|
# [
|
@@ -487,6 +591,31 @@ class poloniex(Exchange, ImplicitAPI):
|
|
487
591
|
# ]
|
488
592
|
# ]
|
489
593
|
#
|
594
|
+
# contract:
|
595
|
+
#
|
596
|
+
# [
|
597
|
+
# "84207.02",
|
598
|
+
# "84320.85",
|
599
|
+
# "84207.02",
|
600
|
+
# "84253.83",
|
601
|
+
# "3707.5395",
|
602
|
+
# "44",
|
603
|
+
# "14",
|
604
|
+
# "1740770040000",
|
605
|
+
# "1740770099999",
|
606
|
+
# ],
|
607
|
+
#
|
608
|
+
ohlcvLength = len(ohlcv)
|
609
|
+
isContract = ohlcvLength == 9
|
610
|
+
if isContract:
|
611
|
+
return [
|
612
|
+
self.safe_integer(ohlcv, 7),
|
613
|
+
self.safe_number(ohlcv, 2),
|
614
|
+
self.safe_number(ohlcv, 1),
|
615
|
+
self.safe_number(ohlcv, 0),
|
616
|
+
self.safe_number(ohlcv, 3),
|
617
|
+
self.safe_number(ohlcv, 5),
|
618
|
+
]
|
490
619
|
return [
|
491
620
|
self.safe_integer(ohlcv, 12),
|
492
621
|
self.safe_number(ohlcv, 2),
|
@@ -501,6 +630,7 @@ class poloniex(Exchange, ImplicitAPI):
|
|
501
630
|
fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
502
631
|
|
503
632
|
https://api-docs.poloniex.com/spot/api/public/market-data#candles
|
633
|
+
https://api-docs.poloniex.com/v3/futures/api/market/get-kline-data
|
504
634
|
|
505
635
|
:param str symbol: unified symbol of the market to fetch OHLCV data for
|
506
636
|
:param str timeframe: the length of time each candle represents
|
@@ -521,12 +651,37 @@ class poloniex(Exchange, ImplicitAPI):
|
|
521
651
|
'symbol': market['id'],
|
522
652
|
'interval': self.safe_string(self.timeframes, timeframe, timeframe),
|
523
653
|
}
|
654
|
+
keyStart = 'startTime' if market['spot'] else 'sTime'
|
655
|
+
keyEnd = 'endTime' if market['spot'] else 'eTime'
|
524
656
|
if since is not None:
|
525
|
-
request[
|
657
|
+
request[keyStart] = since
|
526
658
|
if limit is not None:
|
527
659
|
# limit should in between 100 and 500
|
528
660
|
request['limit'] = limit
|
529
|
-
request, params = self.handle_until_option(
|
661
|
+
request, params = self.handle_until_option(keyEnd, request, params)
|
662
|
+
if market['contract']:
|
663
|
+
if self.in_array(timeframe, ['10m', '1M']):
|
664
|
+
raise NotSupported(self.id + ' ' + timeframe + ' ' + market['type'] + ' fetchOHLCV is not supported')
|
665
|
+
responseRaw = await self.swapPublicGetV3MarketCandles(self.extend(request, params))
|
666
|
+
#
|
667
|
+
# {
|
668
|
+
# code: "200",
|
669
|
+
# msg: "Success",
|
670
|
+
# data: [
|
671
|
+
# [
|
672
|
+
# "84207.02",
|
673
|
+
# "84320.85",
|
674
|
+
# "84207.02",
|
675
|
+
# "84253.83",
|
676
|
+
# "3707.5395",
|
677
|
+
# "44",
|
678
|
+
# "14",
|
679
|
+
# "1740770040000",
|
680
|
+
# "1740770099999",
|
681
|
+
# ],
|
682
|
+
#
|
683
|
+
data = self.safe_list(responseRaw, 'data')
|
684
|
+
return self.parse_ohlcvs(data, market, timeframe, since, limit)
|
530
685
|
response = await self.publicGetMarketsSymbolCandles(self.extend(request, params))
|
531
686
|
#
|
532
687
|
# [
|
@@ -562,10 +717,16 @@ class poloniex(Exchange, ImplicitAPI):
|
|
562
717
|
retrieves data on all markets for poloniex
|
563
718
|
|
564
719
|
https://api-docs.poloniex.com/spot/api/public/reference-data#symbol-information
|
720
|
+
https://api-docs.poloniex.com/v3/futures/api/market/get-all-product-info
|
565
721
|
|
566
722
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
567
723
|
:returns dict[]: an array of objects representing market data
|
568
724
|
"""
|
725
|
+
promises = [self.fetch_spot_markets(params), self.fetch_swap_markets(params)]
|
726
|
+
results = await asyncio.gather(*promises)
|
727
|
+
return self.array_concat(results[0], results[1])
|
728
|
+
|
729
|
+
async def fetch_spot_markets(self, params={}) -> List[Market]:
|
569
730
|
markets = await self.publicGetMarkets(params)
|
570
731
|
#
|
571
732
|
# [
|
@@ -592,7 +753,57 @@ class poloniex(Exchange, ImplicitAPI):
|
|
592
753
|
#
|
593
754
|
return self.parse_markets(markets)
|
594
755
|
|
756
|
+
async def fetch_swap_markets(self, params={}) -> List[Market]:
|
757
|
+
# do similar per https://api-docs.poloniex.com/v3/futures/api/market/get-product-info
|
758
|
+
response = await self.swapPublicGetV3MarketAllInstruments(params)
|
759
|
+
#
|
760
|
+
# {
|
761
|
+
# "code": "200",
|
762
|
+
# "msg": "Success",
|
763
|
+
# "data": [
|
764
|
+
# {
|
765
|
+
# "symbol": "BNB_USDT_PERP",
|
766
|
+
# "bAsset": ".PBNBUSDT",
|
767
|
+
# "bCcy": "BNB",
|
768
|
+
# "qCcy": "USDT",
|
769
|
+
# "visibleStartTime": "1620390600000",
|
770
|
+
# "tradableStartTime": "1620390600000",
|
771
|
+
# "sCcy": "USDT",
|
772
|
+
# "tSz": "0.001",
|
773
|
+
# "pxScale": "0.001,0.01,0.1,1,10",
|
774
|
+
# "lotSz": "1",
|
775
|
+
# "minSz": "1",
|
776
|
+
# "ctVal": "0.1",
|
777
|
+
# "status": "OPEN",
|
778
|
+
# "oDate": "1620287590000",
|
779
|
+
# "maxPx": "1000000",
|
780
|
+
# "minPx": "0.001",
|
781
|
+
# "maxQty": "1000000",
|
782
|
+
# "minQty": "1",
|
783
|
+
# "maxLever": "50",
|
784
|
+
# "lever": "10",
|
785
|
+
# "ctType": "LINEAR",
|
786
|
+
# "alias": "",
|
787
|
+
# "iM": "0.02",
|
788
|
+
# "mM": "0.0115",
|
789
|
+
# "mR": "2000",
|
790
|
+
# "buyLmt": "",
|
791
|
+
# "sellLmt": "",
|
792
|
+
# "ordPxRange": "0.05",
|
793
|
+
# "marketMaxQty": "2800",
|
794
|
+
# "limitMaxQty": "1000000"
|
795
|
+
# },
|
796
|
+
#
|
797
|
+
markets = self.safe_list(response, 'data')
|
798
|
+
return self.parse_markets(markets)
|
799
|
+
|
595
800
|
def parse_market(self, market: dict) -> Market:
|
801
|
+
if 'ctType' in market:
|
802
|
+
return self.parse_swap_market(market)
|
803
|
+
else:
|
804
|
+
return self.parse_spot_market(market)
|
805
|
+
|
806
|
+
def parse_spot_market(self, market: dict) -> Market:
|
596
807
|
id = self.safe_string(market, 'symbol')
|
597
808
|
baseId = self.safe_string(market, 'baseCurrencyName')
|
598
809
|
quoteId = self.safe_string(market, 'quoteCurrencyName')
|
@@ -648,6 +859,113 @@ class poloniex(Exchange, ImplicitAPI):
|
|
648
859
|
'info': market,
|
649
860
|
}
|
650
861
|
|
862
|
+
def parse_swap_market(self, market: dict) -> Market:
|
863
|
+
#
|
864
|
+
# {
|
865
|
+
# "symbol": "BNB_USDT_PERP",
|
866
|
+
# "bAsset": ".PBNBUSDT",
|
867
|
+
# "bCcy": "BNB",
|
868
|
+
# "qCcy": "USDT",
|
869
|
+
# "visibleStartTime": "1620390600000",
|
870
|
+
# "tradableStartTime": "1620390600000",
|
871
|
+
# "sCcy": "USDT",
|
872
|
+
# "tSz": "0.001",
|
873
|
+
# "pxScale": "0.001,0.01,0.1,1,10",
|
874
|
+
# "lotSz": "1",
|
875
|
+
# "minSz": "1",
|
876
|
+
# "ctVal": "0.1",
|
877
|
+
# "status": "OPEN",
|
878
|
+
# "oDate": "1620287590000",
|
879
|
+
# "maxPx": "1000000",
|
880
|
+
# "minPx": "0.001",
|
881
|
+
# "maxQty": "1000000",
|
882
|
+
# "minQty": "1",
|
883
|
+
# "maxLever": "50",
|
884
|
+
# "lever": "10",
|
885
|
+
# "ctType": "LINEAR",
|
886
|
+
# "alias": "",
|
887
|
+
# "iM": "0.02",
|
888
|
+
# "mM": "0.0115",
|
889
|
+
# "mR": "2000",
|
890
|
+
# "buyLmt": "",
|
891
|
+
# "sellLmt": "",
|
892
|
+
# "ordPxRange": "0.05",
|
893
|
+
# "marketMaxQty": "2800",
|
894
|
+
# "limitMaxQty": "1000000"
|
895
|
+
# },
|
896
|
+
#
|
897
|
+
id = self.safe_string(market, 'symbol')
|
898
|
+
baseId = self.safe_string(market, 'bCcy')
|
899
|
+
quoteId = self.safe_string(market, 'qCcy')
|
900
|
+
settleId = self.safe_string(market, 'sCcy')
|
901
|
+
base = self.safe_currency_code(baseId)
|
902
|
+
quote = self.safe_currency_code(quoteId)
|
903
|
+
settle = self.safe_currency_code(settleId)
|
904
|
+
status = self.safe_string(market, 'status')
|
905
|
+
active = status == 'OPEN'
|
906
|
+
linear = market['ctType'] == 'LINEAR'
|
907
|
+
symbol = base + '/' + quote
|
908
|
+
if linear:
|
909
|
+
symbol += ':' + settle
|
910
|
+
else:
|
911
|
+
# actually, exchange does not have any inverse future now
|
912
|
+
symbol += ':' + base
|
913
|
+
alias = self.safe_string(market, 'alias')
|
914
|
+
type = 'swap'
|
915
|
+
if alias is not None:
|
916
|
+
type = 'future'
|
917
|
+
return {
|
918
|
+
'id': id,
|
919
|
+
'symbol': symbol,
|
920
|
+
'base': base,
|
921
|
+
'quote': quote,
|
922
|
+
'settle': settle,
|
923
|
+
'baseId': baseId,
|
924
|
+
'quoteId': quoteId,
|
925
|
+
'settleId': settleId,
|
926
|
+
'type': 'future' if (type == 'future') else 'swap',
|
927
|
+
'spot': False,
|
928
|
+
'margin': False,
|
929
|
+
'swap': type == 'swap',
|
930
|
+
'future': type == 'future',
|
931
|
+
'option': False,
|
932
|
+
'active': active,
|
933
|
+
'contract': True,
|
934
|
+
'linear': linear,
|
935
|
+
'inverse': not linear,
|
936
|
+
'contractSize': self.safe_number(market, 'ctVal'),
|
937
|
+
'expiry': None,
|
938
|
+
'expiryDatetime': None,
|
939
|
+
'strike': None,
|
940
|
+
'optionType': None,
|
941
|
+
'taker': self.safe_number(market, 'tFee'),
|
942
|
+
'maker': self.safe_number(market, 'mFee'),
|
943
|
+
'precision': {
|
944
|
+
'amount': self.safe_number(market, 'lotSz'),
|
945
|
+
'price': self.safe_number(market, 'tSz'),
|
946
|
+
},
|
947
|
+
'limits': {
|
948
|
+
'amount': {
|
949
|
+
'min': self.safe_number(market, 'minSz'),
|
950
|
+
'max': self.safe_number(market, 'limitMaxQty'),
|
951
|
+
},
|
952
|
+
'price': {
|
953
|
+
'min': self.safe_number(market, 'minPx'),
|
954
|
+
'max': self.safe_number(market, 'maxPx'),
|
955
|
+
},
|
956
|
+
'cost': {
|
957
|
+
'min': None,
|
958
|
+
'max': None,
|
959
|
+
},
|
960
|
+
'leverage': {
|
961
|
+
'max': self.safe_number(market, 'maxLever'),
|
962
|
+
'min': None,
|
963
|
+
},
|
964
|
+
},
|
965
|
+
'created': self.safe_integer(market, 'oDate'),
|
966
|
+
'info': market,
|
967
|
+
}
|
968
|
+
|
651
969
|
async def fetch_time(self, params={}) -> Int:
|
652
970
|
"""
|
653
971
|
fetches the current integer timestamp in milliseconds from the exchange server
|
@@ -661,6 +979,8 @@ class poloniex(Exchange, ImplicitAPI):
|
|
661
979
|
return self.safe_integer(response, 'serverTime')
|
662
980
|
|
663
981
|
def parse_ticker(self, ticker: dict, market: Market = None) -> Ticker:
|
982
|
+
#
|
983
|
+
# spot:
|
664
984
|
#
|
665
985
|
# {
|
666
986
|
# "symbol" : "BTC_USDT",
|
@@ -683,36 +1003,56 @@ class poloniex(Exchange, ImplicitAPI):
|
|
683
1003
|
# "markPrice" : "26444.11"
|
684
1004
|
# }
|
685
1005
|
#
|
686
|
-
|
687
|
-
|
1006
|
+
# swap:
|
1007
|
+
#
|
1008
|
+
# {
|
1009
|
+
# "s": "XRP_USDT_PERP",
|
1010
|
+
# "o": "2.0503",
|
1011
|
+
# "l": "2.0066",
|
1012
|
+
# "h": "2.216",
|
1013
|
+
# "c": "2.1798",
|
1014
|
+
# "qty": "21090",
|
1015
|
+
# "amt": "451339.65",
|
1016
|
+
# "tC": "3267",
|
1017
|
+
# "sT": "1740736380000",
|
1018
|
+
# "cT": "1740822777559",
|
1019
|
+
# "dN": "XRP/USDT/PERP",
|
1020
|
+
# "dC": "0.0632",
|
1021
|
+
# "bPx": "2.175",
|
1022
|
+
# "bSz": "3",
|
1023
|
+
# "aPx": "2.1831",
|
1024
|
+
# "aSz": "111",
|
1025
|
+
# "mPx": "2.1798",
|
1026
|
+
# "iPx": "2.1834"
|
1027
|
+
# },
|
1028
|
+
#
|
1029
|
+
timestamp = self.safe_integer_2(ticker, 'ts', 'cT')
|
1030
|
+
marketId = self.safe_string_2(ticker, 'symbol', 's')
|
688
1031
|
market = self.safe_market(marketId)
|
689
|
-
|
690
|
-
relativeChange = self.safe_string(ticker, 'dailyChange')
|
1032
|
+
relativeChange = self.safe_string_2(ticker, 'dailyChange', 'dc')
|
691
1033
|
percentage = Precise.string_mul(relativeChange, '100')
|
692
|
-
bidVolume = self.safe_string(ticker, 'bidQuantity')
|
693
|
-
askVolume = self.safe_string(ticker, 'askQuantity')
|
694
1034
|
return self.safe_ticker({
|
695
1035
|
'id': marketId,
|
696
1036
|
'symbol': market['symbol'],
|
697
1037
|
'timestamp': timestamp,
|
698
1038
|
'datetime': self.iso8601(timestamp),
|
699
|
-
'high': self.
|
700
|
-
'low': self.
|
701
|
-
'bid': self.
|
702
|
-
'bidVolume':
|
703
|
-
'ask': self.
|
704
|
-
'askVolume':
|
1039
|
+
'high': self.safe_string_2(ticker, 'high', 'h'),
|
1040
|
+
'low': self.safe_string_2(ticker, 'low', 'l'),
|
1041
|
+
'bid': self.safe_string_2(ticker, 'bid', 'bPx'),
|
1042
|
+
'bidVolume': self.safe_string_2(ticker, 'bidQuantity', 'bSz'),
|
1043
|
+
'ask': self.safe_string_2(ticker, 'ask', 'aPx'),
|
1044
|
+
'askVolume': self.safe_string_2(ticker, 'askQuantity', 'aSz'),
|
705
1045
|
'vwap': None,
|
706
|
-
'open': self.
|
707
|
-
'close': close,
|
708
|
-
'last': close,
|
1046
|
+
'open': self.safe_string_2(ticker, 'open', 'o'),
|
1047
|
+
'close': self.safe_string_2(ticker, 'close', 'c'),
|
709
1048
|
'previousClose': None,
|
710
1049
|
'change': None,
|
711
1050
|
'percentage': percentage,
|
712
1051
|
'average': None,
|
713
|
-
'baseVolume': self.
|
714
|
-
'quoteVolume': self.
|
715
|
-
'markPrice': self.
|
1052
|
+
'baseVolume': self.safe_string_2(ticker, 'quantity', 'qty'),
|
1053
|
+
'quoteVolume': self.safe_string_2(ticker, 'amount', 'amt'),
|
1054
|
+
'markPrice': self.safe_string_2(ticker, 'markPrice', 'mPx'),
|
1055
|
+
'indexPrice': self.safe_string(ticker, 'iPx'),
|
716
1056
|
'info': ticker,
|
717
1057
|
}, market)
|
718
1058
|
|
@@ -721,13 +1061,54 @@ class poloniex(Exchange, ImplicitAPI):
|
|
721
1061
|
fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
|
722
1062
|
|
723
1063
|
https://api-docs.poloniex.com/spot/api/public/market-data#ticker
|
1064
|
+
https://api-docs.poloniex.com/v3/futures/api/market/get-market-info
|
724
1065
|
|
725
1066
|
:param str[]|None symbols: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
|
726
1067
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
727
1068
|
:returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
|
728
1069
|
"""
|
729
1070
|
await self.load_markets()
|
730
|
-
|
1071
|
+
market = None
|
1072
|
+
request: dict = {}
|
1073
|
+
if symbols is not None:
|
1074
|
+
symbols = self.market_symbols(symbols, None, True, True, False)
|
1075
|
+
symbolsLength = len(symbols)
|
1076
|
+
if symbolsLength > 0:
|
1077
|
+
market = self.market(symbols[0])
|
1078
|
+
if symbolsLength == 1:
|
1079
|
+
request['symbol'] = market['id']
|
1080
|
+
marketType = None
|
1081
|
+
marketType, params = self.handle_market_type_and_params('fetchTickers', market, params)
|
1082
|
+
if marketType == 'swap':
|
1083
|
+
responseRaw = await self.swapPublicGetV3MarketTickers(self.extend(request, params))
|
1084
|
+
#
|
1085
|
+
# {
|
1086
|
+
# "code": "200",
|
1087
|
+
# "msg": "Success",
|
1088
|
+
# "data": [
|
1089
|
+
# {
|
1090
|
+
# "s": "XRP_USDT_PERP",
|
1091
|
+
# "o": "2.0503",
|
1092
|
+
# "l": "2.0066",
|
1093
|
+
# "h": "2.216",
|
1094
|
+
# "c": "2.1798",
|
1095
|
+
# "qty": "21090",
|
1096
|
+
# "amt": "451339.65",
|
1097
|
+
# "tC": "3267",
|
1098
|
+
# "sT": "1740736380000",
|
1099
|
+
# "cT": "1740822777559",
|
1100
|
+
# "dN": "XRP/USDT/PERP",
|
1101
|
+
# "dC": "0.0632",
|
1102
|
+
# "bPx": "2.175",
|
1103
|
+
# "bSz": "3",
|
1104
|
+
# "aPx": "2.1831",
|
1105
|
+
# "aSz": "111",
|
1106
|
+
# "mPx": "2.1798",
|
1107
|
+
# "iPx": "2.1834"
|
1108
|
+
# },
|
1109
|
+
#
|
1110
|
+
data = self.safe_list(responseRaw, 'data')
|
1111
|
+
return self.parse_tickers(data, symbols)
|
731
1112
|
response = await self.publicGetMarketsTicker24h(params)
|
732
1113
|
#
|
733
1114
|
# [
|
@@ -892,6 +1273,7 @@ class poloniex(Exchange, ImplicitAPI):
|
|
892
1273
|
fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
893
1274
|
|
894
1275
|
https://api-docs.poloniex.com/spot/api/public/market-data#ticker
|
1276
|
+
https://api-docs.poloniex.com/v3/futures/api/market/get-market-info
|
895
1277
|
|
896
1278
|
:param str symbol: unified symbol of the market to fetch the ticker for
|
897
1279
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -902,6 +1284,9 @@ class poloniex(Exchange, ImplicitAPI):
|
|
902
1284
|
request: dict = {
|
903
1285
|
'symbol': market['id'],
|
904
1286
|
}
|
1287
|
+
if market['contract']:
|
1288
|
+
tickers = await self.fetch_tickers([market['symbol']], params)
|
1289
|
+
return self.safe_dict(tickers, symbol)
|
905
1290
|
response = await self.publicGetMarketsSymbolTicker24h(self.extend(request, params))
|
906
1291
|
#
|
907
1292
|
# {
|
@@ -931,6 +1316,8 @@ class poloniex(Exchange, ImplicitAPI):
|
|
931
1316
|
#
|
932
1317
|
# fetchTrades
|
933
1318
|
#
|
1319
|
+
# spot:
|
1320
|
+
#
|
934
1321
|
# {
|
935
1322
|
# "id" : "60014521",
|
936
1323
|
# "price" : "23162.94",
|
@@ -941,8 +1328,21 @@ class poloniex(Exchange, ImplicitAPI):
|
|
941
1328
|
# "createTime" : 1659684602036
|
942
1329
|
# }
|
943
1330
|
#
|
1331
|
+
# swap:
|
1332
|
+
#
|
1333
|
+
# {
|
1334
|
+
# "id": "105807376",
|
1335
|
+
# "side": "buy",
|
1336
|
+
# "px": "84410.57",
|
1337
|
+
# "qty": "1",
|
1338
|
+
# "amt": "84.41057",
|
1339
|
+
# "cT": "1740777563557",
|
1340
|
+
# }
|
1341
|
+
#
|
944
1342
|
# fetchMyTrades
|
945
1343
|
#
|
1344
|
+
# spot:
|
1345
|
+
#
|
946
1346
|
# {
|
947
1347
|
# "id": "32164924331503616",
|
948
1348
|
# "symbol": "LINK_USDT",
|
@@ -961,6 +1361,34 @@ class poloniex(Exchange, ImplicitAPI):
|
|
961
1361
|
# "clientOrderId": "myOwnId-321"
|
962
1362
|
# }
|
963
1363
|
#
|
1364
|
+
# swap:
|
1365
|
+
#
|
1366
|
+
# {
|
1367
|
+
# "symbol": "BTC_USDT_PERP",
|
1368
|
+
# "trdId": "105813553",
|
1369
|
+
# "side": "SELL",
|
1370
|
+
# "type": "TRADE",
|
1371
|
+
# "mgnMode": "CROSS",
|
1372
|
+
# "ordType": "MARKET",
|
1373
|
+
# "clOrdId": "polo418912106147315112",
|
1374
|
+
# "role": "TAKER",
|
1375
|
+
# "px": "84704.9",
|
1376
|
+
# "qty": "1",
|
1377
|
+
# "cTime": "1740842829430",
|
1378
|
+
# "uTime": "1740842829450",
|
1379
|
+
# "feeCcy": "USDT",
|
1380
|
+
# "feeAmt": "0.04235245",
|
1381
|
+
# "deductCcy": "",
|
1382
|
+
# "deductAmt": "0",
|
1383
|
+
# "feeRate": "0.0005",
|
1384
|
+
# "id": "418912106342654592",
|
1385
|
+
# "posSide": "BOTH",
|
1386
|
+
# "ordId": "418912106147315112",
|
1387
|
+
# "qCcy": "USDT",
|
1388
|
+
# "value": "84.7049",
|
1389
|
+
# "actType": "TRADING"
|
1390
|
+
# },
|
1391
|
+
#
|
964
1392
|
# fetchOrderTrades(taker trades)
|
965
1393
|
#
|
966
1394
|
# {
|
@@ -981,20 +1409,19 @@ class poloniex(Exchange, ImplicitAPI):
|
|
981
1409
|
# "clientOrderId": ""
|
982
1410
|
# }
|
983
1411
|
#
|
984
|
-
|
985
|
-
|
986
|
-
|
987
|
-
timestamp = self.safe_integer_2(trade, 'ts', 'createTime')
|
1412
|
+
id = self.safe_string_n(trade, ['id', 'tradeID', 'trdId'])
|
1413
|
+
orderId = self.safe_string_2(trade, 'orderId', 'ordId')
|
1414
|
+
timestamp = self.safe_integer_n(trade, ['ts', 'createTime', 'cT', 'cTime'])
|
988
1415
|
marketId = self.safe_string(trade, 'symbol')
|
989
1416
|
market = self.safe_market(marketId, market, '_')
|
990
1417
|
symbol = market['symbol']
|
991
1418
|
side = self.safe_string_lower_2(trade, 'side', 'takerSide')
|
992
1419
|
fee = None
|
993
|
-
priceString = self.
|
994
|
-
amountString = self.
|
995
|
-
costString = self.
|
996
|
-
feeCurrencyId = self.
|
997
|
-
feeCostString = self.
|
1420
|
+
priceString = self.safe_string_2(trade, 'price', 'px')
|
1421
|
+
amountString = self.safe_string_2(trade, 'quantity', 'qty')
|
1422
|
+
costString = self.safe_string_2(trade, 'amount', 'amt')
|
1423
|
+
feeCurrencyId = self.safe_string_2(trade, 'feeCurrency', 'feeCcy')
|
1424
|
+
feeCostString = self.safe_string_2(trade, 'feeAmount', 'feeAmt')
|
998
1425
|
if feeCostString is not None:
|
999
1426
|
feeCurrencyCode = self.safe_currency_code(feeCurrencyId)
|
1000
1427
|
fee = {
|
@@ -1008,9 +1435,9 @@ class poloniex(Exchange, ImplicitAPI):
|
|
1008
1435
|
'datetime': self.iso8601(timestamp),
|
1009
1436
|
'symbol': symbol,
|
1010
1437
|
'order': orderId,
|
1011
|
-
'type': self.
|
1438
|
+
'type': self.safe_string_lower_2(trade, 'ordType', 'type'), # ordType should take precedence
|
1012
1439
|
'side': side,
|
1013
|
-
'takerOrMaker': self.
|
1440
|
+
'takerOrMaker': self.safe_string_lower_2(trade, 'matchRole', 'role'),
|
1014
1441
|
'price': priceString,
|
1015
1442
|
'amount': amountString,
|
1016
1443
|
'cost': costString,
|
@@ -1022,6 +1449,7 @@ class poloniex(Exchange, ImplicitAPI):
|
|
1022
1449
|
get the list of most recent trades for a particular symbol
|
1023
1450
|
|
1024
1451
|
https://api-docs.poloniex.com/spot/api/public/market-data#trades
|
1452
|
+
https://api-docs.poloniex.com/v3/futures/api/market/get-execution-info
|
1025
1453
|
|
1026
1454
|
:param str symbol: unified symbol of the market to fetch trades for
|
1027
1455
|
:param int [since]: timestamp in ms of the earliest trade to fetch
|
@@ -1035,7 +1463,25 @@ class poloniex(Exchange, ImplicitAPI):
|
|
1035
1463
|
'symbol': market['id'],
|
1036
1464
|
}
|
1037
1465
|
if limit is not None:
|
1038
|
-
request['limit'] = limit
|
1466
|
+
request['limit'] = limit # max 1000, for spot & swap
|
1467
|
+
if market['contract']:
|
1468
|
+
response = await self.swapPublicGetV3MarketTrades(self.extend(request, params))
|
1469
|
+
#
|
1470
|
+
# {
|
1471
|
+
# code: "200",
|
1472
|
+
# msg: "Success",
|
1473
|
+
# data: [
|
1474
|
+
# {
|
1475
|
+
# id: "105807320", # descending order
|
1476
|
+
# side: "sell",
|
1477
|
+
# px: "84383.93",
|
1478
|
+
# qty: "1",
|
1479
|
+
# amt: "84.38393",
|
1480
|
+
# cT: "1740777074704",
|
1481
|
+
# },
|
1482
|
+
#
|
1483
|
+
tradesList = self.safe_list(response, 'data')
|
1484
|
+
return self.parse_trades(tradesList, market, since, limit)
|
1039
1485
|
trades = await self.publicGetMarketsSymbolTrades(self.extend(request, params))
|
1040
1486
|
#
|
1041
1487
|
# [
|
@@ -1057,6 +1503,7 @@ class poloniex(Exchange, ImplicitAPI):
|
|
1057
1503
|
fetch all trades made by the user
|
1058
1504
|
|
1059
1505
|
https://api-docs.poloniex.com/spot/api/private/trade#trade-history
|
1506
|
+
https://api-docs.poloniex.com/v3/futures/api/trade/get-execution-details
|
1060
1507
|
|
1061
1508
|
:param str symbol: unified market symbol
|
1062
1509
|
:param int [since]: the earliest time in ms to fetch trades for
|
@@ -1074,15 +1521,57 @@ class poloniex(Exchange, ImplicitAPI):
|
|
1074
1521
|
market: Market = None
|
1075
1522
|
if symbol is not None:
|
1076
1523
|
market = self.market(symbol)
|
1524
|
+
marketType = None
|
1525
|
+
marketType, params = self.handle_market_type_and_params('fetchMyTrades', market, params)
|
1526
|
+
isContract = self.in_array(marketType, ['swap', 'future'])
|
1077
1527
|
request: dict = {
|
1078
1528
|
# 'from': 12345678, # A 'trade Id'. The query begins at ‘from'.
|
1079
1529
|
# 'direction': 'PRE', # PRE, NEXT The direction before or after ‘from'.
|
1080
1530
|
}
|
1531
|
+
startKey = 'sTime' if isContract else 'startTime'
|
1532
|
+
endKey = 'eTime' if isContract else 'endTime'
|
1081
1533
|
if since is not None:
|
1082
|
-
request[
|
1534
|
+
request[startKey] = since
|
1083
1535
|
if limit is not None:
|
1084
1536
|
request['limit'] = limit
|
1085
|
-
|
1537
|
+
if isContract and symbol is not None:
|
1538
|
+
request['symbol'] = market['id']
|
1539
|
+
request, params = self.handle_until_option(endKey, request, params)
|
1540
|
+
if isContract:
|
1541
|
+
raw = await self.swapPrivateGetV3TradeOrderTrades(self.extend(request, params))
|
1542
|
+
#
|
1543
|
+
# {
|
1544
|
+
# "code": "200",
|
1545
|
+
# "msg": "",
|
1546
|
+
# "data": [
|
1547
|
+
# {
|
1548
|
+
# "symbol": "BTC_USDT_PERP",
|
1549
|
+
# "trdId": "105813553",
|
1550
|
+
# "side": "SELL",
|
1551
|
+
# "type": "TRADE",
|
1552
|
+
# "mgnMode": "CROSS",
|
1553
|
+
# "ordType": "MARKET",
|
1554
|
+
# "clOrdId": "polo418912106147315112",
|
1555
|
+
# "role": "TAKER",
|
1556
|
+
# "px": "84704.9",
|
1557
|
+
# "qty": "1",
|
1558
|
+
# "cTime": "1740842829430",
|
1559
|
+
# "uTime": "1740842829450",
|
1560
|
+
# "feeCcy": "USDT",
|
1561
|
+
# "feeAmt": "0.04235245",
|
1562
|
+
# "deductCcy": "",
|
1563
|
+
# "deductAmt": "0",
|
1564
|
+
# "feeRate": "0.0005",
|
1565
|
+
# "id": "418912106342654592",
|
1566
|
+
# "posSide": "BOTH",
|
1567
|
+
# "ordId": "418912106147315112",
|
1568
|
+
# "qCcy": "USDT",
|
1569
|
+
# "value": "84.7049",
|
1570
|
+
# "actType": "TRADING"
|
1571
|
+
# },
|
1572
|
+
#
|
1573
|
+
data = self.safe_list(raw, 'data')
|
1574
|
+
return self.parse_trades(data, market, since, limit)
|
1086
1575
|
response = await self.privateGetTrades(self.extend(request, params))
|
1087
1576
|
#
|
1088
1577
|
# [
|
@@ -1143,7 +1632,9 @@ class poloniex(Exchange, ImplicitAPI):
|
|
1143
1632
|
# "updateTime" : 16xxxxxxxxx36
|
1144
1633
|
# }
|
1145
1634
|
#
|
1146
|
-
# fetchOpenOrders
|
1635
|
+
# fetchOpenOrders(and fetchClosedOrders same for contracts)
|
1636
|
+
#
|
1637
|
+
# spot:
|
1147
1638
|
#
|
1148
1639
|
# {
|
1149
1640
|
# "id": "24993088082542592",
|
@@ -1164,14 +1655,60 @@ class poloniex(Exchange, ImplicitAPI):
|
|
1164
1655
|
# "updateTime": 1646925216548
|
1165
1656
|
# }
|
1166
1657
|
#
|
1658
|
+
# contract:
|
1659
|
+
#
|
1660
|
+
# {
|
1661
|
+
# "symbol": "BTC_USDT_PERP",
|
1662
|
+
# "side": "BUY",
|
1663
|
+
# "type": "LIMIT",
|
1664
|
+
# "ordId": "418890767248232148",
|
1665
|
+
# "clOrdId": "polo418890767248232148",
|
1666
|
+
# "mgnMode": "CROSS",
|
1667
|
+
# "px": "81130.13",
|
1668
|
+
# "reduceOnly": False,
|
1669
|
+
# "lever": "20",
|
1670
|
+
# "state": "NEW",
|
1671
|
+
# "source": "WEB",
|
1672
|
+
# "timeInForce": "GTC",
|
1673
|
+
# "tpTrgPx": "",
|
1674
|
+
# "tpPx": "",
|
1675
|
+
# "tpTrgPxType": "",
|
1676
|
+
# "slTrgPx": "",
|
1677
|
+
# "slPx": "",
|
1678
|
+
# "slTrgPxType": "",
|
1679
|
+
# "avgPx": "0",
|
1680
|
+
# "execQty": "0",
|
1681
|
+
# "execAmt": "0",
|
1682
|
+
# "feeCcy": "",
|
1683
|
+
# "feeAmt": "0",
|
1684
|
+
# "deductCcy": "0",
|
1685
|
+
# "deductAmt": "0",
|
1686
|
+
# "stpMode": "NONE", # todo: selfTradePrevention
|
1687
|
+
# "cTime": "1740837741523",
|
1688
|
+
# "uTime": "1740840846882",
|
1689
|
+
# "sz": "1",
|
1690
|
+
# "posSide": "BOTH",
|
1691
|
+
# "qCcy": "USDT"
|
1692
|
+
# "cancelReason": "", # self field can only be in closed orders
|
1693
|
+
# },
|
1694
|
+
#
|
1167
1695
|
# createOrder, editOrder
|
1168
1696
|
#
|
1697
|
+
# spot:
|
1698
|
+
#
|
1169
1699
|
# {
|
1170
1700
|
# "id": "29772698821328896",
|
1171
1701
|
# "clientOrderId": "1234Abc"
|
1172
1702
|
# }
|
1173
1703
|
#
|
1174
|
-
|
1704
|
+
# contract:
|
1705
|
+
#
|
1706
|
+
# {
|
1707
|
+
# "ordId":"418876147745775616",
|
1708
|
+
# "clOrdId":"polo418876147745775616"
|
1709
|
+
# }
|
1710
|
+
#
|
1711
|
+
timestamp = self.safe_integer_n(order, ['timestamp', 'createTime', 'cTime'])
|
1175
1712
|
if timestamp is None:
|
1176
1713
|
timestamp = self.parse8601(self.safe_string(order, 'date'))
|
1177
1714
|
marketId = self.safe_string(order, 'symbol')
|
@@ -1181,16 +1718,16 @@ class poloniex(Exchange, ImplicitAPI):
|
|
1181
1718
|
if resultingTrades is not None:
|
1182
1719
|
if not isinstance(resultingTrades, list):
|
1183
1720
|
resultingTrades = self.safe_value(resultingTrades, self.safe_string(market, 'id', marketId))
|
1184
|
-
price = self.
|
1185
|
-
amount = self.
|
1186
|
-
filled = self.
|
1721
|
+
price = self.safe_string_n(order, ['price', 'rate', 'px'])
|
1722
|
+
amount = self.safe_string_2(order, 'quantity', 'sz')
|
1723
|
+
filled = self.safe_string_2(order, 'filledQuantity', 'execQty')
|
1187
1724
|
status = self.parse_order_status(self.safe_string(order, 'state'))
|
1188
1725
|
side = self.safe_string_lower(order, 'side')
|
1189
1726
|
rawType = self.safe_string(order, 'type')
|
1190
1727
|
type = self.parse_order_type(rawType)
|
1191
|
-
id = self.safe_string_n(order, ['orderNumber', 'id', 'orderId'])
|
1728
|
+
id = self.safe_string_n(order, ['orderNumber', 'id', 'orderId', 'ordId'])
|
1192
1729
|
fee = None
|
1193
|
-
feeCurrency = self.
|
1730
|
+
feeCurrency = self.safe_string_2(order, 'tokenFeeCurrency', 'feeCcy')
|
1194
1731
|
feeCost: Str = None
|
1195
1732
|
feeCurrencyCode: Str = None
|
1196
1733
|
rate = self.safe_string(order, 'fee')
|
@@ -1199,14 +1736,18 @@ class poloniex(Exchange, ImplicitAPI):
|
|
1199
1736
|
else:
|
1200
1737
|
# poloniex accepts a 30% discount to pay fees in TRX
|
1201
1738
|
feeCurrencyCode = self.safe_currency_code(feeCurrency)
|
1202
|
-
feeCost = self.
|
1739
|
+
feeCost = self.safe_string_2(order, 'tokenFee', 'feeAmt')
|
1203
1740
|
if feeCost is not None:
|
1204
1741
|
fee = {
|
1205
1742
|
'rate': rate,
|
1206
1743
|
'cost': feeCost,
|
1207
1744
|
'currency': feeCurrencyCode,
|
1208
1745
|
}
|
1209
|
-
clientOrderId = self.
|
1746
|
+
clientOrderId = self.safe_string_2(order, 'clientOrderId', 'clOrdId')
|
1747
|
+
marginMode = self.safe_string_lower(order, 'mgnMode')
|
1748
|
+
reduceOnly = self.safe_bool(order, 'reduceOnly')
|
1749
|
+
leverage = self.safe_integer(order, 'lever')
|
1750
|
+
hedged = self.safe_string(order, 'posSide') != 'BOTH'
|
1210
1751
|
return self.safe_order({
|
1211
1752
|
'info': order,
|
1212
1753
|
'id': id,
|
@@ -1218,23 +1759,28 @@ class poloniex(Exchange, ImplicitAPI):
|
|
1218
1759
|
'symbol': symbol,
|
1219
1760
|
'type': type,
|
1220
1761
|
'timeInForce': self.safe_string(order, 'timeInForce'),
|
1221
|
-
'postOnly':
|
1762
|
+
'postOnly': rawType == 'LIMIT_MAKER',
|
1222
1763
|
'side': side,
|
1223
1764
|
'price': price,
|
1224
1765
|
'triggerPrice': self.safe_string_2(order, 'triggerPrice', 'stopPrice'),
|
1225
|
-
'cost':
|
1226
|
-
'average': self.
|
1766
|
+
'cost': self.safe_string(order, 'execAmt'),
|
1767
|
+
'average': self.safe_string_2(order, 'avgPrice', 'avgPx'),
|
1227
1768
|
'amount': amount,
|
1228
1769
|
'filled': filled,
|
1229
1770
|
'remaining': None,
|
1230
1771
|
'trades': resultingTrades,
|
1231
1772
|
'fee': fee,
|
1773
|
+
'marginMode': marginMode,
|
1774
|
+
'reduceOnly': reduceOnly,
|
1775
|
+
'leverage': leverage,
|
1776
|
+
'hedged': hedged,
|
1232
1777
|
}, market)
|
1233
1778
|
|
1234
1779
|
def parse_order_type(self, status):
|
1235
1780
|
statuses: dict = {
|
1236
1781
|
'MARKET': 'market',
|
1237
1782
|
'LIMIT': 'limit',
|
1783
|
+
'LIMIT_MAKER': 'limit',
|
1238
1784
|
'STOP-LIMIT': 'limit',
|
1239
1785
|
'STOP-MARKET': 'market',
|
1240
1786
|
}
|
@@ -1258,6 +1804,7 @@ class poloniex(Exchange, ImplicitAPI):
|
|
1258
1804
|
|
1259
1805
|
https://api-docs.poloniex.com/spot/api/private/order#open-orders
|
1260
1806
|
https://api-docs.poloniex.com/spot/api/private/smart-order#open-orders # trigger orders
|
1807
|
+
https://api-docs.poloniex.com/v3/futures/api/trade/get-current-orders
|
1261
1808
|
|
1262
1809
|
:param str symbol: unified market symbol
|
1263
1810
|
:param int [since]: the earliest time in ms to fetch open orders for
|
@@ -1272,12 +1819,57 @@ class poloniex(Exchange, ImplicitAPI):
|
|
1272
1819
|
if symbol is not None:
|
1273
1820
|
market = self.market(symbol)
|
1274
1821
|
request['symbol'] = market['id']
|
1822
|
+
marketType = None
|
1823
|
+
marketType, params = self.handle_market_type_and_params('fetchOpenOrders', market, params)
|
1275
1824
|
if limit is not None:
|
1276
|
-
|
1825
|
+
max = 2000 if (marketType == 'spot') else 100
|
1826
|
+
request['limit'] = max(limit, max)
|
1277
1827
|
isTrigger = self.safe_value_2(params, 'trigger', 'stop')
|
1278
1828
|
params = self.omit(params, ['trigger', 'stop'])
|
1279
1829
|
response = None
|
1280
|
-
if
|
1830
|
+
if not market['spot']:
|
1831
|
+
raw = await self.swapPrivateGetV3TradeOrderOpens(self.extend(request, params))
|
1832
|
+
#
|
1833
|
+
# {
|
1834
|
+
# "code": "200",
|
1835
|
+
# "msg": "",
|
1836
|
+
# "data": [
|
1837
|
+
# {
|
1838
|
+
# "symbol": "BTC_USDT_PERP",
|
1839
|
+
# "side": "BUY",
|
1840
|
+
# "type": "LIMIT",
|
1841
|
+
# "ordId": "418890767248232148",
|
1842
|
+
# "clOrdId": "polo418890767248232148",
|
1843
|
+
# "mgnMode": "CROSS",
|
1844
|
+
# "px": "81130.13",
|
1845
|
+
# "reduceOnly": False,
|
1846
|
+
# "lever": "20",
|
1847
|
+
# "state": "NEW",
|
1848
|
+
# "source": "WEB",
|
1849
|
+
# "timeInForce": "GTC",
|
1850
|
+
# "tpTrgPx": "",
|
1851
|
+
# "tpPx": "",
|
1852
|
+
# "tpTrgPxType": "",
|
1853
|
+
# "slTrgPx": "",
|
1854
|
+
# "slPx": "",
|
1855
|
+
# "slTrgPxType": "",
|
1856
|
+
# "avgPx": "0",
|
1857
|
+
# "execQty": "0",
|
1858
|
+
# "execAmt": "0",
|
1859
|
+
# "feeCcy": "",
|
1860
|
+
# "feeAmt": "0",
|
1861
|
+
# "deductCcy": "0",
|
1862
|
+
# "deductAmt": "0",
|
1863
|
+
# "stpMode": "NONE",
|
1864
|
+
# "cTime": "1740837741523",
|
1865
|
+
# "uTime": "1740840846882",
|
1866
|
+
# "sz": "1",
|
1867
|
+
# "posSide": "BOTH",
|
1868
|
+
# "qCcy": "USDT"
|
1869
|
+
# },
|
1870
|
+
#
|
1871
|
+
response = self.safe_list(raw, 'data')
|
1872
|
+
elif isTrigger:
|
1281
1873
|
response = await self.privateGetSmartorders(self.extend(request, params))
|
1282
1874
|
else:
|
1283
1875
|
response = await self.privateGetOrders(self.extend(request, params))
|
@@ -1307,6 +1899,78 @@ class poloniex(Exchange, ImplicitAPI):
|
|
1307
1899
|
extension: dict = {'status': 'open'}
|
1308
1900
|
return self.parse_orders(response, market, since, limit, extension)
|
1309
1901
|
|
1902
|
+
async def fetch_closed_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
1903
|
+
"""
|
1904
|
+
|
1905
|
+
https://api-docs.poloniex.com/v3/futures/api/trade/get-order-history
|
1906
|
+
|
1907
|
+
fetches information on multiple closed orders made by the user
|
1908
|
+
:param str symbol: unified market symbol of the market orders were made in
|
1909
|
+
:param int [since]: the earliest time in ms to fetch orders for
|
1910
|
+
:param int [limit]: the maximum number of order structures to retrieve
|
1911
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1912
|
+
:param int [params.until]: timestamp in ms of the latest entry
|
1913
|
+
:returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
1914
|
+
"""
|
1915
|
+
await self.load_markets()
|
1916
|
+
market = None
|
1917
|
+
request: dict = {}
|
1918
|
+
if symbol is not None:
|
1919
|
+
market = self.market(symbol)
|
1920
|
+
request['symbol'] = market['id']
|
1921
|
+
marketType = None
|
1922
|
+
marketType, params = self.handle_market_type_and_params('fetchClosedOrders', market, params, 'swap')
|
1923
|
+
if marketType == 'spot':
|
1924
|
+
raise NotSupported(self.id + ' fetchClosedOrders() is not supported for spot markets yet')
|
1925
|
+
if limit is not None:
|
1926
|
+
request['limit'] = min(200, limit)
|
1927
|
+
if since is not None:
|
1928
|
+
request['sTime'] = since
|
1929
|
+
request, params = self.handle_until_option('eTime', request, params)
|
1930
|
+
response = await self.swapPrivateGetV3TradeOrderHistory(self.extend(request, params))
|
1931
|
+
#
|
1932
|
+
# {
|
1933
|
+
# "code": "200",
|
1934
|
+
# "msg": "",
|
1935
|
+
# "data": [
|
1936
|
+
# {
|
1937
|
+
# "symbol": "BTC_USDT_PERP",
|
1938
|
+
# "side": "SELL",
|
1939
|
+
# "type": "MARKET",
|
1940
|
+
# "ordId": "418912106147315712",
|
1941
|
+
# "clOrdId": "polo418912106147315712",
|
1942
|
+
# "mgnMode": "CROSS",
|
1943
|
+
# "px": "0",
|
1944
|
+
# "sz": "2",
|
1945
|
+
# "lever": "20",
|
1946
|
+
# "state": "FILLED",
|
1947
|
+
# "cancelReason": "",
|
1948
|
+
# "source": "WEB",
|
1949
|
+
# "reduceOnly": "true",
|
1950
|
+
# "timeInForce": "GTC",
|
1951
|
+
# "tpTrgPx": "",
|
1952
|
+
# "tpPx": "",
|
1953
|
+
# "tpTrgPxType": "",
|
1954
|
+
# "slTrgPx": "",
|
1955
|
+
# "slPx": "",
|
1956
|
+
# "slTrgPxType": "",
|
1957
|
+
# "avgPx": "84705.56",
|
1958
|
+
# "execQty": "2",
|
1959
|
+
# "execAmt": "169.41112",
|
1960
|
+
# "feeCcy": "USDT",
|
1961
|
+
# "feeAmt": "0.08470556",
|
1962
|
+
# "deductCcy": "0",
|
1963
|
+
# "deductAmt": "0",
|
1964
|
+
# "stpMode": "NONE",
|
1965
|
+
# "cTime": "1740842829116",
|
1966
|
+
# "uTime": "1740842829130",
|
1967
|
+
# "posSide": "BOTH",
|
1968
|
+
# "qCcy": "USDT"
|
1969
|
+
# },
|
1970
|
+
#
|
1971
|
+
data = self.safe_list(response, 'data', [])
|
1972
|
+
return self.parse_orders(data, market, since, limit)
|
1973
|
+
|
1310
1974
|
async def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
|
1311
1975
|
"""
|
1312
1976
|
create a trade order
|
@@ -1326,19 +1990,23 @@ class poloniex(Exchange, ImplicitAPI):
|
|
1326
1990
|
"""
|
1327
1991
|
await self.load_markets()
|
1328
1992
|
market = self.market(symbol)
|
1329
|
-
if not market['spot']:
|
1330
|
-
raise NotSupported(self.id + ' createOrder() does not support ' + market['type'] + ' orders, only spot orders are accepted')
|
1331
1993
|
request: dict = {
|
1332
1994
|
'symbol': market['id'],
|
1333
|
-
'side': side,
|
1334
|
-
# 'timeInForce': timeInForce,
|
1995
|
+
'side': side.upper(), # uppercase, both for spot & swap
|
1996
|
+
# 'timeInForce': timeInForce, # matches unified values
|
1335
1997
|
# 'accountType': 'SPOT',
|
1336
1998
|
# 'amount': amount,
|
1337
1999
|
}
|
1338
2000
|
triggerPrice = self.safe_number_2(params, 'stopPrice', 'triggerPrice')
|
1339
2001
|
request, params = self.order_request(symbol, type, side, amount, request, price, params)
|
1340
2002
|
response = None
|
1341
|
-
if
|
2003
|
+
if market['swap'] or market['future']:
|
2004
|
+
responseInitial = await self.swapPrivatePostV3TradeOrder(self.extend(request, params))
|
2005
|
+
#
|
2006
|
+
# {"code":200,"msg":"Success","data":{"ordId":"418876147745775616","clOrdId":"polo418876147745775616"}}
|
2007
|
+
#
|
2008
|
+
response = self.safe_dict(responseInitial, 'data')
|
2009
|
+
elif triggerPrice is not None:
|
1342
2010
|
response = await self.privatePostSmartorders(self.extend(request, params))
|
1343
2011
|
else:
|
1344
2012
|
response = await self.privatePostOrders(self.extend(request, params))
|
@@ -1348,19 +2016,31 @@ class poloniex(Exchange, ImplicitAPI):
|
|
1348
2016
|
# "clientOrderId" : ""
|
1349
2017
|
# }
|
1350
2018
|
#
|
1351
|
-
response = self.extend(response, {
|
1352
|
-
'type': type,
|
1353
|
-
'side': side,
|
1354
|
-
})
|
1355
2019
|
return self.parse_order(response, market)
|
1356
2020
|
|
1357
2021
|
def order_request(self, symbol, type, side, amount, request, price=None, params={}):
|
2022
|
+
triggerPrice = self.safe_number_2(params, 'stopPrice', 'triggerPrice')
|
2023
|
+
market = self.market(symbol)
|
2024
|
+
if market['contract']:
|
2025
|
+
marginMode = None
|
2026
|
+
marginMode, params = self.handle_param_string(params, 'marginMode')
|
2027
|
+
if marginMode is not None:
|
2028
|
+
self.check_required_argument('createOrder', marginMode, 'marginMode', ['cross', 'isolated'])
|
2029
|
+
request['mgnMode'] = marginMode.upper()
|
2030
|
+
hedged = None
|
2031
|
+
hedged, params = self.handle_param_string(params, 'hedged')
|
2032
|
+
if hedged:
|
2033
|
+
if marginMode is None:
|
2034
|
+
raise ArgumentsRequired(self.id + ' createOrder() requires a marginMode parameter "cross" or "isolated" for hedged orders')
|
2035
|
+
if not ('posSide' in params):
|
2036
|
+
raise ArgumentsRequired(self.id + ' createOrder() requires a posSide parameter "LONG" or "SHORT" for hedged orders')
|
1358
2037
|
upperCaseType = type.upper()
|
1359
2038
|
isMarket = upperCaseType == 'MARKET'
|
1360
2039
|
isPostOnly = self.is_post_only(isMarket, upperCaseType == 'LIMIT_MAKER', params)
|
1361
|
-
triggerPrice = self.safe_number_2(params, 'stopPrice', 'triggerPrice')
|
1362
2040
|
params = self.omit(params, ['postOnly', 'triggerPrice', 'stopPrice'])
|
1363
2041
|
if triggerPrice is not None:
|
2042
|
+
if not market['spot']:
|
2043
|
+
raise InvalidOrder(self.id + ' createOrder() does not support trigger orders for ' + market['type'] + ' markets')
|
1364
2044
|
upperCaseType = 'STOP' if (price is None) else 'STOP_LIMIT'
|
1365
2045
|
request['stopPrice'] = triggerPrice
|
1366
2046
|
elif isPostOnly:
|
@@ -1375,7 +2055,7 @@ class poloniex(Exchange, ImplicitAPI):
|
|
1375
2055
|
params = self.omit(params, 'cost')
|
1376
2056
|
if cost is not None:
|
1377
2057
|
quoteAmount = self.cost_to_precision(symbol, cost)
|
1378
|
-
elif createMarketBuyOrderRequiresPrice:
|
2058
|
+
elif createMarketBuyOrderRequiresPrice and market['spot']:
|
1379
2059
|
if price is None:
|
1380
2060
|
raise InvalidOrder(self.id + ' createOrder() requires the price argument for market buy orders to calculate the total cost to spend(amount * price), alternatively set the createMarketBuyOrderRequiresPrice option or param to False and pass the cost to spend(quote quantity) in the amount argument')
|
1381
2061
|
else:
|
@@ -1385,12 +2065,16 @@ class poloniex(Exchange, ImplicitAPI):
|
|
1385
2065
|
quoteAmount = self.cost_to_precision(symbol, costRequest)
|
1386
2066
|
else:
|
1387
2067
|
quoteAmount = self.cost_to_precision(symbol, amount)
|
1388
|
-
|
2068
|
+
amountKey = 'amount' if market['spot'] else 'sz'
|
2069
|
+
request[amountKey] = quoteAmount
|
1389
2070
|
else:
|
1390
|
-
|
2071
|
+
amountKey = 'quantity' if market['spot'] else 'sz'
|
2072
|
+
request[amountKey] = self.amount_to_precision(symbol, amount)
|
1391
2073
|
else:
|
1392
|
-
|
1393
|
-
request[
|
2074
|
+
amountKey = 'quantity' if market['spot'] else 'sz'
|
2075
|
+
request[amountKey] = self.amount_to_precision(symbol, amount)
|
2076
|
+
priceKey = 'price' if market['spot'] else 'px'
|
2077
|
+
request[priceKey] = self.price_to_precision(symbol, price)
|
1394
2078
|
clientOrderId = self.safe_string(params, 'clientOrderId')
|
1395
2079
|
if clientOrderId is not None:
|
1396
2080
|
request['clientOrderId'] = clientOrderId
|
@@ -1456,7 +2140,25 @@ class poloniex(Exchange, ImplicitAPI):
|
|
1456
2140
|
# @returns {object} An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
1457
2141
|
#
|
1458
2142
|
await self.load_markets()
|
2143
|
+
if symbol is None:
|
2144
|
+
raise ArgumentsRequired(self.id + ' cancelOrder() requires a symbol argument')
|
2145
|
+
market = self.market(symbol)
|
1459
2146
|
request: dict = {}
|
2147
|
+
if not market['spot']:
|
2148
|
+
request['symbol'] = market['id']
|
2149
|
+
request['ordId'] = id
|
2150
|
+
raw = await self.swapPrivateDeleteV3TradeOrder(self.extend(request, params))
|
2151
|
+
#
|
2152
|
+
# {
|
2153
|
+
# "code": "200",
|
2154
|
+
# "msg": "Success",
|
2155
|
+
# "data": {
|
2156
|
+
# "ordId": "418886099910612040",
|
2157
|
+
# "clOrdId": "polo418886099910612040"
|
2158
|
+
# }
|
2159
|
+
# }
|
2160
|
+
#
|
2161
|
+
return self.parse_order(self.safe_dict(raw, 'data'))
|
1460
2162
|
clientOrderId = self.safe_value(params, 'clientOrderId')
|
1461
2163
|
if clientOrderId is not None:
|
1462
2164
|
id = clientOrderId
|
@@ -1485,6 +2187,7 @@ class poloniex(Exchange, ImplicitAPI):
|
|
1485
2187
|
|
1486
2188
|
https://api-docs.poloniex.com/spot/api/private/order#cancel-all-orders
|
1487
2189
|
https://api-docs.poloniex.com/spot/api/private/smart-order#cancel-all-orders # trigger orders
|
2190
|
+
https://api-docs.poloniex.com/v3/futures/api/trade/cancel-all-orders - contract markets
|
1488
2191
|
|
1489
2192
|
:param str symbol: unified market symbol, only orders in the market of self symbol are cancelled when symbol is not None
|
1490
2193
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -1502,9 +2205,29 @@ class poloniex(Exchange, ImplicitAPI):
|
|
1502
2205
|
request['symbols'] = [
|
1503
2206
|
market['id'],
|
1504
2207
|
]
|
2208
|
+
response = None
|
2209
|
+
marketType = None
|
2210
|
+
marketType, params = self.handle_market_type_and_params('cancelAllOrders', market, params)
|
2211
|
+
if marketType == 'swap' or marketType == 'future':
|
2212
|
+
raw = await self.swapPrivateDeleteV3TradeAllOrders(self.extend(request, params))
|
2213
|
+
#
|
2214
|
+
# {
|
2215
|
+
# "code": "200",
|
2216
|
+
# "msg": "Success",
|
2217
|
+
# "data": [
|
2218
|
+
# {
|
2219
|
+
# "code": "200",
|
2220
|
+
# "msg": "Success",
|
2221
|
+
# "ordId": "418885787866388511",
|
2222
|
+
# "clOrdId": "polo418885787866388511"
|
2223
|
+
# }
|
2224
|
+
# ]
|
2225
|
+
# }
|
2226
|
+
#
|
2227
|
+
response = self.safe_list(raw, 'data')
|
2228
|
+
return self.parse_orders(response, market)
|
1505
2229
|
isTrigger = self.safe_value_2(params, 'trigger', 'stop')
|
1506
2230
|
params = self.omit(params, ['trigger', 'stop'])
|
1507
|
-
response = None
|
1508
2231
|
if isTrigger:
|
1509
2232
|
response = await self.privateDeleteSmartorders(self.extend(request, params))
|
1510
2233
|
else:
|
@@ -1546,6 +2269,14 @@ class poloniex(Exchange, ImplicitAPI):
|
|
1546
2269
|
request: dict = {
|
1547
2270
|
'id': id,
|
1548
2271
|
}
|
2272
|
+
market = None
|
2273
|
+
if symbol is not None:
|
2274
|
+
market = self.market(symbol)
|
2275
|
+
request['symbol'] = market['id']
|
2276
|
+
marketType = None
|
2277
|
+
marketType, params = self.handle_market_type_and_params('fetchOrder', market, params)
|
2278
|
+
if marketType != 'spot':
|
2279
|
+
raise NotSupported(self.id + ' fetchOrder() is not supported for ' + marketType + ' markets yet')
|
1549
2280
|
isTrigger = self.safe_value_2(params, 'trigger', 'stop')
|
1550
2281
|
params = self.omit(params, ['trigger', 'stop'])
|
1551
2282
|
response = None
|
@@ -1632,6 +2363,22 @@ class poloniex(Exchange, ImplicitAPI):
|
|
1632
2363
|
'timestamp': None,
|
1633
2364
|
'datetime': None,
|
1634
2365
|
}
|
2366
|
+
# for swap
|
2367
|
+
if not isinstance(response, list):
|
2368
|
+
ts = self.safe_integer(response, 'uTime')
|
2369
|
+
result['timestamp'] = ts
|
2370
|
+
result['datetime'] = self.iso8601(ts)
|
2371
|
+
details = self.safe_list(response, 'details', [])
|
2372
|
+
for i in range(0, len(details)):
|
2373
|
+
balance = details[i]
|
2374
|
+
currencyId = self.safe_string(balance, 'ccy')
|
2375
|
+
code = self.safe_currency_code(currencyId)
|
2376
|
+
account = self.account()
|
2377
|
+
account['total'] = self.safe_string(balance, 'avail')
|
2378
|
+
account['used'] = self.safe_string(balance, 'im')
|
2379
|
+
result[code] = account
|
2380
|
+
return self.safe_balance(result)
|
2381
|
+
# for spot
|
1635
2382
|
for i in range(0, len(response)):
|
1636
2383
|
account = self.safe_value(response, i, {})
|
1637
2384
|
balances = self.safe_value(account, 'balances')
|
@@ -1650,11 +2397,55 @@ class poloniex(Exchange, ImplicitAPI):
|
|
1650
2397
|
query for balance and get the amount of funds available for trading or funds locked in orders
|
1651
2398
|
|
1652
2399
|
https://api-docs.poloniex.com/spot/api/private/account#all-account-balances
|
2400
|
+
https://api-docs.poloniex.com/v3/futures/api/account/balance
|
1653
2401
|
|
1654
2402
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1655
2403
|
:returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
|
1656
2404
|
"""
|
1657
2405
|
await self.load_markets()
|
2406
|
+
marketType = None
|
2407
|
+
marketType, params = self.handle_market_type_and_params('fetchBalance', None, params)
|
2408
|
+
if marketType != 'spot':
|
2409
|
+
responseRaw = await self.swapPrivateGetV3AccountBalance(params)
|
2410
|
+
#
|
2411
|
+
# {
|
2412
|
+
# "code": "200",
|
2413
|
+
# "msg": "",
|
2414
|
+
# "data": {
|
2415
|
+
# "state": "NORMAL",
|
2416
|
+
# "eq": "9.98571622",
|
2417
|
+
# "isoEq": "0",
|
2418
|
+
# "im": "0",
|
2419
|
+
# "mm": "0",
|
2420
|
+
# "mmr": "0",
|
2421
|
+
# "upl": "0",
|
2422
|
+
# "availMgn": "9.98571622",
|
2423
|
+
# "cTime": "1738093601775",
|
2424
|
+
# "uTime": "1740829116236",
|
2425
|
+
# "details": [
|
2426
|
+
# {
|
2427
|
+
# "ccy": "USDT",
|
2428
|
+
# "eq": "9.98571622",
|
2429
|
+
# "isoEq": "0",
|
2430
|
+
# "avail": "9.98571622",
|
2431
|
+
# "trdHold": "0",
|
2432
|
+
# "upl": "0",
|
2433
|
+
# "isoAvail": "0",
|
2434
|
+
# "isoHold": "0",
|
2435
|
+
# "isoUpl": "0",
|
2436
|
+
# "im": "0",
|
2437
|
+
# "mm": "0",
|
2438
|
+
# "mmr": "0",
|
2439
|
+
# "imr": "0",
|
2440
|
+
# "cTime": "1740829116236",
|
2441
|
+
# "uTime": "1740829116236"
|
2442
|
+
# }
|
2443
|
+
# ]
|
2444
|
+
# }
|
2445
|
+
# }
|
2446
|
+
#
|
2447
|
+
data = self.safe_dict(responseRaw, 'data', {})
|
2448
|
+
return self.parse_balance(data)
|
1658
2449
|
request: dict = {
|
1659
2450
|
'accountType': 'SPOT',
|
1660
2451
|
}
|
@@ -1714,6 +2505,7 @@ class poloniex(Exchange, ImplicitAPI):
|
|
1714
2505
|
fetches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
1715
2506
|
|
1716
2507
|
https://api-docs.poloniex.com/spot/api/public/market-data#order-book
|
2508
|
+
https://api-docs.poloniex.com/v3/futures/api/market/get-order-book
|
1717
2509
|
|
1718
2510
|
:param str symbol: unified symbol of the market to fetch the order book for
|
1719
2511
|
:param int [limit]: the maximum amount of order book entries to return
|
@@ -1727,6 +2519,25 @@ class poloniex(Exchange, ImplicitAPI):
|
|
1727
2519
|
}
|
1728
2520
|
if limit is not None:
|
1729
2521
|
request['limit'] = limit # The default value of limit is 10. Valid limit values are: 5, 10, 20, 50, 100, 150.
|
2522
|
+
if market['contract']:
|
2523
|
+
request['limit'] = self.find_nearest_ceiling([5, 10, 20, 100, 150], limit)
|
2524
|
+
if market['contract']:
|
2525
|
+
responseRaw = await self.swapPublicGetV3MarketOrderBook(self.extend(request, params))
|
2526
|
+
#
|
2527
|
+
# {
|
2528
|
+
# "code": 200,
|
2529
|
+
# "data": {
|
2530
|
+
# "asks": [["58700", "9934"], ..],
|
2531
|
+
# "bids": [["58600", "9952"], ..],
|
2532
|
+
# "s": "100",
|
2533
|
+
# "ts": 1719974138333
|
2534
|
+
# },
|
2535
|
+
# "msg": "Success"
|
2536
|
+
# }
|
2537
|
+
#
|
2538
|
+
data = self.safe_dict(responseRaw, 'data', {})
|
2539
|
+
ts = self.safe_integer(data, 'ts')
|
2540
|
+
return self.parse_order_book(data, symbol, ts)
|
1730
2541
|
response = await self.publicGetMarketsSymbolOrderBook(self.extend(request, params))
|
1731
2542
|
#
|
1732
2543
|
# {
|
@@ -2300,14 +3111,381 @@ class poloniex(Exchange, ImplicitAPI):
|
|
2300
3111
|
},
|
2301
3112
|
}
|
2302
3113
|
|
3114
|
+
async def set_leverage(self, leverage: Int, symbol: Str = None, params={}):
|
3115
|
+
"""
|
3116
|
+
set the level of leverage for a market
|
3117
|
+
|
3118
|
+
https://api-docs.poloniex.com/v3/futures/api/positions/set-leverage
|
3119
|
+
|
3120
|
+
:param int leverage: the rate of leverage
|
3121
|
+
:param str symbol: unified market symbol
|
3122
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
3123
|
+
:param str [params.marginMode]: 'cross' or 'isolated'
|
3124
|
+
:returns dict: response from the exchange
|
3125
|
+
"""
|
3126
|
+
if symbol is None:
|
3127
|
+
raise ArgumentsRequired(self.id + ' setLeverage() requires a symbol argument')
|
3128
|
+
await self.load_markets()
|
3129
|
+
market = self.market(symbol)
|
3130
|
+
marginMode = None
|
3131
|
+
marginMode, params = self.handle_margin_mode_and_params('setLeverage', params)
|
3132
|
+
if marginMode is None:
|
3133
|
+
raise ArgumentsRequired(self.id + ' setLeverage() requires a marginMode parameter "cross" or "isolated"')
|
3134
|
+
hedged: Bool = None
|
3135
|
+
hedged, params = self.handle_param_bool(params, 'hedged', False)
|
3136
|
+
if hedged:
|
3137
|
+
if not ('posSide' in params):
|
3138
|
+
raise ArgumentsRequired(self.id + ' setLeverage() requires a posSide parameter for hedged mode: "LONG" or "SHORT"')
|
3139
|
+
request: dict = {
|
3140
|
+
'lever': leverage,
|
3141
|
+
'mgnMode': marginMode.upper(),
|
3142
|
+
'symbol': market['id'],
|
3143
|
+
}
|
3144
|
+
response = await self.swapPrivatePostV3PositionLeverage(self.extend(request, params))
|
3145
|
+
return response
|
3146
|
+
|
3147
|
+
async def fetch_leverage(self, symbol: str, params={}) -> Leverage:
|
3148
|
+
"""
|
3149
|
+
fetch the set leverage for a market
|
3150
|
+
|
3151
|
+
https://api-docs.poloniex.com/v3/futures/api/positions/get-leverages
|
3152
|
+
|
3153
|
+
:param str symbol: unified market symbol
|
3154
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
3155
|
+
:returns dict: a `leverage structure <https://docs.ccxt.com/#/?id=leverage-structure>`
|
3156
|
+
"""
|
3157
|
+
await self.load_markets()
|
3158
|
+
market = self.market(symbol)
|
3159
|
+
request: dict = {
|
3160
|
+
'symbol': market['id'],
|
3161
|
+
}
|
3162
|
+
marginMode = None
|
3163
|
+
marginMode, params = self.handle_margin_mode_and_params('fetchLeverage', params)
|
3164
|
+
if marginMode is None:
|
3165
|
+
raise ArgumentsRequired(self.id + ' fetchLeverage() requires a marginMode parameter "cross" or "isolated"')
|
3166
|
+
request['mgnMode'] = marginMode.upper()
|
3167
|
+
response = await self.swapPrivateGetV3PositionLeverages(self.extend(request, params))
|
3168
|
+
#
|
3169
|
+
# for one-way mode:
|
3170
|
+
#
|
3171
|
+
# {
|
3172
|
+
# "code": "200",
|
3173
|
+
# "msg": "",
|
3174
|
+
# "data": [
|
3175
|
+
# {
|
3176
|
+
# "symbol": "BTC_USDT_PERP",
|
3177
|
+
# "lever": "10",
|
3178
|
+
# "mgnMode": "CROSS",
|
3179
|
+
# "posSide": "BOTH"
|
3180
|
+
# }
|
3181
|
+
# ]
|
3182
|
+
# }
|
3183
|
+
#
|
3184
|
+
# for hedge:
|
3185
|
+
#
|
3186
|
+
# {
|
3187
|
+
# "code": "200",
|
3188
|
+
# "msg": "",
|
3189
|
+
# "data": [
|
3190
|
+
# {
|
3191
|
+
# "symbol": "BTC_USDT_PERP",
|
3192
|
+
# "lever": "20",
|
3193
|
+
# "mgnMode": "CROSS",
|
3194
|
+
# "posSide": "SHORT"
|
3195
|
+
# },
|
3196
|
+
# {
|
3197
|
+
# "symbol": "BTC_USDT_PERP",
|
3198
|
+
# "lever": "20",
|
3199
|
+
# "mgnMode": "CROSS",
|
3200
|
+
# "posSide": "LONG"
|
3201
|
+
# }
|
3202
|
+
# ]
|
3203
|
+
# }
|
3204
|
+
#
|
3205
|
+
return self.parse_leverage(response, market)
|
3206
|
+
|
3207
|
+
def parse_leverage(self, leverage: dict, market: Market = None) -> Leverage:
|
3208
|
+
shortLeverage: Int = None
|
3209
|
+
longLeverage: Int = None
|
3210
|
+
marketId: Str = None
|
3211
|
+
marginMode: Str = None
|
3212
|
+
data = self.safe_list(leverage, 'data')
|
3213
|
+
for i in range(0, len(data)):
|
3214
|
+
entry = data[i]
|
3215
|
+
marketId = self.safe_string(entry, 'symbol')
|
3216
|
+
marginMode = self.safe_string(entry, 'mgnMode')
|
3217
|
+
lever = self.safe_integer(entry, 'lever')
|
3218
|
+
posSide = self.safe_string(entry, 'posSide')
|
3219
|
+
if posSide == 'LONG':
|
3220
|
+
longLeverage = lever
|
3221
|
+
elif posSide == 'SHORT':
|
3222
|
+
shortLeverage = lever
|
3223
|
+
else:
|
3224
|
+
longLeverage = lever
|
3225
|
+
shortLeverage = lever
|
3226
|
+
return {
|
3227
|
+
'info': leverage,
|
3228
|
+
'symbol': self.safe_symbol(marketId, market),
|
3229
|
+
'marginMode': marginMode,
|
3230
|
+
'longLeverage': longLeverage,
|
3231
|
+
'shortLeverage': shortLeverage,
|
3232
|
+
}
|
3233
|
+
|
3234
|
+
async def fetch_position_mode(self, symbol: Str = None, params={}):
|
3235
|
+
"""
|
3236
|
+
fetchs the position mode, hedged or one way, hedged for binance is set identically for all linear markets or all inverse markets
|
3237
|
+
|
3238
|
+
https://api-docs.poloniex.com/v3/futures/api/positions/position-mode-switch
|
3239
|
+
|
3240
|
+
:param str symbol: unified symbol of the market to fetch the order book for
|
3241
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
3242
|
+
:returns dict: an object detailing whether the market is in hedged or one-way mode
|
3243
|
+
"""
|
3244
|
+
response = await self.swapPrivateGetV3PositionMode(params)
|
3245
|
+
#
|
3246
|
+
# {
|
3247
|
+
# "code": "200",
|
3248
|
+
# "msg": "Success",
|
3249
|
+
# "data": {
|
3250
|
+
# "posMode": "ONE_WAY"
|
3251
|
+
# }
|
3252
|
+
# }
|
3253
|
+
#
|
3254
|
+
data = self.safe_dict(response, 'data', {})
|
3255
|
+
posMode = self.safe_string(data, 'posMode')
|
3256
|
+
hedged = posMode == 'HEDGE'
|
3257
|
+
return {
|
3258
|
+
'info': response,
|
3259
|
+
'hedged': hedged,
|
3260
|
+
}
|
3261
|
+
|
3262
|
+
async def set_position_mode(self, hedged: bool, symbol: Str = None, params={}):
|
3263
|
+
"""
|
3264
|
+
set hedged to True or False for a market
|
3265
|
+
|
3266
|
+
https://api-docs.poloniex.com/v3/futures/api/positions/position-mode-switch
|
3267
|
+
|
3268
|
+
:param bool hedged: set to True to use dualSidePosition
|
3269
|
+
:param str symbol: not used by binance setPositionMode()
|
3270
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
3271
|
+
:returns dict: response from the exchange
|
3272
|
+
"""
|
3273
|
+
mode = 'HEDGE' if hedged else 'ONE_WAY'
|
3274
|
+
request: dict = {
|
3275
|
+
'posMode': mode,
|
3276
|
+
}
|
3277
|
+
response = await self.swapPrivatePostV3PositionMode(self.extend(request, params))
|
3278
|
+
#
|
3279
|
+
# {
|
3280
|
+
# "code": "200",
|
3281
|
+
# "msg": "Success",
|
3282
|
+
# "data": {}
|
3283
|
+
# }
|
3284
|
+
#
|
3285
|
+
return response
|
3286
|
+
|
3287
|
+
async def fetch_positions(self, symbols: Strings = None, params={}):
|
3288
|
+
"""
|
3289
|
+
fetch all open positions
|
3290
|
+
|
3291
|
+
https://api-docs.poloniex.com/v3/futures/api/positions/get-current-position
|
3292
|
+
|
3293
|
+
:param str[]|None symbols: list of unified market symbols
|
3294
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
3295
|
+
:param boolean [params.standard]: whether to fetch standard contract positions
|
3296
|
+
:returns dict[]: a list of `position structures <https://docs.ccxt.com/#/?id=position-structure>`
|
3297
|
+
"""
|
3298
|
+
await self.load_markets()
|
3299
|
+
symbols = self.market_symbols(symbols)
|
3300
|
+
response = await self.swapPrivateGetV3TradePositionOpens(params)
|
3301
|
+
#
|
3302
|
+
# {
|
3303
|
+
# "code": "200",
|
3304
|
+
# "msg": "",
|
3305
|
+
# "data": [
|
3306
|
+
# {
|
3307
|
+
# "symbol": "BTC_USDT_PERP",
|
3308
|
+
# "posSide": "LONG",
|
3309
|
+
# "side": "BUY",
|
3310
|
+
# "mgnMode": "CROSS",
|
3311
|
+
# "openAvgPx": "94193.42",
|
3312
|
+
# "qty": "1",
|
3313
|
+
# "availQty": "1",
|
3314
|
+
# "lever": "20",
|
3315
|
+
# "adl": "0.3007",
|
3316
|
+
# "liqPx": "84918.201844064386317906",
|
3317
|
+
# "im": "4.7047795",
|
3318
|
+
# "mm": "0.56457354",
|
3319
|
+
# "upl": "-0.09783",
|
3320
|
+
# "uplRatio": "-0.0207",
|
3321
|
+
# "pnl": "0",
|
3322
|
+
# "markPx": "94095.59",
|
3323
|
+
# "mgnRatio": "0.0582",
|
3324
|
+
# "state": "NORMAL",
|
3325
|
+
# "cTime": "1740950344401",
|
3326
|
+
# "uTime": "1740950344401",
|
3327
|
+
# "mgn": "4.7047795",
|
3328
|
+
# "actType": "TRADING",
|
3329
|
+
# "maxWAmt": "0",
|
3330
|
+
# "tpTrgPx": "",
|
3331
|
+
# "slTrgPx": ""
|
3332
|
+
# }
|
3333
|
+
# ]
|
3334
|
+
# }
|
3335
|
+
#
|
3336
|
+
positions = self.safe_list(response, 'data', [])
|
3337
|
+
return self.parse_positions(positions, symbols)
|
3338
|
+
|
3339
|
+
def parse_position(self, position: dict, market: Market = None):
|
3340
|
+
#
|
3341
|
+
# {
|
3342
|
+
# "symbol": "BTC_USDT_PERP",
|
3343
|
+
# "posSide": "LONG",
|
3344
|
+
# "side": "BUY",
|
3345
|
+
# "mgnMode": "CROSS",
|
3346
|
+
# "openAvgPx": "94193.42",
|
3347
|
+
# "qty": "1",
|
3348
|
+
# "availQty": "1",
|
3349
|
+
# "lever": "20",
|
3350
|
+
# "adl": "0.3007",
|
3351
|
+
# "liqPx": "84918.201844064386317906",
|
3352
|
+
# "im": "4.7047795",
|
3353
|
+
# "mm": "0.56457354",
|
3354
|
+
# "upl": "-0.09783",
|
3355
|
+
# "uplRatio": "-0.0207",
|
3356
|
+
# "pnl": "0",
|
3357
|
+
# "markPx": "94095.59",
|
3358
|
+
# "mgnRatio": "0.0582",
|
3359
|
+
# "state": "NORMAL",
|
3360
|
+
# "cTime": "1740950344401",
|
3361
|
+
# "uTime": "1740950344401",
|
3362
|
+
# "mgn": "4.7047795",
|
3363
|
+
# "actType": "TRADING",
|
3364
|
+
# "maxWAmt": "0",
|
3365
|
+
# "tpTrgPx": "",
|
3366
|
+
# "slTrgPx": ""
|
3367
|
+
# }
|
3368
|
+
#
|
3369
|
+
marketId = self.safe_string(position, 'symbol')
|
3370
|
+
market = self.safe_market(marketId, market)
|
3371
|
+
timestamp = self.safe_integer(position, 'cTime')
|
3372
|
+
marginMode = self.safe_string_lower(position, 'mgnMode')
|
3373
|
+
leverage = self.safe_string(position, 'lever')
|
3374
|
+
initialMargin = self.safe_string(position, 'im')
|
3375
|
+
notional = Precise.string_mul(leverage, initialMargin)
|
3376
|
+
qty = self.safe_string(position, 'qty')
|
3377
|
+
avgPrice = self.safe_string(position, 'openAvgPx')
|
3378
|
+
collateral = Precise.string_mul(qty, avgPrice)
|
3379
|
+
# todo: some more fields
|
3380
|
+
return self.safe_position({
|
3381
|
+
'info': position,
|
3382
|
+
'id': None,
|
3383
|
+
'symbol': market['symbol'],
|
3384
|
+
'notional': notional,
|
3385
|
+
'marginMode': marginMode,
|
3386
|
+
'liquidationPrice': self.safe_number(position, 'liqPx'),
|
3387
|
+
'entryPrice': self.safe_number(position, 'openAvgPx'),
|
3388
|
+
'unrealizedPnl': self.safe_number(position, 'upl'),
|
3389
|
+
'percentage': None,
|
3390
|
+
'contracts': self.safe_number(position, 'qty'),
|
3391
|
+
'contractSize': None,
|
3392
|
+
'markPrice': self.safe_number(position, 'markPx'),
|
3393
|
+
'lastPrice': None,
|
3394
|
+
'side': self.safe_string_lower(position, 'posSide'),
|
3395
|
+
'hedged': None,
|
3396
|
+
'timestamp': timestamp,
|
3397
|
+
'datetime': self.iso8601(timestamp),
|
3398
|
+
'lastUpdateTimestamp': None,
|
3399
|
+
'maintenanceMargin': self.safe_number(position, 'mm'),
|
3400
|
+
'maintenanceMarginPercentage': None,
|
3401
|
+
'collateral': collateral,
|
3402
|
+
'initialMargin': initialMargin,
|
3403
|
+
'initialMarginPercentage': None,
|
3404
|
+
'leverage': int(leverage),
|
3405
|
+
'marginRatio': self.safe_number(position, 'mgnRatio'),
|
3406
|
+
'stopLossPrice': self.safe_number(position, 'slTrgPx'),
|
3407
|
+
'takeProfitPrice': self.safe_number(position, 'tpTrgPx'),
|
3408
|
+
})
|
3409
|
+
|
3410
|
+
async def modify_margin_helper(self, symbol: str, amount, type, params={}) -> MarginModification:
|
3411
|
+
await self.load_markets()
|
3412
|
+
market = self.market(symbol)
|
3413
|
+
amount = self.amount_to_precision(symbol, amount)
|
3414
|
+
request: dict = {
|
3415
|
+
'symbol': market['id'],
|
3416
|
+
'amt': Precise.string_abs(amount),
|
3417
|
+
'type': type.upper(), # 'ADD' or 'REDUCE'
|
3418
|
+
}
|
3419
|
+
# todo: hedged handling, tricky
|
3420
|
+
if not ('posMode' in params):
|
3421
|
+
request['posMode'] = 'BOTH'
|
3422
|
+
response = await self.swapPrivatePostV3TradePositionMargin(self.extend(request, params))
|
3423
|
+
#
|
3424
|
+
# {
|
3425
|
+
# "code": 200,
|
3426
|
+
# "data": {
|
3427
|
+
# "amt": "50",
|
3428
|
+
# "lever": "20",
|
3429
|
+
# "symbol": "DOT_USDT_PERP",
|
3430
|
+
# "posSide": "BOTH",
|
3431
|
+
# "type": "ADD"
|
3432
|
+
# },
|
3433
|
+
# "msg": "Success"
|
3434
|
+
# }
|
3435
|
+
#
|
3436
|
+
if type == 'reduce':
|
3437
|
+
amount = Precise.string_abs(amount)
|
3438
|
+
data = self.safe_dict(response, 'data')
|
3439
|
+
return self.parse_margin_modification(data, market)
|
3440
|
+
|
3441
|
+
def parse_margin_modification(self, data: dict, market: Market = None) -> MarginModification:
|
3442
|
+
marketId = self.safe_string(data, 'symbol')
|
3443
|
+
market = self.safe_market(marketId, market)
|
3444
|
+
rawType = self.safe_string(data, 'type')
|
3445
|
+
type = 'add' if (rawType == 'ADD') else 'reduce'
|
3446
|
+
return {
|
3447
|
+
'info': data,
|
3448
|
+
'symbol': market['symbol'],
|
3449
|
+
'type': type,
|
3450
|
+
'marginMode': None,
|
3451
|
+
'amount': self.safe_number(data, 'amt'),
|
3452
|
+
'total': None,
|
3453
|
+
'code': None,
|
3454
|
+
'status': 'ok',
|
3455
|
+
'timestamp': None,
|
3456
|
+
'datetime': None,
|
3457
|
+
}
|
3458
|
+
|
3459
|
+
async def reduce_margin(self, symbol: str, amount: float, params={}) -> MarginModification:
|
3460
|
+
"""
|
3461
|
+
remove margin from a position
|
3462
|
+
:param str symbol: unified market symbol
|
3463
|
+
:param float amount: the amount of margin to remove
|
3464
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
3465
|
+
:returns dict: a `margin structure <https://docs.ccxt.com/#/?id=reduce-margin-structure>`
|
3466
|
+
"""
|
3467
|
+
return await self.modify_margin_helper(symbol, -amount, 'reduce', params)
|
3468
|
+
|
3469
|
+
async def add_margin(self, symbol: str, amount: float, params={}) -> MarginModification:
|
3470
|
+
"""
|
3471
|
+
add margin
|
3472
|
+
:param str symbol: unified market symbol
|
3473
|
+
:param float amount: amount of margin to add
|
3474
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
3475
|
+
:returns dict: a `margin structure <https://docs.ccxt.com/#/?id=add-margin-structure>`
|
3476
|
+
"""
|
3477
|
+
return await self.modify_margin_helper(symbol, amount, 'add', params)
|
3478
|
+
|
2303
3479
|
def nonce(self):
|
2304
3480
|
return self.milliseconds()
|
2305
3481
|
|
2306
3482
|
def sign(self, path, api='public', method='GET', params={}, headers=None, body=None):
|
2307
|
-
url = self.urls['api']['
|
3483
|
+
url = self.urls['api']['spot']
|
3484
|
+
if self.in_array(api, ['swapPublic', 'swapPrivate']):
|
3485
|
+
url = self.urls['api']['swap']
|
2308
3486
|
query = self.omit(params, self.extract_params(path))
|
2309
3487
|
implodedPath = self.implode_params(path, params)
|
2310
|
-
if api == 'public':
|
3488
|
+
if api == 'public' or api == 'swapPublic':
|
2311
3489
|
url += '/' + implodedPath
|
2312
3490
|
if query:
|
2313
3491
|
url += '?' + self.urlencode(query)
|