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