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