ccxt 4.4.82__py2.py3-none-any.whl → 4.4.86__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 (121) hide show
  1. ccxt/__init__.py +3 -9
  2. ccxt/abstract/blofin.py +8 -0
  3. ccxt/abstract/btcbox.py +1 -0
  4. ccxt/abstract/myokx.py +2 -0
  5. ccxt/abstract/okx.py +2 -0
  6. ccxt/apex.py +2 -1
  7. ccxt/ascendex.py +187 -151
  8. ccxt/async_support/__init__.py +3 -9
  9. ccxt/async_support/apex.py +2 -1
  10. ccxt/async_support/ascendex.py +187 -151
  11. ccxt/async_support/base/exchange.py +51 -24
  12. ccxt/async_support/base/ws/cache.py +6 -1
  13. ccxt/async_support/bequant.py +1 -1
  14. ccxt/async_support/bitget.py +5 -6
  15. ccxt/async_support/bitmart.py +1 -1
  16. ccxt/async_support/bitrue.py +14 -32
  17. ccxt/async_support/bitso.py +33 -0
  18. ccxt/async_support/bitstamp.py +33 -0
  19. ccxt/async_support/{huobijp.py → bittrade.py} +11 -11
  20. ccxt/async_support/blofin.py +145 -14
  21. ccxt/async_support/btcbox.py +25 -5
  22. ccxt/async_support/bybit.py +16 -37
  23. ccxt/async_support/cex.py +2 -4
  24. ccxt/async_support/coinbase.py +58 -47
  25. ccxt/async_support/coinbaseexchange.py +141 -32
  26. ccxt/async_support/coincatch.py +14 -67
  27. ccxt/async_support/coinex.py +28 -29
  28. ccxt/async_support/coinlist.py +17 -16
  29. ccxt/async_support/coinmetro.py +20 -11
  30. ccxt/async_support/coinone.py +8 -10
  31. ccxt/async_support/coinsph.py +124 -2
  32. ccxt/async_support/cryptocom.py +109 -2
  33. ccxt/async_support/cryptomus.py +42 -80
  34. ccxt/async_support/delta.py +75 -36
  35. ccxt/async_support/deribit.py +4 -5
  36. ccxt/async_support/derive.py +46 -10
  37. ccxt/async_support/ellipx.py +175 -77
  38. ccxt/async_support/gate.py +1 -1
  39. ccxt/async_support/gemini.py +3 -4
  40. ccxt/async_support/hitbtc.py +56 -65
  41. ccxt/async_support/hollaex.py +106 -49
  42. ccxt/async_support/htx.py +20 -43
  43. ccxt/async_support/hyperliquid.py +6 -6
  44. ccxt/async_support/kraken.py +27 -23
  45. ccxt/async_support/kucoinfutures.py +5 -0
  46. ccxt/async_support/lbank.py +1 -1
  47. ccxt/async_support/mexc.py +2 -2
  48. ccxt/async_support/ndax.py +25 -24
  49. ccxt/async_support/okcoin.py +12 -29
  50. ccxt/async_support/okx.py +9 -0
  51. ccxt/async_support/onetrading.py +10 -7
  52. ccxt/async_support/oxfun.py +40 -110
  53. ccxt/async_support/paradex.py +123 -4
  54. ccxt/base/exchange.py +21 -2
  55. ccxt/base/types.py +3 -0
  56. ccxt/bequant.py +1 -1
  57. ccxt/bitget.py +5 -6
  58. ccxt/bitmart.py +1 -1
  59. ccxt/bitrue.py +14 -32
  60. ccxt/bitso.py +33 -0
  61. ccxt/bitstamp.py +33 -0
  62. ccxt/{huobijp.py → bittrade.py} +11 -11
  63. ccxt/blofin.py +145 -14
  64. ccxt/btcbox.py +24 -5
  65. ccxt/bybit.py +16 -37
  66. ccxt/cex.py +2 -4
  67. ccxt/coinbase.py +58 -47
  68. ccxt/coinbaseexchange.py +141 -32
  69. ccxt/coincatch.py +14 -67
  70. ccxt/coinex.py +28 -29
  71. ccxt/coinlist.py +17 -16
  72. ccxt/coinmetro.py +20 -11
  73. ccxt/coinone.py +8 -10
  74. ccxt/coinsph.py +124 -2
  75. ccxt/cryptocom.py +109 -2
  76. ccxt/cryptomus.py +42 -80
  77. ccxt/delta.py +75 -36
  78. ccxt/deribit.py +4 -5
  79. ccxt/derive.py +46 -10
  80. ccxt/ellipx.py +175 -77
  81. ccxt/gate.py +1 -1
  82. ccxt/gemini.py +3 -4
  83. ccxt/hitbtc.py +56 -65
  84. ccxt/hollaex.py +106 -49
  85. ccxt/htx.py +20 -43
  86. ccxt/hyperliquid.py +6 -6
  87. ccxt/kraken.py +27 -23
  88. ccxt/kucoinfutures.py +5 -0
  89. ccxt/lbank.py +1 -1
  90. ccxt/mexc.py +2 -2
  91. ccxt/ndax.py +25 -24
  92. ccxt/okcoin.py +12 -29
  93. ccxt/okx.py +9 -0
  94. ccxt/onetrading.py +10 -7
  95. ccxt/oxfun.py +40 -110
  96. ccxt/paradex.py +123 -4
  97. ccxt/pro/__init__.py +109 -5
  98. ccxt/pro/binance.py +32 -33
  99. ccxt/pro/bithumb.py +5 -3
  100. ccxt/pro/{huobijp.py → bittrade.py} +3 -3
  101. ccxt/pro/kraken.py +249 -79
  102. ccxt/pro/luno.py +6 -5
  103. ccxt/pro/mexc.py +254 -7
  104. ccxt/pro/poloniex.py +6 -2
  105. {ccxt-4.4.82.dist-info → ccxt-4.4.86.dist-info}/METADATA +8 -11
  106. {ccxt-4.4.82.dist-info → ccxt-4.4.86.dist-info}/RECORD +110 -121
  107. ccxt/abstract/bl3p.py +0 -19
  108. ccxt/abstract/idex.py +0 -26
  109. ccxt/abstract/kuna.py +0 -182
  110. ccxt/async_support/base/ws/fast_client.py +0 -97
  111. ccxt/async_support/bl3p.py +0 -543
  112. ccxt/async_support/idex.py +0 -1889
  113. ccxt/async_support/kuna.py +0 -1935
  114. ccxt/bl3p.py +0 -543
  115. ccxt/idex.py +0 -1889
  116. ccxt/kuna.py +0 -1935
  117. ccxt/pro/idex.py +0 -687
  118. /ccxt/abstract/{huobijp.py → bittrade.py} +0 -0
  119. {ccxt-4.4.82.dist-info → ccxt-4.4.86.dist-info}/LICENSE.txt +0 -0
  120. {ccxt-4.4.82.dist-info → ccxt-4.4.86.dist-info}/WHEEL +0 -0
  121. {ccxt-4.4.82.dist-info → ccxt-4.4.86.dist-info}/top_level.txt +0 -0
