ccxt 4.3.1__py2.py3-none-any.whl → 4.3.3__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.

Potentially problematic release.


This version of ccxt might be problematic. Click here for more details.

ccxt/__init__.py CHANGED
@@ -22,7 +22,7 @@
22
22
 
23
23
  # ----------------------------------------------------------------------------
24
24
 
25
- __version__ = '4.3.1'
25
+ __version__ = '4.3.3'
26
26
 
27
27
  # ----------------------------------------------------------------------------
28
28
 
@@ -4,7 +4,7 @@
4
4
 
5
5
  # -----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.3.1'
7
+ __version__ = '4.3.3'
8
8
 
9
9
  # -----------------------------------------------------------------------------
10
10
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  # -----------------------------------------------------------------------------
4
4
 
5
- __version__ = '4.3.1'
5
+ __version__ = '4.3.3'
6
6
 
7
7
  # -----------------------------------------------------------------------------
8
8
 
@@ -25,7 +25,7 @@ from ccxt.async_support.base.throttler import Throttler
25
25
  # -----------------------------------------------------------------------------
26
26
 
27
27
  from ccxt.base.errors import BaseError, BadSymbol, BadRequest, BadResponse, ExchangeError, ExchangeNotAvailable, RequestTimeout, NotSupported, NullResponse, InvalidAddress, RateLimitExceeded
28
- from ccxt.base.types import OrderType, OrderSide, OrderRequest
28
+ from ccxt.base.types import OrderType, OrderSide, OrderRequest, CancellationRequest
29
29
 
30
30
  # -----------------------------------------------------------------------------
31
31
 
@@ -1210,6 +1210,9 @@ class Exchange(BaseExchange):
1210
1210
  async def cancel_all_orders(self, symbol: Str = None, params={}):
1211
1211
  raise NotSupported(self.id + ' cancelAllOrders() is not supported yet')
1212
1212
 
1213
+ async def cancel_orders_for_symbols(self, orders: List[CancellationRequest], params={}):
1214
+ raise NotSupported(self.id + ' cancelOrdersForSymbols() is not supported yet')
1215
+
1213
1216
  async def cancel_all_orders_ws(self, symbol: Str = None, params={}):
1214
1217
  raise NotSupported(self.id + ' cancelAllOrdersWs() is not supported yet')
1215
1218
 
@@ -96,7 +96,9 @@ class binance(Exchange, ImplicitAPI):
96
96
  'fetchClosedOrder': False,
97
97
  'fetchClosedOrders': 'emulated',
98
98
  'fetchConvertCurrencies': True,
99
- 'fetchConvertQuote': False,
99
+ 'fetchConvertQuote': True,
100
+ 'fetchConvertTrade': True,
101
+ 'fetchConvertTradeHistory': True,
100
102
  'fetchCrossBorrowRate': True,
101
103
  'fetchCrossBorrowRates': False,
102
104
  'fetchCurrencies': True,
@@ -11638,55 +11640,328 @@ class binance(Exchange, ImplicitAPI):
11638
11640
  }
11639
11641
  return result
11640
11642
 
11641
- async def create_convert_trade(self, id: str, fromCode: str, toCode: str, amount: Num = None, params={}) -> Conversion:
11643
+ async def fetch_convert_quote(self, fromCode: str, toCode: str, amount: Num = None, params={}) -> Conversion:
11642
11644
  """
11643
- convert from one currency to another
11644
- :see: https://binance-docs.github.io/apidocs/spot/en/#busd-convert-trade
11645
- :param str id: the id of the trade that you want to make
11645
+ fetch a quote for converting from one currency to another
11646
+ :see: https://binance-docs.github.io/apidocs/spot/en/#send-quote-request-user_data
11646
11647
  :param str fromCode: the currency that you want to sell and convert from
11647
11648
  :param str toCode: the currency that you want to buy and convert into
11648
- :param float [amount]: how much you want to trade in units of the from currency
11649
+ :param float amount: how much you want to trade in units of the from currency
11649
11650
  :param dict [params]: extra parameters specific to the exchange API endpoint
11651
+ :param str [params.walletType]: either 'SPOT' or 'FUNDING', the default is 'SPOT'
11650
11652
  :returns dict: a `conversion structure <https://docs.ccxt.com/#/?id=conversion-structure>`
11651
11653
  """
