ccxt 4.4.70__py2.py3-none-any.whl → 4.4.72__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/ascendex.py +1 -1
- ccxt/async_support/__init__.py +1 -3
- ccxt/async_support/ascendex.py +1 -1
- ccxt/async_support/base/exchange.py +3 -3
- ccxt/async_support/binance.py +107 -102
- ccxt/async_support/bingx.py +65 -43
- ccxt/async_support/bitfinex.py +1 -1
- ccxt/async_support/bitfinex1.py +1 -1
- 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/bl3p.py +2 -2
- ccxt/async_support/cex.py +2 -0
- ccxt/async_support/coinbase.py +3 -2
- ccxt/async_support/coinbaseexchange.py +4 -2
- ccxt/async_support/coinbaseinternational.py +3 -2
- ccxt/async_support/coinex.py +1 -1
- ccxt/async_support/deribit.py +3 -1
- ccxt/async_support/derive.py +11 -7
- ccxt/async_support/gate.py +3 -0
- ccxt/async_support/gemini.py +2 -1
- ccxt/async_support/hashkey.py +4 -2
- ccxt/async_support/hitbtc.py +1 -1
- ccxt/async_support/hyperliquid.py +38 -0
- ccxt/async_support/kraken.py +78 -6
- ccxt/async_support/krakenfutures.py +4 -0
- ccxt/async_support/kucoin.py +5 -3
- ccxt/async_support/kuna.py +1 -1
- ccxt/async_support/mexc.py +9 -5
- ccxt/async_support/ndax.py +1 -1
- ccxt/async_support/okcoin.py +4 -0
- ccxt/async_support/okx.py +79 -76
- ccxt/async_support/paradex.py +65 -7
- ccxt/async_support/paymium.py +1 -1
- ccxt/async_support/poloniex.py +1265 -86
- ccxt/async_support/upbit.py +1 -1
- ccxt/async_support/whitebit.py +102 -4
- ccxt/async_support/woo.py +3 -1
- ccxt/async_support/woofipro.py +1 -1
- ccxt/async_support/yobit.py +2 -1
- ccxt/base/errors.py +6 -0
- ccxt/base/exchange.py +31 -4
- ccxt/base/types.py +28 -0
- ccxt/binance.py +107 -102
- ccxt/bingx.py +65 -43
- ccxt/bitfinex.py +1 -1
- ccxt/bitfinex1.py +1 -1
- ccxt/bitget.py +0 -3
- ccxt/bitmart.py +12 -1
- ccxt/bitopro.py +1 -0
- ccxt/bitrue.py +1 -0
- ccxt/bl3p.py +2 -2
- ccxt/cex.py +2 -0
- ccxt/coinbase.py +3 -2
- ccxt/coinbaseexchange.py +4 -2
- ccxt/coinbaseinternational.py +3 -2
- ccxt/coinex.py +1 -1
- ccxt/deribit.py +3 -1
- ccxt/derive.py +11 -7
- ccxt/gate.py +3 -0
- ccxt/gemini.py +2 -1
- ccxt/hashkey.py +4 -2
- ccxt/hitbtc.py +1 -1
- ccxt/hyperliquid.py +38 -0
- ccxt/kraken.py +78 -6
- ccxt/krakenfutures.py +4 -0
- ccxt/kucoin.py +5 -3
- ccxt/kuna.py +1 -1
- ccxt/mexc.py +9 -5
- ccxt/ndax.py +1 -1
- ccxt/okcoin.py +4 -0
- ccxt/okx.py +79 -76
- ccxt/paradex.py +65 -7
- ccxt/paymium.py +1 -1
- ccxt/poloniex.py +1264 -86
- ccxt/pro/__init__.py +1 -3
- ccxt/pro/binance.py +102 -102
- ccxt/pro/bingx.py +63 -52
- ccxt/pro/bitmart.py +15 -7
- ccxt/pro/derive.py +2 -2
- ccxt/pro/krakenfutures.py +1 -1
- ccxt/test/tests_async.py +1 -0
- ccxt/test/tests_sync.py +1 -0
- ccxt/upbit.py +1 -1
- ccxt/whitebit.py +102 -4
- ccxt/woo.py +3 -1
- ccxt/woofipro.py +1 -1
- ccxt/yobit.py +2 -1
- {ccxt-4.4.70.dist-info → ccxt-4.4.72.dist-info}/METADATA +6 -9
- {ccxt-4.4.70.dist-info → ccxt-4.4.72.dist-info}/RECORD +98 -99
- ccxt/abstract/poloniexfutures.py +0 -48
- {ccxt-4.4.70.dist-info → ccxt-4.4.72.dist-info}/LICENSE.txt +0 -0
- {ccxt-4.4.70.dist-info → ccxt-4.4.72.dist-info}/WHEEL +0 -0
- {ccxt-4.4.70.dist-info → ccxt-4.4.72.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,51 @@ 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
|
+
'symbolRequired': 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 = 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 = 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 = promises
|
727
|
+
return self.array_concat(results[0], results[1])
|
728
|
+
|
729
|
+
def fetch_spot_markets(self, params={}) -> List[Market]:
|
569
730
|
markets = 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
|
+
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 = 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
|
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
|
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 = 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 = 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 = self.fetch_tickers([market['symbol']], params)
|
1289
|
+
return self.safe_dict(tickers, symbol)
|
905
1290
|
response = 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 = 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 = 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 = 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 = 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 = 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 = self.privateGetSmartorders(self.extend(request, params))
|
1282
1874
|
else:
|
1283
1875
|
response = 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
|
+
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
|
+
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 = 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
|
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
|
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 = 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 = self.privatePostSmartorders(self.extend(request, params))
|
1343
2011
|
else:
|
1344
2012
|
response = 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
|
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 = 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 = 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 = 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
|
self.load_markets()
|
2406
|
+
marketType = None
|
2407
|
+
marketType, params = self.handle_market_type_and_params('fetchBalance', None, params)
|
2408
|
+
if marketType != 'spot':
|
2409
|
+
responseRaw = 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 = 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 = self.publicGetMarketsSymbolOrderBook(self.extend(request, params))
|
1731
2542
|
#
|
1732
2543
|
# {
|
@@ -1761,7 +2572,7 @@ class poloniex(Exchange, ImplicitAPI):
|
|
1761
2572
|
'nonce': None,
|
1762
2573
|
}
|
1763
2574
|
|
1764
|
-
def create_deposit_address(self, code: str, params={}):
|
2575
|
+
def create_deposit_address(self, code: str, params={}) -> DepositAddress:
|
1765
2576
|
"""
|
1766
2577
|
create a currency deposit address
|
1767
2578
|
|
@@ -2300,14 +3111,381 @@ class poloniex(Exchange, ImplicitAPI):
|
|
2300
3111
|
},
|
2301
3112
|
}
|
2302
3113
|
|
3114
|
+
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
|
+
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 = self.swapPrivatePostV3PositionLeverage(self.extend(request, params))
|
3145
|
+
return response
|
3146
|
+
|
3147
|
+
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
|
+
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 = 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
|
+
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 = 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
|
+
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 = self.swapPrivatePostV3PositionMode(self.extend(request, params))
|
3278
|
+
#
|
3279
|
+
# {
|
3280
|
+
# "code": "200",
|
3281
|
+
# "msg": "Success",
|
3282
|
+
# "data": {}
|
3283
|
+
# }
|
3284
|
+
#
|
3285
|
+
return response
|
3286
|
+
|
3287
|
+
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
|
+
self.load_markets()
|
3299
|
+
symbols = self.market_symbols(symbols)
|
3300
|
+
response = 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
|
+
def modify_margin_helper(self, symbol: str, amount, type, params={}) -> MarginModification:
|
3411
|
+
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 = 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
|
+
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 self.modify_margin_helper(symbol, -amount, 'reduce', params)
|
3468
|
+
|
3469
|
+
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 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)
|