ccxt 4.2.76__py2.py3-none-any.whl → 4.2.78__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.
- ccxt/__init__.py +1 -1
- ccxt/abstract/kucoin.py +1 -0
- ccxt/abstract/kucoinfutures.py +1 -0
- ccxt/async_support/__init__.py +1 -1
- ccxt/async_support/base/exchange.py +1 -1
- ccxt/async_support/binance.py +503 -444
- ccxt/async_support/bingx.py +1 -1
- ccxt/async_support/bitflyer.py +2 -2
- ccxt/async_support/bithumb.py +2 -2
- ccxt/async_support/blofin.py +11 -2
- ccxt/async_support/bybit.py +88 -52
- ccxt/async_support/coinbase.py +21 -10
- ccxt/async_support/delta.py +65 -51
- ccxt/async_support/deribit.py +2 -2
- ccxt/async_support/gate.py +3 -2
- ccxt/async_support/htx.py +34 -27
- ccxt/async_support/hyperliquid.py +7 -5
- ccxt/async_support/kraken.py +8 -8
- ccxt/async_support/kucoin.py +192 -5
- ccxt/async_support/okcoin.py +27 -1
- ccxt/async_support/okx.py +20 -2
- ccxt/async_support/woo.py +62 -3
- ccxt/base/exchange.py +9 -4
- ccxt/binance.py +503 -444
- ccxt/bingx.py +1 -1
- ccxt/bitflyer.py +2 -2
- ccxt/bithumb.py +2 -2
- ccxt/blofin.py +11 -2
- ccxt/bybit.py +88 -52
- ccxt/coinbase.py +21 -10
- ccxt/delta.py +65 -51
- ccxt/deribit.py +2 -2
- ccxt/gate.py +3 -2
- ccxt/htx.py +34 -27
- ccxt/hyperliquid.py +7 -5
- ccxt/kraken.py +8 -8
- ccxt/kucoin.py +192 -5
- ccxt/okcoin.py +27 -1
- ccxt/okx.py +20 -2
- ccxt/pro/__init__.py +1 -1
- ccxt/pro/ascendex.py +1 -1
- ccxt/pro/bitvavo.py +1 -1
- ccxt/pro/coinex.py +20 -14
- ccxt/pro/deribit.py +1 -1
- ccxt/pro/exmo.py +1 -1
- ccxt/pro/krakenfutures.py +1 -1
- ccxt/pro/phemex.py +1 -1
- ccxt/pro/poloniex.py +1 -1
- ccxt/pro/probit.py +1 -1
- ccxt/pro/woo.py +50 -6
- ccxt/test/test_async.py +9 -16
- ccxt/test/test_sync.py +9 -16
- ccxt/woo.py +62 -3
- {ccxt-4.2.76.dist-info → ccxt-4.2.78.dist-info}/METADATA +4 -4
- {ccxt-4.2.76.dist-info → ccxt-4.2.78.dist-info}/RECORD +57 -57
- {ccxt-4.2.76.dist-info → ccxt-4.2.78.dist-info}/WHEEL +0 -0
- {ccxt-4.2.76.dist-info → ccxt-4.2.78.dist-info}/top_level.txt +0 -0
ccxt/async_support/kraken.py
CHANGED
@@ -468,7 +468,7 @@ class kraken(Exchange, ImplicitAPI):
|
|
468
468
|
async def fetch_markets(self, params={}):
|
469
469
|
"""
|
470
470
|
retrieves data on all markets for kraken
|
471
|
-
:see: https://docs.kraken.com/rest/#tag/Market-Data/operation/getTradableAssetPairs
|
471
|
+
:see: https://docs.kraken.com/rest/#tag/Spot-Market-Data/operation/getTradableAssetPairs
|
472
472
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
473
473
|
:returns dict[]: an array of objects representing market data
|
474
474
|
"""
|
@@ -644,7 +644,7 @@ class kraken(Exchange, ImplicitAPI):
|
|
644
644
|
async def fetch_currencies(self, params={}):
|
645
645
|
"""
|
646
646
|
fetches all available currencies on an exchange
|
647
|
-
:see: https://docs.kraken.com/rest/#tag/Market-Data/operation/getAssetInfo
|
647
|
+
:see: https://docs.kraken.com/rest/#tag/Spot-Market-Data/operation/getAssetInfo
|
648
648
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
649
649
|
:returns dict: an associative dictionary of currencies
|
650
650
|
"""
|
@@ -767,7 +767,7 @@ class kraken(Exchange, ImplicitAPI):
|
|
767
767
|
async def fetch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
|
768
768
|
"""
|
769
769
|
fetches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
770
|
-
:see: https://docs.kraken.com/rest/#tag/Market-Data/operation/getOrderBook
|
770
|
+
:see: https://docs.kraken.com/rest/#tag/Spot-Market-Data/operation/getOrderBook
|
771
771
|
:param str symbol: unified symbol of the market to fetch the order book for
|
772
772
|
:param int [limit]: the maximum amount of order book entries to return
|
773
773
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -864,7 +864,7 @@ class kraken(Exchange, ImplicitAPI):
|
|
864
864
|
async def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
|
865
865
|
"""
|
866
866
|
fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
|
867
|
-
:see: https://docs.kraken.com/rest/#tag/Market-Data/operation/getTickerInformation
|
867
|
+
:see: https://docs.kraken.com/rest/#tag/Spot-Market-Data/operation/getTickerInformation
|
868
868
|
:param str[]|None symbols: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
|
869
869
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
870
870
|
:returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
|
@@ -895,7 +895,7 @@ class kraken(Exchange, ImplicitAPI):
|
|
895
895
|
async def fetch_ticker(self, symbol: str, params={}) -> Ticker:
|
896
896
|
"""
|
897
897
|
fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
898
|
-
:see: https://docs.kraken.com/rest/#tag/Market-Data/operation/getTickerInformation
|
898
|
+
:see: https://docs.kraken.com/rest/#tag/Spot-Market-Data/operation/getTickerInformation
|
899
899
|
:param str symbol: unified symbol of the market to fetch the ticker for
|
900
900
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
901
901
|
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
@@ -937,7 +937,7 @@ class kraken(Exchange, ImplicitAPI):
|
|
937
937
|
async def fetch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
|
938
938
|
"""
|
939
939
|
fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
940
|
-
:see: https://docs.kraken.com/rest/#tag/Market-Data/operation/getOHLCData
|
940
|
+
:see: https://docs.kraken.com/rest/#tag/Spot-Market-Data/operation/getOHLCData
|
941
941
|
:param str symbol: unified symbol of the market to fetch OHLCV data for
|
942
942
|
:param str timeframe: the length of time each candle represents
|
943
943
|
:param int [since]: timestamp in ms of the earliest candle to fetch
|
@@ -1212,7 +1212,7 @@ class kraken(Exchange, ImplicitAPI):
|
|
1212
1212
|
async def fetch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
1213
1213
|
"""
|
1214
1214
|
get the list of most recent trades for a particular symbol
|
1215
|
-
:see: https://docs.kraken.com/rest/#tag/Market-Data/operation/getRecentTrades
|
1215
|
+
:see: https://docs.kraken.com/rest/#tag/Spot-Market-Data/operation/getRecentTrades
|
1216
1216
|
:param str symbol: unified symbol of the market to fetch trades for
|
1217
1217
|
:param int [since]: timestamp in ms of the earliest trade to fetch
|
1218
1218
|
:param int [limit]: the maximum amount of trades to fetch
|
@@ -2264,7 +2264,7 @@ class kraken(Exchange, ImplicitAPI):
|
|
2264
2264
|
async def fetch_time(self, params={}):
|
2265
2265
|
"""
|
2266
2266
|
fetches the current integer timestamp in milliseconds from the exchange server
|
2267
|
-
:see: https://docs.kraken.com/rest/#tag/Market-Data/operation/getServerTime
|
2267
|
+
:see: https://docs.kraken.com/rest/#tag/Spot-Market-Data/operation/getServerTime
|
2268
2268
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2269
2269
|
:returns int: the current integer timestamp in milliseconds from the exchange server
|
2270
2270
|
"""
|
ccxt/async_support/kucoin.py
CHANGED
@@ -71,8 +71,8 @@ class kucoin(Exchange, ImplicitAPI):
|
|
71
71
|
'fetchAccounts': True,
|
72
72
|
'fetchBalance': True,
|
73
73
|
'fetchBorrowInterest': True,
|
74
|
-
'fetchBorrowRateHistories':
|
75
|
-
'fetchBorrowRateHistory':
|
74
|
+
'fetchBorrowRateHistories': True,
|
75
|
+
'fetchBorrowRateHistory': True,
|
76
76
|
'fetchClosedOrders': True,
|
77
77
|
'fetchCrossBorrowRate': False,
|
78
78
|
'fetchCrossBorrowRates': False,
|
@@ -246,6 +246,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
246
246
|
'isolated/account/{symbol}': 50, # 50SW
|
247
247
|
'margin/borrow': 15, # 15SW
|
248
248
|
'margin/repay': 15, # 15SW
|
249
|
+
'margin/interest': 20, # 20SW
|
249
250
|
'project/list': 10, # 10SW
|
250
251
|
'project/marketInterestRate': 7.5, # 5PW
|
251
252
|
'redeem/orders': 10, # 10SW
|
@@ -464,6 +465,56 @@ class kucoin(Exchange, ImplicitAPI):
|
|
464
465
|
'130202': ExchangeError, # The system is renewing the loan automatically. Please try again later
|
465
466
|
'130203': InsufficientFunds, # Insufficient account balance
|
466
467
|
'130204': BadRequest, # As the total lending amount for platform leverage reaches the platform's maximum position limit, the system suspends the borrowing function of leverage
|
468
|
+
'130301': InsufficientFunds, # Insufficient account balance
|
469
|
+
'130302': PermissionDenied, # Your relevant permission rights have been restricted, you can contact customer service for processing
|
470
|
+
'130303': NotSupported, # The current trading pair does not support isolated positions
|
471
|
+
'130304': NotSupported, # The trading function of the current trading pair is not enabled
|
472
|
+
'130305': NotSupported, # The current trading pair does not support cross position
|
473
|
+
'130306': NotSupported, # The account has not opened leveraged trading
|
474
|
+
'130307': NotSupported, # Please reopen the leverage agreement
|
475
|
+
'130308': InvalidOrder, # Position renewal freeze
|
476
|
+
'130309': InvalidOrder, # Position forced liquidation freeze
|
477
|
+
'130310': ExchangeError, # Abnormal leverage account status
|
478
|
+
'130311': InvalidOrder, # Failed to place an order, triggering buy limit
|
479
|
+
'130312': InvalidOrder, # Trigger global position limit, suspend buying
|
480
|
+
'130313': InvalidOrder, # Trigger global position limit, suspend selling
|
481
|
+
'130314': InvalidOrder, # Trigger the global position limit and prompt the remaining quantity available for purchase
|
482
|
+
'130315': NotSupported, # This feature has been suspended due to country restrictions
|
483
|
+
'126000': ExchangeError, # Abnormal margin trading
|
484
|
+
'126001': NotSupported, # Users currently do not support high frequency
|
485
|
+
'126002': ExchangeError, # There is a risk problem in your account and transactions are temporarily not allowed!
|
486
|
+
'126003': InvalidOrder, # The commission amount is less than the minimum transaction amount for a single commission
|
487
|
+
'126004': ExchangeError, # Trading pair does not exist or is prohibited
|
488
|
+
'126005': PermissionDenied, # This trading pair requires advanced KYC certification before trading
|
489
|
+
'126006': ExchangeError, # Trading pair is not available
|
490
|
+
'126007': ExchangeError, # Trading pair suspended
|
491
|
+
'126009': ExchangeError, # Trading pair is suspended from creating orders
|
492
|
+
'126010': ExchangeError, # Trading pair suspended order cancellation
|
493
|
+
'126011': ExchangeError, # There are too many orders in the order
|
494
|
+
'126013': InsufficientFunds, # Insufficient account balance
|
495
|
+
'126015': ExchangeError, # It is prohibited to place orders on self trading pair
|
496
|
+
'126021': NotSupported, # This digital asset does not support user participation in your region, thank you for your understanding!
|
497
|
+
'126022': InvalidOrder, # The final transaction price of your order will trigger the price protection strategy. To protect the price from deviating too much, please place an order again.
|
498
|
+
'126027': InvalidOrder, # Only limit orders are supported
|
499
|
+
'126028': InvalidOrder, # Only limit orders are supported before the specified time
|
500
|
+
'126029': InvalidOrder, # The maximum order price is: xxx
|
501
|
+
'126030': InvalidOrder, # The minimum order price is: xxx
|
502
|
+
'126033': InvalidOrder, # Duplicate order
|
503
|
+
'126034': InvalidOrder, # Failed to create take profit and stop loss order
|
504
|
+
'126036': InvalidOrder, # Failed to create margin order
|
505
|
+
'126037': ExchangeError, # Due to country and region restrictions, self function has been suspended!
|
506
|
+
'126038': ExchangeError, # Third-party service call failed(internal exception)
|
507
|
+
'126039': ExchangeError, # Third-party service call failed, reason: xxx
|
508
|
+
'126041': ExchangeError, # clientTimestamp parameter error
|
509
|
+
'126042': ExchangeError, # Exceeded maximum position limit
|
510
|
+
'126043': OrderNotFound, # Order does not exist
|
511
|
+
'126044': InvalidOrder, # clientOid duplicate
|
512
|
+
'126045': NotSupported, # This digital asset does not support user participation in your region, thank you for your understanding!
|
513
|
+
'126046': NotSupported, # This digital asset does not support your IP region, thank you for your understanding!
|
514
|
+
'126047': PermissionDenied, # Please complete identity verification
|
515
|
+
'126048': PermissionDenied, # Please complete authentication for the master account
|
516
|
+
'135005': ExchangeError, # Margin order query business abnormality
|
517
|
+
'135018': ExchangeError, # Margin order query service abnormality
|
467
518
|
'200004': InsufficientFunds,
|
468
519
|
'210014': InvalidOrder, # {"code":"210014","msg":"Exceeds the max. borrowing amount, the remaining amount you can borrow: 0USDT"}
|
469
520
|
'210021': InsufficientFunds, # {"code":"210021","msg":"Balance not enough"}
|
@@ -485,10 +536,12 @@ class kucoin(Exchange, ImplicitAPI):
|
|
485
536
|
'400350': InvalidOrder, # {"code":"400350","msg":"Upper limit for holding: 10,000USDT, you can still buy 10,000USDT worth of coin."}
|
486
537
|
'400370': InvalidOrder, # {"code":"400370","msg":"Max. price: 0.02500000000000000000"}
|
487
538
|
'400400': BadRequest, # Parameter error
|
539
|
+
'400401': AuthenticationError, # User is not logged in
|
488
540
|
'400500': InvalidOrder, # {"code":"400500","msg":"Your located country/region is currently not supported for the trading of self token"}
|
489
541
|
'400600': BadSymbol, # {"code":"400600","msg":"validation.createOrder.symbolNotAvailable"}
|
490
542
|
'400760': InvalidOrder, # {"code":"400760","msg":"order price should be more than XX"}
|
491
543
|
'401000': BadRequest, # {"code":"401000","msg":"The interface has been deprecated"}
|
544
|
+
'408000': BadRequest, # Network timeout, please try again later
|
492
545
|
'411100': AccountSuspended,
|
493
546
|
'415000': BadRequest, # {"code":"415000","msg":"Unsupported Media Type"}
|
494
547
|
'400303': PermissionDenied, # {"msg":"To enjoy the full range of our products and services, we kindly request you complete the identity verification process.","code":"400303"}
|
@@ -607,6 +660,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
607
660
|
'margin/currencies': 'v3',
|
608
661
|
'margin/borrow': 'v3',
|
609
662
|
'margin/repay': 'v3',
|
663
|
+
'margin/interest': 'v3',
|
610
664
|
'project/list': 'v3',
|
611
665
|
'project/marketInterestRate': 'v3',
|
612
666
|
'redeem/orders': 'v3',
|
@@ -3788,12 +3842,19 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3788
3842
|
# "timestamp": 1658531274508488480
|
3789
3843
|
# },
|
3790
3844
|
#
|
3791
|
-
|
3792
|
-
|
3845
|
+
# {
|
3846
|
+
# "createdAt": 1697783812257,
|
3847
|
+
# "currency": "XMR",
|
3848
|
+
# "interestAmount": "0.1",
|
3849
|
+
# "dayRatio": "0.001"
|
3850
|
+
# }
|
3851
|
+
#
|
3852
|
+
timestampId = self.safe_string_2(info, 'createdAt', 'timestamp')
|
3853
|
+
timestamp = self.parse_to_int(timestampId[0:13])
|
3793
3854
|
currencyId = self.safe_string(info, 'currency')
|
3794
3855
|
return {
|
3795
3856
|
'currency': self.safe_currency_code(currencyId, currency),
|
3796
|
-
'rate': self.
|
3857
|
+
'rate': self.safe_number_2(info, 'dailyIntRate', 'dayRatio'),
|
3797
3858
|
'period': 86400000,
|
3798
3859
|
'timestamp': timestamp,
|
3799
3860
|
'datetime': self.iso8601(timestamp),
|
@@ -3969,6 +4030,132 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3969
4030
|
'info': info,
|
3970
4031
|
}
|
3971
4032
|
|
4033
|
+
async def fetch_borrow_rate_histories(self, codes=None, since: Int = None, limit: Int = None, params={}):
|
4034
|
+
"""
|
4035
|
+
retrieves a history of a multiple currencies borrow interest rate at specific time slots, returns all currencies if no symbols passed, default is None
|
4036
|
+
:see: https://www.kucoin.com/docs/rest/margin-trading/margin-trading-v3-/get-cross-isolated-margin-interest-records
|
4037
|
+
:param str[]|None codes: list of unified currency codes, default is None
|
4038
|
+
:param int [since]: timestamp in ms of the earliest borrowRate, default is None
|
4039
|
+
:param int [limit]: max number of borrow rate prices to return, default is None
|
4040
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
4041
|
+
:param str [params.marginMode]: 'cross' or 'isolated' default is 'cross'
|
4042
|
+
:param int [params.until]: the latest time in ms to fetch entries for
|
4043
|
+
:returns dict: a dictionary of `borrow rate structures <https://docs.ccxt.com/#/?id=borrow-rate-structure>` indexed by the market symbol
|
4044
|
+
"""
|
4045
|
+
await self.load_markets()
|
4046
|
+
marginResult = self.handle_margin_mode_and_params('fetchBorrowRateHistories', params)
|
4047
|
+
marginMode = self.safe_string(marginResult, 0, 'cross')
|
4048
|
+
isIsolated = (marginMode == 'isolated') # True-isolated, False-cross
|
4049
|
+
request = {
|
4050
|
+
'isIsolated': isIsolated,
|
4051
|
+
}
|
4052
|
+
if since is not None:
|
4053
|
+
request['startTime'] = since
|
4054
|
+
request, params = self.handle_until_option('endTime', request, params)
|
4055
|
+
if limit is not None:
|
4056
|
+
request['pageSize'] = limit # default:50, min:10, max:500
|
4057
|
+
response = await self.privateGetMarginInterest(self.extend(request, params))
|
4058
|
+
#
|
4059
|
+
# {
|
4060
|
+
# "code": "200000",
|
4061
|
+
# "data": {
|
4062
|
+
# "timestamp": 1710829939673,
|
4063
|
+
# "currentPage": 1,
|
4064
|
+
# "pageSize": 50,
|
4065
|
+
# "totalNum": 0,
|
4066
|
+
# "totalPage": 0,
|
4067
|
+
# "items": [
|
4068
|
+
# {
|
4069
|
+
# "createdAt": 1697783812257,
|
4070
|
+
# "currency": "XMR",
|
4071
|
+
# "interestAmount": "0.1",
|
4072
|
+
# "dayRatio": "0.001"
|
4073
|
+
# }
|
4074
|
+
# ]
|
4075
|
+
# }
|
4076
|
+
# }
|
4077
|
+
#
|
4078
|
+
data = self.safe_dict(response, 'data')
|
4079
|
+
rows = self.safe_list(data, 'items')
|
4080
|
+
return self.parse_borrow_rate_histories(rows, codes, since, limit)
|
4081
|
+
|
4082
|
+
async def fetch_borrow_rate_history(self, code: str, since: Int = None, limit: Int = None, params={}):
|
4083
|
+
"""
|
4084
|
+
retrieves a history of a currencies borrow interest rate at specific time slots
|
4085
|
+
:see: https://www.kucoin.com/docs/rest/margin-trading/margin-trading-v3-/get-cross-isolated-margin-interest-records
|
4086
|
+
:param str code: unified currency code
|
4087
|
+
:param int [since]: timestamp for the earliest borrow rate
|
4088
|
+
:param int [limit]: the maximum number of `borrow rate structures <https://docs.ccxt.com/#/?id=borrow-rate-structure>` to retrieve
|
4089
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
4090
|
+
:param str [params.marginMode]: 'cross' or 'isolated' default is 'cross'
|
4091
|
+
:param int [params.until]: the latest time in ms to fetch entries for
|
4092
|
+
:returns dict[]: an array of `borrow rate structures <https://docs.ccxt.com/#/?id=borrow-rate-structure>`
|
4093
|
+
"""
|
4094
|
+
await self.load_markets()
|
4095
|
+
marginResult = self.handle_margin_mode_and_params('fetchBorrowRateHistories', params)
|
4096
|
+
marginMode = self.safe_string(marginResult, 0, 'cross')
|
4097
|
+
isIsolated = (marginMode == 'isolated') # True-isolated, False-cross
|
4098
|
+
currency = self.currency(code)
|
4099
|
+
request = {
|
4100
|
+
'isIsolated': isIsolated,
|
4101
|
+
'currency': currency['id'],
|
4102
|
+
}
|
4103
|
+
if since is not None:
|
4104
|
+
request['startTime'] = since
|
4105
|
+
request, params = self.handle_until_option('endTime', request, params)
|
4106
|
+
if limit is not None:
|
4107
|
+
request['pageSize'] = limit # default:50, min:10, max:500
|
4108
|
+
response = await self.privateGetMarginInterest(self.extend(request, params))
|
4109
|
+
#
|
4110
|
+
# {
|
4111
|
+
# "code": "200000",
|
4112
|
+
# "data": {
|
4113
|
+
# "timestamp": 1710829939673,
|
4114
|
+
# "currentPage": 1,
|
4115
|
+
# "pageSize": 50,
|
4116
|
+
# "totalNum": 0,
|
4117
|
+
# "totalPage": 0,
|
4118
|
+
# "items": [
|
4119
|
+
# {
|
4120
|
+
# "createdAt": 1697783812257,
|
4121
|
+
# "currency": "XMR",
|
4122
|
+
# "interestAmount": "0.1",
|
4123
|
+
# "dayRatio": "0.001"
|
4124
|
+
# }
|
4125
|
+
# ]
|
4126
|
+
# }
|
4127
|
+
# }
|
4128
|
+
#
|
4129
|
+
data = self.safe_dict(response, 'data')
|
4130
|
+
rows = self.safe_list(data, 'items')
|
4131
|
+
return self.parse_borrow_rate_history(rows, code, since, limit)
|
4132
|
+
|
4133
|
+
def parse_borrow_rate_histories(self, response, codes, since, limit):
|
4134
|
+
#
|
4135
|
+
# [
|
4136
|
+
# {
|
4137
|
+
# "createdAt": 1697783812257,
|
4138
|
+
# "currency": "XMR",
|
4139
|
+
# "interestAmount": "0.1",
|
4140
|
+
# "dayRatio": "0.001"
|
4141
|
+
# }
|
4142
|
+
# ]
|
4143
|
+
#
|
4144
|
+
borrowRateHistories = {}
|
4145
|
+
for i in range(0, len(response)):
|
4146
|
+
item = response[i]
|
4147
|
+
code = self.safe_currency_code(self.safe_string(item, 'currency'))
|
4148
|
+
if codes is None or self.in_array(code, codes):
|
4149
|
+
if not (code in borrowRateHistories):
|
4150
|
+
borrowRateHistories[code] = []
|
4151
|
+
borrowRateStructure = self.parse_borrow_rate(item)
|
4152
|
+
borrowRateHistories[code].append(borrowRateStructure)
|
4153
|
+
keys = list(borrowRateHistories.keys())
|
4154
|
+
for i in range(0, len(keys)):
|
4155
|
+
code = keys[i]
|
4156
|
+
borrowRateHistories[code] = self.filter_by_currency_since_limit(borrowRateHistories[code], code, since, limit)
|
4157
|
+
return borrowRateHistories
|
4158
|
+
|
3972
4159
|
async def borrow_cross_margin(self, code: str, amount: float, params={}):
|
3973
4160
|
"""
|
3974
4161
|
create a loan to borrow margin
|
ccxt/async_support/okcoin.py
CHANGED
@@ -266,6 +266,16 @@ class okcoin(Exchange, ImplicitAPI):
|
|
266
266
|
'50026': ExchangeNotAvailable, # System error, please try again later.
|
267
267
|
'50027': PermissionDenied, # The account is restricted from trading
|
268
268
|
'50028': ExchangeError, # Unable to take the order, please reach out to support center for details
|
269
|
+
'50029': ExchangeError, # This instrument({0}) is unavailable at present due to risk management. Please contact customer service for help.
|
270
|
+
'50030': PermissionDenied, # No permission to use self API
|
271
|
+
'50032': AccountSuspended, # This asset is blocked, allow its trading and try again
|
272
|
+
'50033': AccountSuspended, # This instrument is blocked, allow its trading and try again
|
273
|
+
'50035': BadRequest, # This endpoint requires that APIKey must be bound to IP
|
274
|
+
'50036': BadRequest, # Invalid expTime
|
275
|
+
'50037': BadRequest, # Order expired
|
276
|
+
'50038': ExchangeError, # This feature is temporarily unavailable in demo trading
|
277
|
+
'50039': ExchangeError, # The before parameter is not available for implementing timestamp pagination
|
278
|
+
'50041': ExchangeError, # You are not currently on the whitelist, please contact customer service
|
269
279
|
'50044': BadRequest, # Must select one broker type
|
270
280
|
# API Class
|
271
281
|
'50100': ExchangeError, # API frozen, please contact customer service
|
@@ -309,9 +319,25 @@ class okcoin(Exchange, ImplicitAPI):
|
|
309
319
|
'51024': AccountSuspended, # Unified accountblocked
|
310
320
|
'51025': ExchangeError, # Order count exceeds the limit
|
311
321
|
'51026': BadSymbol, # Instrument type does not match underlying index
|
322
|
+
'51030': InvalidOrder, # Funding fee is being settled.
|
323
|
+
'51031': InvalidOrder, # This order price is not within the closing price range
|
324
|
+
'51032': InvalidOrder, # Closing all positions at market price.
|
325
|
+
'51033': InvalidOrder, # The total amount per order for self pair has reached the upper limit.
|
326
|
+
'51037': InvalidOrder, # The current account risk status only supports you to place IOC orders that can reduce the risk of your account.
|
327
|
+
'51038': InvalidOrder, # There is already an IOC order under the current risk module that reduces the risk of the account.
|
328
|
+
'51044': InvalidOrder, # The order type {0}, {1} is not allowed to set stop loss and take profit
|
312
329
|
'51046': InvalidOrder, # The take profit trigger price must be higher than the order price
|
313
330
|
'51047': InvalidOrder, # The stop loss trigger price must be lower than the order price
|
314
|
-
'
|
331
|
+
'51048': InvalidOrder, # The take profit trigger price should be lower than the order price
|
332
|
+
'51049': InvalidOrder, # The stop loss trigger price should be higher than the order price
|
333
|
+
'51050': InvalidOrder, # The take profit trigger price should be higher than the best ask price
|
334
|
+
'51051': InvalidOrder, # The stop loss trigger price should be lower than the best ask price
|
335
|
+
'51052': InvalidOrder, # The take profit trigger price should be lower than the best bid price
|
336
|
+
'51053': InvalidOrder, # The stop loss trigger price should be higher than the best bid price
|
337
|
+
'51054': BadRequest, # Getting information timed out, please try again later
|
338
|
+
'51056': InvalidOrder, # Action not allowed
|
339
|
+
'51058': InvalidOrder, # No available position for self algo order
|
340
|
+
'51059': InvalidOrder, # Strategy for the current state does not support self operation
|
315
341
|
'51100': InvalidOrder, # Trading amount does not meet the min tradable amount
|
316
342
|
'51102': InvalidOrder, # Entered amount exceeds the max pending count
|
317
343
|
'51103': InvalidOrder, # Entered amount exceeds the max pending order count of the underlying asset
|
ccxt/async_support/okx.py
CHANGED
@@ -7,7 +7,7 @@ from ccxt.async_support.base.exchange import Exchange
|
|
7
7
|
from ccxt.abstract.okx import ImplicitAPI
|
8
8
|
import asyncio
|
9
9
|
import hashlib
|
10
|
-
from ccxt.base.types import Account, Balances, Currency, Greeks, Int, Leverage, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry
|
10
|
+
from ccxt.base.types import Account, Balances, Currency, Greeks, Int, Leverage, Market, MarketInterface, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry
|
11
11
|
from typing import List
|
12
12
|
from ccxt.base.errors import ExchangeError
|
13
13
|
from ccxt.base.errors import PermissionDenied
|
@@ -596,6 +596,7 @@ class okx(Exchange, ImplicitAPI):
|
|
596
596
|
'50027': PermissionDenied, # The account is restricted from trading
|
597
597
|
'50028': ExchangeError, # Unable to take the order, please reach out to support center for details
|
598
598
|
'50044': BadRequest, # Must select one broker type
|
599
|
+
'50061': ExchangeError, # You've reached the maximum order rate limit for self account.
|
599
600
|
'50062': ExchangeError, # This feature is currently unavailable.
|
600
601
|
# API Class
|
601
602
|
'50100': ExchangeError, # API frozen, please contact customer service
|
@@ -783,6 +784,15 @@ class okx(Exchange, ImplicitAPI):
|
|
783
784
|
# SPOT/MARGIN error codes 54000-54999
|
784
785
|
'54000': ExchangeError, # Margin transactions unavailable
|
785
786
|
'54001': ExchangeError, # Only Multi-currency margin account can be set to borrow coins automatically
|
787
|
+
# Trading bot Error Code from 55100 to 55999
|
788
|
+
'55100': InvalidOrder, # Take profit % should be within the range of {parameter1}-{parameter2}
|
789
|
+
'55101': InvalidOrder, # Stop loss % should be within the range of {parameter1}-{parameter2}
|
790
|
+
'55102': InvalidOrder, # Take profit % should be greater than the current bot’s PnL%
|
791
|
+
'55103': InvalidOrder, # Stop loss % should be less than the current bot’s PnL%
|
792
|
+
'55104': InvalidOrder, # Only futures grid supports take profit or stop loss based on profit percentage
|
793
|
+
'55111': InvalidOrder, # This signal name is in use, please try a new name
|
794
|
+
'55112': InvalidOrder, # This signal does not exist
|
795
|
+
'55113': InvalidOrder, # Create signal strategies with leverage greater than the maximum leverage of the instruments
|
786
796
|
# FUNDING error codes 58000-58999
|
787
797
|
'58000': ExchangeError, # Account type {0} does not supported when getting the sub-account balance
|
788
798
|
'58001': AuthenticationError, # Incorrect trade password
|
@@ -1196,7 +1206,7 @@ class okx(Exchange, ImplicitAPI):
|
|
1196
1206
|
'info': None,
|
1197
1207
|
}
|
1198
1208
|
|
1199
|
-
def safe_market(self, marketId=None, market=None, delimiter=None, marketType=None):
|
1209
|
+
def safe_market(self, marketId: Str = None, market: Market = None, delimiter: Str = None, marketType: Str = None) -> MarketInterface:
|
1200
1210
|
isOption = (marketId is not None) and ((marketId.find('-C') > -1) or (marketId.find('-P') > -1))
|
1201
1211
|
if isOption and not (marketId in self.markets_by_id):
|
1202
1212
|
# handle expired option contracts
|
@@ -4700,6 +4710,14 @@ class okx(Exchange, ImplicitAPI):
|
|
4700
4710
|
'3': 'pending',
|
4701
4711
|
'4': 'pending',
|
4702
4712
|
'5': 'pending',
|
4713
|
+
'6': 'pending',
|
4714
|
+
'7': 'pending',
|
4715
|
+
'8': 'pending',
|
4716
|
+
'9': 'pending',
|
4717
|
+
'10': 'pending',
|
4718
|
+
'12': 'pending',
|
4719
|
+
'15': 'pending',
|
4720
|
+
'16': 'pending',
|
4703
4721
|
}
|
4704
4722
|
return self.safe_string(statuses, status, status)
|
4705
4723
|
|
ccxt/async_support/woo.py
CHANGED
@@ -65,7 +65,7 @@ class woo(Exchange, ImplicitAPI):
|
|
65
65
|
'fetchBalance': True,
|
66
66
|
'fetchCanceledOrders': False,
|
67
67
|
'fetchClosedOrder': False,
|
68
|
-
'fetchClosedOrders':
|
68
|
+
'fetchClosedOrders': True,
|
69
69
|
'fetchCurrencies': True,
|
70
70
|
'fetchDepositAddress': True,
|
71
71
|
'fetchDeposits': True,
|
@@ -84,7 +84,7 @@ class woo(Exchange, ImplicitAPI):
|
|
84
84
|
'fetchOHLCV': True,
|
85
85
|
'fetchOpenInterestHistory': False,
|
86
86
|
'fetchOpenOrder': False,
|
87
|
-
'fetchOpenOrders':
|
87
|
+
'fetchOpenOrders': True,
|
88
88
|
'fetchOrder': True,
|
89
89
|
'fetchOrderBook': True,
|
90
90
|
'fetchOrders': True,
|
@@ -1274,9 +1274,14 @@ class woo(Exchange, ImplicitAPI):
|
|
1274
1274
|
:param boolean [params.isTriggered]: whether the order has been triggered(False by default)
|
1275
1275
|
:param str [params.side]: 'buy' or 'sell'
|
1276
1276
|
:param boolean [params.trailing]: set to True if you want to fetch trailing orders
|
1277
|
+
:param boolean [params.paginate]: set to True if you want to fetch orders with pagination
|
1277
1278
|
:returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
1278
1279
|
"""
|
1279
1280
|
await self.load_markets()
|
1281
|
+
paginate = False
|
1282
|
+
paginate, params = self.handle_option_and_params(params, 'fetchOrders', 'paginate')
|
1283
|
+
if paginate:
|
1284
|
+
return await self.fetch_paginated_call_incremental('fetchOrders', symbol, since, limit, params, 'page', 500)
|
1280
1285
|
request = {}
|
1281
1286
|
market: Market = None
|
1282
1287
|
stop = self.safe_bool_2(params, 'stop', 'trigger')
|
@@ -1290,6 +1295,10 @@ class woo(Exchange, ImplicitAPI):
|
|
1290
1295
|
request['createdTimeStart'] = since
|
1291
1296
|
else:
|
1292
1297
|
request['start_t'] = since
|
1298
|
+
if limit is not None:
|
1299
|
+
request['size'] = limit
|
1300
|
+
else:
|
1301
|
+
request['size'] = 500
|
1293
1302
|
if stop:
|
1294
1303
|
request['algoType'] = 'stop'
|
1295
1304
|
elif trailing:
|
@@ -1332,7 +1341,47 @@ class woo(Exchange, ImplicitAPI):
|
|
1332
1341
|
#
|
1333
1342
|
data = self.safe_value(response, 'data', response)
|
1334
1343
|
orders = self.safe_list(data, 'rows')
|
1335
|
-
return self.parse_orders(orders, market, since, limit
|
1344
|
+
return self.parse_orders(orders, market, since, limit)
|
1345
|
+
|
1346
|
+
async def fetch_open_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
1347
|
+
"""
|
1348
|
+
fetches information on multiple orders made by the user
|
1349
|
+
:see: https://docs.woo.org/#get-orders
|
1350
|
+
:see: https://docs.woo.org/#get-algo-orders
|
1351
|
+
:param str symbol: unified market symbol of the market orders were made in
|
1352
|
+
:param int [since]: the earliest time in ms to fetch orders for
|
1353
|
+
:param int [limit]: the maximum number of order structures to retrieve
|
1354
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1355
|
+
:param boolean [params.stop]: whether the order is a stop/algo order
|
1356
|
+
:param boolean [params.isTriggered]: whether the order has been triggered(False by default)
|
1357
|
+
:param str [params.side]: 'buy' or 'sell'
|
1358
|
+
:param boolean [params.trailing]: set to True if you want to fetch trailing orders
|
1359
|
+
:param boolean [params.paginate]: set to True if you want to fetch orders with pagination
|
1360
|
+
:returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
1361
|
+
"""
|
1362
|
+
await self.load_markets()
|
1363
|
+
extendedParams = self.extend(params, {'status': 'INCOMPLETE'})
|
1364
|
+
return await self.fetch_orders(symbol, since, limit, extendedParams)
|
1365
|
+
|
1366
|
+
async def fetch_closed_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
1367
|
+
"""
|
1368
|
+
fetches information on multiple orders made by the user
|
1369
|
+
:see: https://docs.woo.org/#get-orders
|
1370
|
+
:see: https://docs.woo.org/#get-algo-orders
|
1371
|
+
:param str symbol: unified market symbol of the market orders were made in
|
1372
|
+
:param int [since]: the earliest time in ms to fetch orders for
|
1373
|
+
:param int [limit]: the maximum number of order structures to retrieve
|
1374
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1375
|
+
:param boolean [params.stop]: whether the order is a stop/algo order
|
1376
|
+
:param boolean [params.isTriggered]: whether the order has been triggered(False by default)
|
1377
|
+
:param str [params.side]: 'buy' or 'sell'
|
1378
|
+
:param boolean [params.trailing]: set to True if you want to fetch trailing orders
|
1379
|
+
:param boolean [params.paginate]: set to True if you want to fetch orders with pagination
|
1380
|
+
:returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
1381
|
+
"""
|
1382
|
+
await self.load_markets()
|
1383
|
+
extendedParams = self.extend(params, {'status': 'COMPLETED'})
|
1384
|
+
return await self.fetch_orders(symbol, since, limit, extendedParams)
|
1336
1385
|
|
1337
1386
|
def parse_time_in_force(self, timeInForce):
|
1338
1387
|
timeInForces = {
|
@@ -1633,14 +1682,20 @@ class woo(Exchange, ImplicitAPI):
|
|
1633
1682
|
|
1634
1683
|
async def fetch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
|
1635
1684
|
"""
|
1685
|
+
:see: https://docs.woo.org/#get-trades
|
1636
1686
|
fetch all trades made by the user
|
1637
1687
|
:param str symbol: unified market symbol
|
1638
1688
|
:param int [since]: the earliest time in ms to fetch trades for
|
1639
1689
|
:param int [limit]: the maximum number of trades structures to retrieve
|
1640
1690
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1691
|
+
:param boolean [params.paginate]: set to True if you want to fetch trades with pagination
|
1641
1692
|
:returns Trade[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
|
1642
1693
|
"""
|
1643
1694
|
await self.load_markets()
|
1695
|
+
paginate = False
|
1696
|
+
paginate, params = self.handle_option_and_params(params, 'fetchMyTrades', 'paginate')
|
1697
|
+
if paginate:
|
1698
|
+
return await self.fetch_paginated_call_incremental('fetchMyTrades', symbol, since, limit, params, 'page', 500)
|
1644
1699
|
request = {}
|
1645
1700
|
market: Market = None
|
1646
1701
|
if symbol is not None:
|
@@ -1648,6 +1703,10 @@ class woo(Exchange, ImplicitAPI):
|
|
1648
1703
|
request['symbol'] = market['id']
|
1649
1704
|
if since is not None:
|
1650
1705
|
request['start_t'] = since
|
1706
|
+
if limit is not None:
|
1707
|
+
request['size'] = limit
|
1708
|
+
else:
|
1709
|
+
request['size'] = 500
|
1651
1710
|
response = await self.v1PrivateGetClientTrades(self.extend(request, params))
|
1652
1711
|
# {
|
1653
1712
|
# "success": True,
|
ccxt/base/exchange.py
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
|
5
5
|
# -----------------------------------------------------------------------------
|
6
6
|
|
7
|
-
__version__ = '4.2.
|
7
|
+
__version__ = '4.2.78'
|
8
8
|
|
9
9
|
# -----------------------------------------------------------------------------
|
10
10
|
|
@@ -2287,7 +2287,7 @@ class Exchange(object):
|
|
2287
2287
|
return float(stringVersion)
|
2288
2288
|
return int(stringVersion)
|
2289
2289
|
|
2290
|
-
def is_round_number(self, value):
|
2290
|
+
def is_round_number(self, value: float):
|
2291
2291
|
# self method is similar to isInteger, but self is more loyal and does not check for types.
|
2292
2292
|
# i.e. isRoundNumber(1.000) returns True, while isInteger(1.000) returns False
|
2293
2293
|
res = self.parse_to_numeric((value % 1))
|
@@ -3109,7 +3109,7 @@ class Exchange(object):
|
|
3109
3109
|
def watch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}):
|
3110
3110
|
raise NotSupported(self.id + ' watchOHLCV() is not supported yet')
|
3111
3111
|
|
3112
|
-
def convert_trading_view_to_ohlcv(self, ohlcvs, timestamp='t', open='o', high='h', low='l', close='c', volume='v', ms=False):
|
3112
|
+
def convert_trading_view_to_ohlcv(self, ohlcvs: List[List[float]], timestamp='t', open='o', high='h', low='l', close='c', volume='v', ms=False):
|
3113
3113
|
result = []
|
3114
3114
|
timestamps = self.safe_list(ohlcvs, timestamp, [])
|
3115
3115
|
opens = self.safe_list(ohlcvs, open, [])
|
@@ -3128,7 +3128,7 @@ class Exchange(object):
|
|
3128
3128
|
])
|
3129
3129
|
return result
|
3130
3130
|
|
3131
|
-
def convert_ohlcv_to_trading_view(self, ohlcvs, timestamp='t', open='o', high='h', low='l', close='c', volume='v', ms=False):
|
3131
|
+
def convert_ohlcv_to_trading_view(self, ohlcvs: List[List[float]], timestamp='t', open='o', high='h', low='l', close='c', volume='v', ms=False):
|
3132
3132
|
result = {}
|
3133
3133
|
result[timestamp] = []
|
3134
3134
|
result[open] = []
|
@@ -3779,6 +3779,11 @@ class Exchange(object):
|
|
3779
3779
|
return result
|
3780
3780
|
|
3781
3781
|
def check_required_credentials(self, error=True):
|
3782
|
+
"""
|
3783
|
+
* @ignore
|
3784
|
+
:param boolean error: raise an error that a credential is required if True
|
3785
|
+
:returns boolean: True if all required credentials have been set, otherwise False or an error is thrown is param error=true
|
3786
|
+
"""
|
3782
3787
|
keys = list(self.requiredCredentials.keys())
|
3783
3788
|
for i in range(0, len(keys)):
|
3784
3789
|
key = keys[i]
|