11654
+ if amount is None:
11655
+ raise ArgumentsRequired(self.id + ' fetchConvertQuote() requires an amount argument')
11652
11656
  await self.load_markets()
11653
11657
  request = {
11654
- 'clientTranId': id,
11655
- 'asset': fromCode,
11656
- 'targetAsset': toCode,
11657
- 'amount': amount,
11658
+ 'fromAsset': fromCode,
11659
+ 'toAsset': toCode,
11660
+ 'fromAmount': amount,
11658
11661
  }
11659
- response = await self.sapiPostAssetConvertTransfer(self.extend(request, params))
11662
+ response = await self.sapiPostConvertGetQuote(self.extend(request, params))
11660
11663
  #
11661
11664
  # {
11662
- # "tranId": 118263407119,
11663
- # "status": "S"
11665
+ # "quoteId":"12415572564",
11666
+ # "ratio":"38163.7",
11667
+ # "inverseRatio":"0.0000262",
11668
+ # "validTimestamp":1623319461670,
11669
+ # "toAmount":"3816.37",
11670
+ # "fromAmount":"0.1"
11664
11671
  # }
11665
11672
  #
11666
11673
  fromCurrency = self.currency(fromCode)
11667
11674
  toCurrency = self.currency(toCode)
11668
11675
  return self.parse_conversion(response, fromCurrency, toCurrency)
11669
11676
 
