ccxt 4.4.94__py2.py3-none-any.whl → 4.4.96__py2.py3-none-any.whl

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