ccxt 4.4.94__py2.py3-none-any.whl → 4.4.96__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 +3 -1
- ccxt/abstract/bingx.py +3 -0
- ccxt/abstract/foxbit.py +26 -0
- ccxt/abstract/hyperliquid.py +1 -1
- ccxt/abstract/woo.py +59 -4
- ccxt/apex.py +3 -3
- ccxt/ascendex.py +2 -2
- ccxt/async_support/__init__.py +3 -1
- ccxt/async_support/apex.py +3 -3
- ccxt/async_support/ascendex.py +2 -2
- ccxt/async_support/base/exchange.py +5 -3
- ccxt/async_support/base/ws/future.py +5 -1
- ccxt/async_support/bingx.py +129 -92
- ccxt/async_support/bitget.py +31 -144
- ccxt/async_support/bitmart.py +2 -2
- ccxt/async_support/bitrue.py +13 -8
- ccxt/async_support/bitstamp.py +2 -0
- ccxt/async_support/blofin.py +6 -1
- ccxt/async_support/bybit.py +15 -6
- ccxt/async_support/coinbase.py +36 -0
- ccxt/async_support/coinbaseexchange.py +4 -2
- ccxt/async_support/coinbaseinternational.py +2 -2
- ccxt/async_support/coinmate.py +34 -0
- ccxt/async_support/coinone.py +34 -0
- ccxt/async_support/coinsph.py +29 -0
- ccxt/async_support/coinspot.py +36 -1
- ccxt/async_support/cryptocom.py +2 -1
- ccxt/async_support/cryptomus.py +41 -1
- ccxt/async_support/defx.py +1 -1
- ccxt/async_support/derive.py +1 -1
- ccxt/async_support/ellipx.py +40 -0
- ccxt/async_support/foxbit.py +1935 -0
- ccxt/async_support/gate.py +1 -1
- ccxt/async_support/hyperliquid.py +3 -2
- ccxt/async_support/kucoin.py +1 -1
- ccxt/async_support/kucoinfutures.py +3 -2
- ccxt/async_support/mexc.py +28 -13
- ccxt/async_support/modetrade.py +3 -3
- ccxt/async_support/okcoin.py +1 -1
- ccxt/async_support/okx.py +10 -3
- ccxt/async_support/onetrading.py +1 -1
- ccxt/async_support/oxfun.py +2 -1
- ccxt/async_support/paradex.py +2 -2
- ccxt/async_support/vertex.py +3 -2
- ccxt/async_support/woo.py +1255 -875
- ccxt/async_support/woofipro.py +2 -2
- ccxt/base/exchange.py +8 -5
- ccxt/bingx.py +129 -92
- ccxt/bitget.py +31 -144
- ccxt/bitmart.py +2 -2
- ccxt/bitrue.py +13 -8
- ccxt/bitstamp.py +2 -0
- ccxt/blofin.py +6 -1
- ccxt/bybit.py +15 -6
- ccxt/coinbase.py +36 -0
- ccxt/coinbaseexchange.py +4 -2
- ccxt/coinbaseinternational.py +2 -2
- ccxt/coinmate.py +34 -0
- ccxt/coinone.py +34 -0
- ccxt/coinsph.py +29 -0
- ccxt/coinspot.py +36 -1
- ccxt/cryptocom.py +2 -1
- ccxt/cryptomus.py +41 -1
- ccxt/defx.py +1 -1
- ccxt/derive.py +1 -1
- ccxt/ellipx.py +40 -0
- ccxt/foxbit.py +1935 -0
- ccxt/gate.py +1 -1
- ccxt/hyperliquid.py +3 -2
- ccxt/kucoin.py +1 -1
- ccxt/kucoinfutures.py +3 -2
- ccxt/mexc.py +28 -13
- ccxt/modetrade.py +3 -3
- ccxt/okcoin.py +1 -1
- ccxt/okx.py +10 -3
- ccxt/onetrading.py +1 -1
- ccxt/oxfun.py +2 -1
- ccxt/paradex.py +2 -2
- ccxt/pro/__init__.py +1 -1
- ccxt/pro/hyperliquid.py +6 -6
- ccxt/pro/kraken.py +17 -16
- ccxt/pro/mexc.py +10 -10
- ccxt/test/tests_async.py +17 -2
- ccxt/test/tests_sync.py +17 -2
- ccxt/vertex.py +3 -2
- ccxt/woo.py +1255 -875
- ccxt/woofipro.py +2 -2
- {ccxt-4.4.94.dist-info → ccxt-4.4.96.dist-info}/METADATA +8 -8
- {ccxt-4.4.94.dist-info → ccxt-4.4.96.dist-info}/RECORD +92 -89
- {ccxt-4.4.94.dist-info → ccxt-4.4.96.dist-info}/LICENSE.txt +0 -0
- {ccxt-4.4.94.dist-info → ccxt-4.4.96.dist-info}/WHEEL +0 -0
- {ccxt-4.4.94.dist-info → ccxt-4.4.96.dist-info}/top_level.txt +0 -0
ccxt/async_support/woo.py
CHANGED
@@ -7,7 +7,7 @@ from ccxt.async_support.base.exchange import Exchange
|
|
7
7
|
from ccxt.abstract.woo import ImplicitAPI
|
8
8
|
import asyncio
|
9
9
|
import hashlib
|
10
|
-
from ccxt.base.types import Account, Any, Balances, Bool, Conversion, Currencies, Currency, DepositAddress, Int, LedgerEntry, Leverage, MarginModification, Market, MarketType, Num, Order, OrderBook, OrderSide, OrderType, Position, Str, Strings, FundingRate, FundingRates, Trade, TradingFees, Transaction, TransferEntry
|
10
|
+
from ccxt.base.types import Account, Any, Balances, Bool, Conversion, Currencies, Currency, DepositAddress, Int, LedgerEntry, Leverage, MarginModification, Market, MarketType, Num, Order, OrderBook, OrderSide, OrderType, Position, Str, Strings, FundingRate, FundingRates, Trade, TradingFeeInterface, TradingFees, Transaction, TransferEntry
|
11
11
|
from typing import List
|
12
12
|
from ccxt.base.errors import ExchangeError
|
13
13
|
from ccxt.base.errors import AuthenticationError
|
@@ -113,7 +113,7 @@ class woo(Exchange, ImplicitAPI):
|
|
113
113
|
'fetchTickers': False,
|
114
114
|
'fetchTime': True,
|
115
115
|
'fetchTrades': True,
|
116
|
-
'fetchTradingFee':
|
116
|
+
'fetchTradingFee': True,
|
117
117
|
'fetchTradingFees': True,
|
118
118
|
'fetchTransactions': 'emulated',
|
119
119
|
'fetchTransfers': True,
|
@@ -249,19 +249,56 @@ class woo(Exchange, ImplicitAPI):
|
|
249
249
|
'v3': {
|
250
250
|
'public': {
|
251
251
|
'get': {
|
252
|
-
'
|
252
|
+
'systemInfo': 1, # 10/1s
|
253
|
+
'instruments': 1, # 10/1s
|
254
|
+
'token': 1, # 10/1s
|
255
|
+
'tokenNetwork': 1, # 10/1s
|
256
|
+
'tokenInfo': 1, # 10/1s
|
257
|
+
'marketTrades': 1, # 10/1s
|
258
|
+
'marketTradesHistory': 1, # 10/1s
|
259
|
+
'orderbook': 1, # 10/1s
|
260
|
+
'kline': 1, # 10/1s
|
261
|
+
'klineHistory': 1, # 10/1s
|
262
|
+
'futures': 1, # 10/1s
|
263
|
+
'fundingRate': 1, # 10/1s
|
264
|
+
'fundingRateHistory': 1, # 10/1s
|
265
|
+
'insuranceFund': 1, # 10/1s
|
253
266
|
},
|
254
267
|
},
|
255
268
|
'private': {
|
256
269
|
'get': {
|
270
|
+
'trade/order': 2, # 5/1s
|
271
|
+
'trade/orders': 1, # 10/1s
|
272
|
+
'trade/algoOrder': 1, # 10/1s
|
273
|
+
'trade/algoOrders': 1, # 10/1s
|
274
|
+
'trade/transaction': 1, # 10/1s
|
275
|
+
'trade/transactionHistory': 5, # 2/1s
|
276
|
+
'trade/tradingFee': 5, # 2/1s
|
277
|
+
'account/info': 60, # 10/60s
|
278
|
+
'account/tokenConfig': 1, # 10/1s
|
279
|
+
'account/symbolConfig': 1, # 10/1s
|
280
|
+
'account/subAccounts/all': 60, # 10/60s
|
281
|
+
'account/referral/summary': 60, # 10/60s
|
282
|
+
'account/referral/rewardHistory': 60, # 10/60s
|
283
|
+
'account/credentials': 60, # 10/60s
|
284
|
+
'asset/balances': 1, # 10/1s
|
285
|
+
'asset/token/history': 60, # 10/60s
|
286
|
+
'asset/transfer/history': 30, # 20/60s
|
287
|
+
'asset/wallet/history': 60, # 10/60s
|
288
|
+
'asset/wallet/deposit': 60, # 10/60s
|
289
|
+
'asset/staking/yieldHistory': 60, # 10/60s
|
290
|
+
'futures/positions': 3.33, # 30/10s
|
291
|
+
'futures/leverage': 60, # 10/60s
|
292
|
+
'futures/defaultMarginMode': 60, # 10/60s
|
293
|
+
'futures/fundingFee/history': 30, # 20/60s
|
294
|
+
'spotMargin/interestRate': 60, # 10/60s
|
295
|
+
'spotMargin/interestHistory': 60, # 10/60s
|
296
|
+
'spotMargin/maxMargin': 60, # 10/60s
|
257
297
|
'algo/order/{oid}': 1,
|
258
298
|
'algo/orders': 1,
|
259
299
|
'balances': 1,
|
260
|
-
'accountinfo': 60,
|
261
300
|
'positions': 3.33,
|
262
301
|
'buypower': 1,
|
263
|
-
'referrals': 60,
|
264
|
-
'referral_rewards': 60,
|
265
302
|
'convert/exchangeInfo': 1,
|
266
303
|
'convert/assetInfo': 1,
|
267
304
|
'convert/rfq': 60,
|
@@ -269,16 +306,34 @@ class woo(Exchange, ImplicitAPI):
|
|
269
306
|
'convert/trades': 1,
|
270
307
|
},
|
271
308
|
'post': {
|
309
|
+
'trade/order': 2, # 5/1s
|
310
|
+
'trade/algoOrder': 5, # 2/1s
|
311
|
+
'trade/cancelAllAfter': 1, # 10/1s
|
312
|
+
'account/tradingMode': 120, # 5/60s
|
313
|
+
'account/listenKey': 20, # 5/10s
|
314
|
+
'asset/transfer': 30, # 20/60s
|
315
|
+
'asset/wallet/withdraw': 60, # 10/60s
|
316
|
+
'spotMargin/leverage': 120, # 5/60s
|
317
|
+
'spotMargin/interestRepay': 60, # 10/60s
|
272
318
|
'algo/order': 5,
|
273
319
|
'convert/rft': 60,
|
274
320
|
},
|
275
321
|
'put': {
|
322
|
+
'trade/order': 2, # 5/1s
|
323
|
+
'trade/algoOrder': 2, # 5/1s
|
324
|
+
'futures/leverage': 60, # 10/60s
|
325
|
+
'futures/positionMode': 120, # 5/60s
|
276
326
|
'order/{oid}': 2,
|
277
327
|
'order/client/{client_order_id}': 2,
|
278
328
|
'algo/order/{oid}': 2,
|
279
329
|
'algo/order/client/{client_order_id}': 2,
|
280
330
|
},
|
281
331
|
'delete': {
|
332
|
+
'trade/order': 1, # 10/1s
|
333
|
+
'trade/orders': 1, # 10/1s
|
334
|
+
'trade/algoOrder': 1, # 10/1s
|
335
|
+
'trade/algoOrders': 1, # 10/1s
|
336
|
+
'trade/allOrders': 1, # 10/1s
|
282
337
|
'algo/order/{order_id}': 1,
|
283
338
|
'algo/orders/pending': 1,
|
284
339
|
'algo/orders/pending/{symbol}': 1,
|
@@ -457,20 +512,21 @@ class woo(Exchange, ImplicitAPI):
|
|
457
512
|
"""
|
458
513
|
the latest known information on the availability of the exchange API
|
459
514
|
|
460
|
-
https://
|
515
|
+
https://developer.woox.io/api-reference/endpoint/public_data/systemInfo
|
461
516
|
|
462
517
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
463
518
|
:returns dict: a `status structure <https://docs.ccxt.com/#/?id=exchange-status-structure>`
|
464
519
|
"""
|
465
|
-
response = await self.
|
520
|
+
response = await self.v3PublicGetSystemInfo(params)
|
466
521
|
#
|
467
522
|
# {
|
468
523
|
# "success": True,
|
469
524
|
# "data": {
|
470
|
-
# "status":
|
471
|
-
# "msg": "System is functioning properly."
|
525
|
+
# "status": 0,
|
526
|
+
# "msg": "System is functioning properly.",
|
527
|
+
# "estimatedEndTime": 1749963600362
|
472
528
|
# },
|
473
|
-
# "timestamp":
|
529
|
+
# "timestamp": 1751442989564
|
474
530
|
# }
|
475
531
|
#
|
476
532
|
data = self.safe_dict(response, 'data', {})
|
@@ -493,20 +549,21 @@ class woo(Exchange, ImplicitAPI):
|
|
493
549
|
"""
|
494
550
|
fetches the current integer timestamp in milliseconds from the exchange server
|
495
551
|
|
496
|
-
https://
|
552
|
+
https://developer.woox.io/api-reference/endpoint/public_data/systemInfo
|
497
553
|
|
498
554
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
499
555
|
:returns int: the current integer timestamp in milliseconds from the exchange server
|
500
556
|
"""
|
501
|
-
response = await self.
|
557
|
+
response = await self.v3PublicGetSystemInfo(params)
|
502
558
|
#
|
503
559
|
# {
|
504
560
|
# "success": True,
|
505
561
|
# "data": {
|
506
|
-
# "status":
|
507
|
-
# "msg": "System is functioning properly."
|
562
|
+
# "status": 0,
|
563
|
+
# "msg": "System is functioning properly.",
|
564
|
+
# "estimatedEndTime": 1749963600362
|
508
565
|
# },
|
509
|
-
# "timestamp":
|
566
|
+
# "timestamp": 1751442989564
|
510
567
|
# }
|
511
568
|
#
|
512
569
|
return self.safe_integer(response, 'timestamp')
|
@@ -515,37 +572,49 @@ class woo(Exchange, ImplicitAPI):
|
|
515
572
|
"""
|
516
573
|
retrieves data on all markets for woo
|
517
574
|
|
518
|
-
https://
|
575
|
+
https://developer.woox.io/api-reference/endpoint/public_data/instruments
|
519
576
|
|
520
577
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
521
578
|
:returns dict[]: an array of objects representing market data
|
522
579
|
"""
|
523
580
|
if self.options['adjustForTimeDifference']:
|
524
581
|
await self.load_time_difference()
|
525
|
-
response = await self.
|
582
|
+
response = await self.v3PublicGetInstruments(params)
|
526
583
|
#
|
527
|
-
#
|
528
|
-
#
|
529
|
-
# {
|
530
|
-
# "
|
531
|
-
#
|
532
|
-
#
|
533
|
-
#
|
534
|
-
#
|
535
|
-
#
|
536
|
-
#
|
537
|
-
#
|
538
|
-
#
|
539
|
-
#
|
540
|
-
#
|
541
|
-
#
|
584
|
+
# {
|
585
|
+
# "success": True,
|
586
|
+
# "data": {
|
587
|
+
# "rows": [
|
588
|
+
# {
|
589
|
+
# "symbol": "SPOT_AAVE_USDT",
|
590
|
+
# "status": "TRADING",
|
591
|
+
# "baseAsset": "AAVE",
|
592
|
+
# "baseAssetMultiplier": 1,
|
593
|
+
# "quoteAsset": "USDT",
|
594
|
+
# "quoteMin": "0",
|
595
|
+
# "quoteMax": "100000",
|
596
|
+
# "quoteTick": "0.01",
|
597
|
+
# "baseMin": "0.005",
|
598
|
+
# "baseMax": "5000",
|
599
|
+
# "baseTick": "0.0001",
|
600
|
+
# "minNotional": "1",
|
601
|
+
# "bidCapRatio": "1.1",
|
602
|
+
# "bidFloorRatio": null,
|
603
|
+
# "askCapRatio": null,
|
604
|
+
# "askFloorRatio": "0.9",
|
605
|
+
# "orderMode": "NORMAL",
|
606
|
+
# "impactNotional": null,
|
607
|
+
# "isAllowedRpi": False,
|
608
|
+
# "tickGranularity": null
|
609
|
+
# }
|
610
|
+
# ]
|
542
611
|
# },
|
543
|
-
#
|
544
|
-
#
|
545
|
-
# }
|
612
|
+
# "timestamp": 1751512951338
|
613
|
+
# }
|
546
614
|
#
|
547
|
-
data = self.
|
548
|
-
|
615
|
+
data = self.safe_dict(response, 'data', {})
|
616
|
+
rows = self.safe_list(data, 'rows', [])
|
617
|
+
return self.parse_markets(rows)
|
549
618
|
|
550
619
|
def parse_market(self, market: dict) -> Market:
|
551
620
|
marketId = self.safe_string(market, 'symbol')
|
@@ -580,7 +649,7 @@ class woo(Exchange, ImplicitAPI):
|
|
580
649
|
contractSize = self.parse_number('1')
|
581
650
|
linear = True
|
582
651
|
inverse = False
|
583
|
-
active = self.safe_string(market, '
|
652
|
+
active = self.safe_string(market, 'status') == 'TRADING'
|
584
653
|
return {
|
585
654
|
'id': marketId,
|
586
655
|
'symbol': symbol,
|
@@ -606,8 +675,8 @@ class woo(Exchange, ImplicitAPI):
|
|
606
675
|
'strike': None,
|
607
676
|
'optionType': None,
|
608
677
|
'precision': {
|
609
|
-
'amount': self.safe_number(market, '
|
610
|
-
'price': self.safe_number(market, '
|
678
|
+
'amount': self.safe_number(market, 'baseTick'),
|
679
|
+
'price': self.safe_number(market, 'quoteTick'),
|
611
680
|
},
|
612
681
|
'limits': {
|
613
682
|
'leverage': {
|
@@ -615,19 +684,19 @@ class woo(Exchange, ImplicitAPI):
|
|
615
684
|
'max': None,
|
616
685
|
},
|
617
686
|
'amount': {
|
618
|
-
'min': self.safe_number(market, '
|
619
|
-
'max': self.safe_number(market, '
|
687
|
+
'min': self.safe_number(market, 'baseMin'),
|
688
|
+
'max': self.safe_number(market, 'baseMax'),
|
620
689
|
},
|
621
690
|
'price': {
|
622
|
-
'min': self.safe_number(market, '
|
623
|
-
'max': self.safe_number(market, '
|
691
|
+
'min': self.safe_number(market, 'quoteMin'),
|
692
|
+
'max': self.safe_number(market, 'quoteMax'),
|
624
693
|
},
|
625
694
|
'cost': {
|
626
|
-
'min': self.safe_number(market, '
|
695
|
+
'min': self.safe_number(market, 'minNotional'),
|
627
696
|
'max': None,
|
628
697
|
},
|
629
698
|
},
|
630
|
-
'created':
|
699
|
+
'created': None,
|
631
700
|
'info': market,
|
632
701
|
}
|
633
702
|
|
@@ -635,7 +704,7 @@ class woo(Exchange, ImplicitAPI):
|
|
635
704
|
"""
|
636
705
|
get the list of most recent trades for a particular symbol
|
637
706
|
|
638
|
-
https://
|
707
|
+
https://developer.woox.io/api-reference/endpoint/public_data/marketTrades
|
639
708
|
|
640
709
|
:param str symbol: unified symbol of the market to fetch trades for
|
641
710
|
:param int [since]: timestamp in ms of the earliest trade to fetch
|
@@ -650,38 +719,28 @@ class woo(Exchange, ImplicitAPI):
|
|
650
719
|
}
|
651
720
|
if limit is not None:
|
652
721
|
request['limit'] = limit
|
653
|
-
response = await self.
|
722
|
+
response = await self.v3PublicGetMarketTrades(self.extend(request, params))
|
654
723
|
#
|
655
|
-
#
|
656
|
-
#
|
657
|
-
#
|
658
|
-
#
|
659
|
-
#
|
660
|
-
#
|
661
|
-
#
|
662
|
-
#
|
663
|
-
#
|
664
|
-
#
|
665
|
-
#
|
666
|
-
#
|
667
|
-
#
|
668
|
-
# "executed_price": 46222.35,
|
669
|
-
# "executed_quantity": 0.0012,
|
670
|
-
# "executed_timestamp": "1641241162.329"
|
671
|
-
# },
|
672
|
-
# {
|
673
|
-
# "symbol": "SPOT_BTC_USDT",
|
674
|
-
# "side": "BUY",
|
675
|
-
# "executed_price": 46224.32,
|
676
|
-
# "executed_quantity": 0.00039,
|
677
|
-
# "executed_timestamp": "1641241162.287"
|
724
|
+
# {
|
725
|
+
# "success": True,
|
726
|
+
# "data": {
|
727
|
+
# "rows": [
|
728
|
+
# {
|
729
|
+
# "symbol": "SPOT_BTC_USDT",
|
730
|
+
# "side": "SELL",
|
731
|
+
# "source": 0,
|
732
|
+
# "executedPrice": "108741.01",
|
733
|
+
# "executedQuantity": "0.02477",
|
734
|
+
# "executedTimestamp": 1751513940144
|
735
|
+
# }
|
736
|
+
# ]
|
678
737
|
# },
|
679
|
-
#
|
680
|
-
#
|
681
|
-
# }
|
738
|
+
# "timestamp": 1751513988543
|
739
|
+
# }
|
682
740
|
#
|
683
|
-
|
684
|
-
|
741
|
+
data = self.safe_dict(response, 'data', {})
|
742
|
+
rows = self.safe_list(data, 'rows', [])
|
743
|
+
return self.parse_trades(rows, market, since, limit)
|
685
744
|
|
686
745
|
def parse_trade(self, trade: dict, market: Market = None) -> Trade:
|
687
746
|
#
|
@@ -690,36 +749,44 @@ class woo(Exchange, ImplicitAPI):
|
|
690
749
|
# {
|
691
750
|
# "symbol": "SPOT_BTC_USDT",
|
692
751
|
# "side": "SELL",
|
693
|
-
# "
|
694
|
-
# "
|
695
|
-
# "
|
752
|
+
# "source": 0,
|
753
|
+
# "executedPrice": "108741.01",
|
754
|
+
# "executedQuantity": "0.02477",
|
755
|
+
# "executedTimestamp": 1751513940144
|
696
756
|
# }
|
697
757
|
#
|
698
758
|
# fetchOrderTrades, fetchOrder
|
699
759
|
#
|
700
760
|
# {
|
701
|
-
# "id":
|
702
|
-
# "symbol": "
|
703
|
-
# "
|
761
|
+
# "id": 1734947821,
|
762
|
+
# "symbol": "SPOT_LTC_USDT",
|
763
|
+
# "orderId": 60780383217,
|
764
|
+
# "executedPrice": 87.86,
|
765
|
+
# "executedQuantity": 0.1,
|
766
|
+
# "fee": 0.0001,
|
767
|
+
# "realizedPnl": null,
|
768
|
+
# "feeAsset": "LTC",
|
769
|
+
# "orderTag": "default",
|
704
770
|
# "side": "BUY",
|
705
|
-
# "
|
706
|
-
# "
|
707
|
-
# "order_tag": "default", <-- self param only in "fetchOrderTrades"
|
708
|
-
# "executed_price": "1",
|
709
|
-
# "executed_quantity": "12",
|
710
|
-
# "fee_asset": "WOO",
|
711
|
-
# "is_maker": "1"
|
771
|
+
# "executedTimestamp": "1752055173.630",
|
772
|
+
# "isMaker": 0
|
712
773
|
# }
|
713
774
|
#
|
714
775
|
isFromFetchOrder = ('id' in trade)
|
715
|
-
|
776
|
+
timestampString = self.safe_string_2(trade, 'executed_timestamp', 'executedTimestamp')
|
777
|
+
timestamp = None
|
778
|
+
if timestampString is not None:
|
779
|
+
if timestampString.find('.') > -1:
|
780
|
+
timestamp = self.safe_timestamp_2(trade, 'executed_timestamp', 'executedTimestamp')
|
781
|
+
else:
|
782
|
+
timestamp = self.safe_integer(trade, 'executedTimestamp')
|
716
783
|
marketId = self.safe_string(trade, 'symbol')
|
717
784
|
market = self.safe_market(marketId, market)
|
718
785
|
symbol = market['symbol']
|
719
|
-
price = self.
|
720
|
-
amount = self.
|
721
|
-
order_id = self.
|
722
|
-
fee = self.parse_token_and_fee_temp(trade, 'fee_asset', 'fee')
|
786
|
+
price = self.safe_string_2(trade, 'executed_price', 'executedPrice')
|
787
|
+
amount = self.safe_string_2(trade, 'executed_quantity', 'executedQuantity')
|
788
|
+
order_id = self.safe_string_2(trade, 'order_id', 'orderId')
|
789
|
+
fee = self.parse_token_and_fee_temp(trade, ['fee_asset', 'feeAsset'], ['fee'])
|
723
790
|
feeCost = self.safe_string(fee, 'cost')
|
724
791
|
if feeCost is not None:
|
725
792
|
fee['cost'] = feeCost
|
@@ -728,7 +795,7 @@ class woo(Exchange, ImplicitAPI):
|
|
728
795
|
id = self.safe_string(trade, 'id')
|
729
796
|
takerOrMaker: Str = None
|
730
797
|
if isFromFetchOrder:
|
731
|
-
isMaker = self.
|
798
|
+
isMaker = self.safe_string_2(trade, 'is_maker', 'isMaker') == '1'
|
732
799
|
takerOrMaker = 'maker' if isMaker else 'taker'
|
733
800
|
return self.safe_trade({
|
734
801
|
'id': id,
|
@@ -746,11 +813,11 @@ class woo(Exchange, ImplicitAPI):
|
|
746
813
|
'info': trade,
|
747
814
|
}, market)
|
748
815
|
|
749
|
-
def parse_token_and_fee_temp(self, item,
|
750
|
-
feeCost = self.
|
816
|
+
def parse_token_and_fee_temp(self, item, feeTokenKeys, feeAmountKeys):
|
817
|
+
feeCost = self.safe_string_n(item, feeAmountKeys)
|
751
818
|
fee = None
|
752
819
|
if feeCost is not None:
|
753
|
-
feeCurrencyId = self.
|
820
|
+
feeCurrencyId = self.safe_string_n(item, feeTokenKeys)
|
754
821
|
feeCurrencyCode = self.safe_currency_code(feeCurrencyId)
|
755
822
|
fee = {
|
756
823
|
'cost': feeCost,
|
@@ -758,43 +825,90 @@ class woo(Exchange, ImplicitAPI):
|
|
758
825
|
}
|
759
826
|
return fee
|
760
827
|
|
828
|
+
def parse_trading_fee(self, fee: dict, market: Market = None) -> TradingFeeInterface:
|
829
|
+
marketId = self.safe_string(fee, 'symbol')
|
830
|
+
symbol = self.safe_symbol(marketId, market)
|
831
|
+
return {
|
832
|
+
'info': fee,
|
833
|
+
'symbol': symbol,
|
834
|
+
'maker': self.parse_number(Precise.string_div(self.safe_string(fee, 'makerFee'), '100')),
|
835
|
+
'taker': self.parse_number(Precise.string_div(self.safe_string(fee, 'takerFee'), '100')),
|
836
|
+
'percentage': None,
|
837
|
+
'tierBased': None,
|
838
|
+
}
|
839
|
+
|
840
|
+
async def fetch_trading_fee(self, symbol: str, params={}) -> TradingFeeInterface:
|
841
|
+
"""
|
842
|
+
fetch the trading fees for a market
|
843
|
+
|
844
|
+
https://developer.woox.io/api-reference/endpoint/trading/get_tradingFee
|
845
|
+
|
846
|
+
:param str symbol: unified market symbol
|
847
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
848
|
+
:param boolean [params.portfolioMargin]: set to True if you would like to fetch trading fees in a portfolio margin account
|
849
|
+
:param str [params.subType]: "linear" or "inverse"
|
850
|
+
:returns dict: a `fee structure <https://docs.ccxt.com/#/?id=fee-structure>`
|
851
|
+
"""
|
852
|
+
await self.load_markets()
|
853
|
+
market = self.market(symbol)
|
854
|
+
request: dict = {
|
855
|
+
'symbol': market['id'],
|
856
|
+
}
|
857
|
+
response = await self.v3PrivateGetTradeTradingFee(self.extend(request, params))
|
858
|
+
#
|
859
|
+
# {
|
860
|
+
# "success": True,
|
861
|
+
# "data": {
|
862
|
+
# "symbol": "SPOT_BTC_USDT",
|
863
|
+
# "takerFee": "10",
|
864
|
+
# "makerFee": "8"
|
865
|
+
# },
|
866
|
+
# "timestamp": 1751858977368
|
867
|
+
# }
|
868
|
+
#
|
869
|
+
data = self.safe_dict(response, 'data', {})
|
870
|
+
return self.parse_trading_fee(data, market)
|
871
|
+
|
761
872
|
async def fetch_trading_fees(self, params={}) -> TradingFees:
|
762
873
|
"""
|
763
874
|
fetch the trading fees for multiple markets
|
764
875
|
|
765
|
-
https://
|
876
|
+
https://developer.woox.io/api-reference/endpoint/account/get_account_info
|
766
877
|
|
767
878
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
768
879
|
:returns dict: a dictionary of `fee structures <https://docs.ccxt.com/#/?id=fee-structure>` indexed by market symbols
|
769
880
|
"""
|
770
881
|
await self.load_markets()
|
771
|
-
response = await self.
|
882
|
+
response = await self.v3PrivateGetAccountInfo(params)
|
772
883
|
#
|
773
884
|
# {
|
774
885
|
# "success": True,
|
775
886
|
# "data": {
|
776
|
-
# "applicationId": "
|
777
|
-
# "account": "
|
778
|
-
# "alias": "
|
779
|
-
# "accountMode": "MARGIN",
|
780
|
-
# "leverage": 1,
|
781
|
-
# "takerFeeRate": 1,
|
782
|
-
# "makerFeeRate": 1,
|
783
|
-
# "interestRate": 1,
|
784
|
-
# "futuresTakerFeeRate": 1,
|
785
|
-
# "futuresMakerFeeRate": 1,
|
887
|
+
# "applicationId": "251bf5c4-f3c8-4544-bb8b-80001007c3c0",
|
888
|
+
# "account": "carlos_jose_lima@yahoo.com",
|
889
|
+
# "alias": "carlos_jose_lima@yahoo.com",
|
786
890
|
# "otpauth": True,
|
787
|
-
# "
|
788
|
-
# "
|
789
|
-
# "
|
790
|
-
# "
|
791
|
-
# "
|
792
|
-
# "
|
793
|
-
# "
|
794
|
-
# "
|
795
|
-
# "
|
891
|
+
# "accountMode": "FUTURES",
|
892
|
+
# "positionMode": "ONE_WAY",
|
893
|
+
# "leverage": 0,
|
894
|
+
# "makerFeeRate": 0,
|
895
|
+
# "takerFeeRate": 0,
|
896
|
+
# "marginRatio": "10",
|
897
|
+
# "openMarginRatio": "10",
|
898
|
+
# "initialMarginRatio": "10",
|
899
|
+
# "maintenanceMarginRatio": "0.03",
|
900
|
+
# "totalCollateral": "165.55629469",
|
901
|
+
# "freeCollateral": "165.55629469",
|
902
|
+
# "totalAccountValue": "167.32418611",
|
903
|
+
# "totalTradingValue": "167.32418611",
|
904
|
+
# "totalVaultValue": "0",
|
905
|
+
# "totalStakingValue": "0",
|
906
|
+
# "totalLaunchpadValue": "0",
|
907
|
+
# "totalEarnValue": "0",
|
908
|
+
# "referrerID": null,
|
909
|
+
# "accountType": "Main"
|
796
910
|
# },
|
797
|
-
# "timestamp":
|
911
|
+
# "timestamp": 1752062807915
|
798
912
|
# }
|
799
913
|
#
|
800
914
|
data = self.safe_dict(response, 'data', {})
|
@@ -1049,8 +1163,8 @@ class woo(Exchange, ImplicitAPI):
|
|
1049
1163
|
"""
|
1050
1164
|
create a trade order
|
1051
1165
|
|
1052
|
-
https://
|
1053
|
-
https://
|
1166
|
+
https://developer.woox.io/api-reference/endpoint/trading/post_order
|
1167
|
+
https://developer.woox.io/api-reference/endpoint/trading/post_algo_order
|
1054
1168
|
|
1055
1169
|
:param str symbol: unified symbol of the market to create an order in
|
1056
1170
|
:param str type: 'market' or 'limit'
|
@@ -1085,7 +1199,7 @@ class woo(Exchange, ImplicitAPI):
|
|
1085
1199
|
marginMode: Str = None
|
1086
1200
|
marginMode, params = self.handle_margin_mode_and_params('createOrder', params)
|
1087
1201
|
if marginMode is not None:
|
1088
|
-
request['
|
1202
|
+
request['marginMode'] = self.encode_margin_mode(marginMode)
|
1089
1203
|
triggerPrice = self.safe_string_2(params, 'triggerPrice', 'stopPrice')
|
1090
1204
|
stopLoss = self.safe_value(params, 'stopLoss')
|
1091
1205
|
takeProfit = self.safe_value(params, 'takeProfit')
|
@@ -1100,27 +1214,23 @@ class woo(Exchange, ImplicitAPI):
|
|
1100
1214
|
isMarket = orderType == 'MARKET'
|
1101
1215
|
timeInForce = self.safe_string_lower(params, 'timeInForce')
|
1102
1216
|
postOnly = self.is_post_only(isMarket, None, params)
|
1103
|
-
|
1104
|
-
|
1105
|
-
orderQtyKey = 'quantity' if isConditional else 'order_quantity'
|
1106
|
-
priceKey = 'price' if isConditional else 'order_price'
|
1107
|
-
typeKey = 'type' if isConditional else 'order_type'
|
1108
|
-
request[typeKey] = orderType # LIMIT/MARKET/IOC/FOK/POST_ONLY/ASK/BID
|
1217
|
+
clientOrderIdKey = 'clientAlgoOrderId' if isConditional else 'clientOrderId'
|
1218
|
+
request['type'] = orderType # LIMIT/MARKET/IOC/FOK/POST_ONLY/ASK/BID
|
1109
1219
|
if not isConditional:
|
1110
1220
|
if postOnly:
|
1111
|
-
request['
|
1221
|
+
request['type'] = 'POST_ONLY'
|
1112
1222
|
elif timeInForce == 'fok':
|
1113
|
-
request['
|
1223
|
+
request['type'] = 'FOK'
|
1114
1224
|
elif timeInForce == 'ioc':
|
1115
|
-
request['
|
1225
|
+
request['type'] = 'IOC'
|
1116
1226
|
if reduceOnly:
|
1117
|
-
request[
|
1227
|
+
request['reduceOnly'] = reduceOnly
|
1118
1228
|
if not isMarket and price is not None:
|
1119
|
-
request[
|
1229
|
+
request['price'] = self.price_to_precision(symbol, price)
|
1120
1230
|
if isMarket and not isConditional:
|
1121
1231
|
# for market buy it requires the amount of quote currency to spend
|
1122
|
-
cost = self.
|
1123
|
-
params = self.omit(params, ['cost', 'order_amount'])
|
1232
|
+
cost = self.safe_string_n(params, ['cost', 'order_amount', 'orderAmount'])
|
1233
|
+
params = self.omit(params, ['cost', 'order_amount', 'orderAmount'])
|
1124
1234
|
isPriceProvided = price is not None
|
1125
1235
|
if market['spot'] and (isPriceProvided or (cost is not None)):
|
1126
1236
|
quoteAmount = None
|
@@ -1131,11 +1241,11 @@ class woo(Exchange, ImplicitAPI):
|
|
1131
1241
|
priceString = self.number_to_string(price)
|
1132
1242
|
costRequest = Precise.string_mul(amountString, priceString)
|
1133
1243
|
quoteAmount = self.cost_to_precision(symbol, costRequest)
|
1134
|
-
request['
|
1244
|
+
request['amount'] = quoteAmount
|
1135
1245
|
else:
|
1136
|
-
request['
|
1246
|
+
request['quantity'] = self.amount_to_precision(symbol, amount)
|
1137
1247
|
elif algoType != 'POSITIONAL_TP_SL':
|
1138
|
-
request[
|
1248
|
+
request['quantity'] = self.amount_to_precision(symbol, amount)
|
1139
1249
|
clientOrderId = self.safe_string_n(params, ['clOrdID', 'clientOrderId', 'client_order_id'])
|
1140
1250
|
if clientOrderId is not None:
|
1141
1251
|
request[clientOrderIdKey] = clientOrderId
|
@@ -1187,41 +1297,44 @@ class woo(Exchange, ImplicitAPI):
|
|
1187
1297
|
params = self.omit(params, ['clOrdID', 'clientOrderId', 'client_order_id', 'postOnly', 'timeInForce', 'stopPrice', 'triggerPrice', 'stopLoss', 'takeProfit', 'trailingPercent', 'trailingAmount', 'trailingTriggerPrice'])
|
1188
1298
|
response = None
|
1189
1299
|
if isConditional:
|
1190
|
-
response = await self.
|
1300
|
+
response = await self.v3PrivatePostTradeAlgoOrder(self.extend(request, params))
|
1301
|
+
#
|
1302
|
+
# {
|
1303
|
+
# "success": True,
|
1304
|
+
# "data": {
|
1305
|
+
# "rows": [
|
1306
|
+
# {
|
1307
|
+
# "orderId": "1578938",
|
1308
|
+
# "clientOrderId": "0",
|
1309
|
+
# "algoType": "STOP_LOSS",
|
1310
|
+
# "quantity": "0.1"
|
1311
|
+
# }
|
1312
|
+
# ]
|
1313
|
+
# },
|
1314
|
+
# "timestamp": "1686149372216"
|
1315
|
+
# }
|
1316
|
+
#
|
1191
1317
|
else:
|
1192
|
-
response = await self.
|
1193
|
-
|
1194
|
-
|
1195
|
-
|
1196
|
-
|
1197
|
-
|
1198
|
-
|
1199
|
-
|
1200
|
-
|
1201
|
-
|
1202
|
-
|
1203
|
-
|
1204
|
-
|
1205
|
-
|
1206
|
-
|
1207
|
-
|
1208
|
-
|
1209
|
-
|
1210
|
-
|
1211
|
-
|
1212
|
-
# "quantity": "0.1"
|
1213
|
-
# }
|
1214
|
-
# ]
|
1215
|
-
# },
|
1216
|
-
# "timestamp": "1686149372216"
|
1217
|
-
# }
|
1218
|
-
data = self.safe_dict(response, 'data')
|
1219
|
-
if data is not None:
|
1220
|
-
rows = self.safe_list(data, 'rows', [])
|
1221
|
-
return self.parse_order(rows[0], market)
|
1222
|
-
order = self.parse_order(response, market)
|
1223
|
-
order['type'] = type
|
1224
|
-
return order
|
1318
|
+
response = await self.v3PrivatePostTradeOrder(self.extend(request, params))
|
1319
|
+
#
|
1320
|
+
# {
|
1321
|
+
# "success": True,
|
1322
|
+
# "data": {
|
1323
|
+
# "orderId": 60667653330,
|
1324
|
+
# "clientOrderId": 0,
|
1325
|
+
# "type": "LIMIT",
|
1326
|
+
# "price": 60,
|
1327
|
+
# "quantity": 0.1,
|
1328
|
+
# "amount": null,
|
1329
|
+
# "bidAskLevel": null
|
1330
|
+
# },
|
1331
|
+
# "timestamp": 1751871779855
|
1332
|
+
# }
|
1333
|
+
#
|
1334
|
+
data = self.safe_dict(response, 'data', {})
|
1335
|
+
data = self.safe_dict(self.safe_list(data, 'rows'), 0, data)
|
1336
|
+
data['timestamp'] = self.safe_string(response, 'timestamp')
|
1337
|
+
return self.parse_order(data, market)
|
1225
1338
|
|
1226
1339
|
def encode_margin_mode(self, mode):
|
1227
1340
|
modes = {
|
@@ -1317,9 +1430,8 @@ class woo(Exchange, ImplicitAPI):
|
|
1317
1430
|
async def cancel_order(self, id: str, symbol: Str = None, params={}):
|
1318
1431
|
"""
|
1319
1432
|
|
1320
|
-
https://
|
1321
|
-
https://
|
1322
|
-
https://docs.woox.io/#cancel-order-by-client_order_id
|
1433
|
+
https://developer.woox.io/api-reference/endpoint/trading/cancel_order
|
1434
|
+
https://developer.woox.io/api-reference/endpoint/trading/cancel_algo_order
|
1323
1435
|
|
1324
1436
|
cancels an open order
|
1325
1437
|
:param str id: order id
|
@@ -1339,36 +1451,44 @@ class woo(Exchange, ImplicitAPI):
|
|
1339
1451
|
request: dict = {}
|
1340
1452
|
clientOrderIdUnified = self.safe_string_2(params, 'clOrdID', 'clientOrderId')
|
1341
1453
|
clientOrderIdExchangeSpecific = self.safe_string(params, 'client_order_id', clientOrderIdUnified)
|
1454
|
+
params = self.omit(params, ['clOrdID', 'clientOrderId', 'client_order_id'])
|
1342
1455
|
isByClientOrder = clientOrderIdExchangeSpecific is not None
|
1343
1456
|
response = None
|
1344
1457
|
if isTrigger:
|
1345
|
-
|
1346
|
-
|
1458
|
+
if isByClientOrder:
|
1459
|
+
request['clientAlgoOrderId'] = clientOrderIdExchangeSpecific
|
1460
|
+
else:
|
1461
|
+
request['algoOrderId'] = id
|
1462
|
+
response = await self.v3PrivateDeleteTradeAlgoOrder(self.extend(request, params))
|
1347
1463
|
else:
|
1348
1464
|
request['symbol'] = market['id']
|
1349
1465
|
if isByClientOrder:
|
1350
|
-
request['
|
1351
|
-
params = self.omit(params, ['clOrdID', 'clientOrderId', 'client_order_id'])
|
1352
|
-
response = await self.v1PrivateDeleteClientOrder(self.extend(request, params))
|
1466
|
+
request['clientOrderId'] = clientOrderIdExchangeSpecific
|
1353
1467
|
else:
|
1354
|
-
request['
|
1355
|
-
|
1468
|
+
request['orderId'] = id
|
1469
|
+
response = await self.v3PrivateDeleteTradeOrder(self.extend(request, params))
|
1356
1470
|
#
|
1357
|
-
#
|
1471
|
+
# {
|
1472
|
+
# "success": True,
|
1473
|
+
# "data": {
|
1474
|
+
# "status": "CANCEL_SENT"
|
1475
|
+
# },
|
1476
|
+
# "timestamp": 1751940315838
|
1477
|
+
# }
|
1358
1478
|
#
|
1359
|
-
|
1479
|
+
data = self.safe_dict(response, 'data', {})
|
1480
|
+
data['timestamp'] = self.safe_string(response, 'timestamp')
|
1360
1481
|
if isByClientOrder:
|
1361
|
-
|
1482
|
+
data['clientOrderId'] = clientOrderIdExchangeSpecific
|
1362
1483
|
else:
|
1363
|
-
|
1364
|
-
return self.
|
1484
|
+
data['orderId'] = id
|
1485
|
+
return self.parse_order(data, market)
|
1365
1486
|
|
1366
1487
|
async def cancel_all_orders(self, symbol: Str = None, params={}):
|
1367
1488
|
"""
|
1368
1489
|
|
1369
|
-
https://
|
1370
|
-
https://
|
1371
|
-
https://docs.woox.io/#cancel-all-pending-algo-orders
|
1490
|
+
https://developer.woox.io/api-reference/endpoint/trading/cancel_all_order
|
1491
|
+
https://developer.woox.io/api-reference/endpoint/trading/cancel_algo_orders
|
1372
1492
|
|
1373
1493
|
cancel all open orders in a market
|
1374
1494
|
:param str symbol: unified market symbol
|
@@ -1379,30 +1499,32 @@ class woo(Exchange, ImplicitAPI):
|
|
1379
1499
|
await self.load_markets()
|
1380
1500
|
trigger = self.safe_bool_2(params, 'stop', 'trigger')
|
1381
1501
|
params = self.omit(params, ['stop', 'trigger'])
|
1502
|
+
request: dict = {}
|
1503
|
+
if symbol is not None:
|
1504
|
+
market = self.market(symbol)
|
1505
|
+
request['symbol'] = market['id']
|
1506
|
+
response = None
|
1382
1507
|
if trigger:
|
1383
|
-
|
1384
|
-
|
1385
|
-
|
1386
|
-
market = self.market(symbol)
|
1387
|
-
request: dict = {
|
1388
|
-
'symbol': market['id'],
|
1389
|
-
}
|
1390
|
-
response = await self.v1PrivateDeleteOrders(self.extend(request, params))
|
1508
|
+
response = await self.v3PrivateDeleteTradeAlgoOrders(params)
|
1509
|
+
else:
|
1510
|
+
response = await self.v3PrivateDeleteTradeOrders(self.extend(request, params))
|
1391
1511
|
#
|
1392
1512
|
# {
|
1393
|
-
# "success":
|
1394
|
-
# "
|
1513
|
+
# "success": True,
|
1514
|
+
# "data": {
|
1515
|
+
# "status": "CANCEL_ALL_SENT"
|
1516
|
+
# },
|
1517
|
+
# "timestamp": 1751941988134
|
1395
1518
|
# }
|
1396
1519
|
#
|
1397
|
-
|
1398
|
-
|
1399
|
-
]
|
1520
|
+
data = self.safe_dict(response, 'data', {})
|
1521
|
+
return [self.safe_order({'info': data})]
|
1400
1522
|
|
1401
1523
|
async def cancel_all_orders_after(self, timeout: Int, params={}):
|
1402
1524
|
"""
|
1403
1525
|
dead man's switch, cancel all orders after the given timeout
|
1404
1526
|
|
1405
|
-
https://
|
1527
|
+
https://developer.woox.io/api-reference/endpoint/trading/cancel_all_after
|
1406
1528
|
|
1407
1529
|
:param number timeout: time in milliseconds, 0 represents cancel the timer
|
1408
1530
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -1410,27 +1532,25 @@ class woo(Exchange, ImplicitAPI):
|
|
1410
1532
|
"""
|
1411
1533
|
await self.load_markets()
|
1412
1534
|
request: dict = {
|
1413
|
-
'
|
1535
|
+
'triggerAfter': min(timeout, 900000) if (timeout > 0) else 0,
|
1414
1536
|
}
|
1415
|
-
response = await self.
|
1537
|
+
response = await self.v3PrivatePostTradeCancelAllAfter(self.extend(request, params))
|
1416
1538
|
#
|
1417
|
-
#
|
1418
|
-
#
|
1419
|
-
#
|
1420
|
-
#
|
1421
|
-
#
|
1422
|
-
# "timestamp": 1711534302943
|
1539
|
+
# {
|
1540
|
+
# "success": True,
|
1541
|
+
# "timestamp": 123,
|
1542
|
+
# "data": {
|
1543
|
+
# "expectedTriggerTime": 123
|
1423
1544
|
# }
|
1545
|
+
# }
|
1424
1546
|
#
|
1425
|
-
return
|
1426
|
-
self.safe_order(response),
|
1427
|
-
]
|
1547
|
+
return response
|
1428
1548
|
|
1429
1549
|
async def fetch_order(self, id: str, symbol: Str = None, params={}):
|
1430
1550
|
"""
|
1431
1551
|
|
1432
|
-
https://
|
1433
|
-
https://
|
1552
|
+
https://developer.woox.io/api-reference/endpoint/trading/get_order
|
1553
|
+
https://developer.woox.io/api-reference/endpoint/trading/get_algo_order
|
1434
1554
|
|
1435
1555
|
fetches information on an order made by the user
|
1436
1556
|
:param str id: the order id
|
@@ -1440,65 +1560,102 @@ class woo(Exchange, ImplicitAPI):
|
|
1440
1560
|
:returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
1441
1561
|
"""
|
1442
1562
|
await self.load_markets()
|
1443
|
-
market =
|
1563
|
+
market = None
|
1564
|
+
if symbol is not None:
|
1565
|
+
market = self.market(symbol)
|
1444
1566
|
trigger = self.safe_bool_2(params, 'stop', 'trigger')
|
1445
1567
|
params = self.omit(params, ['stop', 'trigger'])
|
1446
1568
|
request: dict = {}
|
1447
1569
|
clientOrderId = self.safe_string_2(params, 'clOrdID', 'clientOrderId')
|
1448
1570
|
response = None
|
1449
1571
|
if trigger:
|
1450
|
-
|
1451
|
-
|
1452
|
-
|
1453
|
-
|
1454
|
-
response = await self.
|
1572
|
+
if clientOrderId is not None:
|
1573
|
+
request['clientAlgoOrderId'] = id
|
1574
|
+
else:
|
1575
|
+
request['algoOrderId'] = id
|
1576
|
+
response = await self.v3PrivateGetTradeAlgoOrder(self.extend(request, params))
|
1577
|
+
#
|
1578
|
+
# {
|
1579
|
+
# "success": True,
|
1580
|
+
# "data": {
|
1581
|
+
# "algoOrderId": 10399260,
|
1582
|
+
# "clientAlgoOrderId": 0,
|
1583
|
+
# "rootAlgoOrderId": 10399260,
|
1584
|
+
# "parentAlgoOrderId": 0,
|
1585
|
+
# "symbol": "SPOT_LTC_USDT",
|
1586
|
+
# "algoOrderTag": "default",
|
1587
|
+
# "algoType": "TAKE_PROFIT",
|
1588
|
+
# "side": "BUY",
|
1589
|
+
# "quantity": 0.1,
|
1590
|
+
# "isTriggered": False,
|
1591
|
+
# "triggerPrice": 65,
|
1592
|
+
# "triggerStatus": "USELESS",
|
1593
|
+
# "type": "LIMIT",
|
1594
|
+
# "rootAlgoStatus": "NEW",
|
1595
|
+
# "algoStatus": "NEW",
|
1596
|
+
# "triggerPriceType": "MARKET_PRICE",
|
1597
|
+
# "price": 60,
|
1598
|
+
# "triggerTime": "0",
|
1599
|
+
# "totalExecutedQuantity": 0,
|
1600
|
+
# "visibleQuantity": 0.1,
|
1601
|
+
# "averageExecutedPrice": 0,
|
1602
|
+
# "totalFee": 0,
|
1603
|
+
# "feeAsset": "",
|
1604
|
+
# "totalRebate": 0,
|
1605
|
+
# "rebateAsset": "",
|
1606
|
+
# "reduceOnly": False,
|
1607
|
+
# "createdTime": "1752049747.732",
|
1608
|
+
# "updatedTime": "1752049747.732",
|
1609
|
+
# "positionSide": "BOTH"
|
1610
|
+
# },
|
1611
|
+
# "timestamp": 1752049767550
|
1612
|
+
# }
|
1613
|
+
#
|
1455
1614
|
else:
|
1456
|
-
|
1457
|
-
|
1458
|
-
|
1459
|
-
|
1460
|
-
|
1461
|
-
|
1462
|
-
|
1463
|
-
|
1464
|
-
|
1465
|
-
|
1466
|
-
|
1467
|
-
|
1468
|
-
|
1469
|
-
|
1470
|
-
|
1471
|
-
|
1472
|
-
|
1473
|
-
|
1474
|
-
|
1475
|
-
|
1476
|
-
|
1477
|
-
|
1478
|
-
|
1479
|
-
|
1480
|
-
|
1481
|
-
|
1482
|
-
|
1483
|
-
|
1484
|
-
|
1485
|
-
|
1486
|
-
|
1487
|
-
|
1488
|
-
|
1489
|
-
|
1490
|
-
|
1491
|
-
|
1492
|
-
|
1493
|
-
orders = self.safe_dict(response, 'data', response)
|
1494
|
-
return self.parse_order(orders, market)
|
1615
|
+
if clientOrderId is not None:
|
1616
|
+
request['clientOrderId'] = clientOrderId
|
1617
|
+
else:
|
1618
|
+
request['orderId'] = id
|
1619
|
+
response = await self.v3PrivateGetTradeOrder(self.extend(request, params))
|
1620
|
+
#
|
1621
|
+
# {
|
1622
|
+
# "success": True,
|
1623
|
+
# "data": {
|
1624
|
+
# "orderId": 60780315704,
|
1625
|
+
# "clientOrderId": 0,
|
1626
|
+
# "symbol": "SPOT_LTC_USDT",
|
1627
|
+
# "orderTag": "default",
|
1628
|
+
# "side": "BUY",
|
1629
|
+
# "quantity": 0.1,
|
1630
|
+
# "amount": null,
|
1631
|
+
# "type": "LIMIT",
|
1632
|
+
# "status": "NEW",
|
1633
|
+
# "price": 60,
|
1634
|
+
# "executed": 0,
|
1635
|
+
# "visible": 0.1,
|
1636
|
+
# "averageExecutedPrice": 0,
|
1637
|
+
# "totalFee": 0,
|
1638
|
+
# "feeAsset": "LTC",
|
1639
|
+
# "totalRebate": 0,
|
1640
|
+
# "rebateAsset": "USDT",
|
1641
|
+
# "reduceOnly": False,
|
1642
|
+
# "createdTime": "1752049062.496",
|
1643
|
+
# "realizedPnl": null,
|
1644
|
+
# "positionSide": "BOTH",
|
1645
|
+
# "bidAskLevel": null
|
1646
|
+
# },
|
1647
|
+
# "timestamp": 1752049393466
|
1648
|
+
# }
|
1649
|
+
#
|
1650
|
+
data = self.safe_dict(response, 'data', {})
|
1651
|
+
return self.parse_order(data, market)
|
1495
1652
|
|
1496
1653
|
async def fetch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
1497
1654
|
"""
|
1498
1655
|
fetches information on multiple orders made by the user
|
1499
1656
|
|
1500
|
-
https://
|
1501
|
-
https://
|
1657
|
+
https://developer.woox.io/api-reference/endpoint/trading/get_orders
|
1658
|
+
https://developer.woox.io/api-reference/endpoint/trading/get_algo_orders
|
1502
1659
|
|
1503
1660
|
:param str symbol: unified market symbol of the market orders were made in
|
1504
1661
|
:param int [since]: the earliest time in ms to fetch orders for
|
@@ -1507,7 +1664,6 @@ class woo(Exchange, ImplicitAPI):
|
|
1507
1664
|
:param boolean [params.trigger]: whether the order is a trigger/algo order
|
1508
1665
|
:param boolean [params.isTriggered]: whether the order has been triggered(False by default)
|
1509
1666
|
:param str [params.side]: 'buy' or 'sell'
|
1510
|
-
:param boolean [params.trailing]: set to True if you want to fetch trailing orders
|
1511
1667
|
:param boolean [params.paginate]: set to True if you want to fetch orders with pagination
|
1512
1668
|
:returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
1513
1669
|
"""
|
@@ -1519,70 +1675,118 @@ class woo(Exchange, ImplicitAPI):
|
|
1519
1675
|
request: dict = {}
|
1520
1676
|
market: Market = None
|
1521
1677
|
trigger = self.safe_bool_2(params, 'stop', 'trigger')
|
1522
|
-
|
1523
|
-
params = self.omit(params, ['stop', 'trailing', 'trigger'])
|
1678
|
+
params = self.omit(params, ['stop', 'trigger'])
|
1524
1679
|
if symbol is not None:
|
1525
1680
|
market = self.market(symbol)
|
1526
1681
|
request['symbol'] = market['id']
|
1527
1682
|
if since is not None:
|
1528
|
-
|
1529
|
-
|
1530
|
-
|
1531
|
-
|
1683
|
+
request['startTime'] = since
|
1684
|
+
until = self.safe_integer(params, 'until') # unified in milliseconds
|
1685
|
+
params = self.omit(params, ['until'])
|
1686
|
+
if until is not None:
|
1687
|
+
request['endTime'] = until
|
1532
1688
|
if limit is not None:
|
1533
|
-
request['size'] = limit
|
1534
|
-
else:
|
1535
|
-
request['size'] = 50 if trailing else 500
|
1536
|
-
if trigger:
|
1537
|
-
request['algoType'] = 'stop'
|
1538
|
-
elif trailing:
|
1539
|
-
request['algoType'] = 'TRAILING_STOP'
|
1689
|
+
request['size'] = min(limit, 500)
|
1540
1690
|
response = None
|
1541
|
-
if trigger
|
1542
|
-
response = await self.
|
1691
|
+
if trigger:
|
1692
|
+
response = await self.v3PrivateGetTradeAlgoOrders(self.extend(request, params))
|
1693
|
+
#
|
1694
|
+
# {
|
1695
|
+
# "success": True,
|
1696
|
+
# "data": {
|
1697
|
+
# "rows": [
|
1698
|
+
# {
|
1699
|
+
# "algoOrderId": 10399260,
|
1700
|
+
# "clientAlgoOrderId": 0,
|
1701
|
+
# "rootAlgoOrderId": 10399260,
|
1702
|
+
# "parentAlgoOrderId": 0,
|
1703
|
+
# "symbol": "SPOT_LTC_USDT",
|
1704
|
+
# "algoOrderTag": "default",
|
1705
|
+
# "algoType": "TAKE_PROFIT",
|
1706
|
+
# "side": "BUY",
|
1707
|
+
# "quantity": 0.1,
|
1708
|
+
# "isTriggered": False,
|
1709
|
+
# "triggerPrice": 65,
|
1710
|
+
# "triggerStatus": "USELESS",
|
1711
|
+
# "type": "LIMIT",
|
1712
|
+
# "rootAlgoStatus": "NEW",
|
1713
|
+
# "algoStatus": "NEW",
|
1714
|
+
# "triggerPriceType": "MARKET_PRICE",
|
1715
|
+
# "price": 60,
|
1716
|
+
# "triggerTime": "0",
|
1717
|
+
# "totalExecutedQuantity": 0,
|
1718
|
+
# "visibleQuantity": 0.1,
|
1719
|
+
# "averageExecutedPrice": 0,
|
1720
|
+
# "totalFee": 0,
|
1721
|
+
# "feeAsset": "",
|
1722
|
+
# "totalRebate": 0,
|
1723
|
+
# "rebateAsset": "",
|
1724
|
+
# "reduceOnly": False,
|
1725
|
+
# "createdTime": "1752049747.730",
|
1726
|
+
# "updatedTime": "1752049747.730",
|
1727
|
+
# "positionSide": "BOTH"
|
1728
|
+
# }
|
1729
|
+
# ],
|
1730
|
+
# "meta": {
|
1731
|
+
# "total": 7,
|
1732
|
+
# "recordsPerPage": 1,
|
1733
|
+
# "currentPage": 1
|
1734
|
+
# }
|
1735
|
+
# },
|
1736
|
+
# "timestamp": 1752053127448
|
1737
|
+
# }
|
1738
|
+
#
|
1543
1739
|
else:
|
1544
|
-
response = await self.
|
1545
|
-
|
1546
|
-
|
1547
|
-
|
1548
|
-
|
1549
|
-
|
1550
|
-
|
1551
|
-
|
1552
|
-
|
1553
|
-
|
1554
|
-
|
1555
|
-
|
1556
|
-
|
1557
|
-
|
1558
|
-
|
1559
|
-
|
1560
|
-
|
1561
|
-
|
1562
|
-
|
1563
|
-
|
1564
|
-
|
1565
|
-
|
1566
|
-
|
1567
|
-
|
1568
|
-
|
1569
|
-
|
1570
|
-
|
1571
|
-
|
1572
|
-
|
1573
|
-
|
1574
|
-
|
1575
|
-
|
1576
|
-
|
1577
|
-
|
1740
|
+
response = await self.v3PrivateGetTradeOrders(self.extend(request, params))
|
1741
|
+
#
|
1742
|
+
# {
|
1743
|
+
# "success": True,
|
1744
|
+
# "data": {
|
1745
|
+
# "rows": [
|
1746
|
+
# {
|
1747
|
+
# "orderId": 60780315704,
|
1748
|
+
# "clientOrderId": 0,
|
1749
|
+
# "symbol": "SPOT_LTC_USDT",
|
1750
|
+
# "orderTag": "default",
|
1751
|
+
# "side": "BUY",
|
1752
|
+
# "quantity": 0.1,
|
1753
|
+
# "amount": null,
|
1754
|
+
# "type": "LIMIT",
|
1755
|
+
# "status": "NEW",
|
1756
|
+
# "price": 60,
|
1757
|
+
# "executed": 0,
|
1758
|
+
# "visible": 0.1,
|
1759
|
+
# "averageExecutedPrice": 0,
|
1760
|
+
# "totalFee": 0,
|
1761
|
+
# "feeAsset": "LTC",
|
1762
|
+
# "totalRebate": 0,
|
1763
|
+
# "rebateAsset": "USDT",
|
1764
|
+
# "reduceOnly": False,
|
1765
|
+
# "createdTime": "1752049062.496",
|
1766
|
+
# "realizedPnl": null,
|
1767
|
+
# "positionSide": "BOTH",
|
1768
|
+
# "bidAskLevel": null
|
1769
|
+
# }
|
1770
|
+
# ],
|
1771
|
+
# "meta": {
|
1772
|
+
# "total": 11,
|
1773
|
+
# "recordsPerPage": 1,
|
1774
|
+
# "currentPage": 1
|
1775
|
+
# }
|
1776
|
+
# },
|
1777
|
+
# "timestamp": 1752053061236
|
1778
|
+
# }
|
1779
|
+
#
|
1780
|
+
data = self.safe_value(response, 'data', {})
|
1781
|
+
orders = self.safe_list(data, 'rows', [])
|
1578
1782
|
return self.parse_orders(orders, market, since, limit)
|
1579
1783
|
|
1580
1784
|
async def fetch_open_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
1581
1785
|
"""
|
1582
1786
|
fetches information on multiple orders made by the user
|
1583
1787
|
|
1584
|
-
https://
|
1585
|
-
https://
|
1788
|
+
https://developer.woox.io/api-reference/endpoint/trading/get_orders
|
1789
|
+
https://developer.woox.io/api-reference/endpoint/trading/get_algo_orders
|
1586
1790
|
|
1587
1791
|
:param str symbol: unified market symbol of the market orders were made in
|
1588
1792
|
:param int [since]: the earliest time in ms to fetch orders for
|
@@ -1603,8 +1807,8 @@ class woo(Exchange, ImplicitAPI):
|
|
1603
1807
|
"""
|
1604
1808
|
fetches information on multiple orders made by the user
|
1605
1809
|
|
1606
|
-
https://
|
1607
|
-
https://
|
1810
|
+
https://developer.woox.io/api-reference/endpoint/trading/get_orders
|
1811
|
+
https://developer.woox.io/api-reference/endpoint/trading/get_algo_orders
|
1608
1812
|
|
1609
1813
|
:param str symbol: unified market symbol of the market orders were made in
|
1610
1814
|
:param int [since]: the earliest time in ms to fetch orders for
|
@@ -1631,81 +1835,107 @@ class woo(Exchange, ImplicitAPI):
|
|
1631
1835
|
|
1632
1836
|
def parse_order(self, order: dict, market: Market = None) -> Order:
|
1633
1837
|
#
|
1634
|
-
#
|
1635
|
-
#
|
1636
|
-
#
|
1637
|
-
#
|
1638
|
-
#
|
1639
|
-
#
|
1640
|
-
#
|
1641
|
-
#
|
1642
|
-
#
|
1643
|
-
#
|
1644
|
-
#
|
1645
|
-
#
|
1646
|
-
#
|
1647
|
-
#
|
1648
|
-
#
|
1649
|
-
#
|
1650
|
-
#
|
1651
|
-
#
|
1652
|
-
#
|
1653
|
-
#
|
1654
|
-
#
|
1655
|
-
#
|
1656
|
-
#
|
1657
|
-
#
|
1658
|
-
#
|
1659
|
-
#
|
1660
|
-
#
|
1661
|
-
#
|
1662
|
-
#
|
1663
|
-
#
|
1664
|
-
#
|
1665
|
-
#
|
1666
|
-
#
|
1667
|
-
#
|
1668
|
-
#
|
1669
|
-
#
|
1670
|
-
#
|
1671
|
-
#
|
1672
|
-
#
|
1673
|
-
#
|
1674
|
-
#
|
1675
|
-
#
|
1676
|
-
#
|
1677
|
-
|
1678
|
-
|
1679
|
-
|
1838
|
+
# createOrder
|
1839
|
+
# {
|
1840
|
+
# "orderId": 60667653330,
|
1841
|
+
# "clientOrderId": 0,
|
1842
|
+
# "type": "LIMIT",
|
1843
|
+
# "price": 60,
|
1844
|
+
# "quantity": 0.1,
|
1845
|
+
# "amount": null,
|
1846
|
+
# "bidAskLevel": null,
|
1847
|
+
# "timestamp": 1751871779855
|
1848
|
+
# }
|
1849
|
+
#
|
1850
|
+
# createOrder - algo
|
1851
|
+
# {
|
1852
|
+
# "orderId": "1578938",
|
1853
|
+
# "clientOrderId": "0",
|
1854
|
+
# "algoType": "STOP_LOSS",
|
1855
|
+
# "quantity": "0.1",
|
1856
|
+
# "timestamp": "1686149372216"
|
1857
|
+
# }
|
1858
|
+
#
|
1859
|
+
# fetchOrder
|
1860
|
+
# {
|
1861
|
+
# "orderId": 60780315704,
|
1862
|
+
# "clientOrderId": 0,
|
1863
|
+
# "symbol": "SPOT_LTC_USDT",
|
1864
|
+
# "orderTag": "default",
|
1865
|
+
# "side": "BUY",
|
1866
|
+
# "quantity": 0.1,
|
1867
|
+
# "amount": null,
|
1868
|
+
# "type": "LIMIT",
|
1869
|
+
# "status": "NEW",
|
1870
|
+
# "price": 60,
|
1871
|
+
# "executed": 0,
|
1872
|
+
# "visible": 0.1,
|
1873
|
+
# "averageExecutedPrice": 0,
|
1874
|
+
# "totalFee": 0,
|
1875
|
+
# "feeAsset": "LTC",
|
1876
|
+
# "totalRebate": 0,
|
1877
|
+
# "rebateAsset": "USDT",
|
1878
|
+
# "reduceOnly": False,
|
1879
|
+
# "createdTime": "1752049062.496",
|
1880
|
+
# "realizedPnl": null,
|
1881
|
+
# "positionSide": "BOTH",
|
1882
|
+
# "bidAskLevel": null
|
1883
|
+
# }
|
1884
|
+
#
|
1885
|
+
# fetchOrder - algo
|
1886
|
+
# {
|
1887
|
+
# "algoOrderId": 10399260,
|
1888
|
+
# "clientAlgoOrderId": 0,
|
1889
|
+
# "rootAlgoOrderId": 10399260,
|
1890
|
+
# "parentAlgoOrderId": 0,
|
1891
|
+
# "symbol": "SPOT_LTC_USDT",
|
1892
|
+
# "algoOrderTag": "default",
|
1893
|
+
# "algoType": "TAKE_PROFIT",
|
1894
|
+
# "side": "BUY",
|
1895
|
+
# "quantity": 0.1,
|
1896
|
+
# "isTriggered": False,
|
1897
|
+
# "triggerPrice": 65,
|
1898
|
+
# "triggerStatus": "USELESS",
|
1899
|
+
# "type": "LIMIT",
|
1900
|
+
# "rootAlgoStatus": "NEW",
|
1901
|
+
# "algoStatus": "NEW",
|
1902
|
+
# "triggerPriceType": "MARKET_PRICE",
|
1903
|
+
# "price": 60,
|
1904
|
+
# "triggerTime": "0",
|
1905
|
+
# "totalExecutedQuantity": 0,
|
1906
|
+
# "visibleQuantity": 0.1,
|
1907
|
+
# "averageExecutedPrice": 0,
|
1908
|
+
# "totalFee": 0,
|
1909
|
+
# "feeAsset": "",
|
1910
|
+
# "totalRebate": 0,
|
1911
|
+
# "rebateAsset": "",
|
1912
|
+
# "reduceOnly": False,
|
1913
|
+
# "createdTime": "1752049747.732",
|
1914
|
+
# "updatedTime": "1752049747.732",
|
1915
|
+
# "positionSide": "BOTH"
|
1916
|
+
# }
|
1917
|
+
#
|
1918
|
+
timestamp = self.safe_timestamp(order, 'createdTime')
|
1919
|
+
if timestamp is None:
|
1920
|
+
timestamp = self.safe_integer(order, 'timestamp')
|
1921
|
+
orderId = self.safe_string_2(order, 'orderId', 'algoOrderId')
|
1922
|
+
clientOrderId = self.omit_zero(self.safe_string_2(order, 'clientOrderId', 'clientAlgoOrderId')) # Somehow, self always returns 0 for limit order
|
1680
1923
|
marketId = self.safe_string(order, 'symbol')
|
1681
1924
|
market = self.safe_market(marketId, market)
|
1682
1925
|
symbol = market['symbol']
|
1683
|
-
price = self.
|
1684
|
-
amount = self.
|
1685
|
-
cost = self.
|
1686
|
-
orderType = self.
|
1926
|
+
price = self.safe_string(order, 'price')
|
1927
|
+
amount = self.safe_string(order, 'quantity') # This is base amount
|
1928
|
+
cost = self.safe_string(order, 'amount') # This is quote amount
|
1929
|
+
orderType = self.safe_string_lower(order, 'type')
|
1687
1930
|
status = self.safe_value_2(order, 'status', 'algoStatus')
|
1688
1931
|
side = self.safe_string_lower(order, 'side')
|
1689
1932
|
filled = self.omit_zero(self.safe_value_2(order, 'executed', 'totalExecutedQuantity'))
|
1690
|
-
average = self.omit_zero(self.
|
1933
|
+
average = self.omit_zero(self.safe_string(order, 'averageExecutedPrice'))
|
1691
1934
|
# remaining = Precise.string_sub(cost, filled)
|
1692
|
-
fee = self.
|
1693
|
-
feeCurrency = self.
|
1694
|
-
transactions = self.safe_value(order, 'Transactions')
|
1935
|
+
fee = self.safe_number(order, 'totalFee')
|
1936
|
+
feeCurrency = self.safe_string(order, 'feeAsset')
|
1695
1937
|
triggerPrice = self.safe_number(order, 'triggerPrice')
|
1696
|
-
|
1697
|
-
stopLossPrice: Num = None
|
1698
|
-
childOrders = self.safe_value(order, 'childOrders')
|
1699
|
-
if childOrders is not None:
|
1700
|
-
first = self.safe_value(childOrders, 0)
|
1701
|
-
innerChildOrders = self.safe_value(first, 'childOrders', [])
|
1702
|
-
innerChildOrdersLength = len(innerChildOrders)
|
1703
|
-
if innerChildOrdersLength > 0:
|
1704
|
-
takeProfitOrder = self.safe_value(innerChildOrders, 0)
|
1705
|
-
stopLossOrder = self.safe_value(innerChildOrders, 1)
|
1706
|
-
takeProfitPrice = self.safe_number(takeProfitOrder, 'triggerPrice')
|
1707
|
-
stopLossPrice = self.safe_number(stopLossOrder, 'triggerPrice')
|
1708
|
-
lastUpdateTimestamp = self.safe_timestamp_2(order, 'updatedTime', 'updated_time')
|
1938
|
+
lastUpdateTimestamp = self.safe_timestamp(order, 'updatedTime')
|
1709
1939
|
return self.safe_order({
|
1710
1940
|
'id': orderId,
|
1711
1941
|
'clientOrderId': clientOrderId,
|
@@ -1718,18 +1948,18 @@ class woo(Exchange, ImplicitAPI):
|
|
1718
1948
|
'type': orderType,
|
1719
1949
|
'timeInForce': self.parse_time_in_force(orderType),
|
1720
1950
|
'postOnly': None, # TO_DO
|
1721
|
-
'reduceOnly': self.safe_bool(order, '
|
1951
|
+
'reduceOnly': self.safe_bool(order, 'reduceOnly'),
|
1722
1952
|
'side': side,
|
1723
1953
|
'price': price,
|
1724
1954
|
'triggerPrice': triggerPrice,
|
1725
|
-
'takeProfitPrice':
|
1726
|
-
'stopLossPrice':
|
1955
|
+
'takeProfitPrice': None,
|
1956
|
+
'stopLossPrice': None,
|
1727
1957
|
'average': average,
|
1728
1958
|
'amount': amount,
|
1729
1959
|
'filled': filled,
|
1730
1960
|
'remaining': None, # TO_DO
|
1731
1961
|
'cost': cost,
|
1732
|
-
'trades':
|
1962
|
+
'trades': None,
|
1733
1963
|
'fee': {
|
1734
1964
|
'cost': fee,
|
1735
1965
|
'currency': feeCurrency,
|
@@ -1757,7 +1987,7 @@ class woo(Exchange, ImplicitAPI):
|
|
1757
1987
|
"""
|
1758
1988
|
fetches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
1759
1989
|
|
1760
|
-
https://
|
1990
|
+
https://developer.woox.io/api-reference/endpoint/public_data/orderbook
|
1761
1991
|
|
1762
1992
|
:param str symbol: unified symbol of the market to fetch the order book for
|
1763
1993
|
:param int [limit]: the maximum amount of order book entries to return
|
@@ -1770,33 +2000,37 @@ class woo(Exchange, ImplicitAPI):
|
|
1770
2000
|
'symbol': market['id'],
|
1771
2001
|
}
|
1772
2002
|
if limit is not None:
|
1773
|
-
|
1774
|
-
|
1775
|
-
response = await self.v1PublicGetOrderbookSymbol(self.extend(request, params))
|
2003
|
+
request['maxLevel'] = limit
|
2004
|
+
response = await self.v3PublicGetOrderbook(self.extend(request, params))
|
1776
2005
|
#
|
1777
|
-
# {
|
1778
|
-
# "success": True,
|
1779
|
-
# "timestamp": "1641562961192",
|
1780
|
-
# "asks": [
|
1781
|
-
# {price: '0.921', quantity: "76.01"},
|
1782
|
-
# {price: '0.933', quantity: "477.10"},
|
1783
|
-
# ...
|
1784
|
-
# ],
|
1785
|
-
# "bids": [
|
1786
|
-
# {price: '0.940', quantity: "13502.47"},
|
1787
|
-
# {price: '0.932', quantity: "43.91"},
|
1788
|
-
# ...
|
1789
|
-
# ]
|
1790
2006
|
# }
|
2007
|
+
# {
|
2008
|
+
# "success": True,
|
2009
|
+
# "timestamp": 1751620923344,
|
2010
|
+
# "data": {
|
2011
|
+
# "asks": [
|
2012
|
+
# {
|
2013
|
+
# "price": "108924.86",
|
2014
|
+
# "quantity": "0.032126"
|
2015
|
+
# }
|
2016
|
+
# ],
|
2017
|
+
# "bids": [
|
2018
|
+
# {
|
2019
|
+
# "price": "108924.85",
|
2020
|
+
# "quantity": "1.714147"
|
2021
|
+
# }
|
2022
|
+
# ]
|
2023
|
+
# }
|
2024
|
+
# }
|
1791
2025
|
#
|
2026
|
+
data = self.safe_dict(response, 'data', {})
|
1792
2027
|
timestamp = self.safe_integer(response, 'timestamp')
|
1793
|
-
return self.parse_order_book(
|
2028
|
+
return self.parse_order_book(data, symbol, timestamp, 'bids', 'asks', 'price', 'quantity')
|
1794
2029
|
|
1795
2030
|
async def fetch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
|
1796
2031
|
"""
|
1797
2032
|
|
1798
|
-
https://
|
1799
|
-
https://docs.woox.io/#kline-historical-data-public
|
2033
|
+
https://developer.woox.io/api-reference/endpoint/public_data/klineHistory
|
1800
2034
|
|
1801
2035
|
fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
1802
2036
|
:param str symbol: unified symbol of the market to fetch OHLCV data for
|
@@ -1804,6 +2038,7 @@ class woo(Exchange, ImplicitAPI):
|
|
1804
2038
|
:param int [since]: timestamp in ms of the earliest candle to fetch
|
1805
2039
|
:param int [limit]: max=1000, max=100 when since is defined and is less than(now - (999 * (timeframe in ms)))
|
1806
2040
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2041
|
+
:param int [params.until]: the latest time in ms to fetch entries for
|
1807
2042
|
:returns int[][]: A list of candles ordered, open, high, low, close, volume
|
1808
2043
|
"""
|
1809
2044
|
await self.load_markets()
|
@@ -1812,70 +2047,44 @@ class woo(Exchange, ImplicitAPI):
|
|
1812
2047
|
'symbol': market['id'],
|
1813
2048
|
'type': self.safe_string(self.timeframes, timeframe, timeframe),
|
1814
2049
|
}
|
1815
|
-
|
1816
|
-
if (limit is not None) and (since is not None):
|
1817
|
-
oneThousandCandles = self.parse_timeframe(timeframe) * 1000 * 999 # 999 because there will be delay between self and the request, causing the latest candle to be excluded sometimes
|
1818
|
-
startWithLimit = self.milliseconds() - oneThousandCandles
|
1819
|
-
useHistEndpoint = since < startWithLimit
|
1820
|
-
if useHistEndpoint:
|
1821
|
-
request['start_time'] = since
|
1822
|
-
elif limit is not None: # the hist endpoint does not accept limit
|
2050
|
+
if limit is not None:
|
1823
2051
|
request['limit'] = min(limit, 1000)
|
1824
|
-
|
1825
|
-
|
1826
|
-
|
1827
|
-
|
1828
|
-
|
1829
|
-
|
1830
|
-
|
1831
|
-
|
1832
|
-
|
1833
|
-
|
1834
|
-
|
1835
|
-
|
1836
|
-
|
1837
|
-
|
1838
|
-
|
1839
|
-
|
1840
|
-
|
1841
|
-
|
1842
|
-
|
1843
|
-
|
1844
|
-
|
1845
|
-
|
1846
|
-
|
1847
|
-
|
1848
|
-
|
1849
|
-
|
1850
|
-
|
1851
|
-
|
1852
|
-
|
1853
|
-
|
1854
|
-
|
1855
|
-
# {
|
1856
|
-
# "symbol": "SPOT_BTC_USDT",
|
1857
|
-
# "open": 44181.40000000,
|
1858
|
-
# "close": 44174.29000000,
|
1859
|
-
# "high": 44193.44000000,
|
1860
|
-
# "low": 44148.34000000,
|
1861
|
-
# "volume": 110.11930100,
|
1862
|
-
# "amount": 4863796.24318878,
|
1863
|
-
# "type": "1m",
|
1864
|
-
# "start_timestamp": 1704153600000,
|
1865
|
-
# "end_timestamp": 1704153660000
|
1866
|
-
# },
|
1867
|
-
# ...
|
1868
|
-
# ]
|
1869
|
-
# }
|
1870
|
-
# }
|
1871
|
-
#
|
1872
|
-
rows = self.safe_list(response, 'rows', [])
|
2052
|
+
if since is not None:
|
2053
|
+
request['after'] = since
|
2054
|
+
until = self.safe_integer(params, 'until')
|
2055
|
+
params = self.omit(params, 'until')
|
2056
|
+
if until is not None:
|
2057
|
+
request['before'] = until
|
2058
|
+
response = await self.v3PublicGetKlineHistory(self.extend(request, params))
|
2059
|
+
#
|
2060
|
+
# {
|
2061
|
+
# "success": True,
|
2062
|
+
# "data": {
|
2063
|
+
# "rows": [
|
2064
|
+
# {
|
2065
|
+
# "symbol": "SPOT_BTC_USDT",
|
2066
|
+
# "open": "108994.16",
|
2067
|
+
# "close": "108994.16",
|
2068
|
+
# "high": "108994.16",
|
2069
|
+
# "low": "108994.16",
|
2070
|
+
# "volume": "0",
|
2071
|
+
# "amount": "0",
|
2072
|
+
# "type": "1m",
|
2073
|
+
# "startTimestamp": 1751622120000,
|
2074
|
+
# "endTimestamp": 1751622180000
|
2075
|
+
# }
|
2076
|
+
# ]
|
2077
|
+
# },
|
2078
|
+
# "timestamp": 1751622205410
|
2079
|
+
# }
|
2080
|
+
#
|
2081
|
+
data = self.safe_dict(response, 'data', {})
|
2082
|
+
rows = self.safe_list(data, 'rows', [])
|
1873
2083
|
return self.parse_ohlcvs(rows, market, timeframe, since, limit)
|
1874
2084
|
|
1875
2085
|
def parse_ohlcv(self, ohlcv, market: Market = None) -> list:
|
1876
|
-
# example response in fetchOHLCV
|
1877
2086
|
return [
|
1878
|
-
self.safe_integer(ohlcv, '
|
2087
|
+
self.safe_integer(ohlcv, 'startTimestamp'),
|
1879
2088
|
self.safe_number(ohlcv, 'open'),
|
1880
2089
|
self.safe_number(ohlcv, 'high'),
|
1881
2090
|
self.safe_number(ohlcv, 'low'),
|
@@ -1929,7 +2138,7 @@ class woo(Exchange, ImplicitAPI):
|
|
1929
2138
|
"""
|
1930
2139
|
fetch all trades made by the user
|
1931
2140
|
|
1932
|
-
https://
|
2141
|
+
https://developer.woox.io/api-reference/endpoint/trading/get_transactions
|
1933
2142
|
|
1934
2143
|
:param str symbol: unified market symbol
|
1935
2144
|
:param int [since]: the earliest time in ms to fetch trades for
|
@@ -1949,83 +2158,149 @@ class woo(Exchange, ImplicitAPI):
|
|
1949
2158
|
market = self.market(symbol)
|
1950
2159
|
request['symbol'] = market['id']
|
1951
2160
|
if since is not None:
|
1952
|
-
request['
|
1953
|
-
|
2161
|
+
request['startTime'] = since
|
2162
|
+
until = self.safe_integer(params, 'until') # unified in milliseconds
|
2163
|
+
params = self.omit(params, ['until'])
|
2164
|
+
if until is not None:
|
2165
|
+
request['endTime'] = until
|
1954
2166
|
if limit is not None:
|
1955
|
-
request['
|
1956
|
-
|
1957
|
-
|
1958
|
-
|
1959
|
-
#
|
1960
|
-
#
|
1961
|
-
#
|
1962
|
-
#
|
1963
|
-
#
|
1964
|
-
#
|
1965
|
-
#
|
1966
|
-
#
|
1967
|
-
#
|
1968
|
-
#
|
1969
|
-
#
|
1970
|
-
#
|
1971
|
-
#
|
1972
|
-
#
|
1973
|
-
#
|
1974
|
-
#
|
1975
|
-
#
|
1976
|
-
#
|
1977
|
-
# "
|
2167
|
+
request['limit'] = limit
|
2168
|
+
response = await self.v3PrivateGetTradeTransactionHistory(self.extend(request, params))
|
2169
|
+
#
|
2170
|
+
# {
|
2171
|
+
# "success": True,
|
2172
|
+
# "data": {
|
2173
|
+
# "rows": [
|
2174
|
+
# {
|
2175
|
+
# "id": 1734947821,
|
2176
|
+
# "symbol": "SPOT_LTC_USDT",
|
2177
|
+
# "orderId": 60780383217,
|
2178
|
+
# "executedPrice": 87.86,
|
2179
|
+
# "executedQuantity": 0.1,
|
2180
|
+
# "fee": 0.0001,
|
2181
|
+
# "realizedPnl": null,
|
2182
|
+
# "feeAsset": "LTC",
|
2183
|
+
# "orderTag": "default",
|
2184
|
+
# "side": "BUY",
|
2185
|
+
# "executedTimestamp": "1752055173.630",
|
2186
|
+
# "isMaker": 0
|
2187
|
+
# }
|
2188
|
+
# ],
|
2189
|
+
# "meta": {
|
2190
|
+
# "total": 1,
|
2191
|
+
# "recordsPerPage": 100,
|
2192
|
+
# "currentPage": 1
|
2193
|
+
# }
|
1978
2194
|
# },
|
1979
|
-
#
|
1980
|
-
#
|
1981
|
-
#
|
1982
|
-
|
2195
|
+
# "timestamp": 1752055545121
|
2196
|
+
# }
|
2197
|
+
#
|
2198
|
+
data = self.safe_dict(response, 'data', {})
|
2199
|
+
trades = self.safe_list(data, 'rows', [])
|
1983
2200
|
return self.parse_trades(trades, market, since, limit, params)
|
1984
2201
|
|
1985
2202
|
async def fetch_accounts(self, params={}) -> List[Account]:
|
1986
2203
|
"""
|
1987
2204
|
fetch all the accounts associated with a profile
|
1988
2205
|
|
1989
|
-
https://
|
2206
|
+
https://developer.woox.io/api-reference/endpoint/account/get_account_info
|
2207
|
+
https://developer.woox.io/api-reference/endpoint/account/sub_accounts
|
1990
2208
|
|
1991
2209
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1992
2210
|
:returns dict: a dictionary of `account structures <https://docs.ccxt.com/#/?id=account-structure>` indexed by the account type
|
1993
2211
|
"""
|
1994
|
-
|
2212
|
+
mainAccountPromise = self.v3PrivateGetAccountInfo(params)
|
1995
2213
|
#
|
1996
2214
|
# {
|
1997
|
-
# "
|
1998
|
-
#
|
1999
|
-
#
|
2000
|
-
#
|
2001
|
-
#
|
2002
|
-
#
|
2003
|
-
#
|
2004
|
-
#
|
2005
|
-
#
|
2006
|
-
#
|
2007
|
-
#
|
2008
|
-
#
|
2215
|
+
# "success": True,
|
2216
|
+
# "data": {
|
2217
|
+
# "applicationId": "251bf5c4-f3c8-4544-bb8b-80001007c3c0",
|
2218
|
+
# "account": "carlos_jose_lima@yahoo.com",
|
2219
|
+
# "alias": "carlos_jose_lima@yahoo.com",
|
2220
|
+
# "otpauth": True,
|
2221
|
+
# "accountMode": "FUTURES",
|
2222
|
+
# "positionMode": "ONE_WAY",
|
2223
|
+
# "leverage": 0,
|
2224
|
+
# "marginRatio": "10",
|
2225
|
+
# "openMarginRatio": "10",
|
2226
|
+
# "initialMarginRatio": "10",
|
2227
|
+
# "maintenanceMarginRatio": "0.03",
|
2228
|
+
# "totalCollateral": "165.55629469",
|
2229
|
+
# "freeCollateral": "165.55629469",
|
2230
|
+
# "totalAccountValue": "167.32418611",
|
2231
|
+
# "totalTradingValue": "167.32418611",
|
2232
|
+
# "totalVaultValue": "0",
|
2233
|
+
# "totalStakingValue": "0",
|
2234
|
+
# "totalLaunchpadValue": "0",
|
2235
|
+
# "totalEarnValue": "0",
|
2236
|
+
# "referrerID": null,
|
2237
|
+
# "accountType": "Main"
|
2238
|
+
# },
|
2239
|
+
# "timestamp": 1752062807915
|
2009
2240
|
# }
|
2010
2241
|
#
|
2011
|
-
|
2242
|
+
subAccountPromise = self.v3PrivateGetAccountSubAccountsAll(params)
|
2243
|
+
#
|
2244
|
+
# {
|
2245
|
+
# "success": True,
|
2246
|
+
# "data": {
|
2247
|
+
# "rows": [
|
2248
|
+
# {
|
2249
|
+
# "applicationId": "6b43de5c-0955-4887-9862-d84e4689f9fe",
|
2250
|
+
# "name": "sub_account_2",
|
2251
|
+
# "createdTime": "1606897264.994"
|
2252
|
+
# },
|
2253
|
+
# ]
|
2254
|
+
# },
|
2255
|
+
# "timestamp": 1721295317627
|
2256
|
+
# }
|
2257
|
+
#
|
2258
|
+
mainAccountResponse, subAccountResponse = await asyncio.gather(*[mainAccountPromise, subAccountPromise])
|
2259
|
+
mainData = self.safe_dict(mainAccountResponse, 'data', {})
|
2260
|
+
mainRows = [mainData]
|
2261
|
+
subData = self.safe_dict(subAccountResponse, 'data', {})
|
2262
|
+
subRows = self.safe_list(subData, 'rows', [])
|
2263
|
+
rows = self.array_concat(mainRows, subRows)
|
2012
2264
|
return self.parse_accounts(rows, params)
|
2013
2265
|
|
2014
2266
|
def parse_account(self, account):
|
2015
2267
|
#
|
2016
2268
|
# {
|
2017
|
-
# "
|
2018
|
-
# "account": "
|
2019
|
-
# "
|
2269
|
+
# "applicationId": "251bf5c4-f3c8-4544-bb8b-80001007c3c0",
|
2270
|
+
# "account": "carlos_jose_lima@yahoo.com",
|
2271
|
+
# "alias": "carlos_jose_lima@yahoo.com",
|
2272
|
+
# "otpauth": True,
|
2273
|
+
# "accountMode": "FUTURES",
|
2274
|
+
# "positionMode": "ONE_WAY",
|
2275
|
+
# "leverage": 0,
|
2276
|
+
# "marginRatio": "10",
|
2277
|
+
# "openMarginRatio": "10",
|
2278
|
+
# "initialMarginRatio": "10",
|
2279
|
+
# "maintenanceMarginRatio": "0.03",
|
2280
|
+
# "totalCollateral": "165.55629469",
|
2281
|
+
# "freeCollateral": "165.55629469",
|
2282
|
+
# "totalAccountValue": "167.32418611",
|
2283
|
+
# "totalTradingValue": "167.32418611",
|
2284
|
+
# "totalVaultValue": "0",
|
2285
|
+
# "totalStakingValue": "0",
|
2286
|
+
# "totalLaunchpadValue": "0",
|
2287
|
+
# "totalEarnValue": "0",
|
2288
|
+
# "referrerID": null,
|
2289
|
+
# "accountType": "Main"
|
2290
|
+
# }
|
2291
|
+
#
|
2292
|
+
# {
|
2293
|
+
# "applicationId": "6b43de5c-0955-4887-9862-d84e4689f9fe",
|
2294
|
+
# "name": "sub_account_2",
|
2295
|
+
# "createdTime": "1606897264.994"
|
2020
2296
|
# }
|
2021
2297
|
#
|
2022
|
-
accountId = self.safe_string(account, 'account')
|
2023
2298
|
return {
|
2024
2299
|
'info': account,
|
2025
|
-
'id': self.safe_string(account, '
|
2026
|
-
'name':
|
2300
|
+
'id': self.safe_string(account, 'applicationId'),
|
2301
|
+
'name': self.safe_string_n(account, ['name', 'account', 'alias']),
|
2027
2302
|
'code': None,
|
2028
|
-
'type':
|
2303
|
+
'type': self.safe_string_lower(account, 'accountType', 'subaccount'),
|
2029
2304
|
}
|
2030
2305
|
|
2031
2306
|
async def fetch_balance(self, params={}) -> Balances:
|
@@ -2083,7 +2358,7 @@ class woo(Exchange, ImplicitAPI):
|
|
2083
2358
|
"""
|
2084
2359
|
fetch the deposit address for a currency associated with self account
|
2085
2360
|
|
2086
|
-
https://
|
2361
|
+
https://developer.woox.io/api-reference/endpoint/assets/get_wallet_deposit
|
2087
2362
|
|
2088
2363
|
:param str code: unified currency code
|
2089
2364
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -2092,18 +2367,25 @@ class woo(Exchange, ImplicitAPI):
|
|
2092
2367
|
# self method is TODO because of networks unification
|
2093
2368
|
await self.load_markets()
|
2094
2369
|
currency = self.currency(code)
|
2095
|
-
|
2096
|
-
|
2370
|
+
networkCode = None
|
2371
|
+
networkCode, params = self.handle_network_code_and_params(params)
|
2097
2372
|
request: dict = {
|
2098
|
-
'token':
|
2373
|
+
'token': currency['id'],
|
2374
|
+
'network': self.network_code_to_id(networkCode),
|
2099
2375
|
}
|
2100
|
-
response = await self.
|
2101
|
-
#
|
2102
|
-
#
|
2103
|
-
#
|
2104
|
-
#
|
2105
|
-
#
|
2106
|
-
|
2376
|
+
response = await self.v3PrivateGetAssetWalletDeposit(self.extend(request, params))
|
2377
|
+
#
|
2378
|
+
# {
|
2379
|
+
# "success": True,
|
2380
|
+
# "data": {
|
2381
|
+
# "address": "0x31d64B3230f8baDD91dE1710A65DF536aF8f7cDa",
|
2382
|
+
# "extra": ""
|
2383
|
+
# },
|
2384
|
+
# "timestamp": 1721300689532
|
2385
|
+
# }
|
2386
|
+
#
|
2387
|
+
data = self.safe_dict(response, 'data', {})
|
2388
|
+
return self.parse_deposit_address(data, currency)
|
2107
2389
|
|
2108
2390
|
def get_dedicated_network_id(self, currency, params: dict) -> Any:
|
2109
2391
|
networkCode = None
|
@@ -2133,57 +2415,63 @@ class woo(Exchange, ImplicitAPI):
|
|
2133
2415
|
currency: Currency = None
|
2134
2416
|
if code is not None:
|
2135
2417
|
currency = self.currency(code)
|
2136
|
-
request['
|
2418
|
+
request['token'] = currency['id']
|
2419
|
+
networkCode = None
|
2420
|
+
networkCode, params = self.handle_network_code_and_params(params)
|
2421
|
+
if networkCode is not None:
|
2422
|
+
request['network'] = self.network_code_to_id(networkCode)
|
2137
2423
|
if since is not None:
|
2138
|
-
request['
|
2424
|
+
request['startTime'] = since
|
2139
2425
|
if limit is not None:
|
2140
|
-
request['
|
2426
|
+
request['size'] = min(limit, 1000)
|
2141
2427
|
transactionType = self.safe_string(params, 'type')
|
2142
2428
|
params = self.omit(params, 'type')
|
2143
2429
|
if transactionType is not None:
|
2144
2430
|
request['type'] = transactionType
|
2145
|
-
response = await self.
|
2146
|
-
#
|
2147
|
-
#
|
2148
|
-
#
|
2149
|
-
# "
|
2150
|
-
#
|
2151
|
-
#
|
2152
|
-
#
|
2153
|
-
#
|
2154
|
-
#
|
2155
|
-
#
|
2156
|
-
#
|
2157
|
-
#
|
2158
|
-
#
|
2159
|
-
#
|
2160
|
-
#
|
2161
|
-
#
|
2162
|
-
#
|
2163
|
-
#
|
2164
|
-
#
|
2165
|
-
#
|
2166
|
-
#
|
2167
|
-
#
|
2168
|
-
#
|
2169
|
-
#
|
2170
|
-
#
|
2171
|
-
#
|
2172
|
-
#
|
2173
|
-
#
|
2174
|
-
#
|
2175
|
-
#
|
2176
|
-
#
|
2177
|
-
#
|
2178
|
-
#
|
2179
|
-
#
|
2180
|
-
|
2431
|
+
response = await self.v3PrivateGetAssetWalletHistory(self.extend(request, params))
|
2432
|
+
#
|
2433
|
+
# {
|
2434
|
+
# "success": True,
|
2435
|
+
# "data": {
|
2436
|
+
# "rows": [
|
2437
|
+
# {
|
2438
|
+
# "createdTime": "1734964440.523",
|
2439
|
+
# "updatedTime": "1734964614.081",
|
2440
|
+
# "id": "24122314340000585",
|
2441
|
+
# "externalId": "241223143600621",
|
2442
|
+
# "applicationId": "251bf5c4-f3c8-4544-bb8b-80001007c3c0",
|
2443
|
+
# "token": "ARB_USDCNATIVE",
|
2444
|
+
# "targetAddress": "0x4d6802d2736daa85e6242ef0dc0f00aa0e68f635",
|
2445
|
+
# "sourceAddress": "0x63DFE4e34A3bFC00eB0220786238a7C6cEF8Ffc4",
|
2446
|
+
# "extra": "",
|
2447
|
+
# "type": "BALANCE",
|
2448
|
+
# "tokenSide": "WITHDRAW",
|
2449
|
+
# "amount": "10.00000000",
|
2450
|
+
# "txId": "0x891ade0a47fd55466bb9d06702bea4edcb75ed9367d9afbc47b93a84f496d2e6",
|
2451
|
+
# "feeToken": "USDC",
|
2452
|
+
# "feeAmount": "2",
|
2453
|
+
# "status": "COMPLETED",
|
2454
|
+
# "confirmingThreshold": null,
|
2455
|
+
# "confirmedNumber": null
|
2456
|
+
# }
|
2457
|
+
# ],
|
2458
|
+
# "meta": {
|
2459
|
+
# "total": 1,
|
2460
|
+
# "records_per_page": 25,
|
2461
|
+
# "current_page": 1
|
2462
|
+
# }
|
2463
|
+
# },
|
2464
|
+
# "timestamp": 1752485344719
|
2465
|
+
# }
|
2466
|
+
#
|
2467
|
+
data = self.safe_dict(response, 'data', {})
|
2468
|
+
return [currency, self.safe_list(data, 'rows', [])]
|
2181
2469
|
|
2182
2470
|
async def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[LedgerEntry]:
|
2183
2471
|
"""
|
2184
2472
|
fetch the history of changes, actions done by the user or operations that altered balance of the user
|
2185
2473
|
|
2186
|
-
https://
|
2474
|
+
https://developer.woox.io/api-reference/endpoint/assets/get_wallet_history
|
2187
2475
|
|
2188
2476
|
:param str [code]: unified currency code, default is None
|
2189
2477
|
:param int [since]: timestamp in ms of the earliest ledger entry, default is None
|
@@ -2197,22 +2485,43 @@ class woo(Exchange, ImplicitAPI):
|
|
2197
2485
|
return self.parse_ledger(rows, currency, since, limit, params)
|
2198
2486
|
|
2199
2487
|
def parse_ledger_entry(self, item: dict, currency: Currency = None) -> LedgerEntry:
|
2488
|
+
#
|
2489
|
+
# {
|
2490
|
+
# "createdTime": "1734964440.523",
|
2491
|
+
# "updatedTime": "1734964614.081",
|
2492
|
+
# "id": "24122314340000585",
|
2493
|
+
# "externalId": "241223143600621",
|
2494
|
+
# "applicationId": "251bf5c4-f3c8-4544-bb8b-80001007c3c0",
|
2495
|
+
# "token": "ARB_USDCNATIVE",
|
2496
|
+
# "targetAddress": "0x4d6802d2736daa85e6242ef0dc0f00aa0e68f635",
|
2497
|
+
# "sourceAddress": "0x63DFE4e34A3bFC00eB0220786238a7C6cEF8Ffc4",
|
2498
|
+
# "extra": "",
|
2499
|
+
# "type": "BALANCE",
|
2500
|
+
# "tokenSide": "WITHDRAW",
|
2501
|
+
# "amount": "10.00000000",
|
2502
|
+
# "txId": "0x891ade0a47fd55466bb9d06702bea4edcb75ed9367d9afbc47b93a84f496d2e6",
|
2503
|
+
# "feeToken": "USDC",
|
2504
|
+
# "feeAmount": "2",
|
2505
|
+
# "status": "COMPLETED",
|
2506
|
+
# "confirmingThreshold": null,
|
2507
|
+
# "confirmedNumber": null
|
2508
|
+
# }
|
2509
|
+
#
|
2200
2510
|
networkizedCode = self.safe_string(item, 'token')
|
2201
|
-
|
2202
|
-
code = currencyDefined['code']
|
2511
|
+
code = self.safe_currency_code(networkizedCode, currency)
|
2203
2512
|
currency = self.safe_currency(code, currency)
|
2204
2513
|
amount = self.safe_number(item, 'amount')
|
2205
|
-
side = self.safe_string(item, '
|
2514
|
+
side = self.safe_string(item, 'tokenSide')
|
2206
2515
|
direction = 'in' if (side == 'DEPOSIT') else 'out'
|
2207
|
-
timestamp = self.safe_timestamp(item, '
|
2208
|
-
fee = self.parse_token_and_fee_temp(item, '
|
2516
|
+
timestamp = self.safe_timestamp(item, 'createdTime')
|
2517
|
+
fee = self.parse_token_and_fee_temp(item, ['feeToken'], ['feeAmount'])
|
2209
2518
|
return self.safe_ledger_entry({
|
2210
2519
|
'info': item,
|
2211
2520
|
'id': self.safe_string(item, 'id'),
|
2212
2521
|
'currency': code,
|
2213
2522
|
'account': self.safe_string(item, 'account'),
|
2214
2523
|
'referenceAccount': None,
|
2215
|
-
'referenceId': self.safe_string(item, '
|
2524
|
+
'referenceId': self.safe_string(item, 'txId'),
|
2216
2525
|
'status': self.parse_transaction_status(self.safe_string(item, 'status')),
|
2217
2526
|
'amount': amount,
|
2218
2527
|
'before': None,
|
@@ -2248,7 +2557,7 @@ class woo(Exchange, ImplicitAPI):
|
|
2248
2557
|
"""
|
2249
2558
|
fetch all deposits made to an account
|
2250
2559
|
|
2251
|
-
https://
|
2560
|
+
https://developer.woox.io/api-reference/endpoint/assets/get_wallet_history
|
2252
2561
|
|
2253
2562
|
:param str code: unified currency code
|
2254
2563
|
:param int [since]: the earliest time in ms to fetch deposits for
|
@@ -2257,7 +2566,7 @@ class woo(Exchange, ImplicitAPI):
|
|
2257
2566
|
:returns dict[]: a list of `transaction structures <https://docs.ccxt.com/#/?id=transaction-structure>`
|
2258
2567
|
"""
|
2259
2568
|
request: dict = {
|
2260
|
-
'
|
2569
|
+
'tokenSide': 'DEPOSIT',
|
2261
2570
|
}
|
2262
2571
|
return await self.fetch_deposits_withdrawals(code, since, limit, self.extend(request, params))
|
2263
2572
|
|
@@ -2265,7 +2574,7 @@ class woo(Exchange, ImplicitAPI):
|
|
2265
2574
|
"""
|
2266
2575
|
fetch all withdrawals made from an account
|
2267
2576
|
|
2268
|
-
https://
|
2577
|
+
https://developer.woox.io/api-reference/endpoint/assets/get_wallet_history
|
2269
2578
|
|
2270
2579
|
:param str code: unified currency code
|
2271
2580
|
:param int [since]: the earliest time in ms to fetch withdrawals for
|
@@ -2274,7 +2583,7 @@ class woo(Exchange, ImplicitAPI):
|
|
2274
2583
|
:returns dict[]: a list of `transaction structures <https://docs.ccxt.com/#/?id=transaction-structure>`
|
2275
2584
|
"""
|
2276
2585
|
request: dict = {
|
2277
|
-
'
|
2586
|
+
'tokenSide': 'WITHDRAW',
|
2278
2587
|
}
|
2279
2588
|
return await self.fetch_deposits_withdrawals(code, since, limit, self.extend(request, params))
|
2280
2589
|
|
@@ -2282,7 +2591,7 @@ class woo(Exchange, ImplicitAPI):
|
|
2282
2591
|
"""
|
2283
2592
|
fetch history of deposits and withdrawals
|
2284
2593
|
|
2285
|
-
https://
|
2594
|
+
https://developer.woox.io/api-reference/endpoint/assets/get_wallet_history
|
2286
2595
|
|
2287
2596
|
:param str [code]: unified currency code for the currency of the deposit/withdrawals, default is None
|
2288
2597
|
:param int [since]: timestamp in ms of the earliest deposit/withdrawal, default is None
|
@@ -2296,35 +2605,45 @@ class woo(Exchange, ImplicitAPI):
|
|
2296
2605
|
currencyRows = await self.get_asset_history_rows(code, since, limit, self.extend(request, params))
|
2297
2606
|
currency = self.safe_value(currencyRows, 0)
|
2298
2607
|
rows = self.safe_list(currencyRows, 1)
|
2608
|
+
return self.parse_transactions(rows, currency, since, limit, params)
|
2609
|
+
|
2610
|
+
def parse_transaction(self, transaction: dict, currency: Currency = None) -> Transaction:
|
2299
2611
|
#
|
2300
2612
|
# {
|
2301
|
-
# "
|
2302
|
-
# "
|
2303
|
-
#
|
2304
|
-
#
|
2305
|
-
#
|
2306
|
-
#
|
2307
|
-
# "
|
2613
|
+
# "createdTime": "1734964440.523",
|
2614
|
+
# "updatedTime": "1734964614.081",
|
2615
|
+
# "id": "24122314340000585",
|
2616
|
+
# "externalId": "241223143600621",
|
2617
|
+
# "applicationId": "251bf5c4-f3c8-4544-bb8b-80001007c3c0",
|
2618
|
+
# "token": "ARB_USDCNATIVE",
|
2619
|
+
# "targetAddress": "0x4d6802d2736daa85e6242ef0dc0f00aa0e68f635",
|
2620
|
+
# "sourceAddress": "0x63DFE4e34A3bFC00eB0220786238a7C6cEF8Ffc4",
|
2621
|
+
# "extra": "",
|
2622
|
+
# "type": "BALANCE",
|
2623
|
+
# "tokenSide": "WITHDRAW",
|
2624
|
+
# "amount": "10.00000000",
|
2625
|
+
# "txId": "0x891ade0a47fd55466bb9d06702bea4edcb75ed9367d9afbc47b93a84f496d2e6",
|
2626
|
+
# "feeToken": "USDC",
|
2627
|
+
# "feeAmount": "2",
|
2628
|
+
# "status": "COMPLETED",
|
2629
|
+
# "confirmingThreshold": null,
|
2630
|
+
# "confirmedNumber": null
|
2308
2631
|
# }
|
2309
2632
|
#
|
2310
|
-
return self.parse_transactions(rows, currency, since, limit, params)
|
2311
|
-
|
2312
|
-
def parse_transaction(self, transaction: dict, currency: Currency = None) -> Transaction:
|
2313
|
-
# example in fetchLedger
|
2314
2633
|
networkizedCode = self.safe_string(transaction, 'token')
|
2315
2634
|
currencyDefined = self.get_currency_from_chaincode(networkizedCode, currency)
|
2316
2635
|
code = currencyDefined['code']
|
2317
|
-
movementDirection = self.
|
2636
|
+
movementDirection = self.safe_string_lower_2(transaction, 'token_side', 'tokenSide')
|
2318
2637
|
if movementDirection == 'withdraw':
|
2319
2638
|
movementDirection = 'withdrawal'
|
2320
|
-
fee = self.parse_token_and_fee_temp(transaction, 'fee_token', 'fee_amount')
|
2321
|
-
addressTo = self.
|
2322
|
-
addressFrom = self.
|
2323
|
-
timestamp = self.
|
2639
|
+
fee = self.parse_token_and_fee_temp(transaction, ['fee_token', 'feeToken'], ['fee_amount', 'feeAmount'])
|
2640
|
+
addressTo = self.safe_string_2(transaction, 'target_address', 'targetAddress')
|
2641
|
+
addressFrom = self.safe_string_2(transaction, 'source_address', 'sourceAddress')
|
2642
|
+
timestamp = self.safe_timestamp_2(transaction, 'created_time', 'createdTime')
|
2324
2643
|
return {
|
2325
2644
|
'info': transaction,
|
2326
|
-
'id': self.
|
2327
|
-
'txid': self.
|
2645
|
+
'id': self.safe_string_n(transaction, ['id', 'withdraw_id', 'withdrawId']),
|
2646
|
+
'txid': self.safe_string_2(transaction, 'tx_id', 'txId'),
|
2328
2647
|
'timestamp': timestamp,
|
2329
2648
|
'datetime': self.iso8601(timestamp),
|
2330
2649
|
'address': None,
|
@@ -2337,7 +2656,7 @@ class woo(Exchange, ImplicitAPI):
|
|
2337
2656
|
'amount': self.safe_number(transaction, 'amount'),
|
2338
2657
|
'currency': code,
|
2339
2658
|
'status': self.parse_transaction_status(self.safe_string(transaction, 'status')),
|
2340
|
-
'updated': self.
|
2659
|
+
'updated': self.safe_timestamp_2(transaction, 'updated_time', 'updatedTime'),
|
2341
2660
|
'comment': None,
|
2342
2661
|
'internal': None,
|
2343
2662
|
'fee': fee,
|
@@ -2395,7 +2714,7 @@ class woo(Exchange, ImplicitAPI):
|
|
2395
2714
|
"""
|
2396
2715
|
fetch a history of internal transfers made on an account
|
2397
2716
|
|
2398
|
-
https://
|
2717
|
+
https://developer.woox.io/api-reference/endpoint/assets/get_transfer_history
|
2399
2718
|
|
2400
2719
|
:param str code: unified currency code of the currency transferred
|
2401
2720
|
:param int [since]: the earliest time in ms to fetch transfers for
|
@@ -2405,41 +2724,52 @@ class woo(Exchange, ImplicitAPI):
|
|
2405
2724
|
:returns dict[]: a list of `transfer structures <https://docs.ccxt.com/#/?id=transfer-structure>`
|
2406
2725
|
"""
|
2407
2726
|
request: dict = {}
|
2727
|
+
currency = None
|
2728
|
+
if code is not None:
|
2729
|
+
currency = self.currency(code)
|
2408
2730
|
if limit is not None:
|
2409
2731
|
request['size'] = limit
|
2410
2732
|
if since is not None:
|
2411
|
-
request['
|
2733
|
+
request['startTime'] = since
|
2412
2734
|
until = self.safe_integer(params, 'until') # unified in milliseconds
|
2413
2735
|
params = self.omit(params, ['until'])
|
2414
2736
|
if until is not None:
|
2415
|
-
request['
|
2416
|
-
response = await self.
|
2737
|
+
request['endTime'] = until
|
2738
|
+
response = await self.v3PrivateGetAssetTransferHistory(self.extend(request, params))
|
2417
2739
|
#
|
2418
2740
|
# {
|
2419
|
-
# "
|
2420
|
-
#
|
2421
|
-
#
|
2422
|
-
#
|
2423
|
-
#
|
2424
|
-
#
|
2425
|
-
#
|
2426
|
-
#
|
2427
|
-
#
|
2428
|
-
#
|
2429
|
-
#
|
2430
|
-
#
|
2741
|
+
# "success": True,
|
2742
|
+
# "data": {
|
2743
|
+
# "rows": [
|
2744
|
+
# {
|
2745
|
+
# "id": 225,
|
2746
|
+
# "token": "USDT",
|
2747
|
+
# "amount": "1000000",
|
2748
|
+
# "status": "COMPLETED",
|
2749
|
+
# "from": {
|
2750
|
+
# "applicationId": "046b5c5c-5b44-4d27-9593-ddc32c0a08ae",
|
2751
|
+
# "accountName": "Main"
|
2752
|
+
# },
|
2753
|
+
# "to": {
|
2754
|
+
# "applicationId": "082ae5ae-e26a-4fb1-be5b-03e5b4867663",
|
2755
|
+
# "accountName": "sub001"
|
2756
|
+
# },
|
2757
|
+
# "createdTime": "1642660941.534",
|
2758
|
+
# "updatedTime": "1642660941.950"
|
2759
|
+
# }
|
2760
|
+
# ],
|
2761
|
+
# "meta": {
|
2762
|
+
# "total": 46,
|
2763
|
+
# "recordsPerPage": 1,
|
2764
|
+
# "currentPage": 1
|
2431
2765
|
# }
|
2432
|
-
# ],
|
2433
|
-
# "meta": {
|
2434
|
-
# "total": 50,
|
2435
|
-
# "records_per_page": 25,
|
2436
|
-
# "current_page": 1
|
2437
2766
|
# },
|
2438
|
-
# "
|
2767
|
+
# "timestamp": 1721295317627
|
2439
2768
|
# }
|
2440
2769
|
#
|
2441
|
-
data = self.
|
2442
|
-
|
2770
|
+
data = self.safe_dict(response, 'data', {})
|
2771
|
+
rows = self.safe_list(data, 'rows', [])
|
2772
|
+
return self.parse_transfers(rows, currency, since, limit, params)
|
2443
2773
|
|
2444
2774
|
def parse_transfer(self, transfer: dict, currency: Currency = None) -> TransferEntry:
|
2445
2775
|
#
|
@@ -2456,6 +2786,22 @@ class woo(Exchange, ImplicitAPI):
|
|
2456
2786
|
# "created_time": "1709022325.427",
|
2457
2787
|
# "updated_time": "1709022325.542"
|
2458
2788
|
# }
|
2789
|
+
# {
|
2790
|
+
# "id": 225,
|
2791
|
+
# "token": "USDT",
|
2792
|
+
# "amount": "1000000",
|
2793
|
+
# "status": "COMPLETED",
|
2794
|
+
# "from": {
|
2795
|
+
# "applicationId": "046b5c5c-5b44-4d27-9593-ddc32c0a08ae",
|
2796
|
+
# "accountName": "Main"
|
2797
|
+
# },
|
2798
|
+
# "to": {
|
2799
|
+
# "applicationId": "082ae5ae-e26a-4fb1-be5b-03e5b4867663",
|
2800
|
+
# "accountName": "sub001"
|
2801
|
+
# },
|
2802
|
+
# "createdTime": "1642660941.534",
|
2803
|
+
# "updatedTime": "1642660941.950"
|
2804
|
+
# }
|
2459
2805
|
#
|
2460
2806
|
# transfer
|
2461
2807
|
# {
|
@@ -2463,22 +2809,22 @@ class woo(Exchange, ImplicitAPI):
|
|
2463
2809
|
# "id": 200
|
2464
2810
|
# }
|
2465
2811
|
#
|
2466
|
-
|
2467
|
-
|
2468
|
-
code = currencyDefined['code']
|
2469
|
-
timestamp = self.safe_timestamp(transfer, 'created_time')
|
2812
|
+
code = self.safe_currency_code(self.safe_string(transfer, 'token'), currency)
|
2813
|
+
timestamp = self.safe_timestamp(transfer, 'createdTime')
|
2470
2814
|
success = self.safe_bool(transfer, 'success')
|
2471
2815
|
status: Str = None
|
2472
2816
|
if success is not None:
|
2473
2817
|
status = 'ok' if success else 'failed'
|
2818
|
+
fromAccount = self.safe_dict(transfer, 'from', {})
|
2819
|
+
toAccount = self.safe_dict(transfer, 'to', {})
|
2474
2820
|
return {
|
2475
2821
|
'id': self.safe_string(transfer, 'id'),
|
2476
2822
|
'timestamp': timestamp,
|
2477
2823
|
'datetime': self.iso8601(timestamp),
|
2478
2824
|
'currency': code,
|
2479
2825
|
'amount': self.safe_number(transfer, 'amount'),
|
2480
|
-
'fromAccount': self.safe_string(
|
2481
|
-
'toAccount': self.safe_string(
|
2826
|
+
'fromAccount': self.safe_string(fromAccount, 'applicationId'),
|
2827
|
+
'toAccount': self.safe_string(toAccount, 'applicationId'),
|
2482
2828
|
'status': self.parse_transfer_status(self.safe_string(transfer, 'status', status)),
|
2483
2829
|
'info': transfer,
|
2484
2830
|
}
|
@@ -2599,7 +2945,7 @@ class woo(Exchange, ImplicitAPI):
|
|
2599
2945
|
url += '?' + self.urlencode(params)
|
2600
2946
|
else:
|
2601
2947
|
self.check_required_credentials()
|
2602
|
-
if method == 'POST' and (path == '
|
2948
|
+
if method == 'POST' and (path == 'trade/algoOrder' or path == 'trade/order'):
|
2603
2949
|
isSandboxMode = self.safe_bool(self.options, 'sandboxMode', False)
|
2604
2950
|
if not isSandboxMode:
|
2605
2951
|
applicationId = 'bc830de7-50f3-460b-9ee0-f430f83f9dad'
|
@@ -2619,15 +2965,15 @@ class woo(Exchange, ImplicitAPI):
|
|
2619
2965
|
}
|
2620
2966
|
if version == 'v3':
|
2621
2967
|
auth = ts + method + '/' + version + '/' + pathWithParams
|
2622
|
-
if method == 'POST' or method == 'PUT'
|
2968
|
+
if method == 'POST' or method == 'PUT':
|
2623
2969
|
body = self.json(params)
|
2624
2970
|
auth += body
|
2971
|
+
headers['content-type'] = 'application/json'
|
2625
2972
|
else:
|
2626
2973
|
if params:
|
2627
2974
|
query = self.urlencode(params)
|
2628
2975
|
url += '?' + query
|
2629
2976
|
auth += '?' + query
|
2630
|
-
headers['content-type'] = 'application/json'
|
2631
2977
|
else:
|
2632
2978
|
auth = self.urlencode(params)
|
2633
2979
|
if method == 'POST' or method == 'PUT' or method == 'DELETE':
|
@@ -2658,25 +3004,26 @@ class woo(Exchange, ImplicitAPI):
|
|
2658
3004
|
def parse_income(self, income, market: Market = None):
|
2659
3005
|
#
|
2660
3006
|
# {
|
2661
|
-
# "id":
|
2662
|
-
# "symbol":"PERP_BTC_USDT",
|
2663
|
-
# "
|
2664
|
-
# "
|
2665
|
-
# "
|
2666
|
-
# "
|
2667
|
-
# "
|
2668
|
-
# "
|
2669
|
-
# "
|
3007
|
+
# "id": 1286360,
|
3008
|
+
# "symbol": "PERP_BTC_USDT",
|
3009
|
+
# "fundingRate": -0.00001445,
|
3010
|
+
# "markPrice": "26930.60000000",
|
3011
|
+
# "fundingFee": "9.56021744",
|
3012
|
+
# "fundingIntervalHours": 8,
|
3013
|
+
# "paymentType": "Pay",
|
3014
|
+
# "status": "COMPLETED",
|
3015
|
+
# "createdTime": 1696060873259,
|
3016
|
+
# "updatedTime": 1696060873286
|
2670
3017
|
# }
|
2671
3018
|
#
|
2672
3019
|
marketId = self.safe_string(income, 'symbol')
|
2673
3020
|
symbol = self.safe_symbol(marketId, market)
|
2674
|
-
amount = self.safe_string(income, '
|
3021
|
+
amount = self.safe_string(income, 'fundingFee')
|
2675
3022
|
code = self.safe_currency_code('USD')
|
2676
3023
|
id = self.safe_string(income, 'id')
|
2677
|
-
timestamp = self.
|
2678
|
-
rate = self.safe_number(income, '
|
2679
|
-
paymentType = self.safe_string(income, '
|
3024
|
+
timestamp = self.safe_integer(income, 'updatedTime')
|
3025
|
+
rate = self.safe_number(income, 'fundingRate')
|
3026
|
+
paymentType = self.safe_string(income, 'paymentType')
|
2680
3027
|
amount = Precise.string_neg(amount) if (paymentType == 'Pay') else amount
|
2681
3028
|
return {
|
2682
3029
|
'info': income,
|
@@ -2693,7 +3040,7 @@ class woo(Exchange, ImplicitAPI):
|
|
2693
3040
|
"""
|
2694
3041
|
fetch the history of funding payments paid and received on self account
|
2695
3042
|
|
2696
|
-
https://
|
3043
|
+
https://developer.woox.io/api-reference/endpoint/futures/get_fundingFee_history
|
2697
3044
|
|
2698
3045
|
:param str [symbol]: unified market symbol
|
2699
3046
|
:param int [since]: the earliest time in ms to fetch funding history for
|
@@ -2706,73 +3053,71 @@ class woo(Exchange, ImplicitAPI):
|
|
2706
3053
|
paginate = False
|
2707
3054
|
paginate, params = self.handle_option_and_params(params, 'fetchFundingHistory', 'paginate')
|
2708
3055
|
if paginate:
|
2709
|
-
return await self.
|
3056
|
+
return await self.fetch_paginated_call_incremental('fetchFundingHistory', symbol, since, limit, params, 'page', 500)
|
2710
3057
|
request: dict = {}
|
2711
3058
|
market: Market = None
|
2712
3059
|
if symbol is not None:
|
2713
3060
|
market = self.market(symbol)
|
2714
3061
|
request['symbol'] = market['id']
|
2715
3062
|
if since is not None:
|
2716
|
-
request['
|
3063
|
+
request['startTime'] = since
|
3064
|
+
until = self.safe_integer(params, 'until') # unified in milliseconds
|
3065
|
+
params = self.omit(params, ['until'])
|
3066
|
+
if until is not None:
|
3067
|
+
request['endTime'] = until
|
2717
3068
|
if limit is not None:
|
2718
|
-
request['size'] = limit
|
2719
|
-
|
2720
|
-
request['size'] = 5000
|
2721
|
-
response = await self.v1PrivateGetFundingFeeHistory(self.extend(request, params))
|
3069
|
+
request['size'] = min(limit, 500)
|
3070
|
+
response = await self.v3PrivateGetFuturesFundingFeeHistory(self.extend(request, params))
|
2722
3071
|
#
|
2723
3072
|
# {
|
2724
|
-
# "
|
2725
|
-
#
|
2726
|
-
#
|
2727
|
-
# "
|
2728
|
-
# "
|
2729
|
-
# "
|
2730
|
-
#
|
2731
|
-
#
|
2732
|
-
#
|
2733
|
-
#
|
2734
|
-
#
|
2735
|
-
#
|
2736
|
-
#
|
2737
|
-
#
|
2738
|
-
#
|
2739
|
-
#
|
2740
|
-
#
|
3073
|
+
# "success": True,
|
3074
|
+
# "data": {
|
3075
|
+
# "meta": {
|
3076
|
+
# "total": 670,
|
3077
|
+
# "recordsPerPage": 25,
|
3078
|
+
# "currentPage": 1
|
3079
|
+
# },
|
3080
|
+
# "rows": [
|
3081
|
+
# {
|
3082
|
+
# "id": 1286360,
|
3083
|
+
# "symbol": "PERP_BTC_USDT",
|
3084
|
+
# "fundingRate": -0.00001445,
|
3085
|
+
# "markPrice": "26930.60000000",
|
3086
|
+
# "fundingFee": "9.56021744",
|
3087
|
+
# "fundingIntervalHours": 8,
|
3088
|
+
# "paymentType": "Pay",
|
3089
|
+
# "status": "COMPLETED",
|
3090
|
+
# "createdTime": 1696060873259,
|
3091
|
+
# "updatedTime": 1696060873286
|
3092
|
+
# }
|
3093
|
+
# ]
|
2741
3094
|
# },
|
2742
|
-
# "
|
3095
|
+
# "timestamp": 1721351502594
|
2743
3096
|
# }
|
2744
3097
|
#
|
2745
|
-
|
2746
|
-
|
2747
|
-
|
2748
|
-
resultLength = len(result)
|
2749
|
-
if resultLength > 0:
|
2750
|
-
lastItem = result[resultLength - 1]
|
2751
|
-
lastItem['page'] = cursor
|
2752
|
-
result[resultLength - 1] = lastItem
|
2753
|
-
return self.parse_incomes(result, market, since, limit)
|
3098
|
+
data = self.safe_dict(response, 'data', {})
|
3099
|
+
rows = self.safe_list(data, 'rows', [])
|
3100
|
+
return self.parse_incomes(rows, market, since, limit)
|
2754
3101
|
|
2755
3102
|
def parse_funding_rate(self, fundingRate, market: Market = None) -> FundingRate:
|
2756
3103
|
#
|
2757
3104
|
# {
|
2758
|
-
# "success": True,
|
2759
|
-
# "timestamp": 1727427915529,
|
2760
3105
|
# "symbol": "PERP_BTC_USDT",
|
2761
|
-
# "
|
2762
|
-
# "
|
2763
|
-
# "
|
2764
|
-
# "
|
2765
|
-
# "
|
2766
|
-
# "
|
2767
|
-
# "
|
3106
|
+
# "estFundingRate": "-0.00000441",
|
3107
|
+
# "estFundingRateTimestamp": 1751623979022,
|
3108
|
+
# "lastFundingRate": "-0.00004953",
|
3109
|
+
# "lastFundingRateTimestamp": 1751616000000,
|
3110
|
+
# "nextFundingTime": 1751644800000,
|
3111
|
+
# "lastFundingIntervalHours": 8,
|
3112
|
+
# "estFundingIntervalHours": 8
|
2768
3113
|
# }
|
2769
3114
|
#
|
2770
3115
|
symbol = self.safe_string(fundingRate, 'symbol')
|
2771
3116
|
market = self.market(symbol)
|
2772
|
-
nextFundingTimestamp = self.safe_integer(fundingRate, '
|
2773
|
-
estFundingRateTimestamp = self.safe_integer(fundingRate, '
|
2774
|
-
lastFundingRateTimestamp = self.safe_integer(fundingRate, '
|
2775
|
-
intervalString = self.safe_string(fundingRate, '
|
3117
|
+
nextFundingTimestamp = self.safe_integer(fundingRate, 'nextFundingTime')
|
3118
|
+
estFundingRateTimestamp = self.safe_integer(fundingRate, 'estFundingRateTimestamp')
|
3119
|
+
lastFundingRateTimestamp = self.safe_integer(fundingRate, 'lastFundingRateTimestamp')
|
3120
|
+
intervalString = self.safe_string(fundingRate, 'estFundingIntervalHours')
|
2776
3121
|
return {
|
2777
3122
|
'info': fundingRate,
|
2778
3123
|
'symbol': market['symbol'],
|
@@ -2782,13 +3127,13 @@ class woo(Exchange, ImplicitAPI):
|
|
2782
3127
|
'estimatedSettlePrice': None,
|
2783
3128
|
'timestamp': estFundingRateTimestamp,
|
2784
3129
|
'datetime': self.iso8601(estFundingRateTimestamp),
|
2785
|
-
'fundingRate': self.safe_number(fundingRate, '
|
3130
|
+
'fundingRate': self.safe_number(fundingRate, 'estFundingRate'),
|
2786
3131
|
'fundingTimestamp': nextFundingTimestamp,
|
2787
3132
|
'fundingDatetime': self.iso8601(nextFundingTimestamp),
|
2788
3133
|
'nextFundingRate': None,
|
2789
3134
|
'nextFundingTimestamp': None,
|
2790
3135
|
'nextFundingDatetime': None,
|
2791
|
-
'previousFundingRate': self.safe_number(fundingRate, '
|
3136
|
+
'previousFundingRate': self.safe_number(fundingRate, 'lastFundingRate'),
|
2792
3137
|
'previousFundingTimestamp': lastFundingRateTimestamp,
|
2793
3138
|
'previousFundingDatetime': self.iso8601(lastFundingRateTimestamp),
|
2794
3139
|
'interval': intervalString + 'h',
|
@@ -2798,7 +3143,7 @@ class woo(Exchange, ImplicitAPI):
|
|
2798
3143
|
"""
|
2799
3144
|
fetch the current funding rate interval
|
2800
3145
|
|
2801
|
-
https://
|
3146
|
+
https://developer.woox.io/api-reference/endpoint/public_data/fundingRate
|
2802
3147
|
|
2803
3148
|
:param str symbol: unified market symbol
|
2804
3149
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -2810,7 +3155,7 @@ class woo(Exchange, ImplicitAPI):
|
|
2810
3155
|
"""
|
2811
3156
|
fetch the current funding rate
|
2812
3157
|
|
2813
|
-
https://
|
3158
|
+
https://developer.woox.io/api-reference/endpoint/public_data/fundingRate
|
2814
3159
|
|
2815
3160
|
:param str symbol: unified market symbol
|
2816
3161
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -2821,28 +3166,37 @@ class woo(Exchange, ImplicitAPI):
|
|
2821
3166
|
request: dict = {
|
2822
3167
|
'symbol': market['id'],
|
2823
3168
|
}
|
2824
|
-
response = await self.
|
3169
|
+
response = await self.v3PublicGetFundingRate(self.extend(request, params))
|
2825
3170
|
#
|
2826
3171
|
# {
|
2827
3172
|
# "success": True,
|
2828
|
-
# "
|
2829
|
-
#
|
2830
|
-
#
|
2831
|
-
#
|
2832
|
-
#
|
2833
|
-
#
|
2834
|
-
#
|
2835
|
-
#
|
2836
|
-
#
|
3173
|
+
# "data": {
|
3174
|
+
# "rows": [
|
3175
|
+
# {
|
3176
|
+
# "symbol": "PERP_BTC_USDT",
|
3177
|
+
# "estFundingRate": "-0.00000441",
|
3178
|
+
# "estFundingRateTimestamp": 1751623979022,
|
3179
|
+
# "lastFundingRate": "-0.00004953",
|
3180
|
+
# "lastFundingRateTimestamp": 1751616000000,
|
3181
|
+
# "nextFundingTime": 1751644800000,
|
3182
|
+
# "lastFundingIntervalHours": 8,
|
3183
|
+
# "estFundingIntervalHours": 8
|
3184
|
+
# }
|
3185
|
+
# ]
|
3186
|
+
# },
|
3187
|
+
# "timestamp": 1751624037798
|
2837
3188
|
# }
|
2838
3189
|
#
|
2839
|
-
|
3190
|
+
data = self.safe_dict(response, 'data', {})
|
3191
|
+
rows = self.safe_list(data, 'rows', [])
|
3192
|
+
first = self.safe_dict(rows, 0, {})
|
3193
|
+
return self.parse_funding_rate(first, market)
|
2840
3194
|
|
2841
3195
|
async def fetch_funding_rates(self, symbols: Strings = None, params={}) -> FundingRates:
|
2842
3196
|
"""
|
2843
3197
|
fetch the funding rate for multiple markets
|
2844
3198
|
|
2845
|
-
https://
|
3199
|
+
https://developer.woox.io/api-reference/endpoint/public_data/fundingRate
|
2846
3200
|
|
2847
3201
|
:param str[]|None symbols: list of unified market symbols
|
2848
3202
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -2850,31 +3204,36 @@ class woo(Exchange, ImplicitAPI):
|
|
2850
3204
|
"""
|
2851
3205
|
await self.load_markets()
|
2852
3206
|
symbols = self.market_symbols(symbols)
|
2853
|
-
response = await self.
|
3207
|
+
response = await self.v3PublicGetFundingRate(params)
|
2854
3208
|
#
|
2855
3209
|
# {
|
2856
|
-
# "success":
|
2857
|
-
# "
|
2858
|
-
#
|
2859
|
-
#
|
2860
|
-
#
|
2861
|
-
#
|
2862
|
-
#
|
2863
|
-
#
|
2864
|
-
#
|
2865
|
-
#
|
2866
|
-
#
|
2867
|
-
#
|
3210
|
+
# "success": True,
|
3211
|
+
# "data": {
|
3212
|
+
# "rows": [
|
3213
|
+
# {
|
3214
|
+
# "symbol": "PERP_BTC_USDT",
|
3215
|
+
# "estFundingRate": "-0.00000441",
|
3216
|
+
# "estFundingRateTimestamp": 1751623979022,
|
3217
|
+
# "lastFundingRate": "-0.00004953",
|
3218
|
+
# "lastFundingRateTimestamp": 1751616000000,
|
3219
|
+
# "nextFundingTime": 1751644800000,
|
3220
|
+
# "lastFundingIntervalHours": 8,
|
3221
|
+
# "estFundingIntervalHours": 8
|
3222
|
+
# }
|
3223
|
+
# ]
|
3224
|
+
# },
|
3225
|
+
# "timestamp": 1751624037798
|
2868
3226
|
# }
|
2869
3227
|
#
|
2870
|
-
|
3228
|
+
data = self.safe_dict(response, 'data', {})
|
3229
|
+
rows = self.safe_list(data, 'rows', [])
|
2871
3230
|
return self.parse_funding_rates(rows, symbols)
|
2872
3231
|
|
2873
3232
|
async def fetch_funding_rate_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
|
2874
3233
|
"""
|
2875
3234
|
fetches historical funding rate prices
|
2876
3235
|
|
2877
|
-
https://
|
3236
|
+
https://developer.woox.io/api-reference/endpoint/public_data/fundingRateHistory
|
2878
3237
|
|
2879
3238
|
:param str symbol: unified symbol of the market to fetch the funding rate history for
|
2880
3239
|
:param int [since]: timestamp in ms of the earliest funding rate to fetch
|
@@ -2889,44 +3248,50 @@ class woo(Exchange, ImplicitAPI):
|
|
2889
3248
|
paginate, params = self.handle_option_and_params(params, 'fetchFundingRateHistory', 'paginate')
|
2890
3249
|
if paginate:
|
2891
3250
|
return await self.fetch_paginated_call_incremental('fetchFundingRateHistory', symbol, since, limit, params, 'page', 25)
|
2892
|
-
|
2893
|
-
|
2894
|
-
|
2895
|
-
|
2896
|
-
|
3251
|
+
if symbol is None:
|
3252
|
+
raise ArgumentsRequired(self.id + ' fetchFundingRateHistory() requires a symbol argument')
|
3253
|
+
market = self.market(symbol)
|
3254
|
+
symbol = market['symbol']
|
3255
|
+
request: dict = {
|
3256
|
+
'symbol': market['id'],
|
3257
|
+
}
|
2897
3258
|
if since is not None:
|
2898
|
-
request['
|
2899
|
-
request, params = self.handle_until_option('
|
2900
|
-
response = await self.
|
3259
|
+
request['startTime'] = since
|
3260
|
+
request, params = self.handle_until_option('endTime', request, params)
|
3261
|
+
response = await self.v3PublicGetFundingRateHistory(self.extend(request, params))
|
2901
3262
|
#
|
2902
3263
|
# {
|
2903
|
-
# "success":
|
2904
|
-
# "
|
2905
|
-
# "
|
2906
|
-
#
|
2907
|
-
#
|
2908
|
-
#
|
2909
|
-
#
|
2910
|
-
#
|
2911
|
-
#
|
2912
|
-
#
|
2913
|
-
#
|
2914
|
-
#
|
3264
|
+
# "success": True,
|
3265
|
+
# "data": {
|
3266
|
+
# "rows": [
|
3267
|
+
# {
|
3268
|
+
# "symbol": "PERP_BTC_USDT",
|
3269
|
+
# "fundingRate": "-0.00004953",
|
3270
|
+
# "fundingRateTimestamp": 1751616000000,
|
3271
|
+
# "nextFundingTime": 1751644800000,
|
3272
|
+
# "markPrice": "108708"
|
3273
|
+
# }
|
3274
|
+
# ],
|
3275
|
+
# "meta": {
|
3276
|
+
# "total": 11690,
|
3277
|
+
# "recordsPerPage": 25,
|
3278
|
+
# "currentPage": 1
|
2915
3279
|
# }
|
2916
|
-
#
|
2917
|
-
# "timestamp":
|
3280
|
+
# },
|
3281
|
+
# "timestamp": 1751632390031
|
2918
3282
|
# }
|
2919
3283
|
#
|
2920
|
-
|
3284
|
+
data = self.safe_dict(response, 'data', {})
|
3285
|
+
rows = self.safe_list(data, 'rows', [])
|
2921
3286
|
rates = []
|
2922
|
-
for i in range(0, len(
|
2923
|
-
entry =
|
3287
|
+
for i in range(0, len(rows)):
|
3288
|
+
entry = rows[i]
|
2924
3289
|
marketId = self.safe_string(entry, 'symbol')
|
2925
|
-
timestamp = self.safe_integer(entry, '
|
3290
|
+
timestamp = self.safe_integer(entry, 'fundingRateTimestamp')
|
2926
3291
|
rates.append({
|
2927
3292
|
'info': entry,
|
2928
3293
|
'symbol': self.safe_symbol(marketId),
|
2929
|
-
'fundingRate': self.safe_number(entry, '
|
3294
|
+
'fundingRate': self.safe_number(entry, 'fundingRate'),
|
2930
3295
|
'timestamp': timestamp,
|
2931
3296
|
'datetime': self.iso8601(timestamp),
|
2932
3297
|
})
|
@@ -2937,7 +3302,7 @@ class woo(Exchange, ImplicitAPI):
|
|
2937
3302
|
"""
|
2938
3303
|
set hedged to True or False for a market
|
2939
3304
|
|
2940
|
-
https://
|
3305
|
+
https://developer.woox.io/api-reference/endpoint/futures/position_mode
|
2941
3306
|
|
2942
3307
|
:param bool hedged: set to True to use HEDGE_MODE, False for ONE_WAY
|
2943
3308
|
:param str symbol: not used by woo setPositionMode
|
@@ -2950,14 +3315,13 @@ class woo(Exchange, ImplicitAPI):
|
|
2950
3315
|
else:
|
2951
3316
|
hedgeMode = 'ONE_WAY'
|
2952
3317
|
request: dict = {
|
2953
|
-
'
|
3318
|
+
'positionMode': hedgeMode,
|
2954
3319
|
}
|
2955
|
-
response = await self.
|
3320
|
+
response = await self.v3PrivatePutFuturesPositionMode(self.extend(request, params))
|
2956
3321
|
#
|
2957
3322
|
# {
|
2958
3323
|
# "success": True,
|
2959
|
-
# "
|
2960
|
-
# "timestamp": "1709195608551"
|
3324
|
+
# "timestamp": 1752550492845
|
2961
3325
|
# }
|
2962
3326
|
#
|
2963
3327
|
return response
|
@@ -2966,19 +3330,20 @@ class woo(Exchange, ImplicitAPI):
|
|
2966
3330
|
"""
|
2967
3331
|
fetch the set leverage for a market
|
2968
3332
|
|
2969
|
-
https://
|
3333
|
+
https://developer.woox.io/api-reference/endpoint/account/get_account_info
|
3334
|
+
https://developer.woox.io/api-reference/endpoint/futures/get_leverage
|
2970
3335
|
|
2971
3336
|
:param str symbol: unified market symbol
|
2972
3337
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2973
3338
|
:param str [params.marginMode]: *for swap markets only* 'cross' or 'isolated'
|
2974
|
-
:param str [params.
|
3339
|
+
:param str [params.positionMode]: *for swap markets only* 'ONE_WAY' or 'HEDGE_MODE'
|
2975
3340
|
:returns dict: a `leverage structure <https://docs.ccxt.com/#/?id=leverage-structure>`
|
2976
3341
|
"""
|
2977
3342
|
await self.load_markets()
|
2978
3343
|
market = self.market(symbol)
|
2979
3344
|
response: dict = None
|
2980
3345
|
if market['spot']:
|
2981
|
-
response = await self.
|
3346
|
+
response = await self.v3PrivateGetAccountInfo(params)
|
2982
3347
|
#
|
2983
3348
|
# {
|
2984
3349
|
# "success": True,
|
@@ -2986,25 +3351,26 @@ class woo(Exchange, ImplicitAPI):
|
|
2986
3351
|
# "applicationId": "dsa",
|
2987
3352
|
# "account": "dsa",
|
2988
3353
|
# "alias": "haha",
|
2989
|
-
# "accountMode": "MARGIN",
|
2990
|
-
# "leverage": 1,
|
2991
|
-
# "takerFeeRate": 1,
|
2992
|
-
# "makerFeeRate": 1,
|
2993
|
-
# "interestRate": 1,
|
2994
|
-
# "futuresTakerFeeRate": 1,
|
2995
|
-
# "futuresMakerFeeRate": 1,
|
2996
3354
|
# "otpauth": True,
|
2997
|
-
# "
|
2998
|
-
# "
|
2999
|
-
# "
|
3000
|
-
# "
|
3001
|
-
# "
|
3002
|
-
# "
|
3003
|
-
# "
|
3004
|
-
# "
|
3005
|
-
# "
|
3355
|
+
# "accountMode": "FUTURES",
|
3356
|
+
# "positionMode": "ONE_WAY",
|
3357
|
+
# "leverage": 0,
|
3358
|
+
# "marginRatio": "10",
|
3359
|
+
# "openMarginRatio": "10",
|
3360
|
+
# "initialMarginRatio": "10",
|
3361
|
+
# "maintenanceMarginRatio": "0.03",
|
3362
|
+
# "totalCollateral": "165.6115334",
|
3363
|
+
# "freeCollateral": "165.6115334",
|
3364
|
+
# "totalAccountValue": "167.52723093",
|
3365
|
+
# "totalTradingValue": "167.52723093",
|
3366
|
+
# "totalVaultValue": "0",
|
3367
|
+
# "totalStakingValue": "0",
|
3368
|
+
# "totalLaunchpadValue": "0",
|
3369
|
+
# "totalEarnValue": "0",
|
3370
|
+
# "referrerID": null,
|
3371
|
+
# "accountType": "Main"
|
3006
3372
|
# },
|
3007
|
-
# "timestamp":
|
3373
|
+
# "timestamp": 1752645129054
|
3008
3374
|
# }
|
3009
3375
|
#
|
3010
3376
|
elif market['swap']:
|
@@ -3013,8 +3379,8 @@ class woo(Exchange, ImplicitAPI):
|
|
3013
3379
|
}
|
3014
3380
|
marginMode: Str = None
|
3015
3381
|
marginMode, params = self.handle_margin_mode_and_params('fetchLeverage', params, 'cross')
|
3016
|
-
request['
|
3017
|
-
response = await self.
|
3382
|
+
request['marginMode'] = self.encode_margin_mode(marginMode)
|
3383
|
+
response = await self.v3PrivateGetFuturesLeverage(self.extend(request, params))
|
3018
3384
|
#
|
3019
3385
|
# HEDGE_MODE
|
3020
3386
|
# {
|
@@ -3022,15 +3388,15 @@ class woo(Exchange, ImplicitAPI):
|
|
3022
3388
|
# "data":
|
3023
3389
|
# {
|
3024
3390
|
# "symbol": "PERP_ETH_USDT",
|
3025
|
-
# "
|
3026
|
-
# "
|
3391
|
+
# "marginMode": "CROSS",
|
3392
|
+
# "positionMode": "HEDGE_MODE",
|
3027
3393
|
# "details": [
|
3028
3394
|
# {
|
3029
|
-
# "
|
3395
|
+
# "positionSide": "LONG",
|
3030
3396
|
# "leverage": 10
|
3031
3397
|
# },
|
3032
3398
|
# {
|
3033
|
-
# "
|
3399
|
+
# "positionSide": "SHORT",
|
3034
3400
|
# "leverage": 10
|
3035
3401
|
# }
|
3036
3402
|
# ]
|
@@ -3043,11 +3409,11 @@ class woo(Exchange, ImplicitAPI):
|
|
3043
3409
|
# "success": True,
|
3044
3410
|
# "data": {
|
3045
3411
|
# "symbol": "PERP_ETH_USDT",
|
3046
|
-
# "
|
3047
|
-
# "
|
3412
|
+
# "marginMode": "ISOLATED",
|
3413
|
+
# "positionMode": "ONE_WAY",
|
3048
3414
|
# "details": [
|
3049
3415
|
# {
|
3050
|
-
# "
|
3416
|
+
# "positionSide": "BOTH",
|
3051
3417
|
# "leverage": 10
|
3052
3418
|
# }
|
3053
3419
|
# ]
|
@@ -3063,15 +3429,17 @@ class woo(Exchange, ImplicitAPI):
|
|
3063
3429
|
def parse_leverage(self, leverage: dict, market: Market = None) -> Leverage:
|
3064
3430
|
marketId = self.safe_string(leverage, 'symbol')
|
3065
3431
|
market = self.safe_market(marketId, market)
|
3066
|
-
marginMode = self.safe_string_lower(leverage, '
|
3432
|
+
marginMode = self.safe_string_lower(leverage, 'marginMode')
|
3067
3433
|
spotLeverage = self.safe_integer(leverage, 'leverage')
|
3434
|
+
if spotLeverage == 0:
|
3435
|
+
spotLeverage = None
|
3068
3436
|
longLeverage = spotLeverage
|
3069
3437
|
shortLeverage = spotLeverage
|
3070
3438
|
details = self.safe_list(leverage, 'details', [])
|
3071
3439
|
for i in range(0, len(details)):
|
3072
3440
|
position = self.safe_dict(details, i, {})
|
3073
3441
|
positionLeverage = self.safe_integer(position, 'leverage')
|
3074
|
-
side = self.safe_string(position, '
|
3442
|
+
side = self.safe_string(position, 'positionSide')
|
3075
3443
|
if side == 'BOTH':
|
3076
3444
|
longLeverage = positionLeverage
|
3077
3445
|
shortLeverage = positionLeverage
|
@@ -3091,14 +3459,14 @@ class woo(Exchange, ImplicitAPI):
|
|
3091
3459
|
"""
|
3092
3460
|
set the level of leverage for a market
|
3093
3461
|
|
3094
|
-
https://
|
3095
|
-
https://
|
3462
|
+
https://developer.woox.io/api-reference/endpoint/spot_margin/set_leverage
|
3463
|
+
https://developer.woox.io/api-reference/endpoint/futures/set_leverage
|
3096
3464
|
|
3097
3465
|
:param float leverage: the rate of leverage(1, 2, 3, 4 or 5 for spot markets, 1, 2, 3, 4, 5, 10, 15, 20 for swap markets)
|
3098
3466
|
:param str [symbol]: unified market symbol(is mandatory for swap markets)
|
3099
3467
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
3100
3468
|
:param str [params.marginMode]: *for swap markets only* 'cross' or 'isolated'
|
3101
|
-
:param str [params.
|
3469
|
+
:param str [params.positionMode]: *for swap markets only* 'ONE_WAY' or 'HEDGE_MODE'
|
3102
3470
|
:returns dict: response from the exchange
|
3103
3471
|
"""
|
3104
3472
|
await self.load_markets()
|
@@ -3109,13 +3477,13 @@ class woo(Exchange, ImplicitAPI):
|
|
3109
3477
|
if symbol is not None:
|
3110
3478
|
market = self.market(symbol)
|
3111
3479
|
if (symbol is None) or market['spot']:
|
3112
|
-
return await self.
|
3480
|
+
return await self.v3PrivatePostSpotMarginLeverage(self.extend(request, params))
|
3113
3481
|
elif market['swap']:
|
3114
3482
|
request['symbol'] = market['id']
|
3115
3483
|
marginMode: Str = None
|
3116
3484
|
marginMode, params = self.handle_margin_mode_and_params('fetchLeverage', params, 'cross')
|
3117
|
-
request['
|
3118
|
-
return await self.
|
3485
|
+
request['marginMode'] = self.encode_margin_mode(marginMode)
|
3486
|
+
return await self.v3PrivatePutFuturesLeverage(self.extend(request, params))
|
3119
3487
|
else:
|
3120
3488
|
raise NotSupported(self.id + ' fetchLeverage() is not supported for ' + market['type'] + ' markets')
|
3121
3489
|
|
@@ -3159,92 +3527,98 @@ class woo(Exchange, ImplicitAPI):
|
|
3159
3527
|
return await self.v1PrivatePostClientIsolatedMargin(self.extend(request, params))
|
3160
3528
|
|
3161
3529
|
async def fetch_position(self, symbol: Str, params={}):
|
3530
|
+
"""
|
3531
|
+
fetch data on an open position
|
3532
|
+
|
3533
|
+
https://developer.woox.io/api-reference/endpoint/futures/get_positions
|
3534
|
+
|
3535
|
+
:param str symbol: unified market symbol of the market the position is held in
|
3536
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
3537
|
+
:returns dict: a `position structure <https://docs.ccxt.com/#/?id=position-structure>`
|
3538
|
+
"""
|
3162
3539
|
await self.load_markets()
|
3163
3540
|
market = self.market(symbol)
|
3164
3541
|
request: dict = {
|
3165
3542
|
'symbol': market['id'],
|
3166
3543
|
}
|
3167
|
-
response = await self.
|
3544
|
+
response = await self.v3PrivateGetFuturesPositions(self.extend(request, params))
|
3168
3545
|
#
|
3169
3546
|
# {
|
3170
|
-
# "symbol": "PERP_ETH_USDT",
|
3171
|
-
# "position_side": "BOTH",
|
3172
|
-
# "leverage": 10,
|
3173
|
-
# "margin_mode": "CROSS",
|
3174
|
-
# "average_open_price": 3139.9,
|
3175
|
-
# "isolated_margin_amount": 0.0,
|
3176
|
-
# "isolated_margin_token": "",
|
3177
|
-
# "opening_time": "1720627963.094",
|
3178
|
-
# "mark_price": 3155.19169891,
|
3179
|
-
# "pending_short_qty": 0.0,
|
3180
|
-
# "pending_long_qty": 0.0,
|
3181
|
-
# "holding": -0.7,
|
3182
|
-
# "pnl_24_h": 0.0,
|
3183
|
-
# "est_liq_price": 9107.40055552,
|
3184
|
-
# "settle_price": 3151.0319904,
|
3185
3547
|
# "success": True,
|
3186
|
-
# "
|
3187
|
-
#
|
3188
|
-
#
|
3189
|
-
#
|
3548
|
+
# "data": {
|
3549
|
+
# "positions": [
|
3550
|
+
# {
|
3551
|
+
# "symbol": "PERP_LTC_USDT",
|
3552
|
+
# "holding": "0.1",
|
3553
|
+
# "pendingLongQty": "0",
|
3554
|
+
# "pendingShortQty": "0",
|
3555
|
+
# "settlePrice": "96.87",
|
3556
|
+
# "averageOpenPrice": "96.87",
|
3557
|
+
# "pnl24H": "0",
|
3558
|
+
# "fee24H": "0.0048435",
|
3559
|
+
# "markPrice": "96.83793449",
|
3560
|
+
# "estLiqPrice": "0",
|
3561
|
+
# "timestamp": 1752500555823,
|
3562
|
+
# "adlQuantile": 2,
|
3563
|
+
# "positionSide": "BOTH",
|
3564
|
+
# "marginMode": "CROSS",
|
3565
|
+
# "isolatedMarginToken": "",
|
3566
|
+
# "isolatedMarginAmount": "0",
|
3567
|
+
# "isolatedFrozenLong": "0",
|
3568
|
+
# "isolatedFrozenShort": "0",
|
3569
|
+
# "leverage": 10
|
3570
|
+
# }
|
3571
|
+
# ]
|
3572
|
+
# },
|
3573
|
+
# "timestamp": 1752500579848
|
3190
3574
|
# }
|
3191
3575
|
#
|
3192
|
-
|
3576
|
+
result = self.safe_dict(response, 'data', {})
|
3577
|
+
positions = self.safe_list(result, 'positions', [])
|
3578
|
+
first = self.safe_dict(positions, 0, {})
|
3579
|
+
return self.parse_position(first, market)
|
3193
3580
|
|
3194
3581
|
async def fetch_positions(self, symbols: Strings = None, params={}) -> List[Position]:
|
3582
|
+
"""
|
3583
|
+
fetch all open positions
|
3584
|
+
|
3585
|
+
https://developer.woox.io/api-reference/endpoint/futures/get_positions
|
3586
|
+
|
3587
|
+
:param str[] [symbols]: list of unified market symbols
|
3588
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
3589
|
+
:returns dict[]: a list of `position structure <https://docs.ccxt.com/#/?id=position-structure>`
|
3590
|
+
"""
|
3195
3591
|
await self.load_markets()
|
3196
|
-
response = await self.
|
3592
|
+
response = await self.v3PrivateGetFuturesPositions(params)
|
3197
3593
|
#
|
3198
3594
|
# {
|
3199
3595
|
# "success": True,
|
3200
|
-
# "data":
|
3201
|
-
# {
|
3596
|
+
# "data": {
|
3202
3597
|
# "positions": [
|
3203
3598
|
# {
|
3204
|
-
# "symbol": "
|
3205
|
-
# "holding":
|
3206
|
-
# "pendingLongQty": 0
|
3207
|
-
# "pendingShortQty": 0
|
3208
|
-
# "settlePrice":
|
3209
|
-
# "averageOpenPrice":
|
3210
|
-
# "pnl24H": 0
|
3211
|
-
# "fee24H":
|
3212
|
-
# "markPrice":
|
3213
|
-
# "estLiqPrice":
|
3214
|
-
# "timestamp":
|
3215
|
-
# "adlQuantile":
|
3216
|
-
# "positionSide": "BOTH",
|
3217
|
-
# "marginMode": "ISOLATED",
|
3218
|
-
# "isolatedMarginToken": "USDT",
|
3219
|
-
# "isolatedMarginAmount": 314.62426,
|
3220
|
-
# "isolatedFrozenLong": 0.0,
|
3221
|
-
# "isolatedFrozenShort": 0.0,
|
3222
|
-
# "leverage": 10
|
3223
|
-
# },
|
3224
|
-
# {
|
3225
|
-
# "symbol": "PERP_SOL_USDT",
|
3226
|
-
# "holding": -1.0,
|
3227
|
-
# "pendingLongQty": 0.0,
|
3228
|
-
# "pendingShortQty": 0.0,
|
3229
|
-
# "settlePrice": 141.89933923,
|
3230
|
-
# "averageOpenPrice": 171.38,
|
3231
|
-
# "pnl24H": 0.0,
|
3232
|
-
# "fee24H": 0.0,
|
3233
|
-
# "markPrice": 141.65155427,
|
3234
|
-
# "estLiqPrice": 4242.73548551,
|
3235
|
-
# "timestamp": 1720616702.68,
|
3236
|
-
# "adlQuantile": 5,
|
3599
|
+
# "symbol": "PERP_LTC_USDT",
|
3600
|
+
# "holding": "0.1",
|
3601
|
+
# "pendingLongQty": "0",
|
3602
|
+
# "pendingShortQty": "0",
|
3603
|
+
# "settlePrice": "96.87",
|
3604
|
+
# "averageOpenPrice": "96.87",
|
3605
|
+
# "pnl24H": "0",
|
3606
|
+
# "fee24H": "0.0048435",
|
3607
|
+
# "markPrice": "96.83793449",
|
3608
|
+
# "estLiqPrice": "0",
|
3609
|
+
# "timestamp": 1752500555823,
|
3610
|
+
# "adlQuantile": 2,
|
3237
3611
|
# "positionSide": "BOTH",
|
3238
3612
|
# "marginMode": "CROSS",
|
3239
3613
|
# "isolatedMarginToken": "",
|
3240
|
-
# "isolatedMarginAmount": 0
|
3241
|
-
# "isolatedFrozenLong": 0
|
3242
|
-
# "isolatedFrozenShort": 0
|
3614
|
+
# "isolatedMarginAmount": "0",
|
3615
|
+
# "isolatedFrozenLong": "0",
|
3616
|
+
# "isolatedFrozenShort": "0",
|
3243
3617
|
# "leverage": 10
|
3244
3618
|
# }
|
3245
3619
|
# ]
|
3246
3620
|
# },
|
3247
|
-
# "timestamp":
|
3621
|
+
# "timestamp": 1752500579848
|
3248
3622
|
# }
|
3249
3623
|
#
|
3250
3624
|
result = self.safe_dict(response, 'data', {})
|
@@ -3279,24 +3653,24 @@ class woo(Exchange, ImplicitAPI):
|
|
3279
3653
|
#
|
3280
3654
|
# v3PrivateGetPositions
|
3281
3655
|
# {
|
3282
|
-
# "symbol": "
|
3283
|
-
# "holding":
|
3284
|
-
# "pendingLongQty": 0
|
3285
|
-
# "pendingShortQty": 0
|
3286
|
-
# "settlePrice":
|
3287
|
-
# "averageOpenPrice":
|
3288
|
-
# "pnl24H": 0
|
3289
|
-
# "fee24H":
|
3290
|
-
# "markPrice":
|
3291
|
-
# "estLiqPrice":
|
3292
|
-
# "timestamp":
|
3293
|
-
# "adlQuantile":
|
3656
|
+
# "symbol": "PERP_LTC_USDT",
|
3657
|
+
# "holding": "0.1",
|
3658
|
+
# "pendingLongQty": "0",
|
3659
|
+
# "pendingShortQty": "0",
|
3660
|
+
# "settlePrice": "96.87",
|
3661
|
+
# "averageOpenPrice": "96.87",
|
3662
|
+
# "pnl24H": "0",
|
3663
|
+
# "fee24H": "0.0048435",
|
3664
|
+
# "markPrice": "96.83793449",
|
3665
|
+
# "estLiqPrice": "0",
|
3666
|
+
# "timestamp": 1752500555823,
|
3667
|
+
# "adlQuantile": 2,
|
3294
3668
|
# "positionSide": "BOTH",
|
3295
|
-
# "marginMode": "
|
3296
|
-
# "isolatedMarginToken": "
|
3297
|
-
# "isolatedMarginAmount":
|
3298
|
-
# "isolatedFrozenLong": 0
|
3299
|
-
# "isolatedFrozenShort": 0
|
3669
|
+
# "marginMode": "CROSS",
|
3670
|
+
# "isolatedMarginToken": "",
|
3671
|
+
# "isolatedMarginAmount": "0",
|
3672
|
+
# "isolatedFrozenLong": "0",
|
3673
|
+
# "isolatedFrozenShort": "0",
|
3300
3674
|
# "leverage": 10
|
3301
3675
|
# }
|
3302
3676
|
#
|
@@ -3310,7 +3684,13 @@ class woo(Exchange, ImplicitAPI):
|
|
3310
3684
|
side = 'short'
|
3311
3685
|
contractSize = self.safe_string(market, 'contractSize')
|
3312
3686
|
markPrice = self.safe_string_2(position, 'markPrice', 'mark_price')
|
3313
|
-
|
3687
|
+
timestampString = self.safe_string(position, 'timestamp')
|
3688
|
+
timestamp = None
|
3689
|
+
if timestampString is not None:
|
3690
|
+
if timestampString.find('.') > -1:
|
3691
|
+
timestamp = self.safe_timestamp(position, 'timestamp')
|
3692
|
+
else:
|
3693
|
+
timestamp = self.safe_integer(position, 'timestamp')
|
3314
3694
|
entryPrice = self.safe_string_2(position, 'averageOpenPrice', 'average_open_price')
|
3315
3695
|
priceDifference = Precise.string_sub(markPrice, entryPrice)
|
3316
3696
|
unrealisedPnl = Precise.string_mul(priceDifference, size)
|