11677
+ async def create_convert_trade(self, id: str, fromCode: str, toCode: str, amount: Num = None, params={}) -> Conversion:
11678
+ """
11679
+ convert from one currency to another
11680
+ :see: https://binance-docs.github.io/apidocs/spot/en/#busd-convert-trade
11681
+ :see: https://binance-docs.github.io/apidocs/spot/en/#accept-quote-trade
11682
+ :param str id: the id of the trade that you want to make
11683
+ :param str fromCode: the currency that you want to sell and convert from
11684
+ :param str toCode: the currency that you want to buy and convert into
11685
+ :param float [amount]: how much you want to trade in units of the from currency
11686
+ :param dict [params]: extra parameters specific to the exchange API endpoint
11687
+ :returns dict: a `conversion structure <https://docs.ccxt.com/#/?id=conversion-structure>`
11688
+ """
11689
+ await self.load_markets()
11690
+ request = {}
11691
+ response = None
11692
+ if (fromCode == 'BUSD') or (toCode == 'BUSD'):
11693
+ if amount is None:
11694
+ raise ArgumentsRequired(self.id + ' createConvertTrade() requires an amount argument')
11695
+ request['clientTranId'] = id
11696
+ request['asset'] = fromCode
11697
+ request['targetAsset'] = toCode
11698
+ request['amount'] = amount
11699
+ response = await self.sapiPostAssetConvertTransfer(self.extend(request, params))
11700
+ #
11701
+ # {
11702
+ # "tranId": 118263407119,
11703
+ # "status": "S"
11704
+ # }
11705
+ #
11706
+ else:
11707
+ request['quoteId'] = id
11708
+ response = await self.sapiPostConvertAcceptQuote(self.extend(request, params))
11709
+ #
11710
+ # {
11711
+ # "orderId":"933256278426274426",
11712
+ # "createTime":1623381330472,
11713
+ # "orderStatus":"PROCESS"
11714
+ # }
11715
+ #
11716
+ fromCurrency = self.currency(fromCode)
11717
+ toCurrency = self.currency(toCode)
11718
+ return self.parse_conversion(response, fromCurrency, toCurrency)
11719
+
11720
+ async def fetch_convert_trade(self, id: str, code: Str = None, params={}) -> Conversion:
11721
+ """
11722
+ fetch the data for a conversion trade
11723
+ :see: https://binance-docs.github.io/apidocs/spot/en/#busd-convert-history-user_data
11724
+ :see: https://binance-docs.github.io/apidocs/spot/en/#order-status-user_data
11725
+ :param str id: the id of the trade that you want to fetch
11726
+ :param str [code]: the unified currency code of the conversion trade
11727
+ :param dict [params]: extra parameters specific to the exchange API endpoint
11728
+ :returns dict: a `conversion structure <https://docs.ccxt.com/#/?id=conversion-structure>`
11729
+ """
11730
+ await self.load_markets()
11731
+ request = {}
11732
+ response = None
11733
+ if code == 'BUSD':
11734
+ msInDay = 86400000
11735
+ now = self.milliseconds()
11736
+ if code is not None:
11737
+ currency = self.currency(code)
11738
+ request['asset'] = currency['id']
11739
+ request['tranId'] = id
11740
+ request['startTime'] = now - msInDay
11741
+ request['endTime'] = now
11742
+ response = await self.sapiGetAssetConvertTransferQueryByPage(self.extend(request, params))
11743
+ #
11744
+ # {
11745
+ # "total": 3,
11746
+ # "rows": [
11747
+ # {
11748
+ # "tranId": 118263615991,
11749
+ # "type": 244,
11750
+ # "time": 1664442078000,
11751
+ # "deductedAsset": "BUSD",
11752
+ # "deductedAmount": "1",
11753
+ # "targetAsset": "USDC",
11754
+ # "targetAmount": "1",
11755
+ # "status": "S",
11756
+ # "accountType": "MAIN"
11757
+ # },
11758
+ # ]
11759
+ # }
11760
+ #
11761
+ else:
11762
+ request['orderId'] = id
11763
+ response = await self.sapiGetConvertOrderStatus(self.extend(request, params))
11764
+ #
11765
+ # {
11766
+ # "orderId":933256278426274426,
11767
+ # "orderStatus":"SUCCESS",
11768
+ # "fromAsset":"BTC",
11769
+ # "fromAmount":"0.00054414",
11770
+ # "toAsset":"USDT",
11771
+ # "toAmount":"20",
11772
+ # "ratio":"36755",
11773
+ # "inverseRatio":"0.00002721",
11774
+ # "createTime":1623381330472
11775
+ # }
11776
+ #
11777
+ data = response
11778
+ if code == 'BUSD':
11779
+ rows = self.safe_list(response, 'rows', [])
11780
+ data = self.safe_dict(rows, 0, {})
11781
+ fromCurrencyId = self.safe_string_2(data, 'deductedAsset', 'fromAsset')
11782
+ toCurrencyId = self.safe_string_2(data, 'targetAsset', 'toAsset')
11783
+ fromCurrency = None
11784
+ toCurrency = None
11785
+ if fromCurrencyId is not None:
11786
+ fromCurrency = self.currency(fromCurrencyId)
11787
+ if toCurrencyId is not None:
11788
+ toCurrency = self.currency(toCurrencyId)
11789
+ return self.parse_conversion(data, fromCurrency, toCurrency)
11790
+
11791
+ async def fetch_convert_trade_history(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Conversion]:
11792
+ """
11793
+ fetch the users history of conversion trades
11794
+ :see: https://binance-docs.github.io/apidocs/spot/en/#busd-convert-history-user_data
11795
+ :see: https://binance-docs.github.io/apidocs/spot/en/#get-convert-trade-history-user_data
11796
+ :param str [code]: the unified currency code
11797
+ :param int [since]: the earliest time in ms to fetch conversions for
11798
+ :param int [limit]: the maximum number of conversion structures to retrieve
11799
+ :param dict [params]: extra parameters specific to the exchange API endpoint
11800
+ :param int [params.until]: timestamp in ms of the latest conversion to fetch
11801
+ :returns dict[]: a list of `conversion structures <https://docs.ccxt.com/#/?id=conversion-structure>`
11802
+ """
11803
+ await self.load_markets()
11804
+ request = {}
11805
+ msInThirtyDays = 2592000000
11806
+ now = self.milliseconds()
11807
+ if since is not None:
11808
+ request['startTime'] = since
11809
+ else:
11810
+ request['startTime'] = now - msInThirtyDays
11811
+ endTime = self.safe_string_2(params, 'endTime', 'until')
11812
+ if endTime is not None:
11813
+ request['endTime'] = endTime
11814
+ else:
11815
+ request['endTime'] = now
11816
+ params = self.omit(params, 'until')
11817
+ response = None
11818
+ responseQuery = None
11819
+ fromCurrencyKey = None
11820
+ toCurrencyKey = None
11821
+ if code == 'BUSD':
11822
+ currency = self.currency(code)
11823
+ request['asset'] = currency['id']
11824
+ if limit is not None:
11825
+ request['size'] = limit
11826
+ fromCurrencyKey = 'deductedAsset'
11827
+ toCurrencyKey = 'targetAsset'
11828
+ responseQuery = 'rows'
11829
+ response = await self.sapiGetAssetConvertTransferQueryByPage(self.extend(request, params))
11830
+ #
11831
+ # {
11832
+ # "total": 3,
11833
+ # "rows": [
11834
+ # {
11835
+ # "tranId": 118263615991,
11836
+ # "type": 244,
11837
+ # "time": 1664442078000,
11838
+ # "deductedAsset": "BUSD",
11839
+ # "deductedAmount": "1",
11840
+ # "targetAsset": "USDC",
11841
+ # "targetAmount": "1",
11842
+ # "status": "S",
11843
+ # "accountType": "MAIN"
11844
+ # },
11845
+ # ]
11846
+ # }
11847
+ #
11848
+ else:
11849
+ if limit is not None:
11850
+ request['limit'] = limit
11851
+ fromCurrencyKey = 'fromAsset'
11852
+ toCurrencyKey = 'toAsset'
11853
+ responseQuery = 'list'
11854
+ response = await self.sapiGetConvertTradeFlow(self.extend(request, params))
11855
+ #
11856
+ # {
11857
+ # "list": [
11858
+ # {
11859
+ # "quoteId": "f3b91c525b2644c7bc1e1cd31b6e1aa6",
11860
+ # "orderId": 940708407462087195,
11861
+ # "orderStatus": "SUCCESS",
11862
+ # "fromAsset": "USDT",
11863
+ # "fromAmount": "20",
11864
+ # "toAsset": "BNB",
11865
+ # "toAmount": "0.06154036",
11866
+ # "ratio": "0.00307702",
11867
+ # "inverseRatio": "324.99",
11868
+ # "createTime": 1624248872184
11869
+ # }
11870
+ # ],
11871
+ # "startTime": 1623824139000,
11872
+ # "endTime": 1626416139000,
11873
+ # "limit": 100,
11874
+ # "moreData": False
11875
+ # }
11876
+ #
11877
+ rows = self.safe_list(response, responseQuery, [])
11878
+ return self.parse_conversions(rows, fromCurrencyKey, toCurrencyKey, since, limit)
11879
+
11670
11880
  def parse_conversion(self, conversion, fromCurrency: Currency = None, toCurrency: Currency = None) -> Conversion:
11881
+ #
11882
+ # fetchConvertQuote
11883
+ #
11884
+ # {
11885
+ # "quoteId":"12415572564",
11886
+ # "ratio":"38163.7",
11887
+ # "inverseRatio":"0.0000262",
11888
+ # "validTimestamp":1623319461670,
11889
+ # "toAmount":"3816.37",
11890
+ # "fromAmount":"0.1"
11891
+ # }
11671
11892
  #
11672
11893
  # createConvertTrade
11673
11894
  #
11674
11895
  # {
11896
+ # "orderId":"933256278426274426",
11897
+ # "createTime":1623381330472,
11898
+ # "orderStatus":"PROCESS"
11899
+ # }
11900
+ #
11901
+ # createConvertTrade BUSD
11902
+ #
11903
+ # {
11675
11904
  # "tranId": 118263407119,
11676
11905
  # "status": "S"
11677
11906
  # }
11678
11907
  #
11679
- fromCode = self.safe_currency_code(None, fromCurrency)
11680
- toCode = self.safe_currency_code(None, toCurrency)
11908
+ # fetchConvertTrade, fetchConvertTradeHistory BUSD
11909
+ #
11910
+ # {
11911
+ # "tranId": 118263615991,
11912
+ # "type": 244,
11913
+ # "time": 1664442078000,
11914
+ # "deductedAsset": "BUSD",
11915
+ # "deductedAmount": "1",
11916
+ # "targetAsset": "USDC",
11917
+ # "targetAmount": "1",
11918
+ # "status": "S",
11919
+ # "accountType": "MAIN"
11920
+ # }
11921
+ #
11922
+ # fetchConvertTrade
11923
+ #
11924
+ # {
11925
+ # "orderId":933256278426274426,
11926
+ # "orderStatus":"SUCCESS",
11927
+ # "fromAsset":"BTC",
11928
+ # "fromAmount":"0.00054414",
11929
+ # "toAsset":"USDT",
11930
+ # "toAmount":"20",
11931
+ # "ratio":"36755",
11932
+ # "inverseRatio":"0.00002721",
11933
+ # "createTime":1623381330472
11934
+ # }
11935
+ #
11936
+ # fetchConvertTradeHistory
11937
+ #
11938
+ # {
11939
+ # "quoteId": "f3b91c525b2644c7bc1e1cd31b6e1aa6",
11940
+ # "orderId": 940708407462087195,
11941
+ # "orderStatus": "SUCCESS",
11942
+ # "fromAsset": "USDT",
11943
+ # "fromAmount": "20",
11944
+ # "toAsset": "BNB",
11945
+ # "toAmount": "0.06154036",
11946
+ # "ratio": "0.00307702",
11947
+ # "inverseRatio": "324.99",
11948
+ # "createTime": 1624248872184
11949
+ # }
11950
+ #
11951
+ timestamp = self.safe_integer_n(conversion, ['time', 'validTimestamp', 'createTime'])
11952
+ fromCur = self.safe_string_2(conversion, 'deductedAsset', 'fromAsset')
11953
+ fromCode = self.safe_currency_code(fromCur, fromCurrency)
11954
+ to = self.safe_string_2(conversion, 'targetAsset', 'toAsset')
11955
+ toCode = self.safe_currency_code(to, toCurrency)
11681
11956
  return {
11682
11957
  'info': conversion,
11683
- 'timestamp': None,
11684
- 'datetime': None,
11685
- 'id': self.safe_string(conversion, 'tranId'),
11958
+ 'timestamp': timestamp,
11959
+ 'datetime': self.iso8601(timestamp),
11960
+ 'id': self.safe_string_n(conversion, ['tranId', 'orderId', 'quoteId']),
11686
11961
  'fromCurrency': fromCode,
11687
- 'fromAmount': None,
11962
+ 'fromAmount': self.safe_number_2(conversion, 'deductedAmount', 'fromAmount'),
11688
11963
  'toCurrency': toCode,
11689
- 'toAmount': None,
11964
+ 'toAmount': self.safe_number_2(conversion, 'targetAmount', 'toAmount'),
11690
11965
  'price': None,
11691
11966
  'fee': None,
11692
11967
  }
