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