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
ccxt/okcoin.py CHANGED
@@ -840,47 +840,30 @@ class okcoin(Exchange, ImplicitAPI):
840
840
  return None
841
841
  else:
842
842
  response = 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
  def fetch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
ccxt/okx.py CHANGED
@@ -388,6 +388,7 @@ class okx(Exchange, ImplicitAPI):
388
388
  'account/spot-manual-borrow-repay': 10,
389
389
  'account/set-auto-repay': 4,
390
390
  'account/spot-borrow-repay-history': 4,
391
+ 'account/move-positions-history': 10,
391
392
  # subaccount
392
393
  'users/subaccount/list': 10,
393
394
  'account/subaccount/balances': 10 / 3,
@@ -525,6 +526,7 @@ class okx(Exchange, ImplicitAPI):
525
526
  'account/fixed-loan/manual-reborrow': 5,
526
527
  'account/fixed-loan/repay-borrowing-order': 5,
527
528
  'account/bills-history-archive': 72000, # 12 req/day
529
+ 'account/move-positions': 10,
528
530
  # subaccount
529
531
  'users/subaccount/modify-apikey': 10,
530
532
  'asset/subaccount/transfer': 10,
@@ -991,6 +993,13 @@ class okx(Exchange, ImplicitAPI):
991
993
  '70010': BadRequest, # Timestamp parameters need to be in Unix timestamp format in milliseconds.
992
994
  '70013': BadRequest, # endTs needs to be bigger than or equal to beginTs.
993
995
  '70016': BadRequest, # Please specify your instrument settings for at least one instType.
996
+ '70060': BadRequest, # The account doesn’t exist or the position side is incorrect. To and from accounts must be under the same main account.
997
+ '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.
998
+ '70062': BadRequest, # account has reached the maximum number of position transfers allowed per day.
999
+ '70064': BadRequest, # Position does not exist.
1000
+ '70065': BadRequest, # Couldn’t move position. Execution price cannot be determined
1001
+ '70066': BadRequest, # Moving positions isn't supported in spot mode. Switch to any other account mode and try again.
1002
+ '70067': BadRequest, # Moving positions isn't supported in margin trading.
994
1003
  '1009': BadRequest, # Request message exceeds the maximum frame length
995
1004
  '4001': AuthenticationError, # Login Failed
996
1005
  '4002': BadRequest, # Invalid Request
ccxt/onetrading.py CHANGED
@@ -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
  def fetch_markets(self, params={}) -> List[Market]:
ccxt/oxfun.py CHANGED
@@ -24,7 +24,6 @@ from ccxt.base.errors import NetworkError
24
24
  from ccxt.base.errors import RateLimitExceeded
25
25
  from ccxt.base.errors import RequestTimeout
26
26
  from ccxt.base.decimal_to_precision import TICK_SIZE
27
- from ccxt.base.precise import Precise
28
27
 
29
28
 
30
29
  class oxfun(Exchange, ImplicitAPI):
@@ -612,66 +611,7 @@ class oxfun(Exchange, ImplicitAPI):
612
611
  # "minDeposit": "0.00010",
613
612
  # "minWithdrawal": "0.00010"
614
613
  # },
615
- # {
616
- # "network": "Arbitrum",
617
- # "tokenId": "0xba0Dda8762C24dA9487f5FA026a9B64b695A07Ea",
618
- # "transactionPrecision": "18",
619
- # "isWithdrawalFeeChargedToUser": True,
620
- # "canDeposit": True,
621
- # "canWithdraw": True,
622
- # "minDeposit": "0.00010",
623
- # "minWithdrawal": "0.00010"
624
- # },
625
- # {
626
- # "network": "Ethereum",
627
- # "tokenId": "0xba0Dda8762C24dA9487f5FA026a9B64b695A07Ea",
628
- # "transactionPrecision": "18",
629
- # "isWithdrawalFeeChargedToUser": True,
630
- # "canDeposit": True,
631
- # "canWithdraw": True,
632
- # "minDeposit": "0.00010",
633
- # "minWithdrawal": "0.00010"
634
- # },
635
- # {
636
- # "network": "Arbitrum",
637
- # "tokenId": "0x78a0A62Fba6Fb21A83FE8a3433d44C73a4017A6f",
638
- # "transactionPrecision": "18",
639
- # "isWithdrawalFeeChargedToUser": True,
640
- # "canDeposit": True,
641
- # "canWithdraw": False,
642
- # "minDeposit": "0.00010",
643
- # "minWithdrawal": "0.00010"
644
- # },
645
- # {
646
- # "network": "Avalanche",
647
- # "tokenId": "0x78a0A62Fba6Fb21A83FE8a3433d44C73a4017A6f",
648
- # "transactionPrecision": "18",
649
- # "isWithdrawalFeeChargedToUser": True,
650
- # "canDeposit": True,
651
- # "canWithdraw": False,
652
- # "minDeposit": "0.00010",
653
- # "minWithdrawal": "0.00010"
654
- # },
655
- # {
656
- # "network": "Solana",
657
- # "tokenId": "DV3845GEAVXfwpyVGGgWbqBVCtzHdCXNCGfcdboSEuZz",
658
- # "transactionPrecision": "8",
659
- # "isWithdrawalFeeChargedToUser": True,
660
- # "canDeposit": True,
661
- # "canWithdraw": True,
662
- # "minDeposit": "0.00010",
663
- # "minWithdrawal": "0.00010"
664
- # },
665
- # {
666
- # "network": "Ethereum",
667
- # "tokenId": "0x78a0A62Fba6Fb21A83FE8a3433d44C73a4017A6f",
668
- # "transactionPrecision": "18",
669
- # "isWithdrawalFeeChargedToUser": True,
670
- # "canDeposit": True,
671
- # "canWithdraw": False,
672
- # "minDeposit": "0.00010",
673
- # "minWithdrawal": "0.00010"
674
- # }
614
+ # ...
675
615
  # ]
