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