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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. ccxt/__init__.py +1 -1
  2. ccxt/abstract/bingx.py +3 -0
  3. ccxt/abstract/hyperliquid.py +1 -1
  4. ccxt/abstract/woo.py +59 -4
  5. ccxt/async_support/__init__.py +1 -1
  6. ccxt/async_support/base/exchange.py +1 -1
  7. ccxt/async_support/base/ws/future.py +2 -0
  8. ccxt/async_support/bingx.py +129 -92
  9. ccxt/async_support/bitget.py +1 -1
  10. ccxt/async_support/bitstamp.py +2 -0
  11. ccxt/async_support/blofin.py +6 -1
  12. ccxt/async_support/bybit.py +1 -1
  13. ccxt/async_support/coinbase.py +36 -0
  14. ccxt/async_support/coinmate.py +34 -0
  15. ccxt/async_support/coinone.py +34 -0
  16. ccxt/async_support/coinsph.py +29 -0
  17. ccxt/async_support/gate.py +1 -1
  18. ccxt/async_support/hyperliquid.py +2 -1
  19. ccxt/async_support/woo.py +1251 -875
  20. ccxt/base/errors.py +0 -6
  21. ccxt/base/exchange.py +3 -3
  22. ccxt/bingx.py +129 -92
  23. ccxt/bitget.py +1 -1
  24. ccxt/bitstamp.py +2 -0
  25. ccxt/blofin.py +6 -1
  26. ccxt/bybit.py +1 -1
  27. ccxt/coinbase.py +36 -0
  28. ccxt/coinmate.py +34 -0
  29. ccxt/coinone.py +34 -0
  30. ccxt/coinsph.py +29 -0
  31. ccxt/gate.py +1 -1
  32. ccxt/hyperliquid.py +2 -1
  33. ccxt/pro/__init__.py +1 -1
  34. ccxt/pro/hyperliquid.py +6 -6
  35. ccxt/pro/kraken.py +17 -16
  36. ccxt/pro/mexc.py +10 -10
  37. ccxt/test/tests_async.py +2 -2
  38. ccxt/test/tests_sync.py +2 -2
  39. ccxt/woo.py +1251 -875
  40. {ccxt-4.4.94.dist-info → ccxt-4.4.95.dist-info}/METADATA +4 -4
  41. {ccxt-4.4.94.dist-info → ccxt-4.4.95.dist-info}/RECORD +44 -44
  42. {ccxt-4.4.94.dist-info → ccxt-4.4.95.dist-info}/LICENSE.txt +0 -0
  43. {ccxt-4.4.94.dist-info → ccxt-4.4.95.dist-info}/WHEEL +0 -0
  44. {ccxt-4.4.94.dist-info → ccxt-4.4.95.dist-info}/top_level.txt +0 -0
ccxt/woo.py CHANGED
@@ -6,7 +6,7 @@
6
6
  from ccxt.base.exchange import Exchange
7
7
  from ccxt.abstract.woo import ImplicitAPI
8
8
  import hashlib
9
- from ccxt.base.types import Account, Any, Balances, Bool, Conversion, Currencies, Currency, DepositAddress, Int, LedgerEntry, Leverage, MarginModification, Market, MarketType, Num, Order, OrderBook, OrderSide, OrderType, Position, Str, Strings, FundingRate, FundingRates, Trade, TradingFees, Transaction, TransferEntry
9
+ from ccxt.base.types import Account, Any, Balances, Bool, Conversion, Currencies, Currency, DepositAddress, Int, LedgerEntry, Leverage, MarginModification, Market, MarketType, Num, Order, OrderBook, OrderSide, OrderType, Position, Str, Strings, FundingRate, FundingRates, Trade, TradingFeeInterface, TradingFees, Transaction, TransferEntry
10
10
  from typing import List
11
11
  from ccxt.base.errors import ExchangeError
12
12
  from ccxt.base.errors import AuthenticationError
@@ -112,7 +112,7 @@ class woo(Exchange, ImplicitAPI):
112
112
  'fetchTickers': False,
113
113
  'fetchTime': True,
114
114
  'fetchTrades': True,
115
- 'fetchTradingFee': 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,28 @@ class woo(Exchange, ImplicitAPI):
1378
1498
  self.load_markets()
1379
1499
  trigger = self.safe_bool_2(params, 'stop', 'trigger')
1380
1500
  params = self.omit(params, ['stop', 'trigger'])
1501
+ request: dict = {}
1502
+ if symbol is not None:
1503
+ market = self.market(symbol)
1504
+ request['symbol'] = market['id']
1381
1505
  if trigger:
1382
- return self.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))
1506
+ return self.v3PrivateDeleteTradeAlgoOrders(params)
1390
1507
  #
1391
1508
  # {
1392
- # "success":true,
1393
- # "status":"CANCEL_ALL_SENT"
1509
+ # "success": True,
1510
+ # "data": {
1511
+ # "status": "CANCEL_ALL_SENT"
1512
+ # },
1513
+ # "timestamp": 1751941988134
1394
1514
  # }
1395
1515
  #
1396
- return [
1397
- self.safe_order(response),
1398
- ]
1516
+ return self.v3PrivateDeleteTradeOrders(self.extend(request, params))
1399
1517
 
1400
1518
  def cancel_all_orders_after(self, timeout: Int, params={}):
1401
1519
  """
1402
1520
  dead man's switch, cancel all orders after the given timeout
1403
1521
 
1404
- https://docs.woox.io/#cancel-all-after
1522
+ https://developer.woox.io/api-reference/endpoint/trading/cancel_all_after
1405
1523
 
1406
1524
  :param number timeout: time in milliseconds, 0 represents cancel the timer
1407
1525
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -1409,27 +1527,25 @@ class woo(Exchange, ImplicitAPI):
1409
1527
  """
1410
1528
  self.load_markets()
1411
1529
  request: dict = {
1412
- 'trigger_after': timeout if (timeout > 0) else 0,
1530
+ 'triggerAfter': min(timeout, 900000) if (timeout > 0) else 0,
1413
1531
  }
1414
- response = self.v1PrivatePostOrderCancelAllAfter(self.extend(request, params))
1532
+ response = self.v3PrivatePostTradeCancelAllAfter(self.extend(request, params))
1415
1533
  #
1416
- # {
1417
- # "success": True,
1418
- # "data": {
1419
- # "expected_trigger_time": 1711534302938
1420
- # },
1421
- # "timestamp": 1711534302943
1534
+ # {
1535
+ # "success": True,
1536
+ # "timestamp": 123,
1537
+ # "data": {
1538
+ # "expectedTriggerTime": 123
1422
1539
  # }
1540
+ # }
1423
1541
  #
1424
- return [
1425
- self.safe_order(response),
1426
- ]
1542
+ return response
1427
1543
 
1428
1544
  def fetch_order(self, id: str, symbol: Str = None, params={}):
1429
1545
  """
1430
1546
 
1431
- https://docs.woox.io/#get-algo-order
1432
- https://docs.woox.io/#get-order
1547
+ https://developer.woox.io/api-reference/endpoint/trading/get_order
1548
+ https://developer.woox.io/api-reference/endpoint/trading/get_algo_order
1433
1549
 
1434
1550
  fetches information on an order made by the user
1435
1551
  :param str id: the order id
@@ -1439,65 +1555,102 @@ class woo(Exchange, ImplicitAPI):
1439
1555
  :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1440
1556
  """
1441
1557
  self.load_markets()
1442
- market = self.market(symbol) if (symbol is not None) else None
1558
+ market = None
1559
+ if symbol is not None:
1560
+ market = self.market(symbol)
1443
1561
  trigger = self.safe_bool_2(params, 'stop', 'trigger')
1444
1562
  params = self.omit(params, ['stop', 'trigger'])
1445
1563
  request: dict = {}
1446
1564
  clientOrderId = self.safe_string_2(params, 'clOrdID', 'clientOrderId')
1447
1565
  response = None
1448
1566
  if trigger:
1449
- 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))
1567
+ if clientOrderId is not None:
1568
+ request['clientAlgoOrderId'] = id
1569
+ else:
1570
+ request['algoOrderId'] = id
1571
+ response = self.v3PrivateGetTradeAlgoOrder(self.extend(request, params))
1572
+ #
1573
+ # {
1574
+ # "success": True,
1575
+ # "data": {
1576
+ # "algoOrderId": 10399260,
1577
+ # "clientAlgoOrderId": 0,
1578
+ # "rootAlgoOrderId": 10399260,
1579
+ # "parentAlgoOrderId": 0,
1580
+ # "symbol": "SPOT_LTC_USDT",
1581
+ # "algoOrderTag": "default",
1582
+ # "algoType": "TAKE_PROFIT",
1583
+ # "side": "BUY",
1584
+ # "quantity": 0.1,
1585
+ # "isTriggered": False,
1586
+ # "triggerPrice": 65,
1587
+ # "triggerStatus": "USELESS",
1588
+ # "type": "LIMIT",
1589
+ # "rootAlgoStatus": "NEW",
1590
+ # "algoStatus": "NEW",
1591
+ # "triggerPriceType": "MARKET_PRICE",
1592
+ # "price": 60,
1593
+ # "triggerTime": "0",
1594
+ # "totalExecutedQuantity": 0,
1595
+ # "visibleQuantity": 0.1,
1596
+ # "averageExecutedPrice": 0,
1597
+ # "totalFee": 0,
1598
+ # "feeAsset": "",
1599
+ # "totalRebate": 0,
1600
+ # "rebateAsset": "",
1601
+ # "reduceOnly": False,
1602
+ # "createdTime": "1752049747.732",
1603
+ # "updatedTime": "1752049747.732",
1604
+ # "positionSide": "BOTH"
1605
+ # },
1606
+ # "timestamp": 1752049767550
1607
+ # }
1608
+ #
1454
1609
  else:
1455
- 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)
1610
+ if clientOrderId is not None:
1611
+ request['clientOrderId'] = clientOrderId
1612
+ else:
1613
+ request['orderId'] = id
1614
+ response = self.v3PrivateGetTradeOrder(self.extend(request, params))
1615
+ #
1616
+ # {
1617
+ # "success": True,
1618
+ # "data": {
1619
+ # "orderId": 60780315704,
1620
+ # "clientOrderId": 0,
1621
+ # "symbol": "SPOT_LTC_USDT",
1622
+ # "orderTag": "default",
1623
+ # "side": "BUY",
1624
+ # "quantity": 0.1,
1625
+ # "amount": null,
1626
+ # "type": "LIMIT",
1627
+ # "status": "NEW",
1628
+ # "price": 60,
1629
+ # "executed": 0,
1630
+ # "visible": 0.1,
1631
+ # "averageExecutedPrice": 0,
1632
+ # "totalFee": 0,
1633
+ # "feeAsset": "LTC",
1634
+ # "totalRebate": 0,
1635
+ # "rebateAsset": "USDT",
1636
+ # "reduceOnly": False,
1637
+ # "createdTime": "1752049062.496",
1638
+ # "realizedPnl": null,
1639
+ # "positionSide": "BOTH",
1640
+ # "bidAskLevel": null
1641
+ # },
1642
+ # "timestamp": 1752049393466
1643
+ # }
1644
+ #
1645
+ data = self.safe_dict(response, 'data', {})
1646
+ return self.parse_order(data, market)
1494
1647
 
1495
1648
  def fetch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