676
616
  # },
677
617
  # {
@@ -721,74 +661,64 @@ class oxfun(Exchange, ImplicitAPI):
721
661
  parts = fullId.split('.')
722
662
  id = parts[0]
723
663
  code = self.safe_currency_code(id)
724
- networks: dict = {}
664
+ if not (code in result):
665
+ result[code] = {
666
+ 'id': id,
667
+ 'code': code,
668
+ 'precision': None,
669
+ 'type': None,
670
+ 'name': None,
671
+ 'active': None,
672
+ 'deposit': None,
673
+ 'withdraw': None,
674
+ 'fee': None,
675
+ 'limits': {
676
+ 'withdraw': {
677
+ 'min': None,
678
+ 'max': None,
679
+ },
680
+ 'deposit': {
681
+ 'min': None,
682
+ 'max': None,
683
+ },
684
+ },
685
+ 'networks': {},
686
+ 'info': [],
687
+ }
725
688
  chains = self.safe_list(currency, 'networkList', [])
726
- currencyMaxPrecision: Str = None
727
- currencyDepositEnabled: Bool = None
728
- currencyWithdrawEnabled: Bool = None
729
689
  for j in range(0, len(chains)):
730
690
  chain = chains[j]
731
691
  networkId = self.safe_string(chain, 'network')
732
692
  networkCode = self.network_id_to_code(networkId)
733
- deposit = self.safe_bool(chain, 'canDeposit')
734
- withdraw = self.safe_bool(chain, 'canWithdraw')
735
- active = (deposit and withdraw)
736
- minDeposit = self.safe_string(chain, 'minDeposit')
737
- minWithdrawal = self.safe_string(chain, 'minWithdrawal')
738
- precision = self.parse_precision(self.safe_string(chain, 'transactionPrecision'))
739
- networks[networkCode] = {
693
+ result[code]['networks'][networkCode] = {
740
694
  'id': networkId,
741
695
  'network': networkCode,
742
696
  'margin': None,
743
- 'deposit': deposit,
744
- 'withdraw': withdraw,
745
- 'active': active,
697
+ 'deposit': self.safe_bool(chain, 'canDeposit'),
698
+ 'withdraw': self.safe_bool(chain, 'canWithdraw'),
699
+ 'active': None,
746
700
  'fee': None,
747
- 'precision': self.parse_number(precision),
701
+ 'precision': self.parse_number(self.parse_precision(self.safe_string(chain, 'transactionPrecision'))),
748
702
  'limits': {
749
703
  'deposit': {
750
- 'min': minDeposit,
704
+ 'min': self.safe_number(chain, 'minDeposit'),
751
705
  'max': None,
752
706
  },
753
707
  'withdraw': {
754
- 'min': minWithdrawal,
708
+ 'min': self.safe_number(chain, 'minWithdrawal'),
755
709
  'max': None,
756
710
  },
757
711
  },
758
712
  'info': chain,
759
713
  }
760
- if (currencyDepositEnabled is None) or deposit:
761
- currencyDepositEnabled = deposit
762
- if (currencyWithdrawEnabled is None) or withdraw:
763
- currencyWithdrawEnabled = withdraw
764
- if (currencyMaxPrecision is None) or Precise.string_gt(currencyMaxPrecision, precision):
765
- currencyMaxPrecision = precision
766
- if code in result:
767
- # checking for specific ids.ARB
768
- networks = self.extend(result[code]['networks'], networks)
769
- result[code] = {
770
- 'id': id,
771
- 'code': code,
772
- 'name': None,
773
- 'type': None,
774
- 'active': None,
775
- 'deposit': currencyDepositEnabled,
776
- 'withdraw': currencyWithdrawEnabled,
777
- 'fee': None,
778
- 'precision': self.parse_number(currencyMaxPrecision),
779
- 'limits': {
780
- 'amount': {
781
- 'min': None,
782
- 'max': None,
783
- },
784
- 'withdraw': {
785
- 'min': None,
786
- 'max': None,
787
- },
788
- },
789
- 'networks': networks,
790
- 'info': currency,
791
- }
714
+ infos = self.safe_list(result[code], 'info', [])
715
+ infos.append(currency)
716
+ result[code]['info'] = infos
717
+ # only after all entries are formed in currencies, restructure each entry
718
+ allKeys = list(result.keys())
719
+ for i in range(0, len(allKeys)):
720
+ code = allKeys[i]
721
+ result[code] = self.safe_currency_structure(result[code]) # self is needed after adding network entry
792
722
  return result
793
723
 
794
724
  def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
ccxt/paradex.py CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  from ccxt.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 self.privatePostAccountMarginMarket(self.extend(request, params))
2286
2291
 
2292
+ 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
+ self.load_markets()
2303
+ market = self.market(symbol)
2304
+ request: dict = {
2305
+ 'market': market['id'],
2306
+ }
2307
+ response = 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))