@@ -20,6 +20,7 @@ from ccxt.base.errors import BadSymbol
20
20
  from ccxt.base.errors import InsufficientFunds
21
21
  from ccxt.base.errors import OrderNotFound
22
22
  from ccxt.base.errors import NotSupported
23
+ from ccxt.base.errors import OperationFailed
23
24
  from ccxt.base.errors import DDoSProtection
24
25
  from ccxt.base.decimal_to_precision import DECIMAL_PLACES
25
26
  from ccxt.base.precise import Precise
@@ -398,17 +399,17 @@ class bingx(Exchange, ImplicitAPI):
398
399
  '100400': BadRequest,
399
400
  '100421': BadSymbol, # {"code":100421,"msg":"This pair is currently restricted from API trading","debugMsg":""}
400
401
  '100440': ExchangeError,
401
- '100500': ExchangeError,
402
+ '100500': OperationFailed, # {"code":100500,"msg":"The current system is busy, please try again later","debugMsg":""}
402
403
  '100503': ExchangeError,
403
404
  '80001': BadRequest,
404
- '80012': InsufficientFunds, # bingx {"code":80012,"msg":"{\"Code\":101253,\"Msg\":\"margin is not enough\"}}
405
+ '80012': InsufficientFunds, # {"code":80012,"msg":"{\"Code\":101253,\"Msg\":\"margin is not enough\"}}
405
406
  '80014': BadRequest,
