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