@@ -840,47 +840,30 @@ class okcoin(Exchange, ImplicitAPI):
840
840
  return None
841
841
  else:
842
842
  response = await self.privateGetAssetCurrencies(params)
843
- data = self.safe_value(response, 'data', [])
843
+ data = self.safe_list(response, 'data', [])
844
844
  result: dict = {}
845
845
  dataByCurrencyId = self.group_by(data, 'ccy')
846
846
  currencyIds = list(dataByCurrencyId.keys())
847
847
  for i in range(0, len(currencyIds)):
848
848
  currencyId = currencyIds[i]
849
- currency = self.safe_currency(currencyId)
850
- code = currency['code']
849
+ code = self.safe_currency_code(currencyId)
851
850
  chains = dataByCurrencyId[currencyId]
852
851
  networks: dict = {}
853
- currencyActive = False
854
- depositEnabled = False
855
- withdrawEnabled = False
856
- maxPrecision = None
857
852
  for j in range(0, len(chains)):
858
853
  chain = chains[j]
859
- canDeposit = self.safe_value(chain, 'canDep')
860
- depositEnabled = canDeposit if (canDeposit) else depositEnabled
861
- canWithdraw = self.safe_value(chain, 'canWd')
862
- withdrawEnabled = canWithdraw if (canWithdraw) else withdrawEnabled
863
- canInternal = self.safe_value(chain, 'canInternal')
864
- active = True if (canDeposit and canWithdraw and canInternal) else False
865
- currencyActive = active if (active) else currencyActive
866
854
  networkId = self.safe_string(chain, 'chain')
867
855
  if (networkId is not None) and (networkId.find('-') >= 0):
868
856
  parts = networkId.split('-')
869
857
  chainPart = self.safe_string(parts, 1, networkId)
870
858
  networkCode = self.network_id_to_code(chainPart)