406
407
  '80016': OrderNotFound,
407
408
  '80017': OrderNotFound,
408
409
  '100414': AccountSuspended, # {"code":100414,"msg":"Code: 100414, Msg: risk control check fail,code(1)","debugMsg":""}
409
410
  '100419': PermissionDenied, # {"code":100419,"msg":"IP does not match IP whitelist","success":false,"timestamp":1705274099347}
410
411
  '100437': BadRequest, # {"code":100437,"msg":"The withdrawal amount is lower than the minimum limit, please re-enter.","timestamp":1689258588845}
411
- '101204': InsufficientFunds, # bingx {"code":101204,"msg":"","data":{}}
412
+ '101204': InsufficientFunds, # {"code":101204,"msg":"","data":{}}
412
413
  },
413
414
  'broad': {},
414
415
  },
@@ -3718,7 +3719,7 @@ class bingx(Exchange, ImplicitAPI):
3718
3719
  market = None
3719
3720
  if symbol is not None:
3720
3721
  market = self.market(symbol)
3721
- request['symbol'] = symbol
3722
+ request['symbol'] = market['id']
3722
3723
  if since is not None:
3723
3724
  request['startTime'] = since
3724
3725
  if limit is not None:
@@ -88,6 +88,8 @@ class bitget(Exchange, ImplicitAPI):
88
88
  'fetchClosedOrders': True,
89
89
  'fetchConvertCurrencies': True,
90
90
  'fetchConvertQuote': True,
91
+ 'fetchConvertTrade': False,
92
+ 'fetchConvertTradeHistory': True,
91
93
  'fetchCrossBorrowRate': True,
92
94
  'fetchCrossBorrowRates': False,
93
95
  'fetchCurrencies': True,
@@ -7944,6 +7946,59 @@ class bitget(Exchange, ImplicitAPI):
7944
7946
  toCurrency = self.currency(toCurrencyId)
7945
7947
  return self.parse_conversion(data, None, toCurrency)
7946
7948
 