1496
1649
  """
1497
1650
  fetches information on multiple orders made by the user
1498
1651
 
1499
- https://docs.woox.io/#get-orders
1500
- https://docs.woox.io/#get-algo-orders
1652
+ https://developer.woox.io/api-reference/endpoint/trading/get_orders
1653
+ https://developer.woox.io/api-reference/endpoint/trading/get_algo_orders
1501
1654
 
1502
1655
  :param str symbol: unified market symbol of the market orders were made in
1503
1656
  :param int [since]: the earliest time in ms to fetch orders for
@@ -1506,7 +1659,6 @@ class woo(Exchange, ImplicitAPI):
1506
1659
  :param boolean [params.trigger]: whether the order is a trigger/algo order
1507
1660
  :param boolean [params.isTriggered]: whether the order has been triggered(False by default)
1508
1661
  :param str [params.side]: 'buy' or 'sell'
1509
- :param boolean [params.trailing]: set to True if you want to fetch trailing orders
1510
1662
  :param boolean [params.paginate]: set to True if you want to fetch orders with pagination
1511
1663
  :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1512
1664
  """
@@ -1518,70 +1670,118 @@ class woo(Exchange, ImplicitAPI):
1518
1670
  request: dict = {}
1519
1671
  market: Market = None
1520
1672
  trigger = self.safe_bool_2(params, 'stop', 'trigger')
1521
- trailing = self.safe_bool(params, 'trailing', False)
1522
- params = self.omit(params, ['stop', 'trailing', 'trigger'])
1673
+ params = self.omit(params, ['stop', 'trigger'])
1523
1674
  if symbol is not None:
1524
1675
  market = self.market(symbol)
1525
1676
  request['symbol'] = market['id']
1526
1677
  if since is not None:
1527
- if trigger or trailing:
1528
- request['createdTimeStart'] = since
1529
- else:
1530
- request['start_t'] = since
1678
+ request['startTime'] = since
1679
+ until = self.safe_integer(params, 'until') # unified in milliseconds
1680
+ params = self.omit(params, ['until'])
1681
+ if until is not None:
1682
+ request['endTime'] = until
1531
1683
  if limit is not None:
1532
- request['size'] = limit
1533
- else:
1534
- request['size'] = 50 if trailing else 500
1535
- if trigger:
1536
- request['algoType'] = 'stop'
1537
- elif trailing:
1538
- request['algoType'] = 'TRAILING_STOP'
1684
+ request['size'] = min(limit, 500)
1539
1685
  response = None
1540
- if trigger or trailing:
1541
- response = self.v3PrivateGetAlgoOrders(self.extend(request, params))
1686
+ if trigger:
1687
+ response = self.v3PrivateGetTradeAlgoOrders(self.extend(request, params))
1688
+ #
1689
+ # {
1690
+ # "success": True,
1691
+ # "data": {
1692
+ # "rows": [
1693
+ # {
1694
+ # "algoOrderId": 10399260,
1695
+ # "clientAlgoOrderId": 0,
1696
+ # "rootAlgoOrderId": 10399260,
1697
+ # "parentAlgoOrderId": 0,
1698
+ # "symbol": "SPOT_LTC_USDT",
1699
+ # "algoOrderTag": "default",
1700
+ # "algoType": "TAKE_PROFIT",
1701
+ # "side": "BUY",
1702
+ # "quantity": 0.1,
1703
+ # "isTriggered": False,
1704
+ # "triggerPrice": 65,
1705
+ # "triggerStatus": "USELESS",
1706
+ # "type": "LIMIT",
1707
+ # "rootAlgoStatus": "NEW",
1708
+ # "algoStatus": "NEW",
1709
+ # "triggerPriceType": "MARKET_PRICE",
1710
+ # "price": 60,
1711
+ # "triggerTime": "0",
1712
+ # "totalExecutedQuantity": 0,
1713
+ # "visibleQuantity": 0.1,
1714
+ # "averageExecutedPrice": 0,
1715
+ # "totalFee": 0,
1716
+ # "feeAsset": "",
1717
+ # "totalRebate": 0,
1718
+ # "rebateAsset": "",
1719
+ # "reduceOnly": False,
1720
+ # "createdTime": "1752049747.730",
1721
+ # "updatedTime": "1752049747.730",
1722
+ # "positionSide": "BOTH"
1723
+ # }
1724
+ # ],
1725
+ # "meta": {
1726
+ # "total": 7,
1727
+ # "recordsPerPage": 1,
1728
+ # "currentPage": 1
1729
+ # }
1730
+ # },
1731
+ # "timestamp": 1752053127448
1732
+ # }
1733
+ #
1542
1734
  else:
1543
- response = self.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')
1735
+ response = self.v3PrivateGetTradeOrders(self.extend(request, params))
1736
+ #
1737
+ # {
1738
+ # "success": True,
1739
+ # "data": {
1740
+ # "rows": [
1741
+ # {
1742
+ # "orderId": 60780315704,
1743
+ # "clientOrderId": 0,
1744
+ # "symbol": "SPOT_LTC_USDT",
1745
+ # "orderTag": "default",
1746
+ # "side": "BUY",
1747
+ # "quantity": 0.1,
1748
+ # "amount": null,
1749
+ # "type": "LIMIT",
1750
+ # "status": "NEW",
1751
+ # "price": 60,
1752
+ # "executed": 0,
1753
+ # "visible": 0.1,
1754
+ # "averageExecutedPrice": 0,
1755
+ # "totalFee": 0,
1756
+ # "feeAsset": "LTC",
1757
+ # "totalRebate": 0,
1758
+ # "rebateAsset": "USDT",
1759
+ # "reduceOnly": False,
1760
+ # "createdTime": "1752049062.496",
1761
+ # "realizedPnl": null,
1762
+ # "positionSide": "BOTH",
1763
+ # "bidAskLevel": null
1764
+ # }
1765
+ # ],
1766
+ # "meta": {
1767
+ # "total": 11,
1768
+ # "recordsPerPage": 1,
1769
+ # "currentPage": 1
1770
+ # }
1771
+ # },
1772
+ # "timestamp": 1752053061236
1773
+ # }
1774
+ #
1775
+ data = self.safe_value(response, 'data', {})
1776
+ orders = self.safe_list(data, 'rows', [])
1577
1777
  return self.parse_orders(orders, market, since, limit)
1578
1778
 
1579
1779
  def fetch_open_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
1580
1780
  """
1581
1781
  fetches information on multiple orders made by the user
1582
1782
 
1583
- https://docs.woox.io/#get-orders
1584
- https://docs.woox.io/#get-algo-orders
1783
+ https://developer.woox.io/api-reference/endpoint/trading/get_orders
1784
+ https://developer.woox.io/api-reference/endpoint/trading/get_algo_orders
1585
1785
 
1586
1786
  :param str symbol: unified market symbol of the market orders were made in
1587
1787
  :param int [since]: the earliest time in ms to fetch orders for
@@ -1602,8 +1802,8 @@ class woo(Exchange, ImplicitAPI):
1602
1802
  """
1603
1803
  fetches information on multiple orders made by the user
1604
1804
 
1605
- https://docs.woox.io/#get-orders
1606
- https://docs.woox.io/#get-algo-orders
1805
+ https://developer.woox.io/api-reference/endpoint/trading/get_orders
1806
+ https://developer.woox.io/api-reference/endpoint/trading/get_algo_orders
1607
1807
 
1608
1808
  :param str symbol: unified market symbol of the market orders were made in
1609
1809
  :param int [since]: the earliest time in ms to fetch orders for
@@ -1630,81 +1830,107 @@ class woo(Exchange, ImplicitAPI):
1630
1830
 
1631
1831
  def parse_order(self, order: dict, market: Market = None) -> Order:
1632
1832
  #
1633
- # 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
1833
+ # createOrder
1834
+ # {
1835
+ # "orderId": 60667653330,
1836
+ # "clientOrderId": 0,
1837
+ # "type": "LIMIT",
1838
+ # "price": 60,
1839
+ # "quantity": 0.1,
1840
+ # "amount": null,
1841
+ # "bidAskLevel": null,
1842
+ # "timestamp": 1751871779855
1843
+ # }
1844
+ #
1845
+ # createOrder - algo
1846
+ # {
1847
+ # "orderId": "1578938",
1848
+ # "clientOrderId": "0",
1849
+ # "algoType": "STOP_LOSS",
1850
+ # "quantity": "0.1",
1851
+ # "timestamp": "1686149372216"
1852
+ # }
1853
+ #
1854
+ # fetchOrder
1855
+ # {
1856
+ # "orderId": 60780315704,
1857
+ # "clientOrderId": 0,
1858
+ # "symbol": "SPOT_LTC_USDT",
1859
+ # "orderTag": "default",
1860
+ # "side": "BUY",
1861
+ # "quantity": 0.1,
1862
+ # "amount": null,
1863
+ # "type": "LIMIT",
1864
+ # "status": "NEW",
1865
+ # "price": 60,
1866
+ # "executed": 0,
1867
+ # "visible": 0.1,
1868
+ # "averageExecutedPrice": 0,
1869
+ # "totalFee": 0,
1870
+ # "feeAsset": "LTC",
1871
+ # "totalRebate": 0,
1872
+ # "rebateAsset": "USDT",
1873
+ # "reduceOnly": False,
1874
+ # "createdTime": "1752049062.496",
1875
+ # "realizedPnl": null,
1876
+ # "positionSide": "BOTH",
1877
+ # "bidAskLevel": null
1878
+ # }
1879
+ #
1880
+ # fetchOrder - algo
1881
+ # {
1882
+ # "algoOrderId": 10399260,
1883
+ # "clientAlgoOrderId": 0,
1884
+ # "rootAlgoOrderId": 10399260,
1885
+ # "parentAlgoOrderId": 0,
1886
+ # "symbol": "SPOT_LTC_USDT",
1887
+ # "algoOrderTag": "default",
1888
+ # "algoType": "TAKE_PROFIT",
1889
+ # "side": "BUY",
1890
+ # "quantity": 0.1,
1891
+ # "isTriggered": False,
1892
+ # "triggerPrice": 65,
1893
+ # "triggerStatus": "USELESS",
1894
+ # "type": "LIMIT",
1895
+ # "rootAlgoStatus": "NEW",
1896
+ # "algoStatus": "NEW",
1897
+ # "triggerPriceType": "MARKET_PRICE",
1898
+ # "price": 60,
1899
+ # "triggerTime": "0",
1900
+ # "totalExecutedQuantity": 0,
1901
+ # "visibleQuantity": 0.1,
1902
+ # "averageExecutedPrice": 0,
1903
+ # "totalFee": 0,
1904
+ # "feeAsset": "",
1905
+ # "totalRebate": 0,
1906
+ # "rebateAsset": "",
1907
+ # "reduceOnly": False,
1908
+ # "createdTime": "1752049747.732",
1909
+ # "updatedTime": "1752049747.732",
1910
+ # "positionSide": "BOTH"
1911
+ # }
1912
+ #
1913
+ timestamp = self.safe_timestamp(order, 'createdTime')
1914
+ if timestamp is None:
1915
+ timestamp = self.safe_integer(order, 'timestamp')
1916
+ orderId = self.safe_string_2(order, 'orderId', 'algoOrderId')
1917
+ clientOrderId = self.omit_zero(self.safe_string_2(order, 'clientOrderId', 'clientAlgoOrderId')) # Somehow, self always returns 0 for limit order
1679
1918
  marketId = self.safe_string(order, 'symbol')
1680
1919
  market = self.safe_market(marketId, market)
1681
1920
  symbol = market['symbol']
1682
- price = self.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')
1921
+ price = self.safe_string(order, 'price')
1922
+ amount = self.safe_string(order, 'quantity') # This is base amount
1923
+ cost = self.safe_string(order, 'amount') # This is quote amount
1924
+ orderType = self.safe_string_lower(order, 'type')
1686
1925
  status = self.safe_value_2(order, 'status', 'algoStatus')
1687
1926
  side = self.safe_string_lower(order, 'side')
1688
1927
  filled = self.omit_zero(self.safe_value_2(order, 'executed', 'totalExecutedQuantity'))
1689
- average = self.omit_zero(self.safe_string_2(order, 'average_executed_price', 'averageExecutedPrice'))
1928
+ average = self.omit_zero(self.safe_string(order, 'averageExecutedPrice'))
1690
1929
  # 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')