871
- precision = self.parse_precision(self.safe_string(chain, 'wdTickSz'))
872
- if maxPrecision is None:
873
- maxPrecision = precision
874
- else:
875
- maxPrecision = Precise.string_min(maxPrecision, precision)
876
859
  networks[networkCode] = {
877
860
  'id': networkId,
878
861
  'network': networkCode,
879
- 'active': active,
880
- 'deposit': canDeposit,
881
- 'withdraw': canWithdraw,
862
+ 'active': None,
863
+ 'deposit': self.safe_bool(chain, 'canDep'),
864
+ 'withdraw': self.safe_bool(chain, 'canWd'),
882
865
  'fee': self.safe_number(chain, 'minFee'),
883
- 'precision': self.parse_number(precision),
866
+ 'precision': self.parse_number(self.parse_precision(self.safe_string(chain, 'wdTickSz'))),
884
867
  'limits': {
885
868
  'withdraw': {
886
869
  'min': self.safe_number(chain, 'minWd'),
@@ -890,16 +873,16 @@ class okcoin(Exchange, ImplicitAPI):
890
873
  'info': chain,
891
874
  }
892
875
  firstChain = self.safe_value(chains, 0)
893
- result[code] = {
876
+ result[code] = self.safe_currency_structure({
894
877
  'info': chains,
895
878
  'code': code,
896
879
  'id': currencyId,
897
880
  'name': self.safe_string(firstChain, 'name'),
898
- 'active': currencyActive,
899
- 'deposit': depositEnabled,
900
- 'withdraw': withdrawEnabled,
881
+ 'active': None,
882
+ 'deposit': None,
883
+ 'withdraw': None,
901
884
  'fee': None,
902
- 'precision': self.parse_number(maxPrecision),
885
+ 'precision': None,
903
886
  'limits': {
904
887
  'amount': {
905
888
  'min': None,
@@ -907,7 +890,7 @@ class okcoin(Exchange, ImplicitAPI):
907
890
  },
908
891
  },
909
892
  'networks': networks,
910
- }
893
+ })
911
894
  return result
912
895
 
913
896
  async def fetch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
ccxt/async_support/okx.py CHANGED
@@ -389,6 +389,7 @@ class okx(Exchange, ImplicitAPI):
389
389
  'account/spot-manual-borrow-repay': 10,
390
390
  'account/set-auto-repay': 4,
391
391
  'account/spot-borrow-repay-history': 4,
392
+ 'account/move-positions-history': 10,
392
393
  # subaccount
393
394
  'users/subaccount/list': 10,
394
395
  'account/subaccount/balances': 10 / 3,
@@ -526,6 +527,7 @@ class okx(Exchange, ImplicitAPI):
526
527
  'account/fixed-loan/manual-reborrow': 5,
527
528
  'account/fixed-loan/repay-borrowing-order': 5,
528
529
  'account/bills-history-archive': 72000, # 12 req/day
530
+ 'account/move-positions': 10,
529
531
  # subaccount
530
532
  'users/subaccount/modify-apikey': 10,
531
533
  'asset/subaccount/transfer': 10,
@@ -992,6 +994,13 @@ class okx(Exchange, ImplicitAPI):
992
994
  '70010': BadRequest, # Timestamp parameters need to be in Unix timestamp format in milliseconds.
993
995
  '70013': BadRequest, # endTs needs to be bigger than or equal to beginTs.
994
996
  '70016': BadRequest, # Please specify your instrument settings for at least one instType.
997
+ '70060': BadRequest, # The account doesn’t exist or the position side is incorrect. To and from accounts must be under the same main account.
998
+ '70061': BadRequest, # To move position, please enter a position that’s opposite to your current side and is smaller than or equal to your current size.
999
+ '70062': BadRequest, # account has reached the maximum number of position transfers allowed per day.
1000
+ '70064': BadRequest, # Position does not exist.
1001
+ '70065': BadRequest, # Couldn’t move position. Execution price cannot be determined
1002
+ '70066': BadRequest, # Moving positions isn't supported in spot mode. Switch to any other account mode and try again.
1003
+ '70067': BadRequest, # Moving positions isn't supported in margin trading.
995
1004
  '1009': BadRequest, # Request message exceeds the maximum frame length
996
1005
  '4001': AuthenticationError, # Login Failed
997
1006
  '4002': BadRequest, # Invalid Request
@@ -405,9 +405,12 @@ class onetrading(Exchange, ImplicitAPI):
405
405
  #
406
406
  # [
407
407
  # {
408
- # "code":"BEST",
409
- # "precision":8
410
- # }
408
+ # "code": "USDT",
409
+ # "precision": 6,
410
+ # "unified_cryptoasset_id": 825,
411
+ # "name": "Tether USDt",
412
+ # "collateral_percentage": 0
413
+ # },
411
414
  # ]
412
415
  #
413
416
  result: dict = {}
@@ -415,11 +418,11 @@ class onetrading(Exchange, ImplicitAPI):
415
418
  currency = response[i]
416
419
  id = self.safe_string(currency, 'code')
417
420
  code = self.safe_currency_code(id)
418
- result[code] = {
421
+ result[code] = self.safe_currency_structure({
419
422
  'id': id,
420
423
  'code': code,
421
- 'name': None,
422
- 'info': currency, # the original payload
424
+ 'name': self.safe_string(currency, 'name'),
425
+ 'info': currency,
423
426
  'active': None,
424
427
  'fee': None,
425
428
  'precision': self.parse_number(self.parse_precision(self.safe_string(currency, 'precision'))),
@@ -430,7 +433,7 @@ class onetrading(Exchange, ImplicitAPI):
430
433
  'withdraw': {'min': None, 'max': None},
431
434
  },
432
435
  'networks': {},
433
- }
436
+ })
434
437
  return result
435
438
 
436
439
  async def fetch_markets(self, params={}) -> List[Market]:
@@ -25,7 +25,6 @@ from ccxt.base.errors import NetworkError
25
25
  from ccxt.base.errors import RateLimitExceeded
26
26
  from ccxt.base.errors import RequestTimeout
27
27
  from ccxt.base.decimal_to_precision import TICK_SIZE
28
- from ccxt.base.precise import Precise
29
28
 
30
29
 
31
30
  class oxfun(Exchange, ImplicitAPI):
@@ -613,66 +612,7 @@ class oxfun(Exchange, ImplicitAPI):
613
612
  # "minDeposit": "0.00010",
614
613
  # "minWithdrawal": "0.00010"
615
614
  # },
616
- # {
617
- # "network": "Arbitrum",
618
- # "tokenId": "0xba0Dda8762C24dA9487f5FA026a9B64b695A07Ea",
619
- # "transactionPrecision": "18",
620
- # "isWithdrawalFeeChargedToUser": True,
621
- # "canDeposit": True,
622
- # "canWithdraw": True,
623
- # "minDeposit": "0.00010",
624
- # "minWithdrawal": "0.00010"
625
- # },
626
- # {
627
- # "network": "Ethereum",
628
- # "tokenId": "0xba0Dda8762C24dA9487f5FA026a9B64b695A07Ea",
629
- # "transactionPrecision": "18",
630
- # "isWithdrawalFeeChargedToUser": True,
631
- # "canDeposit": True,
632
- # "canWithdraw": True,
633
- # "minDeposit": "0.00010",
634
- # "minWithdrawal": "0.00010"
635
- # },
636
- # {
637
- # "network": "Arbitrum",
638
- # "tokenId": "0x78a0A62Fba6Fb21A83FE8a3433d44C73a4017A6f",
639
- # "transactionPrecision": "18",
640
- # "isWithdrawalFeeChargedToUser": True,
641
- # "canDeposit": True,
642
- # "canWithdraw": False,
643
- # "minDeposit": "0.00010",
644
- # "minWithdrawal": "0.00010"
645
- # },
646
- # {
647
- # "network": "Avalanche",
648
- # "tokenId": "0x78a0A62Fba6Fb21A83FE8a3433d44C73a4017A6f",
649
- # "transactionPrecision": "18",
650
- # "isWithdrawalFeeChargedToUser": True,
651
- # "canDeposit": True,
652
- # "canWithdraw": False,
653
- # "minDeposit": "0.00010",
654
- # "minWithdrawal": "0.00010"
655
- # },
656
- # {
657
- # "network": "Solana",
658
- # "tokenId": "DV3845GEAVXfwpyVGGgWbqBVCtzHdCXNCGfcdboSEuZz",
659
- # "transactionPrecision": "8",
660
- # "isWithdrawalFeeChargedToUser": True,
661
- # "canDeposit": True,
662
- # "canWithdraw": True,
663
- # "minDeposit": "0.00010",
664
- # "minWithdrawal": "0.00010"
665
- # },
666
- # {
667
- # "network": "Ethereum",
668
- # "tokenId": "0x78a0A62Fba6Fb21A83FE8a3433d44C73a4017A6f",
669
- # "transactionPrecision": "18",
670
- # "isWithdrawalFeeChargedToUser": True,
671
- # "canDeposit": True,
672
- # "canWithdraw": False,
673
- # "minDeposit": "0.00010",
674
- # "minWithdrawal": "0.00010"
675
- # }
615
+ # ...
676
616
  # ]
677
617
  # },
678
618
  # {
@@ -722,74 +662,64 @@ class oxfun(Exchange, ImplicitAPI):
722
662
  parts = fullId.split('.')
723
663
  id = parts[0]
724
664
  code = self.safe_currency_code(id)
725
- networks: dict = {}
665
+ if not (code in result):
666
+ result[code] = {
667
+ 'id': id,
668
+ 'code': code,
669
+ 'precision': None,
670
+ 'type': None,
671
+ 'name': None,
672
+ 'active': None,
673
+ 'deposit': None,
674
+ 'withdraw': None,
675
+ 'fee': None,
676
+ 'limits': {
677
+ 'withdraw': {
678
+ 'min': None,
679
+ 'max': None,
680
+ },
681
+ 'deposit': {
682
+ 'min': None,
683
+ 'max': None,
684
+ },
685
+ },
686
+ 'networks': {},
687
+ 'info': [],
688
+ }
726
689
  chains = self.safe_list(currency, 'networkList', [])
727
- currencyMaxPrecision: Str = None
728
- currencyDepositEnabled: Bool = None
729
- currencyWithdrawEnabled: Bool = None
730
690
  for j in range(0, len(chains)):
731
691
  chain = chains[j]
732
692
  networkId = self.safe_string(chain, 'network')
733
693
  networkCode = self.network_id_to_code(networkId)
734
- deposit = self.safe_bool(chain, 'canDeposit')
735
- withdraw = self.safe_bool(chain, 'canWithdraw')
736
- active = (deposit and withdraw)
737
- minDeposit = self.safe_string(chain, 'minDeposit')
738
- minWithdrawal = self.safe_string(chain, 'minWithdrawal')
739
- precision = self.parse_precision(self.safe_string(chain, 'transactionPrecision'))
740
- networks[networkCode] = {
694
+ result[code]['networks'][networkCode] = {
741
695
  'id': networkId,
742
696
  'network': networkCode,
743
697
  'margin': None,
744
- 'deposit': deposit,
745
- 'withdraw': withdraw,
746
- 'active': active,
698
+ 'deposit': self.safe_bool(chain, 'canDeposit'),
699
+ 'withdraw': self.safe_bool(chain, 'canWithdraw'),
700
+ 'active': None,
747
701
  'fee': None,
748
- 'precision': self.parse_number(precision),
702
+ 'precision': self.parse_number(self.parse_precision(self.safe_string(chain, 'transactionPrecision'))),
749
703
  'limits': {
750
704
  'deposit': {
751
- 'min': minDeposit,
705
+ 'min': self.safe_number(chain, 'minDeposit'),
752
706
  'max': None,
753
707
  },
754
708
  'withdraw': {
755
- 'min': minWithdrawal,
709
+ 'min': self.safe_number(chain, 'minWithdrawal'),
756
710
  'max': None,
757
711
  },
758
712
  },
759
713
  'info': chain,
760
714
  }
761
- if (currencyDepositEnabled is None) or deposit:
762
- currencyDepositEnabled = deposit
763
- if (currencyWithdrawEnabled is None) or withdraw:
764
- currencyWithdrawEnabled = withdraw
765
- if (currencyMaxPrecision is None) or Precise.string_gt(currencyMaxPrecision, precision):
766
- currencyMaxPrecision = precision
767
- if code in result:
768
- # checking for specific ids.ARB
769
- networks = self.extend(result[code]['networks'], networks)
770
- result[code] = {
771
- 'id': id,
772
- 'code': code,
773
- 'name': None,
774
- 'type': None,
775
- 'active': None,
776
- 'deposit': currencyDepositEnabled,
777
- 'withdraw': currencyWithdrawEnabled,
778
- 'fee': None,
779
- 'precision': self.parse_number(currencyMaxPrecision),
780
- 'limits': {
781
- 'amount': {
782
- 'min': None,
783
- 'max': None,
784
- },
785
- 'withdraw': {
786
- 'min': None,
787
- 'max': None,
788
- },
789
- },
790
- 'networks': networks,
791
- 'info': currency,
792
- }
715
+ infos = self.safe_list(result[code], 'info', [])
716
+ infos.append(currency)
717
+ result[code]['info'] = infos
718
+ # only after all entries are formed in currencies, restructure each entry
719
+ allKeys = list(result.keys())
720
+ for i in range(0, len(allKeys)):
721
+ code = allKeys[i]
722
+ result[code] = self.safe_currency_structure(result[code]) # self is needed after adding network entry
793
723
  return result
794
724
 
795
725
  async def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
@@ -5,7 +5,7 @@
5
5
 
6
6
  from ccxt.async_support.base.exchange import Exchange
7
7
  from ccxt.abstract.paradex import ImplicitAPI
8
- from ccxt.base.types import Any, Balances, Currency, Int, Leverage, MarginMode, Market, Num, Order, OrderBook, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, Trade, Transaction
8
+ from ccxt.base.types import Any, Balances, Currency, Greeks, Int, Leverage, MarginMode, Market, Num, Order, OrderBook, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, Trade, Transaction
9
9
  from typing import List
10
10
  from ccxt.base.errors import ExchangeError
11
11
  from ccxt.base.errors import AuthenticationError
@@ -75,6 +75,7 @@ class paradex(Exchange, ImplicitAPI):
75
75
  'fetchFundingRate': False,
76
76
  'fetchFundingRateHistory': False,
77
77
  'fetchFundingRates': False,
78
+ 'fetchGreeks': True,
78
79
  'fetchIndexOHLCV': False,
79
80
  'fetchIsolatedBorrowRate': False,
80
81
  'fetchIsolatedBorrowRates': False,
@@ -558,13 +559,14 @@ class paradex(Exchange, ImplicitAPI):
558
559
  expiry = self.safe_integer(market, 'expiry_at')
559
560
  optionType = self.safe_string(market, 'option_type')
560
561
  strikePrice = self.safe_string(market, 'strike_price')
562
+ takerFee = self.parse_number('0.0003')
563
+ makerFee = self.parse_number('-0.00005')
561
564
  if isOption:
562
565
  optionTypeSuffix = 'C' if (optionType == 'CALL') else 'P'
563
566
  symbol = symbol + '-' + strikePrice + '-' + optionTypeSuffix
567
+ makerFee = self.parse_number('0.0003')
564
568
  else:
565
569
  expiry = None
566
- takerFee = self.parse_number('0.0003')
567
- makerFee = self.parse_number('-0.00005')
568
570
  return self.safe_market_structure({
569
571
  'id': marketId,
570
572
  'symbol': symbol,
@@ -1243,7 +1245,10 @@ class paradex(Exchange, ImplicitAPI):
1243
1245
  price = self.safe_string(order, 'price')
1244
1246
  amount = self.safe_string(order, 'size')
1245
1247
  orderType = self.safe_string(order, 'type')
1248
+ cancelReason = self.safe_string(order, 'cancel_reason')
1246
1249
  status = self.safe_string(order, 'status')
1250
+ if cancelReason is not None:
1251
+ status = 'canceled'
1247
1252
  side = self.safe_string_lower(order, 'side')
1248
1253
  average = self.omit_zero(self.safe_string(order, 'avg_fill_price'))
1249
1254
  remaining = self.omit_zero(self.safe_string(order, 'remaining_size'))
@@ -1262,7 +1267,7 @@ class paradex(Exchange, ImplicitAPI):
1262
1267
  'status': self.parse_order_status(status),
1263
1268
  'symbol': symbol,
1264
1269
  'type': self.parse_order_type(orderType),
1265
- 'timeInForce': self.parse_time_in_force(self.safe_string(order, 'instrunction')),
1270
+ 'timeInForce': self.parse_time_in_force(self.safe_string(order, 'instruction')),
1266
1271
  'postOnly': None,
1267
1272
  'reduceOnly': reduceOnly,
1268
1273
  'side': side,
@@ -2284,6 +2289,120 @@ class paradex(Exchange, ImplicitAPI):
2284
2289
  }
2285
2290
  return await self.privatePostAccountMarginMarket(self.extend(request, params))
2286
2291
 
2292
+ async def fetch_greeks(self, symbol: str, params={}) -> Greeks:
2293
+ """
2294
+ fetches an option contracts greeks, financial metrics used to measure the factors that affect the price of an options contract
2295
+
2296
+ https://docs.api.testnet.paradex.trade/#list-available-markets-summary
2297
+
2298
+ :param str symbol: unified symbol of the market to fetch greeks for
2299
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2300
+ :returns dict: a `greeks structure <https://docs.ccxt.com/#/?id=greeks-structure>`
2301
+ """
2302
+ await self.load_markets()
2303
+ market = self.market(symbol)
2304
+ request: dict = {
2305
+ 'market': market['id'],
2306
+ }
2307
+ response = await self.publicGetMarketsSummary(self.extend(request, params))
2308
+ #
2309
+ # {
2310
+ # "results": [
2311
+ # {
2312
+ # "symbol": "BTC-USD-114000-P",
2313
+ # "mark_price": "10835.66892602",
2314
+ # "mark_iv": "0.71781855",
2315
+ # "delta": "-0.98726024",
2316
+ # "greeks": {
2317
+ # "delta": "-0.9872602390817709",
2318
+ # "gamma": "0.000004560958862297231",
2319
+ # "vega": "227.11344863639806",
2320
+ # "rho": "-302.0617972461581",
2321
+ # "vanna": "0.06609830491614832",
2322
+ # "volga": "925.9501532805552"
2323
+ # },
2324
+ # "last_traded_price": "10551.5",
2325
+ # "bid": "10794.9",
2326
+ # "bid_iv": "0.05",
2327
+ # "ask": "10887.3",
2328
+ # "ask_iv": "0.8783283",
2329
+ # "last_iv": "0.05",
2330
+ # "volume_24h": "0",
2331
+ # "total_volume": "195240.72672261014",
2332
+ # "created_at": 1747644009995,
2333
+ # "underlying_price": "103164.79162649",
2334
+ # "open_interest": "0",
2335
+ # "funding_rate": "0.000004464241170536191",
2336
+ # "price_change_rate_24h": "0.074915",
2337
+ # "future_funding_rate": "0.0001"
2338
+ # }
2339
+ # ]
2340
+ # }
2341
+ #
2342
+ data = self.safe_list(response, 'results', [])
2343
+ greeks = self.safe_dict(data, 0, {})
2344
+ return self.parse_greeks(greeks, market)
2345
+
2346
+ def parse_greeks(self, greeks: dict, market: Market = None) -> Greeks:
2347
+ #
2348
+ # {
2349
+ # "symbol": "BTC-USD-114000-P",
2350
+ # "mark_price": "10835.66892602",
2351
+ # "mark_iv": "0.71781855",
2352
+ # "delta": "-0.98726024",
2353
+ # "greeks": {
2354
+ # "delta": "-0.9872602390817709",
2355
+ # "gamma": "0.000004560958862297231",
2356
+ # "vega": "227.11344863639806",
2357
+ # "rho": "-302.0617972461581",
2358
+ # "vanna": "0.06609830491614832",
2359
+ # "volga": "925.9501532805552"
2360
+ # },
2361
+ # "last_traded_price": "10551.5",
2362
+ # "bid": "10794.9",
2363
+ # "bid_iv": "0.05",
2364
+ # "ask": "10887.3",
2365
+ # "ask_iv": "0.8783283",
2366
+ # "last_iv": "0.05",
2367
+ # "volume_24h": "0",
2368
+ # "total_volume": "195240.72672261014",
2369
+ # "created_at": 1747644009995,
2370
+ # "underlying_price": "103164.79162649",
2371
+ # "open_interest": "0",
2372
+ # "funding_rate": "0.000004464241170536191",
2373
+ # "price_change_rate_24h": "0.074915",
2374
+ # "future_funding_rate": "0.0001"
2375
+ # }
2376
+ #
2377
+ marketId = self.safe_string(greeks, 'symbol')
2378
+ market = self.safe_market(marketId, market, None, 'option')
2379
+ symbol = market['symbol']
2380
+ timestamp = self.safe_integer(greeks, 'created_at')
2381
+ greeksData = self.safe_dict(greeks, 'greeks', {})
2382
+ return {
2383
+ 'symbol': symbol,
2384
+ 'timestamp': timestamp,
2385
+ 'datetime': self.iso8601(timestamp),
2386
+ 'delta': self.safe_number(greeksData, 'delta'),
2387
+ 'gamma': self.safe_number(greeksData, 'gamma'),
2388
+ 'theta': None,
2389
+ 'vega': self.safe_number(greeksData, 'vega'),
2390
+ 'rho': self.safe_number(greeksData, 'rho'),
2391
+ 'vanna': self.safe_number(greeksData, 'vanna'),
2392
+ 'volga': self.safe_number(greeksData, 'volga'),
2393
+ 'bidSize': None,
2394
+ 'askSize': None,
2395
+ 'bidImpliedVolatility': self.safe_number(greeks, 'bid_iv'),
2396
+ 'askImpliedVolatility': self.safe_number(greeks, 'ask_iv'),
2397
+ 'markImpliedVolatility': self.safe_number(greeks, 'mark_iv'),
2398
+ 'bidPrice': self.safe_number(greeks, 'bid'),
2399
+ 'askPrice': self.safe_number(greeks, 'ask'),
2400
+ 'markPrice': self.safe_number(greeks, 'mark_price'),
2401
+ 'lastPrice': self.safe_number(greeks, 'last_traded_price'),
2402
+ 'underlyingPrice': self.safe_number(greeks, 'underlying_price'),
2403
+ 'info': greeks,
2404
+ }
2405
+
2287
2406
  def sign(self, path, api='public', method='GET', params={}, headers=None, body=None):
2288
2407
  url = self.implode_hostname(self.urls['api'][self.version]) + '/' + self.implode_params(path, params)
2289
2408
  query = self.omit(params, self.extract_params(path))
ccxt/base/exchange.py CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # -----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.4.82'
7
+ __version__ = '4.4.86'
8
8
 
9
9
  # -----------------------------------------------------------------------------
10
10
 
@@ -1506,6 +1506,25 @@ class Exchange(object):
1506
1506
  return len(parts[1]) if len(parts) > 1 else 0
1507
1507
 
1508
1508
  def load_markets(self, reload=False, params={}):
1509
+ """
1510
+ Loads and prepares the markets for trading.
1511
+
1512
+ Args:
1513
+ reload (bool): If True, the markets will be reloaded from the exchange.
1514
+ params (dict): Additional exchange-specific parameters for the request.
1515
+
1516
+ Returns:
1517
+ dict: A dictionary of markets.
1518
+
1519
+ Raises:
1520
+ Exception: If the markets cannot be loaded or prepared.
1521
+
1522
+ Notes:
1523
+ It ensures that the markets are only loaded once, even if called multiple times.
1524
+ If the markets are already loaded and `reload` is False or not provided, it returns the existing markets.
1525
+ If a reload is in progress, it waits for completion before returning.
1526
+ If an error occurs during loading or preparation, an exception is raised.
1527
+ """
1509
1528
  if not reload:
1510
1529
  if self.markets:
1511
1530
  if not self.markets_by_id:
@@ -3008,7 +3027,7 @@ class Exchange(object):
3008
3027
  currency['networks'][key]['active'] = True
3009
3028
  elif deposit is not None and withdraw is not None:
3010
3029
  currency['networks'][key]['active'] = False
3011
- active = self.safe_bool(network, 'active')
3030
+ active = self.safe_bool(currency['networks'][key], 'active') # dict might have been updated on above lines, so access directly instead of `network` variable
3012
3031
  currencyActive = self.safe_bool(currency, 'active')
3013
3032
  if currencyActive is None or active:
3014
3033
  currency['active'] = active
ccxt/base/types.py CHANGED
@@ -308,6 +308,9 @@ class Greeks(TypedDict):
308
308
  theta: Num
309
309
  vega: Num
310
310
  rho: Num
311
+ vanna: Num
312
+ volga: Num
313
+ charm: Num
311
314
  bidSize: Num
312
315
  askSize: Num
313
316
  bidImpliedVolatility: Num
ccxt/bequant.py CHANGED
@@ -14,8 +14,8 @@ class bequant(hitbtc, ImplicitAPI):
14
14
  return self.deep_extend(super(bequant, self).describe(), {
15
15
  'id': 'bequant',
16
16
  'name': 'Bequant',
17
- 'countries': ['MT'], # Malta
18
17
  'pro': True,
18
+ 'countries': ['MT'], # Malta
19
19
  'urls': {
20
20
  'logo': 'https://github.com/user-attachments/assets/0583ef1f-29fe-4b7c-8189-63565a0e2867',
21
21
  'api': {
ccxt/bitget.py CHANGED
@@ -2071,8 +2071,7 @@ class bitget(Exchange, ImplicitAPI):
2071
2071
  chain = chains[j]
2072
2072
  networkId = self.safe_string(chain, 'chain')
2073
2073
  network = self.network_id_to_code(networkId, code)
2074
- if network is not None:
2075
- network = network.upper()
2074
+ network = network.upper()
2076
2075
  networks[network] = {
2077
2076
  'info': chain,
2078
2077
  'id': networkId,
@@ -2371,7 +2370,7 @@ class bitget(Exchange, ImplicitAPI):
2371
2370
  'coin': currency['id'],
2372
2371
  'address': address,
2373
2372
  'chain': networkId,
2374
- 'size': amount,
2373
+ 'size': self.currency_to_precision(code, amount, networkCode),
2375
2374
  'transferType': 'on_chain',
2376
2375
  }
2377
2376
  if tag is not None:
@@ -2395,8 +2394,6 @@ class bitget(Exchange, ImplicitAPI):
2395
2394
  fillResponseFromRequest = self.safe_bool(withdrawOptions, 'fillResponseFromRequest', True)
2396
2395
  if fillResponseFromRequest:
2397
2396
  result['currency'] = code
2398
- result['timestamp'] = self.milliseconds()
2399
- result['datetime'] = self.iso8601(self.milliseconds())
2400
2397
  result['amount'] = amount
2401
2398
  result['tag'] = tag
2402
2399
  result['address'] = address
@@ -2514,7 +2511,9 @@ class bitget(Exchange, ImplicitAPI):
2514
2511
  status = self.safe_string(transaction, 'status')
2515
2512
  tag = self.safe_string(transaction, 'tag')
2516
2513
  feeCostString = self.safe_string(transaction, 'fee')
2517
- feeCostAbsString = Precise.string_abs(feeCostString)
2514
+ feeCostAbsString = None
2515
+ if feeCostString is not None:
2516
+ feeCostAbsString = Precise.string_abs(feeCostString)
2518
2517
  fee = None
2519
2518
  amountString = self.safe_string(transaction, 'size')
2520
2519
  if feeCostAbsString is not None:
ccxt/bitmart.py CHANGED
@@ -2306,7 +2306,7 @@ class bitmart(Exchange, ImplicitAPI):
2306
2306
  code = self.safe_currency_code(currencyId)
2307
2307
  account = self.account()
2308
2308
  account['free'] = self.safe_string_2(balance, 'available', 'available_balance')
2309
- account['used'] = self.safe_string_2(balance, 'frozen', 'frozen_balance')
2309
+ account['used'] = self.safe_string_n(balance, ['unAvailable', 'frozen', 'frozen_balance'])
2310
2310
  result[code] = account
2311
2311
  return self.safe_balance(result)
2312
2312