7949
+ async def fetch_convert_trade_history(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Conversion]:
7950
+ """
7951
+ fetch the users history of conversion trades
7952
+ :see: https://www.bitget.com/api-doc/common/convert/Get-Convert-Record
7953
+ :param str [code]: the unified currency code
7954
+ :param int [since]: the earliest time in ms to fetch conversions for
7955
+ :param int [limit]: the maximum number of conversion structures to retrieve
7956
+ :param dict [params]: extra parameters specific to the exchange API endpoint
7957
+ :returns dict[]: a list of `conversion structures <https://docs.ccxt.com/#/?id=conversion-structure>`
7958
+ """
7959
+ await self.load_markets()
7960
+ request = {}
7961
+ msInDay = 86400000
7962
+ now = self.milliseconds()
7963
+ if since is not None:
7964
+ request['startTime'] = since
7965
+ else:
7966
+ request['startTime'] = now - msInDay
7967
+ endTime = self.safe_string_2(params, 'endTime', 'until')
7968
+ if endTime is not None:
7969
+ request['endTime'] = endTime
7970
+ else:
7971
+ request['endTime'] = now
7972
+ if limit is not None:
7973
+ request['limit'] = limit
7974
+ params = self.omit(params, 'until')
7975
+ response = await self.privateConvertGetV2ConvertConvertRecord(self.extend(request, params))
7976
+ #
7977
+ # {
7978
+ # "code": "00000",
7979
+ # "msg": "success",
7980
+ # "requestTime": 1712124371799,
7981
+ # "data": {
7982
+ # "dataList": [
7983
+ # {
7984
+ # "id": "1159296505255219205",
7985
+ # "fromCoin": "USDT",
7986
+ # "fromCoinSize": "5",
7987
+ # "cnvtPrice": "0.99940076",
7988
+ # "toCoin": "USDC",
7989
+ # "toCoinSize": "4.99700379",
7990
+ # "ts": "1712123746217",
7991
+ # "fee": "0"
7992
+ # }
7993
+ # ],
7994
+ # "endId": "1159296505255219205"
7995
+ # }
7996
+ # }
7997
+ #
7998
+ data = self.safe_dict(response, 'data', {})
7999
+ dataList = self.safe_list(data, 'dataList', [])
8000
+ return self.parse_conversions(dataList, 'fromCoin', 'toCoin', since, limit)
8001
+
7947
8002
  def parse_conversion(self, conversion, fromCurrency: Currency = None, toCurrency: Currency = None) -> Conversion:
7948
8003
  #
7949
8004
  # fetchConvertQuote
@@ -7967,6 +8022,19 @@ class bitget(Exchange, ImplicitAPI):
7967
8022
  # "ts": "1712123746217"
7968
8023
  # }
7969
8024
  #
8025
+ # fetchConvertTradeHistory
8026
+ #
8027
+ # {
8028
+ # "id": "1159296505255219205",
8029
+ # "fromCoin": "USDT",
8030
+ # "fromCoinSize": "5",
8031
+ # "cnvtPrice": "0.99940076",
8032
+ # "toCoin": "USDC",
8033
+ # "toCoinSize": "4.99700379",
8034
+ # "ts": "1712123746217",
8035
+ # "fee": "0"
8036
+ # }
8037
+ #
7970
8038
  timestamp = self.safe_integer(conversion, 'ts')
7971
8039
  fromCoin = self.safe_string(conversion, 'fromCoin')
7972
8040
  fromCode = self.safe_currency_code(fromCoin, fromCurrency)
@@ -7976,7 +8044,7 @@ class bitget(Exchange, ImplicitAPI):
7976
8044
  'info': conversion,
7977
8045
  'timestamp': timestamp,
7978
8046
  'datetime': self.iso8601(timestamp),
7979
- 'id': self.safe_string(conversion, 'traceId'),
8047
+ 'id': self.safe_string_2(conversion, 'id', 'traceId'),
7980
8048
  'fromCurrency': fromCode,
7981
8049
  'fromAmount': self.safe_number(conversion, 'fromCoinSize'),
7982
8050
  'toCurrency': toCode,
@@ -8051,6 +8119,8 @@ class bitget(Exchange, ImplicitAPI):
8051
8119
  #
8052
8120
  # spot
8053
8121
  #
8122
+ # {"code":"00000","msg":"success","requestTime":1713294492511,"data":[...]}"
8123
+ #
8054
8124
  # {"status":"fail","err_code":"01001","err_msg":"系统异常,请稍后重试"}
8055
8125
  # {"status":"error","ts":1595594160149,"err_code":"invalid-parameter","err_msg":"invalid size, valid range: [1,2000]"}
8056
8126
  # {"status":"error","ts":1595684716042,"err_code":"invalid-parameter","err_msg":"illegal sign invalid"}
@@ -8072,13 +8142,13 @@ class bitget(Exchange, ImplicitAPI):
8072
8142
  # {"code":"40108","msg":"","requestTime":1595885064600,"data":null}
8073
8143
  # {"order_id":"513468410013679613","client_oid":null,"symbol":"ethusd","result":false,"err_code":"order_no_exist_error","err_msg":"订单不存在!"}