1930
+ fee = self.safe_number(order, 'totalFee')
1931
+ feeCurrency = self.safe_string(order, 'feeAsset')
1694
1932
  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')
1933
+ lastUpdateTimestamp = self.safe_timestamp(order, 'updatedTime')
1708
1934
  return self.safe_order({
1709
1935
  'id': orderId,
1710
1936
  'clientOrderId': clientOrderId,
@@ -1717,18 +1943,18 @@ class woo(Exchange, ImplicitAPI):
1717
1943
  'type': orderType,
1718
1944
  'timeInForce': self.parse_time_in_force(orderType),
1719
1945
  'postOnly': None, # TO_DO
1720
- 'reduceOnly': self.safe_bool(order, 'reduce_only'),
1946
+ 'reduceOnly': self.safe_bool(order, 'reduceOnly'),
1721
1947
  'side': side,
1722
1948
  'price': price,
1723
1949
  'triggerPrice': triggerPrice,
1724
- 'takeProfitPrice': takeProfitPrice,
1725
- 'stopLossPrice': stopLossPrice,
1950
+ 'takeProfitPrice': None,
1951
+ 'stopLossPrice': None,
1726
1952
  'average': average,
1727
1953
  'amount': amount,
1728
1954
  'filled': filled,
1729
1955
  'remaining': None, # TO_DO
1730
1956
  'cost': cost,
1731
- 'trades': transactions,
1957
+ 'trades': None,
1732
1958
  'fee': {
1733
1959
  'cost': fee,
1734
1960
  'currency': feeCurrency,
@@ -1756,7 +1982,7 @@ class woo(Exchange, ImplicitAPI):
1756
1982
  """
1757
1983
  fetches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
1758
1984
 
1759
- https://docs.woox.io/#orderbook-snapshot-public
1985
+ https://developer.woox.io/api-reference/endpoint/public_data/orderbook
1760
1986
 
1761
1987
  :param str symbol: unified symbol of the market to fetch the order book for
1762
1988
  :param int [limit]: the maximum amount of order book entries to return
@@ -1769,33 +1995,37 @@ class woo(Exchange, ImplicitAPI):
1769
1995
  'symbol': market['id'],
1770
1996
  }
1771
1997
  if limit is not None:
1772
- limit = min(limit, 1000)
1773
- request['max_level'] = limit
1774
- response = self.v1PublicGetOrderbookSymbol(self.extend(request, params))
1998
+ request['maxLevel'] = limit
1999
+ response = self.v3PublicGetOrderbook(self.extend(request, params))
1775
2000
  #
1776
- # {
1777
- # "success": True,
1778
- # "timestamp": "1641562961192",
1779
- # "asks": [
1780
- # {price: '0.921', quantity: "76.01"},
1781
- # {price: '0.933', quantity: "477.10"},
1782
- # ...
1783
- # ],
1784
- # "bids": [
1785
- # {price: '0.940', quantity: "13502.47"},
1786
- # {price: '0.932', quantity: "43.91"},
1787
- # ...
1788
- # ]
1789
2001
  # }
2002
+ # {
2003
+ # "success": True,
2004
+ # "timestamp": 1751620923344,
2005
+ # "data": {
2006
+ # "asks": [
2007
+ # {
2008
+ # "price": "108924.86",
2009
+ # "quantity": "0.032126"
2010
+ # }
2011
+ # ],
2012
+ # "bids": [
2013
+ # {
2014
+ # "price": "108924.85",
2015
+ # "quantity": "1.714147"
2016
+ # }
2017
+ # ]
2018
+ # }
2019
+ # }
1790
2020
  #
2021
+ data = self.safe_dict(response, 'data', {})
1791
2022
  timestamp = self.safe_integer(response, 'timestamp')
1792
- return self.parse_order_book(response, symbol, timestamp, 'bids', 'asks', 'price', 'quantity')
2023
+ return self.parse_order_book(data, symbol, timestamp, 'bids', 'asks', 'price', 'quantity')
1793
2024
 
1794
2025
  def fetch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
1795
2026
  """
1796
2027
 
1797
- https://docs.woox.io/#kline-public
1798
- https://docs.woox.io/#kline-historical-data-public
2028
+ https://developer.woox.io/api-reference/endpoint/public_data/klineHistory
1799
2029
 
1800
2030
  fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
1801
2031
  :param str symbol: unified symbol of the market to fetch OHLCV data for
@@ -1803,6 +2033,7 @@ class woo(Exchange, ImplicitAPI):
1803
2033
  :param int [since]: timestamp in ms of the earliest candle to fetch
1804
2034
  :param int [limit]: max=1000, max=100 when since is defined and is less than(now - (999 * (timeframe in ms)))
1805
2035
  :param dict [params]: extra parameters specific to the exchange API endpoint
2036
+ :param int [params.until]: the latest time in ms to fetch entries for
1806
2037
  :returns int[][]: A list of candles ordered, open, high, low, close, volume
1807
2038
  """
1808
2039
  self.load_markets()
@@ -1811,70 +2042,44 @@ class woo(Exchange, ImplicitAPI):
1811
2042
  'symbol': market['id'],
1812
2043
  'type': self.safe_string(self.timeframes, timeframe, timeframe),
1813
2044
  }
1814
- 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
2045
+ if limit is not None:
1822
2046
  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', [])
2047
+ if since is not None:
2048
+ request['after'] = since
2049
+ until = self.safe_integer(params, 'until')
2050
+ params = self.omit(params, 'until')
2051
+ if until is not None:
2052
+ request['before'] = until
2053
+ response = self.v3PublicGetKlineHistory(self.extend(request, params))
2054
+ #
2055
+ # {
2056
+ # "success": True,
2057
+ # "data": {
2058
+ # "rows": [
2059
+ # {
2060
+ # "symbol": "SPOT_BTC_USDT",
2061
+ # "open": "108994.16",
2062
+ # "close": "108994.16",
2063
+ # "high": "108994.16",
2064
+ # "low": "108994.16",
2065
+ # "volume": "0",
2066
+ # "amount": "0",
2067
+ # "type": "1m",
2068
+ # "startTimestamp": 1751622120000,
2069
+ # "endTimestamp": 1751622180000
2070
+ # }
2071
+ # ]
2072
+ # },
2073
+ # "timestamp": 1751622205410
2074
+ # }
2075
+ #
2076
+ data = self.safe_dict(response, 'data', {})
2077
+ rows = self.safe_list(data, 'rows', [])
1872
2078
  return self.parse_ohlcvs(rows, market, timeframe, since, limit)
1873
2079
 
1874
2080
  def parse_ohlcv(self, ohlcv, market: Market = None) -> list:
1875
- # example response in fetchOHLCV
1876
2081
  return [
1877
- self.safe_integer(ohlcv, 'start_timestamp'),
2082
+ self.safe_integer(ohlcv, 'startTimestamp'),
1878
2083
  self.safe_number(ohlcv, 'open'),
1879
2084
  self.safe_number(ohlcv, 'high'),
1880
2085
  self.safe_number(ohlcv, 'low'),
@@ -1928,7 +2133,7 @@ class woo(Exchange, ImplicitAPI):
1928
2133
  """
1929
2134
  fetch all trades made by the user
1930
2135
 
1931
- https://docs.woox.io/#get-trade-history
2136
+ https://developer.woox.io/api-reference/endpoint/trading/get_transactions
1932
2137
 
1933
2138
  :param str symbol: unified market symbol
1934
2139
  :param int [since]: the earliest time in ms to fetch trades for
@@ -1948,83 +2153,149 @@ class woo(Exchange, ImplicitAPI):
1948
2153
  market = self.market(symbol)
1949
2154
  request['symbol'] = market['id']
1950
2155
  if since is not None:
1951
- request['start_t'] = since
1952
- request, params = self.handle_until_option('end_t', request, params)
2156
+ request['startTime'] = since
2157
+ until = self.safe_integer(params, 'until') # unified in milliseconds
2158
+ params = self.omit(params, ['until'])
2159
+ if until is not None:
2160
+ request['endTime'] = until
1953
2161
  if limit is not None:
1954
- request['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"
2162
+ request['limit'] = limit
2163
+ response = self.v3PrivateGetTradeTransactionHistory(self.extend(request, params))
2164
+ #
2165
+ # {
2166
+ # "success": True,
2167
+ # "data": {
2168
+ # "rows": [
2169
+ # {
2170
+ # "id": 1734947821,
2171
+ # "symbol": "SPOT_LTC_USDT",
2172
+ # "orderId": 60780383217,
2173
+ # "executedPrice": 87.86,
2174
+ # "executedQuantity": 0.1,
2175
+ # "fee": 0.0001,
2176
+ # "realizedPnl": null,
2177
+ # "feeAsset": "LTC",
2178
+ # "orderTag": "default",
2179
+ # "side": "BUY",
2180
+ # "executedTimestamp": "1752055173.630",
2181
+ # "isMaker": 0
2182
+ # }
2183
+ # ],
2184
+ # "meta": {
2185
+ # "total": 1,
2186
+ # "recordsPerPage": 100,
2187
+ # "currentPage": 1
2188
+ # }
1977
2189
  # },
1978
- # ...
1979
- # ]
1980
- # }
1981
- trades = self.safe_list(response, 'rows', [])
2190
+ # "timestamp": 1752055545121
2191
+ # }
2192
+ #
2193
+ data = self.safe_dict(response, 'data', {})
2194
+ trades = self.safe_list(data, 'rows', [])
1982
2195
  return self.parse_trades(trades, market, since, limit, params)
1983
2196
 
1984
2197
  def fetch_accounts(self, params={}) -> List[Account]:
1985
2198
  """
1986
2199
  fetch all the accounts associated with a profile
1987
2200
 
1988
- https://docs.woox.io/#get-assets-of-subaccounts
2201
+ https://developer.woox.io/api-reference/endpoint/account/get_account_info
2202
+ https://developer.woox.io/api-reference/endpoint/account/sub_accounts
1989
2203
 
1990
2204
  :param dict [params]: extra parameters specific to the exchange API endpoint
1991
2205
  :returns dict: a dictionary of `account structures <https://docs.ccxt.com/#/?id=account-structure>` indexed by the account type
1992
2206
  """
1993
- response = self.v1PrivateGetSubAccountAssets(params)
2207
+ mainAccountPromise = self.v3PrivateGetAccountInfo(params)
1994
2208
  #
1995
2209
  # {
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
2210
+ # "success": True,
2211
+ # "data": {
2212
+ # "applicationId": "251bf5c4-f3c8-4544-bb8b-80001007c3c0",
2213
+ # "account": "carlos_jose_lima@yahoo.com",
2214
+ # "alias": "carlos_jose_lima@yahoo.com",
2215
+ # "otpauth": True,
2216
+ # "accountMode": "FUTURES",
2217
+ # "positionMode": "ONE_WAY",
2218
+ # "leverage": 0,
2219
+ # "marginRatio": "10",
2220
+ # "openMarginRatio": "10",
2221
+ # "initialMarginRatio": "10",
2222
+ # "maintenanceMarginRatio": "0.03",
2223
+ # "totalCollateral": "165.55629469",
2224
+ # "freeCollateral": "165.55629469",
2225
+ # "totalAccountValue": "167.32418611",
2226
+ # "totalTradingValue": "167.32418611",
2227
+ # "totalVaultValue": "0",
2228
+ # "totalStakingValue": "0",
2229
+ # "totalLaunchpadValue": "0",
2230
+ # "totalEarnValue": "0",
2231
+ # "referrerID": null,
2232
+ # "accountType": "Main"
2233
+ # },
2234
+ # "timestamp": 1752062807915
2008
2235
  # }
2009
2236
  #
2010
- rows = self.safe_list(response, 'rows', [])
2237
+ subAccountPromise = self.v3PrivateGetAccountSubAccountsAll(params)
2238
+ #
2239
+ # {
2240
+ # "success": True,
2241
+ # "data": {
2242
+ # "rows": [
2243
+ # {
2244
+ # "applicationId": "6b43de5c-0955-4887-9862-d84e4689f9fe",
2245
+ # "name": "sub_account_2",
2246
+ # "createdTime": "1606897264.994"
2247
+ # },
2248
+ # ]
2249
+ # },
2250
+ # "timestamp": 1721295317627
2251
+ # }
2252
+ #
2253
+ mainAccountResponse, subAccountResponse = [mainAccountPromise, subAccountPromise]
2254
+ mainData = self.safe_dict(mainAccountResponse, 'data', {})
2255
+ mainRows = [mainData]
2256
+ subData = self.safe_dict(subAccountResponse, 'data', {})
2257
+ subRows = self.safe_list(subData, 'rows', [])
2258
+ rows = self.array_concat(mainRows, subRows)
2011
2259
  return self.parse_accounts(rows, params)
2012
2260
 
2013
2261
  def parse_account(self, account):
2014
2262
  #
2015
2263
  # {
2016
- # "application_id": "336952aa-a401-4e26-aff6-972920aebba3",
2017
- # "account": "subaccount",
2018
- # "usdt_balance": "1.0",
2264
+ # "applicationId": "251bf5c4-f3c8-4544-bb8b-80001007c3c0",
2265
+ # "account": "carlos_jose_lima@yahoo.com",
2266
+ # "alias": "carlos_jose_lima@yahoo.com",
2267
+ # "otpauth": True,
2268
+ # "accountMode": "FUTURES",
2269
+ # "positionMode": "ONE_WAY",
2270
+ # "leverage": 0,
2271
+ # "marginRatio": "10",
2272
+ # "openMarginRatio": "10",
2273
+ # "initialMarginRatio": "10",
2274
+ # "maintenanceMarginRatio": "0.03",
2275
+ # "totalCollateral": "165.55629469",
2276
+ # "freeCollateral": "165.55629469",
2277
+ # "totalAccountValue": "167.32418611",
2278
+ # "totalTradingValue": "167.32418611",
2279
+ # "totalVaultValue": "0",
2280
+ # "totalStakingValue": "0",
2281
+ # "totalLaunchpadValue": "0",
2282
+ # "totalEarnValue": "0",
2283
+ # "referrerID": null,
2284
+ # "accountType": "Main"
2285
+ # }
2286
+ #
2287
+ # {
2288
+ # "applicationId": "6b43de5c-0955-4887-9862-d84e4689f9fe",
2289
+ # "name": "sub_account_2",
2290
+ # "createdTime": "1606897264.994"
2019
2291
  # }
2020
2292
  #
2021
- accountId = self.safe_string(account, 'account')
2022
2293
  return {
2023
2294
  'info': account,
2024
- 'id': self.safe_string(account, 'application_id'),
2025
- 'name': accountId,
2295
+ 'id': self.safe_string(account, 'applicationId'),
2296
+ 'name': self.safe_string_n(account, ['name', 'account', 'alias']),
2026
2297
  'code': None,
2027
- 'type': accountId == 'main' if 'Main' else 'subaccount',
2298
+ 'type': self.safe_string_lower(account, 'accountType', 'subaccount'),
2028
2299
  }
2029
2300
 
2030
2301
  def fetch_balance(self, params={}) -> Balances:
@@ -2082,7 +2353,7 @@ class woo(Exchange, ImplicitAPI):
2082
2353
  """
2083
2354
  fetch the deposit address for a currency associated with self account
2084
2355
 
2085
- https://docs.woox.io/#get-token-deposit-address
2356
+ https://developer.woox.io/api-reference/endpoint/assets/get_wallet_deposit
2086
2357
 
2087
2358
  :param str code: unified currency code
2088
2359
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -2091,18 +2362,25 @@ class woo(Exchange, ImplicitAPI):
2091
2362
  # self method is TODO because of networks unification
2092
2363
  self.load_markets()
2093
2364
  currency = self.currency(code)
2094
- specialNetworkId: Str = None
2095
- specialNetworkId, params = self.get_dedicated_network_id(currency, params)
2365
+ networkCode = None
2366
+ networkCode, params = self.handle_network_code_and_params(params)
2096
2367
  request: dict = {
2097
- 'token': specialNetworkId,
2368
+ 'token': currency['id'],
2369
+ 'network': self.network_code_to_id(networkCode),
2098
2370
  }
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)
2371
+ response = self.v3PrivateGetAssetWalletDeposit(self.extend(request, params))
2372
+ #
2373
+ # {
2374
+ # "success": True,
2375
+ # "data": {
2376
+ # "address": "0x31d64B3230f8baDD91dE1710A65DF536aF8f7cDa",
2377
+ # "extra": ""
2378
+ # },
2379
+ # "timestamp": 1721300689532
2380
+ # }
2381
+ #
2382
+ data = self.safe_dict(response, 'data', {})
2383
+ return self.parse_deposit_address(data, currency)
2106
2384
 
2107
2385
  def get_dedicated_network_id(self, currency, params: dict) -> Any:
2108
2386
  networkCode = None
@@ -2132,57 +2410,63 @@ class woo(Exchange, ImplicitAPI):
2132
2410
  currency: Currency = None
2133
2411
  if code is not None:
2134
2412
  currency = self.currency(code)
2135
- request['balance_token'] = currency['id']
2413
+ request['token'] = currency['id']
2414
+ networkCode = None
2415
+ networkCode, params = self.handle_network_code_and_params(params)
2416
+ if networkCode is not None:
2417
+ request['network'] = self.network_code_to_id(networkCode)
2136
2418
  if since is not None:
2137
- request['start_t'] = since
2419
+ request['startTime'] = since
2138
2420
  if limit is not None:
2139
- request['pageSize'] = limit
2421
+ request['size'] = min(limit, 1000)
2140
2422
  transactionType = self.safe_string(params, 'type')
2141
2423
  params = self.omit(params, 'type')
2142
2424
  if transactionType is not None:
2143
2425
  request['type'] = transactionType
2144
- response = self.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', [])]
2426
+ response = self.v3PrivateGetAssetWalletHistory(self.extend(request, params))
2427
+ #
2428
+ # {
2429
+ # "success": True,
2430
+ # "data": {
2431
+ # "rows": [
2432
+ # {
2433
+ # "createdTime": "1734964440.523",
2434
+ # "updatedTime": "1734964614.081",
2435
+ # "id": "24122314340000585",
2436
+ # "externalId": "241223143600621",
2437
+ # "applicationId": "251bf5c4-f3c8-4544-bb8b-80001007c3c0",
2438
+ # "token": "ARB_USDCNATIVE",
2439
+ # "targetAddress": "0x4d6802d2736daa85e6242ef0dc0f00aa0e68f635",
2440
+ # "sourceAddress": "0x63DFE4e34A3bFC00eB0220786238a7C6cEF8Ffc4",
2441
+ # "extra": "",
2442
+ # "type": "BALANCE",
2443
+ # "tokenSide": "WITHDRAW",
2444
+ # "amount": "10.00000000",
2445
+ # "txId": "0x891ade0a47fd55466bb9d06702bea4edcb75ed9367d9afbc47b93a84f496d2e6",
2446
+ # "feeToken": "USDC",
2447
+ # "feeAmount": "2",
2448
+ # "status": "COMPLETED",
2449
+ # "confirmingThreshold": null,
2450
+ # "confirmedNumber": null
2451
+ # }
2452
+ # ],
2453
+ # "meta": {
2454
+ # "total": 1,
2455
+ # "records_per_page": 25,
2456
+ # "current_page": 1
2457
+ # }
2458
+ # },
2459
+ # "timestamp": 1752485344719
2460
+ # }
2461
+ #
2462
+ data = self.safe_dict(response, 'data', {})
2463
+ return [currency, self.safe_list(data, 'rows', [])]
2180
2464
 
2181
2465
  def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[LedgerEntry]:
2182
2466
  """
2183
2467
  fetch the history of changes, actions done by the user or operations that altered balance of the user
2184
2468
 
2185
- https://docs.woox.io/#get-asset-history
2469
+ https://developer.woox.io/api-reference/endpoint/assets/get_wallet_history
2186
2470
 
2187
2471
  :param str [code]: unified currency code, default is None
2188
2472
  :param int [since]: timestamp in ms of the earliest ledger entry, default is None
@@ -2196,22 +2480,43 @@ class woo(Exchange, ImplicitAPI):
2196
2480
  return self.parse_ledger(rows, currency, since, limit, params)
2197
2481
 
2198
2482
  def parse_ledger_entry(self, item: dict, currency: Currency = None) -> LedgerEntry:
2483
+ #
2484
+ # {
2485
+ # "createdTime": "1734964440.523",
2486
+ # "updatedTime": "1734964614.081",
2487
+ # "id": "24122314340000585",
2488
+ # "externalId": "241223143600621",
2489
+ # "applicationId": "251bf5c4-f3c8-4544-bb8b-80001007c3c0",
2490
+ # "token": "ARB_USDCNATIVE",
2491
+ # "targetAddress": "0x4d6802d2736daa85e6242ef0dc0f00aa0e68f635",
2492
+ # "sourceAddress": "0x63DFE4e34A3bFC00eB0220786238a7C6cEF8Ffc4",
2493
+ # "extra": "",
2494
+ # "type": "BALANCE",
2495
+ # "tokenSide": "WITHDRAW",
2496
+ # "amount": "10.00000000",
2497
+ # "txId": "0x891ade0a47fd55466bb9d06702bea4edcb75ed9367d9afbc47b93a84f496d2e6",
2498
+ # "feeToken": "USDC",
2499
+ # "feeAmount": "2",
2500
+ # "status": "COMPLETED",
2501
+ # "confirmingThreshold": null,
2502
+ # "confirmedNumber": null
2503
+ # }
2504
+ #
2199
2505
  networkizedCode = self.safe_string(item, 'token')
2200
- currencyDefined = self.get_currency_from_chaincode(networkizedCode, currency)
2201
- code = currencyDefined['code']
2506
+ code = self.safe_currency_code(networkizedCode, currency)
2202
2507
  currency = self.safe_currency(code, currency)
2203
2508
  amount = self.safe_number(item, 'amount')
2204
- side = self.safe_string(item, 'token_side')
2509
+ side = self.safe_string(item, 'tokenSide')
2205
2510
  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')
2511
+ timestamp = self.safe_timestamp(item, 'createdTime')
2512
+ fee = self.parse_token_and_fee_temp(item, ['feeToken'], ['feeAmount'])
2208
2513
  return self.safe_ledger_entry({
2209
2514
  'info': item,
2210
2515
  'id': self.safe_string(item, 'id'),
2211
2516
  'currency': code,
2212
2517
  'account': self.safe_string(item, 'account'),
2213
2518
  'referenceAccount': None,
2214
- 'referenceId': self.safe_string(item, 'tx_id'),
2519
+ 'referenceId': self.safe_string(item, 'txId'),
2215
2520
  'status': self.parse_transaction_status(self.safe_string(item, 'status')),
2216
2521
  'amount': amount,
2217
2522
  'before': None,
@@ -2247,7 +2552,7 @@ class woo(Exchange, ImplicitAPI):
2247
2552
  """
2248
2553
  fetch all deposits made to an account
2249
2554
 
2250
- https://docs.woox.io/#get-asset-history
2555
+ https://developer.woox.io/api-reference/endpoint/assets/get_wallet_history
2251
2556
 
2252
2557
  :param str code: unified currency code
2253
2558
  :param int [since]: the earliest time in ms to fetch deposits for
@@ -2256,7 +2561,7 @@ class woo(Exchange, ImplicitAPI):
2256
2561
  :returns dict[]: a list of `transaction structures <https://docs.ccxt.com/#/?id=transaction-structure>`
2257
2562
  """
2258
2563
  request: dict = {
2259
- 'token_side': 'DEPOSIT',
2564
+ 'tokenSide': 'DEPOSIT',
2260
2565
  }
2261
2566
  return self.fetch_deposits_withdrawals(code, since, limit, self.extend(request, params))
2262
2567
 
@@ -2264,7 +2569,7 @@ class woo(Exchange, ImplicitAPI):
2264
2569
  """
2265
2570
  fetch all withdrawals made from an account
2266
2571
 
2267
- https://docs.woox.io/#get-asset-history
2572
+ https://developer.woox.io/api-reference/endpoint/assets/get_wallet_history
2268
2573
 
2269
2574
  :param str code: unified currency code
2270
2575
  :param int [since]: the earliest time in ms to fetch withdrawals for
@@ -2273,7 +2578,7 @@ class woo(Exchange, ImplicitAPI):
2273
2578
  :returns dict[]: a list of `transaction structures <https://docs.ccxt.com/#/?id=transaction-structure>`
2274
2579
  """
2275
2580
  request: dict = {
2276
- 'token_side': 'WITHDRAW',
2581
+ 'tokenSide': 'WITHDRAW',
2277
2582
  }
2278
2583
  return self.fetch_deposits_withdrawals(code, since, limit, self.extend(request, params))
2279
2584
 
@@ -2281,7 +2586,7 @@ class woo(Exchange, ImplicitAPI):
2281
2586
  """
2282
2587
  fetch history of deposits and withdrawals
2283
2588
 
2284
- https://docs.woox.io/#get-asset-history
2589
+ https://developer.woox.io/api-reference/endpoint/assets/get_wallet_history
2285
2590
 
2286
2591
  :param str [code]: unified currency code for the currency of the deposit/withdrawals, default is None
2287
2592
  :param int [since]: timestamp in ms of the earliest deposit/withdrawal, default is None
@@ -2295,35 +2600,45 @@ class woo(Exchange, ImplicitAPI):
2295
2600
  currencyRows = self.get_asset_history_rows(code, since, limit, self.extend(request, params))
2296
2601
  currency = self.safe_value(currencyRows, 0)
2297
2602
  rows = self.safe_list(currencyRows, 1)
2603
+ return self.parse_transactions(rows, currency, since, limit, params)
2604
+
2605
+ def parse_transaction(self, transaction: dict, currency: Currency = None) -> Transaction:
2298
2606
  #
2299
2607
  # {
2300
- # "rows":[],
2301
- # "meta":{
2302
- # "total":0,
2303
- # "records_per_page":25,
2304
- # "current_page":1
2305
- # },
2306
- # "success":true
2608
+ # "createdTime": "1734964440.523",
2609
+ # "updatedTime": "1734964614.081",
2610
+ # "id": "24122314340000585",
2611
+ # "externalId": "241223143600621",
2612
+ # "applicationId": "251bf5c4-f3c8-4544-bb8b-80001007c3c0",
2613
+ # "token": "ARB_USDCNATIVE",
2614
+ # "targetAddress": "0x4d6802d2736daa85e6242ef0dc0f00aa0e68f635",
2615
+ # "sourceAddress": "0x63DFE4e34A3bFC00eB0220786238a7C6cEF8Ffc4",
2616
+ # "extra": "",
2617
+ # "type": "BALANCE",
2618
+ # "tokenSide": "WITHDRAW",
2619
+ # "amount": "10.00000000",
2620
+ # "txId": "0x891ade0a47fd55466bb9d06702bea4edcb75ed9367d9afbc47b93a84f496d2e6",
2621
+ # "feeToken": "USDC",
2622
+ # "feeAmount": "2",
2623
+ # "status": "COMPLETED",
2624
+ # "confirmingThreshold": null,
2625
+ # "confirmedNumber": null
2307
2626
  # }
2308
2627
  #
2309
- return self.parse_transactions(rows, currency, since, limit, params)
2310
-
2311
- def parse_transaction(self, transaction: dict, currency: Currency = None) -> Transaction:
2312
- # example in fetchLedger
2313
2628
  networkizedCode = self.safe_string(transaction, 'token')
2314
2629
  currencyDefined = self.get_currency_from_chaincode(networkizedCode, currency)
2315
2630
  code = currencyDefined['code']
2316
- movementDirection = self.safe_string_lower(transaction, 'token_side')
2631
+ movementDirection = self.safe_string_lower_2(transaction, 'token_side', 'tokenSide')
2317
2632
  if movementDirection == 'withdraw':
2318
2633
  movementDirection = 'withdrawal'
2319
- fee = self.parse_token_and_fee_temp(transaction, 'fee_token', 'fee_amount')
2320
- addressTo = self.safe_string(transaction, 'target_address')
2321
- addressFrom = self.safe_string(transaction, 'source_address')
2322
- timestamp = self.safe_timestamp(transaction, 'created_time')
2634
+ fee = self.parse_token_and_fee_temp(transaction, ['fee_token', 'feeToken'], ['fee_amount', 'feeAmount'])
2635
+ addressTo = self.safe_string_2(transaction, 'target_address', 'targetAddress')
2636
+ addressFrom = self.safe_string_2(transaction, 'source_address', 'sourceAddress')
2637
+ timestamp = self.safe_timestamp_2(transaction, 'created_time', 'createdTime')
2323
2638
  return {
2324
2639
  'info': transaction,
2325
- 'id': self.safe_string_2(transaction, 'id', 'withdraw_id'),
2326
- 'txid': self.safe_string(transaction, 'tx_id'),
2640
+ 'id': self.safe_string_n(transaction, ['id', 'withdraw_id', 'withdrawId']),
2641
+ 'txid': self.safe_string_2(transaction, 'tx_id', 'txId'),
2327
2642
  'timestamp': timestamp,
2328
2643
  'datetime': self.iso8601(timestamp),
2329
2644
  'address': None,
@@ -2336,7 +2651,7 @@ class woo(Exchange, ImplicitAPI):
2336
2651
  'amount': self.safe_number(transaction, 'amount'),
2337
2652
  'currency': code,
2338
2653
  'status': self.parse_transaction_status(self.safe_string(transaction, 'status')),
2339
- 'updated': self.safe_timestamp(transaction, 'updated_time'),
2654
+ 'updated': self.safe_timestamp_2(transaction, 'updated_time', 'updatedTime'),
2340
2655
  'comment': None,
2341
2656
  'internal': None,
2342
2657
  'fee': fee,
@@ -2394,7 +2709,7 @@ class woo(Exchange, ImplicitAPI):
2394
2709
  """
2395
2710
  fetch a history of internal transfers made on an account
2396
2711
 
2397
- https://docs.woox.io/#get-transfer-history
2712
+ https://developer.woox.io/api-reference/endpoint/assets/get_transfer_history
2398
2713
 
2399
2714
  :param str code: unified currency code of the currency transferred
2400
2715
  :param int [since]: the earliest time in ms to fetch transfers for
@@ -2404,41 +2719,52 @@ class woo(Exchange, ImplicitAPI):
2404
2719
  :returns dict[]: a list of `transfer structures <https://docs.ccxt.com/#/?id=transfer-structure>`
2405
2720
  """
2406
2721
  request: dict = {}
2722
+ currency = None
2723
+ if code is not None:
2724
+ currency = self.currency(code)
2407
2725
  if limit is not None:
2408
2726
  request['size'] = limit
2409
2727
  if since is not None:
2410
- request['start_t'] = since
2728
+ request['startTime'] = since
2411
2729
  until = self.safe_integer(params, 'until') # unified in milliseconds
2412
2730
  params = self.omit(params, ['until'])
2413
2731
  if until is not None:
2414
- request['end_t'] = until
2415
- response = self.v1PrivateGetAssetMainSubTransferHistory(self.extend(request, params))
2732
+ request['endTime'] = until
2733
+ response = self.v3PrivateGetAssetTransferHistory(self.extend(request, params))
2416
2734
  #
2417
2735
  # {
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"
2736
+ # "success": True,
2737
+ # "data": {
2738
+ # "rows": [
2739
+ # {
2740
+ # "id": 225,
2741
+ # "token": "USDT",
2742
+ # "amount": "1000000",
2743
+ # "status": "COMPLETED",
2744
+ # "from": {
2745
+ # "applicationId": "046b5c5c-5b44-4d27-9593-ddc32c0a08ae",
2746
+ # "accountName": "Main"
2747
+ # },
2748
+ # "to": {
2749
+ # "applicationId": "082ae5ae-e26a-4fb1-be5b-03e5b4867663",
2750
+ # "accountName": "sub001"
2751
+ # },
2752
+ # "createdTime": "1642660941.534",
2753
+ # "updatedTime": "1642660941.950"
2754
+ # }
2755
+ # ],
2756
+ # "meta": {
2757
+ # "total": 46,
2758
+ # "recordsPerPage": 1,
2759
+ # "currentPage": 1
2430
2760
  # }
2431
- # ],
2432
- # "meta": {
2433
- # "total": 50,
2434
- # "records_per_page": 25,
2435
- # "current_page": 1
2436
2761
  # },
2437
- # "success": True
2762
+ # "timestamp": 1721295317627
2438
2763
  # }
2439
2764
  #
2440
- data = self.safe_list(response, 'rows', [])
2441
- return self.parse_transfers(data, None, since, limit, params)
2765
+ data = self.safe_dict(response, 'data', {})
2766
+ rows = self.safe_list(data, 'rows', [])
2767
+ return self.parse_transfers(rows, currency, since, limit, params)
2442
2768
 
2443
2769
  def parse_transfer(self, transfer: dict, currency: Currency = None) -> TransferEntry:
2444
2770
  #
@@ -2455,6 +2781,22 @@ class woo(Exchange, ImplicitAPI):
2455
2781
  # "created_time": "1709022325.427",
2456
2782
  # "updated_time": "1709022325.542"
2457
2783
  # }
2784
+ # {
2785
+ # "id": 225,
2786
+ # "token": "USDT",
2787
+ # "amount": "1000000",
2788
+ # "status": "COMPLETED",
2789
+ # "from": {
2790
+ # "applicationId": "046b5c5c-5b44-4d27-9593-ddc32c0a08ae",
2791
+ # "accountName": "Main"
2792
+ # },
2793
+ # "to": {
2794
+ # "applicationId": "082ae5ae-e26a-4fb1-be5b-03e5b4867663",
2795
+ # "accountName": "sub001"
2796
+ # },
2797
+ # "createdTime": "1642660941.534",
2798
+ # "updatedTime": "1642660941.950"
2799
+ # }
2458
2800
  #
2459
2801
  # transfer
2460
2802
  # {
@@ -2462,22 +2804,22 @@ class woo(Exchange, ImplicitAPI):
2462
2804
  # "id": 200
2463
2805
  # }
2464
2806
  #
2465
- 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')
2807
+ code = self.safe_currency_code(self.safe_string(transfer, 'token'), currency)
2808
+ timestamp = self.safe_timestamp(transfer, 'createdTime')
2469
2809
  success = self.safe_bool(transfer, 'success')
2470
2810
  status: Str = None
2471
2811
  if success is not None:
2472
2812
  status = 'ok' if success else 'failed'
2813
+ fromAccount = self.safe_dict(transfer, 'from', {})
2814
+ toAccount = self.safe_dict(transfer, 'to', {})
2473
2815
  return {
2474
2816
  'id': self.safe_string(transfer, 'id'),
2475
2817
  'timestamp': timestamp,
2476
2818
  'datetime': self.iso8601(timestamp),
2477
2819
  'currency': code,
2478
2820
  'amount': self.safe_number(transfer, 'amount'),
2479
- 'fromAccount': self.safe_string(transfer, 'from_application_id'),
2480
- 'toAccount': self.safe_string(transfer, 'to_application_id'),
2821
+ 'fromAccount': self.safe_string(fromAccount, 'applicationId'),
2822
+ 'toAccount': self.safe_string(toAccount, 'applicationId'),
2481
2823
  'status': self.parse_transfer_status(self.safe_string(transfer, 'status', status)),
2482
2824
  'info': transfer,
2483
2825
  }
@@ -2598,7 +2940,7 @@ class woo(Exchange, ImplicitAPI):
2598
2940
  url += '?' + self.urlencode(params)
2599
2941
  else:
2600
2942
  self.check_required_credentials()
2601
- if method == 'POST' and (path == 'algo/order' or path == 'order'):
2943
+ if method == 'POST' and (path == 'trade/algoOrder' or path == 'trade/order'):
2602
2944
  isSandboxMode = self.safe_bool(self.options, 'sandboxMode', False)
2603
2945
  if not isSandboxMode:
2604
2946
  applicationId = 'bc830de7-50f3-460b-9ee0-f430f83f9dad'
@@ -2618,15 +2960,15 @@ class woo(Exchange, ImplicitAPI):
2618
2960
  }
2619
2961
  if version == 'v3':
2620
2962
  auth = ts + method + '/' + version + '/' + pathWithParams
2621
- if method == 'POST' or method == 'PUT' or method == 'DELETE':
2963
+ if method == 'POST' or method == 'PUT':
2622
2964
  body = self.json(params)
2623
2965
  auth += body
2966
+ headers['content-type'] = 'application/json'
2624
2967
  else:
2625
2968
  if params:
2626
2969
  query = self.urlencode(params)
2627
2970
  url += '?' + query
2628
2971
  auth += '?' + query
2629
- headers['content-type'] = 'application/json'
2630
2972
  else:
2631
2973
  auth = self.urlencode(params)
2632
2974
  if method == 'POST' or method == 'PUT' or method == 'DELETE':
@@ -2657,25 +2999,26 @@ class woo(Exchange, ImplicitAPI):
2657
2999
  def parse_income(self, income, market: Market = None):
2658
3000
  #
2659
3001
  # {
2660
- # "id":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"
3002
+ # "id": 1286360,
3003
+ # "symbol": "PERP_BTC_USDT",
3004
+ # "fundingRate": -0.00001445,
3005
+ # "markPrice": "26930.60000000",
3006
+ # "fundingFee": "9.56021744",
3007
+ # "fundingIntervalHours": 8,
3008
+ # "paymentType": "Pay",
3009
+ # "status": "COMPLETED",
3010
+ # "createdTime": 1696060873259,
3011
+ # "updatedTime": 1696060873286
2669
3012
  # }
2670
3013
  #
2671
3014
  marketId = self.safe_string(income, 'symbol')
2672
3015
  symbol = self.safe_symbol(marketId, market)
2673
- amount = self.safe_string(income, 'funding_fee')
3016
+ amount = self.safe_string(income, 'fundingFee')
2674
3017
  code = self.safe_currency_code('USD')
2675
3018
  id = self.safe_string(income, 'id')
2676
- timestamp = self.safe_timestamp(income, 'updated_time')
2677
- rate = self.safe_number(income, 'funding_rate')
2678
- paymentType = self.safe_string(income, 'payment_type')
3019
+ timestamp = self.safe_integer(income, 'updatedTime')
3020
+ rate = self.safe_number(income, 'fundingRate')
3021
+ paymentType = self.safe_string(income, 'paymentType')
2679
3022
  amount = Precise.string_neg(amount) if (paymentType == 'Pay') else amount
2680
3023
  return {
2681
3024
  'info': income,
@@ -2692,7 +3035,7 @@ class woo(Exchange, ImplicitAPI):
2692
3035
  """
2693
3036
  fetch the history of funding payments paid and received on self account
2694
3037
 
2695
- https://docs.woox.io/#get-funding-fee-history
3038
+ https://developer.woox.io/api-reference/endpoint/futures/get_fundingFee_history
2696
3039
 
2697
3040
  :param str [symbol]: unified market symbol
2698
3041
  :param int [since]: the earliest time in ms to fetch funding history for
@@ -2705,73 +3048,71 @@ class woo(Exchange, ImplicitAPI):
2705
3048
  paginate = False
2706
3049
  paginate, params = self.handle_option_and_params(params, 'fetchFundingHistory', 'paginate')
2707
3050
  if paginate:
2708
- return self.fetch_paginated_call_cursor('fetchFundingHistory', symbol, since, limit, params, 'page', 'page', 1, 500)
3051
+ return self.fetch_paginated_call_incremental('fetchFundingHistory', symbol, since, limit, params, 'page', 500)
2709
3052
  request: dict = {}
2710
3053
  market: Market = None
2711
3054
  if symbol is not None:
2712
3055
  market = self.market(symbol)
2713
3056
  request['symbol'] = market['id']
2714
3057
  if since is not None:
2715
- request['start_t'] = since
3058
+ request['startTime'] = since
3059
+ until = self.safe_integer(params, 'until') # unified in milliseconds
3060
+ params = self.omit(params, ['until'])
3061
+ if until is not None:
3062
+ request['endTime'] = until
2716
3063
  if limit is not None:
2717
- request['size'] = limit
2718
- else:
2719
- request['size'] = 5000
2720
- response = self.v1PrivateGetFundingFeeHistory(self.extend(request, params))
3064
+ request['size'] = min(limit, 500)
3065
+ response = self.v3PrivateGetFuturesFundingFeeHistory(self.extend(request, params))
2721
3066
  #
2722
3067
  # {
2723
- # "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
3068
+ # "success": True,
3069
+ # "data": {
3070
+ # "meta": {
3071
+ # "total": 670,
3072
+ # "recordsPerPage": 25,
3073
+ # "currentPage": 1
3074
+ # },
3075
+ # "rows": [
3076
+ # {
3077
+ # "id": 1286360,
3078
+ # "symbol": "PERP_BTC_USDT",
3079
+ # "fundingRate": -0.00001445,
3080
+ # "markPrice": "26930.60000000",
3081
+ # "fundingFee": "9.56021744",
3082
+ # "fundingIntervalHours": 8,
3083
+ # "paymentType": "Pay",
3084
+ # "status": "COMPLETED",
3085
+ # "createdTime": 1696060873259,
3086
+ # "updatedTime": 1696060873286
3087
+ # }
3088
+ # ]
2740
3089
  # },
2741
- # "success":true
3090
+ # "timestamp": 1721351502594
2742
3091
  # }
2743
3092
  #
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)
3093
+ data = self.safe_dict(response, 'data', {})
3094
+ rows = self.safe_list(data, 'rows', [])
3095
+ return self.parse_incomes(rows, market, since, limit)
2753
3096
 
2754
3097
  def parse_funding_rate(self, fundingRate, market: Market = None) -> FundingRate:
2755
3098
  #
2756
3099
  # {
2757
- # "success": True,
2758
- # "timestamp": 1727427915529,
2759
3100
  # "symbol": "PERP_BTC_USDT",
2760
- # "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
3101
+ # "estFundingRate": "-0.00000441",
3102
+ # "estFundingRateTimestamp": 1751623979022,
3103
+ # "lastFundingRate": "-0.00004953",
3104
+ # "lastFundingRateTimestamp": 1751616000000,
3105
+ # "nextFundingTime": 1751644800000,
3106
+ # "lastFundingIntervalHours": 8,
3107
+ # "estFundingIntervalHours": 8
2767
3108
  # }
2768
3109
  #
2769
3110
  symbol = self.safe_string(fundingRate, 'symbol')
2770
3111
  market = self.market(symbol)
2771
- nextFundingTimestamp = self.safe_integer(fundingRate, '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')
3112
+ nextFundingTimestamp = self.safe_integer(fundingRate, 'nextFundingTime')
3113
+ estFundingRateTimestamp = self.safe_integer(fundingRate, 'estFundingRateTimestamp')
3114
+ lastFundingRateTimestamp = self.safe_integer(fundingRate, 'lastFundingRateTimestamp')
3115
+ intervalString = self.safe_string(fundingRate, 'estFundingIntervalHours')
2775
3116
  return {
2776
3117
  'info': fundingRate,
2777
3118
  'symbol': market['symbol'],
@@ -2781,13 +3122,13 @@ class woo(Exchange, ImplicitAPI):
2781
3122
  'estimatedSettlePrice': None,
2782
3123
  'timestamp': estFundingRateTimestamp,
2783
3124
  'datetime': self.iso8601(estFundingRateTimestamp),
2784
- 'fundingRate': self.safe_number(fundingRate, 'est_funding_rate'),
3125
+ 'fundingRate': self.safe_number(fundingRate, 'estFundingRate'),
2785
3126
  'fundingTimestamp': nextFundingTimestamp,
2786
3127
  'fundingDatetime': self.iso8601(nextFundingTimestamp),
2787
3128
  'nextFundingRate': None,
2788
3129
  'nextFundingTimestamp': None,
2789
3130
  'nextFundingDatetime': None,
2790
- 'previousFundingRate': self.safe_number(fundingRate, 'last_funding_rate'),
3131
+ 'previousFundingRate': self.safe_number(fundingRate, 'lastFundingRate'),
2791
3132
  'previousFundingTimestamp': lastFundingRateTimestamp,
2792
3133
  'previousFundingDatetime': self.iso8601(lastFundingRateTimestamp),
2793
3134
  'interval': intervalString + 'h',
@@ -2797,7 +3138,7 @@ class woo(Exchange, ImplicitAPI):
2797
3138
  """
2798
3139
  fetch the current funding rate interval
2799
3140
 
2800
- https://docs.woox.io/#get-predicted-funding-rate-for-one-market-public
3141
+ https://developer.woox.io/api-reference/endpoint/public_data/fundingRate
2801
3142
 
2802
3143
  :param str symbol: unified market symbol
2803
3144
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -2809,7 +3150,7 @@ class woo(Exchange, ImplicitAPI):
2809
3150
  """
2810
3151
  fetch the current funding rate
2811
3152
 
2812
- https://docs.woox.io/#get-predicted-funding-rate-for-one-market-public
3153
+ https://developer.woox.io/api-reference/endpoint/public_data/fundingRate
2813
3154
 
2814
3155
  :param str symbol: unified market symbol
2815
3156
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -2820,28 +3161,37 @@ class woo(Exchange, ImplicitAPI):
2820
3161
  request: dict = {
2821
3162
  'symbol': market['id'],
2822
3163
  }
2823
- response = self.v1PublicGetFundingRateSymbol(self.extend(request, params))
3164
+ response = self.v3PublicGetFundingRate(self.extend(request, params))
2824
3165
  #
2825
3166
  # {
2826
3167
  # "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
3168
+ # "data": {
3169
+ # "rows": [
3170
+ # {
3171
+ # "symbol": "PERP_BTC_USDT",
3172
+ # "estFundingRate": "-0.00000441",
3173
+ # "estFundingRateTimestamp": 1751623979022,
3174
+ # "lastFundingRate": "-0.00004953",
3175
+ # "lastFundingRateTimestamp": 1751616000000,
3176
+ # "nextFundingTime": 1751644800000,
3177
+ # "lastFundingIntervalHours": 8,
3178
+ # "estFundingIntervalHours": 8
3179
+ # }
3180
+ # ]
3181
+ # },
3182
+ # "timestamp": 1751624037798
2836
3183
  # }
2837
3184
  #
2838
- return self.parse_funding_rate(response, market)
3185
+ data = self.safe_dict(response, 'data', {})
3186
+ rows = self.safe_list(data, 'rows', [])
3187
+ first = self.safe_dict(rows, 0, {})
3188
+ return self.parse_funding_rate(first, market)
2839
3189
 
2840
3190
  def fetch_funding_rates(self, symbols: Strings = None, params={}) -> FundingRates:
2841
3191
  """
2842
3192
  fetch the funding rate for multiple markets
2843
3193
 
2844
- https://docs.woox.io/#get-predicted-funding-rate-for-all-markets-public
3194
+ https://developer.woox.io/api-reference/endpoint/public_data/fundingRate
2845
3195
 
2846
3196
  :param str[]|None symbols: list of unified market symbols
2847
3197
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -2849,31 +3199,36 @@ class woo(Exchange, ImplicitAPI):
2849
3199
  """
2850
3200
  self.load_markets()
2851
3201
  symbols = self.market_symbols(symbols)
2852
- response = self.v1PublicGetFundingRates(params)
3202
+ response = self.v3PublicGetFundingRate(params)
2853
3203
  #
2854
3204
  # {
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
3205
+ # "success": True,
3206
+ # "data": {
3207
+ # "rows": [
3208
+ # {
3209
+ # "symbol": "PERP_BTC_USDT",
3210
+ # "estFundingRate": "-0.00000441",
3211
+ # "estFundingRateTimestamp": 1751623979022,
3212
+ # "lastFundingRate": "-0.00004953",
3213
+ # "lastFundingRateTimestamp": 1751616000000,
3214
+ # "nextFundingTime": 1751644800000,
3215
+ # "lastFundingIntervalHours": 8,
3216
+ # "estFundingIntervalHours": 8
3217
+ # }
3218
+ # ]
3219
+ # },
3220
+ # "timestamp": 1751624037798
2867
3221
  # }
2868
3222
  #
2869
- rows = self.safe_list(response, 'rows', [])
3223
+ data = self.safe_dict(response, 'data', {})
3224
+ rows = self.safe_list(data, 'rows', [])
2870
3225
  return self.parse_funding_rates(rows, symbols)
2871
3226
 
2872
3227
  def fetch_funding_rate_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
2873
3228
  """
2874
3229
  fetches historical funding rate prices
2875
3230
 
2876
- https://docs.woox.io/#get-funding-rate-history-for-one-market-public
3231
+ https://developer.woox.io/api-reference/endpoint/public_data/fundingRateHistory
2877
3232
 
2878
3233
  :param str symbol: unified symbol of the market to fetch the funding rate history for
2879
3234
  :param int [since]: timestamp in ms of the earliest funding rate to fetch
@@ -2888,44 +3243,50 @@ class woo(Exchange, ImplicitAPI):
2888
3243
  paginate, params = self.handle_option_and_params(params, 'fetchFundingRateHistory', 'paginate')
2889
3244
  if paginate:
2890
3245
  return self.fetch_paginated_call_incremental('fetchFundingRateHistory', symbol, since, limit, params, 'page', 25)
2891
- request: dict = {}
2892
- if symbol is not None:
2893
- market = self.market(symbol)
2894
- symbol = market['symbol']
2895
- request['symbol'] = market['id']
3246
+ if symbol is None:
3247
+ raise ArgumentsRequired(self.id + ' fetchFundingRateHistory() requires a symbol argument')
3248
+ market = self.market(symbol)
3249
+ symbol = market['symbol']
3250
+ request: dict = {
3251
+ 'symbol': market['id'],
3252
+ }
2896
3253
  if since is not None:
2897
- request['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))
3254
+ request['startTime'] = since
3255
+ request, params = self.handle_until_option('endTime', request, params)
3256
+ response = self.v3PublicGetFundingRateHistory(self.extend(request, params))
2900
3257
  #
2901
3258
  # {
2902
- # "success":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
3259
+ # "success": True,
3260
+ # "data": {
3261
+ # "rows": [
3262
+ # {
3263
+ # "symbol": "PERP_BTC_USDT",
3264
+ # "fundingRate": "-0.00004953",
3265
+ # "fundingRateTimestamp": 1751616000000,
3266
+ # "nextFundingTime": 1751644800000,
3267
+ # "markPrice": "108708"
3268
+ # }
3269
+ # ],
3270
+ # "meta": {
3271
+ # "total": 11690,
3272
+ # "recordsPerPage": 25,
3273
+ # "currentPage": 1
2914
3274
  # }
2915
- # ],
2916
- # "timestamp":1653640814885
3275
+ # },
3276
+ # "timestamp": 1751632390031
2917
3277
  # }
2918
3278
  #
2919
- result = self.safe_list(response, 'rows')
3279
+ data = self.safe_dict(response, 'data', {})
3280
+ rows = self.safe_list(data, 'rows', [])
2920
3281
  rates = []
2921
- for i in range(0, len(result)):
2922
- entry = result[i]
3282
+ for i in range(0, len(rows)):
3283
+ entry = rows[i]
2923
3284
  marketId = self.safe_string(entry, 'symbol')
2924
- timestamp = self.safe_integer(entry, 'funding_rate_timestamp')
3285
+ timestamp = self.safe_integer(entry, 'fundingRateTimestamp')
2925
3286
  rates.append({
2926
3287
  'info': entry,
2927
3288
  'symbol': self.safe_symbol(marketId),
2928
- 'fundingRate': self.safe_number(entry, 'funding_rate'),
3289
+ 'fundingRate': self.safe_number(entry, 'fundingRate'),
2929
3290
  'timestamp': timestamp,
2930
3291
  'datetime': self.iso8601(timestamp),
2931
3292
  })
@@ -2936,7 +3297,7 @@ class woo(Exchange, ImplicitAPI):
2936
3297
  """
2937
3298
  set hedged to True or False for a market
2938
3299
 
2939
- https://docs.woox.io/#update-position-mode
3300
+ https://developer.woox.io/api-reference/endpoint/futures/position_mode
2940
3301
 
2941
3302
  :param bool hedged: set to True to use HEDGE_MODE, False for ONE_WAY
2942
3303
  :param str symbol: not used by woo setPositionMode
@@ -2949,14 +3310,13 @@ class woo(Exchange, ImplicitAPI):
2949
3310
  else:
2950
3311
  hedgeMode = 'ONE_WAY'
2951
3312
  request: dict = {
2952
- 'position_mode': hedgeMode,
3313
+ 'positionMode': hedgeMode,
2953
3314
  }
2954
- response = self.v1PrivatePostClientPositionMode(self.extend(request, params))
3315
+ response = self.v3PrivatePutFuturesPositionMode(self.extend(request, params))
2955
3316
  #
2956
3317
  # {
2957
3318
  # "success": True,
2958
- # "data": {},
2959
- # "timestamp": "1709195608551"
3319
+ # "timestamp": 1752550492845
2960
3320
  # }
2961
3321
  #
2962
3322
  return response
@@ -2965,19 +3325,20 @@ class woo(Exchange, ImplicitAPI):
2965
3325
  """
2966
3326
  fetch the set leverage for a market
2967
3327
 
2968
- https://docs.woox.io/#get-account-information-new
3328
+ https://developer.woox.io/api-reference/endpoint/account/get_account_info
3329
+ https://developer.woox.io/api-reference/endpoint/futures/get_leverage
2969
3330
 
2970
3331
  :param str symbol: unified market symbol
2971
3332
  :param dict [params]: extra parameters specific to the exchange API endpoint
2972
3333
  :param str [params.marginMode]: *for swap markets only* 'cross' or 'isolated'
2973
- :param str [params.position_mode]: *for swap markets only* 'ONE_WAY' or 'HEDGE_MODE'
3334
+ :param str [params.positionMode]: *for swap markets only* 'ONE_WAY' or 'HEDGE_MODE'
2974
3335
  :returns dict: a `leverage structure <https://docs.ccxt.com/#/?id=leverage-structure>`
2975
3336
  """
2976
3337
  self.load_markets()
2977
3338
  market = self.market(symbol)
2978
3339
  response: dict = None
2979
3340
  if market['spot']:
2980
- response = self.v3PrivateGetAccountinfo(params)
3341
+ response = self.v3PrivateGetAccountInfo(params)
2981
3342
  #
2982
3343
  # {
2983
3344
  # "success": True,
@@ -2985,25 +3346,26 @@ class woo(Exchange, ImplicitAPI):
2985
3346
  # "applicationId": "dsa",
2986
3347
  # "account": "dsa",
2987
3348
  # "alias": "haha",
2988
- # "accountMode": "MARGIN",
2989
- # "leverage": 1,
2990
- # "takerFeeRate": 1,
2991
- # "makerFeeRate": 1,
2992
- # "interestRate": 1,
2993
- # "futuresTakerFeeRate": 1,
2994
- # "futuresMakerFeeRate": 1,
2995
3349
  # "otpauth": True,
2996
- # "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
3350
+ # "accountMode": "FUTURES",
3351
+ # "positionMode": "ONE_WAY",
3352
+ # "leverage": 0,
3353
+ # "marginRatio": "10",
3354
+ # "openMarginRatio": "10",
3355
+ # "initialMarginRatio": "10",
3356
+ # "maintenanceMarginRatio": "0.03",
3357
+ # "totalCollateral": "165.6115334",
3358
+ # "freeCollateral": "165.6115334",
3359
+ # "totalAccountValue": "167.52723093",
3360
+ # "totalTradingValue": "167.52723093",
3361
+ # "totalVaultValue": "0",
3362
+ # "totalStakingValue": "0",
3363
+ # "totalLaunchpadValue": "0",
3364
+ # "totalEarnValue": "0",
3365
+ # "referrerID": null,
3366
+ # "accountType": "Main"
3005
3367
  # },
3006
- # "timestamp": 1673323685109
3368
+ # "timestamp": 1752645129054
3007
3369
  # }
3008
3370
  #
3009
3371
  elif market['swap']:
@@ -3012,8 +3374,8 @@ class woo(Exchange, ImplicitAPI):
3012
3374
  }
3013
3375
  marginMode: Str = None
3014
3376
  marginMode, params = self.handle_margin_mode_and_params('fetchLeverage', params, 'cross')
3015
- request['margin_mode'] = self.encode_margin_mode(marginMode)
3016
- response = self.v1PrivateGetClientFuturesLeverage(self.extend(request, params))
3377
+ request['marginMode'] = self.encode_margin_mode(marginMode)
3378
+ response = self.v3PrivateGetFuturesLeverage(self.extend(request, params))
3017
3379
  #
3018
3380
  # HEDGE_MODE
3019
3381
  # {
@@ -3021,15 +3383,15 @@ class woo(Exchange, ImplicitAPI):
3021
3383
  # "data":
3022
3384
  # {
3023
3385
  # "symbol": "PERP_ETH_USDT",
3024
- # "default_margin_mode": "CROSS",
3025
- # "position_mode": "HEDGE_MODE",
3386
+ # "marginMode": "CROSS",
3387
+ # "positionMode": "HEDGE_MODE",
3026
3388
  # "details": [
3027
3389
  # {
3028
- # "position_side": "LONG",
3390
+ # "positionSide": "LONG",
3029
3391
  # "leverage": 10
3030
3392
  # },
3031
3393
  # {
3032
- # "position_side": "SHORT",
3394
+ # "positionSide": "SHORT",
3033
3395
  # "leverage": 10
3034
3396
  # }
3035
3397
  # ]
@@ -3042,11 +3404,11 @@ class woo(Exchange, ImplicitAPI):
3042
3404
  # "success": True,
3043
3405
  # "data": {
3044
3406
  # "symbol": "PERP_ETH_USDT",
3045
- # "default_margin_mode": "ISOLATED",
3046
- # "position_mode": "ONE_WAY",
3407
+ # "marginMode": "ISOLATED",
3408
+ # "positionMode": "ONE_WAY",
3047
3409
  # "details": [
3048
3410
  # {
3049
- # "position_side": "BOTH",
3411
+ # "positionSide": "BOTH",
3050
3412
  # "leverage": 10
3051
3413
  # }
3052
3414
  # ]
@@ -3062,15 +3424,17 @@ class woo(Exchange, ImplicitAPI):
3062
3424
  def parse_leverage(self, leverage: dict, market: Market = None) -> Leverage:
3063
3425
  marketId = self.safe_string(leverage, 'symbol')
3064
3426
  market = self.safe_market(marketId, market)
3065
- marginMode = self.safe_string_lower(leverage, 'default_margin_mode')
3427
+ marginMode = self.safe_string_lower(leverage, 'marginMode')
3066
3428
  spotLeverage = self.safe_integer(leverage, 'leverage')
3429
+ if spotLeverage == 0:
3430
+ spotLeverage = None
3067
3431
  longLeverage = spotLeverage
3068
3432
  shortLeverage = spotLeverage
3069
3433
  details = self.safe_list(leverage, 'details', [])
3070
3434
  for i in range(0, len(details)):
3071
3435
  position = self.safe_dict(details, i, {})
3072
3436
  positionLeverage = self.safe_integer(position, 'leverage')
3073
- side = self.safe_string(position, 'position_side')
3437
+ side = self.safe_string(position, 'positionSide')
3074
3438
  if side == 'BOTH':
3075
3439
  longLeverage = positionLeverage
3076
3440
  shortLeverage = positionLeverage
@@ -3090,14 +3454,14 @@ class woo(Exchange, ImplicitAPI):
3090
3454
  """
3091
3455
  set the level of leverage for a market
3092
3456
 
3093
- https://docs.woox.io/#update-leverage-setting
3094
- https://docs.woox.io/#update-futures-leverage-setting
3457
+ https://developer.woox.io/api-reference/endpoint/spot_margin/set_leverage
3458
+ https://developer.woox.io/api-reference/endpoint/futures/set_leverage
3095
3459
 
3096
3460
  :param float leverage: the rate of leverage(1, 2, 3, 4 or 5 for spot markets, 1, 2, 3, 4, 5, 10, 15, 20 for swap markets)
3097
3461
  :param str [symbol]: unified market symbol(is mandatory for swap markets)
3098
3462
  :param dict [params]: extra parameters specific to the exchange API endpoint
3099
3463
  :param str [params.marginMode]: *for swap markets only* 'cross' or 'isolated'
3100
- :param str [params.position_side]: *for swap markets only* 'LONG' or 'SHORT' in hedge mode, 'BOTH' in one way mode.
3464
+ :param str [params.positionMode]: *for swap markets only* 'ONE_WAY' or 'HEDGE_MODE'
3101
3465
  :returns dict: response from the exchange
3102
3466
  """
3103
3467
  self.load_markets()
@@ -3108,13 +3472,13 @@ class woo(Exchange, ImplicitAPI):
3108
3472
  if symbol is not None:
3109
3473
  market = self.market(symbol)
3110
3474
  if (symbol is None) or market['spot']:
3111
- return self.v1PrivatePostClientLeverage(self.extend(request, params))
3475
+ return self.v3PrivatePostSpotMarginLeverage(self.extend(request, params))
3112
3476
  elif market['swap']:
3113
3477
  request['symbol'] = market['id']
3114
3478
  marginMode: Str = None
3115
3479
  marginMode, params = self.handle_margin_mode_and_params('fetchLeverage', params, 'cross')
3116
- request['margin_mode'] = self.encode_margin_mode(marginMode)
3117
- return self.v1PrivatePostClientFuturesLeverage(self.extend(request, params))
3480
+ request['marginMode'] = self.encode_margin_mode(marginMode)
3481
+ return self.v3PrivatePutFuturesLeverage(self.extend(request, params))
3118
3482
  else:
3119
3483
  raise NotSupported(self.id + ' fetchLeverage() is not supported for ' + market['type'] + ' markets')
3120
3484
 
@@ -3158,92 +3522,98 @@ class woo(Exchange, ImplicitAPI):
3158
3522
  return self.v1PrivatePostClientIsolatedMargin(self.extend(request, params))
3159
3523
 
3160
3524
  def fetch_position(self, symbol: Str, params={}):
3525
+ """
3526
+ fetch data on an open position
3527
+
3528
+ https://developer.woox.io/api-reference/endpoint/futures/get_positions
3529
+
3530
+ :param str symbol: unified market symbol of the market the position is held in
3531
+ :param dict [params]: extra parameters specific to the exchange API endpoint
3532
+ :returns dict: a `position structure <https://docs.ccxt.com/#/?id=position-structure>`
3533
+ """
3161
3534
  self.load_markets()
3162
3535
  market = self.market(symbol)
3163
3536
  request: dict = {
3164
3537
  'symbol': market['id'],
3165
3538
  }
3166
- response = self.v1PrivateGetPositionSymbol(self.extend(request, params))
3539
+ response = self.v3PrivateGetFuturesPositions(self.extend(request, params))
3167
3540
  #
3168
3541
  # {
3169
- # "symbol": "PERP_ETH_USDT",
3170
- # "position_side": "BOTH",
3171
- # "leverage": 10,
3172
- # "margin_mode": "CROSS",
3173
- # "average_open_price": 3139.9,
3174
- # "isolated_margin_amount": 0.0,
3175
- # "isolated_margin_token": "",
3176
- # "opening_time": "1720627963.094",
3177
- # "mark_price": 3155.19169891,
3178
- # "pending_short_qty": 0.0,
3179
- # "pending_long_qty": 0.0,
3180
- # "holding": -0.7,
3181
- # "pnl_24_h": 0.0,
3182
- # "est_liq_price": 9107.40055552,
3183
- # "settle_price": 3151.0319904,
3184
3542
  # "success": True,
3185
- # "fee_24_h": 0.0,
3186
- # "isolated_frozen_long": 0.0,
3187
- # "isolated_frozen_short": 0.0,
3188
- # "timestamp": "1720867502.544"
3543
+ # "data": {
3544
+ # "positions": [
3545
+ # {
3546
+ # "symbol": "PERP_LTC_USDT",
3547
+ # "holding": "0.1",
3548
+ # "pendingLongQty": "0",
3549
+ # "pendingShortQty": "0",
3550
+ # "settlePrice": "96.87",
3551
+ # "averageOpenPrice": "96.87",
3552
+ # "pnl24H": "0",
3553
+ # "fee24H": "0.0048435",
3554
+ # "markPrice": "96.83793449",
3555
+ # "estLiqPrice": "0",
3556
+ # "timestamp": 1752500555823,
3557
+ # "adlQuantile": 2,
3558
+ # "positionSide": "BOTH",
3559
+ # "marginMode": "CROSS",
3560
+ # "isolatedMarginToken": "",
3561
+ # "isolatedMarginAmount": "0",
3562
+ # "isolatedFrozenLong": "0",
3563
+ # "isolatedFrozenShort": "0",
3564
+ # "leverage": 10
3565
+ # }
3566
+ # ]
3567
+ # },
3568
+ # "timestamp": 1752500579848
3189
3569
  # }
3190
3570
  #
3191
- return self.parse_position(response, market)
3571
+ result = self.safe_dict(response, 'data', {})
3572
+ positions = self.safe_list(result, 'positions', [])
3573
+ first = self.safe_dict(positions, 0, {})
3574
+ return self.parse_position(first, market)
3192
3575
 
3193
3576
  def fetch_positions(self, symbols: Strings = None, params={}) -> List[Position]:
3577
+ """
3578
+ fetch all open positions
3579
+
3580
+ https://developer.woox.io/api-reference/endpoint/futures/get_positions
3581
+
3582
+ :param str[] [symbols]: list of unified market symbols
3583
+ :param dict [params]: extra parameters specific to the exchange API endpoint
3584
+ :returns dict[]: a list of `position structure <https://docs.ccxt.com/#/?id=position-structure>`
3585
+ """
3194
3586
  self.load_markets()
3195
- response = self.v3PrivateGetPositions(params)
3587
+ response = self.v3PrivateGetFuturesPositions(params)
3196
3588
  #
3197
3589
  # {
3198
3590
  # "success": True,
3199
- # "data":
3200
- # {
3591
+ # "data": {
3201
3592
  # "positions": [
3202
3593
  # {
3203
- # "symbol": "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,
3594
+ # "symbol": "PERP_LTC_USDT",
3595
+ # "holding": "0.1",
3596
+ # "pendingLongQty": "0",
3597
+ # "pendingShortQty": "0",
3598
+ # "settlePrice": "96.87",
3599
+ # "averageOpenPrice": "96.87",
3600
+ # "pnl24H": "0",
3601
+ # "fee24H": "0.0048435",
3602
+ # "markPrice": "96.83793449",
3603
+ # "estLiqPrice": "0",
3604
+ # "timestamp": 1752500555823,
3605
+ # "adlQuantile": 2,
3236
3606
  # "positionSide": "BOTH",
3237
3607
  # "marginMode": "CROSS",
3238
3608
  # "isolatedMarginToken": "",
3239
- # "isolatedMarginAmount": 0.0,
3240
- # "isolatedFrozenLong": 0.0,
3241
- # "isolatedFrozenShort": 0.0,
3609
+ # "isolatedMarginAmount": "0",
3610
+ # "isolatedFrozenLong": "0",
3611
+ # "isolatedFrozenShort": "0",
3242
3612
  # "leverage": 10
3243
3613
  # }
3244
3614
  # ]
3245
3615
  # },
3246
- # "timestamp": 1720628675078
3616
+ # "timestamp": 1752500579848
3247
3617
  # }
3248
3618
  #
3249
3619
  result = self.safe_dict(response, 'data', {})
@@ -3278,24 +3648,24 @@ class woo(Exchange, ImplicitAPI):
3278
3648
  #
3279
3649
  # v3PrivateGetPositions
3280
3650
  # {
3281
- # "symbol": "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,
3651
+ # "symbol": "PERP_LTC_USDT",
3652
+ # "holding": "0.1",
3653
+ # "pendingLongQty": "0",
3654
+ # "pendingShortQty": "0",
3655
+ # "settlePrice": "96.87",
3656
+ # "averageOpenPrice": "96.87",
3657
+ # "pnl24H": "0",
3658
+ # "fee24H": "0.0048435",
3659
+ # "markPrice": "96.83793449",
3660
+ # "estLiqPrice": "0",
3661
+ # "timestamp": 1752500555823,
3662
+ # "adlQuantile": 2,
3293
3663
  # "positionSide": "BOTH",
3294
- # "marginMode": "ISOLATED",
3295
- # "isolatedMarginToken": "USDT", # todo: check
3296
- # "isolatedMarginAmount": 314.62426, # todo: check
3297
- # "isolatedFrozenLong": 0.0, # todo: check
3298
- # "isolatedFrozenShort": 0.0, # todo: check
3664
+ # "marginMode": "CROSS",
3665
+ # "isolatedMarginToken": "",
3666
+ # "isolatedMarginAmount": "0",
3667
+ # "isolatedFrozenLong": "0",
3668
+ # "isolatedFrozenShort": "0",
3299
3669
  # "leverage": 10
3300
3670
  # }
3301
3671
  #
@@ -3309,7 +3679,13 @@ class woo(Exchange, ImplicitAPI):
3309
3679
  side = 'short'
3310
3680
  contractSize = self.safe_string(market, 'contractSize')
3311
3681
  markPrice = self.safe_string_2(position, 'markPrice', 'mark_price')
3312
- timestamp = self.safe_timestamp(position, 'timestamp')
3682
+ timestampString = self.safe_string(position, 'timestamp')
3683
+ timestamp = None
3684
+ if timestampString is not None:
3685
+ if timestampString.find('.') > -1:
3686
+ timestamp = self.safe_timestamp(position, 'timestamp')
3687
+ else:
3688
+ timestamp = self.safe_integer(position, 'timestamp')
3313
3689
  entryPrice = self.safe_string_2(position, 'averageOpenPrice', 'average_open_price')
3314
3690
  priceDifference = Precise.string_sub(markPrice, entryPrice)
3315
3691
  unrealisedPnl = Precise.string_mul(priceDifference, size)