8074
8144
  #
8075
- message = self.safe_string(response, 'err_msg')
8076
- errorCode = self.safe_string_2(response, 'code', 'err_code')
8145
+ message = self.safe_string_2(response, 'err_msg', 'msg')
8077
8146
  feedback = self.id + ' ' + body
8078
- nonEmptyMessage = ((message is not None) and (message != ''))
8147
+ nonEmptyMessage = ((message is not None) and (message != '') and (message != 'success'))
8079
8148
  if nonEmptyMessage:
8080
8149
  self.throw_exactly_matched_exception(self.exceptions['exact'], message, feedback)
8081
8150
  self.throw_broadly_matched_exception(self.exceptions['broad'], message, feedback)
8151
+ errorCode = self.safe_string_2(response, 'code', 'err_code')
8082
8152
  nonZeroErrorCode = (errorCode is not None) and (errorCode != '00000')
8083
8153
  if nonZeroErrorCode:
8084
8154
  self.throw_exactly_matched_exception(self.exceptions['exact'], errorCode, feedback)
@@ -28,9 +28,10 @@ class coinbase(Exchange, ImplicitAPI):
28
28
  def describe(self):
29
29
  return self.deep_extend(super(coinbase, self).describe(), {
30
30
  'id': 'coinbase',
31
- 'name': 'Coinbase',
31
+ 'name': 'Coinbase Advanced',
32
32
  'countries': ['US'],
33
33
  'pro': True,
34
+ 'certified': True,
34
35
  # rate-limits:
35
36
  # ADVANCED API: https://docs.cloud.coinbase.com/advanced-trade-api/docs/rest-api-rate-limits
36
37
  # - max 30 req/second for private data, 10 req/s for public data
@@ -2491,7 +2492,7 @@ class coinbase(Exchange, ImplicitAPI):
2491
2492
  :param float [params.stopLossPrice]: price to trigger stop-loss orders
2492
2493
  :param float [params.takeProfitPrice]: price to trigger take-profit orders
2493
2494
  :param bool [params.postOnly]: True or False
2494
- :param str [params.timeInForce]: 'GTC', 'IOC', 'GTD' or 'PO'
2495
+ :param str [params.timeInForce]: 'GTC', 'IOC', 'GTD' or 'PO', 'FOK'
2495
2496
  :param str [params.stop_direction]: 'UNKNOWN_STOP_DIRECTION', 'STOP_DIRECTION_STOP_UP', 'STOP_DIRECTION_STOP_DOWN' the direction the stopPrice is triggered from
2496
2497
  :param str [params.end_time]: '2023-05-25T17:01:05.092Z' for 'GTD' orders
2497
2498
  :param float [params.cost]: *spot market buy only* the quote quantity that can be used alternative for the amount
@@ -2583,6 +2584,13 @@ class coinbase(Exchange, ImplicitAPI):
2583
2584
  'limit_price': self.price_to_precision(symbol, price),
2584
2585
  },
2585
2586
  }
2587
+ elif timeInForce == 'FOK':
2588
+ request['order_configuration'] = {
2589
+ 'limit_limit_fok': {
2590
+ 'base_size': self.amount_to_precision(symbol, amount),
2591
+ 'limit_price': self.price_to_precision(symbol, price),
2592
+ },
2593
+ }
2586
2594
  else:
2587
2595
  request['order_configuration'] = {
2588
2596
  'limit_limit_gtc': {
@@ -27,7 +27,7 @@ class coinbasepro(Exchange, ImplicitAPI):
27
27
  def describe(self):
28
28
  return self.deep_extend(super(coinbasepro, self).describe(), {
29
29
  'id': 'coinbasepro',
30
- 'name': 'Coinbase Pro',
30
+ 'name': 'Coinbase Pro(Deprecated)',
31
31
  'countries': ['US'],
32
32
  'rateLimit': 100,
33
33
  'userAgent': self.userAgents['chrome'],