ccxt 4.4.25__py2.py3-none-any.whl → 4.4.27__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 (123) hide show
  1. ccxt/__init__.py +1 -1
  2. ccxt/abstract/alpaca.py +3 -0
  3. ccxt/abstract/bingx.py +1 -0
  4. ccxt/abstract/hyperliquid.py +1 -1
  5. ccxt/abstract/okx.py +1 -0
  6. ccxt/abstract/phemex.py +1 -0
  7. ccxt/ace.py +1 -1
  8. ccxt/alpaca.py +426 -17
  9. ccxt/ascendex.py +1 -1
  10. ccxt/async_support/__init__.py +1 -1
  11. ccxt/async_support/ace.py +1 -1
  12. ccxt/async_support/alpaca.py +426 -17
  13. ccxt/async_support/ascendex.py +1 -1
  14. ccxt/async_support/base/exchange.py +24 -6
  15. ccxt/async_support/bequant.py +1 -1
  16. ccxt/async_support/bigone.py +1 -1
  17. ccxt/async_support/binance.py +6 -7
  18. ccxt/async_support/binancecoinm.py +1 -1
  19. ccxt/async_support/binanceus.py +1 -1
  20. ccxt/async_support/binanceusdm.py +1 -1
  21. ccxt/async_support/bingx.py +29 -29
  22. ccxt/async_support/bit2c.py +1 -1
  23. ccxt/async_support/bitbank.py +1 -1
  24. ccxt/async_support/bitbns.py +1 -1
  25. ccxt/async_support/bitfinex.py +1 -1
  26. ccxt/async_support/bitfinex2.py +1 -1
  27. ccxt/async_support/bitflyer.py +1 -1
  28. ccxt/async_support/bitget.py +6 -6
  29. ccxt/async_support/bithumb.py +1 -1
  30. ccxt/async_support/bitmart.py +7 -7
  31. ccxt/async_support/bitmex.py +1 -1
  32. ccxt/async_support/bitopro.py +1 -1
  33. ccxt/async_support/bitrue.py +1 -1
  34. ccxt/async_support/bitso.py +1 -1
  35. ccxt/async_support/bitstamp.py +1 -1
  36. ccxt/async_support/bitteam.py +1 -1
  37. ccxt/async_support/bitvavo.py +1 -1
  38. ccxt/async_support/bl3p.py +1 -1
  39. ccxt/async_support/blockchaincom.py +1 -1
  40. ccxt/async_support/blofin.py +1 -1
  41. ccxt/async_support/btcalpha.py +1 -1
  42. ccxt/async_support/btcbox.py +1 -1
  43. ccxt/async_support/btcmarkets.py +1 -1
  44. ccxt/async_support/btcturk.py +1 -1
  45. ccxt/async_support/bybit.py +10 -16
  46. ccxt/async_support/cex.py +36 -0
  47. ccxt/async_support/coinbase.py +89 -11
  48. ccxt/async_support/coinex.py +6 -8
  49. ccxt/async_support/digifinex.py +5 -5
  50. ccxt/async_support/exmo.py +1 -0
  51. ccxt/async_support/gate.py +26 -22
  52. ccxt/async_support/htx.py +5 -6
  53. ccxt/async_support/hyperliquid.py +31 -5
  54. ccxt/async_support/kucoin.py +5 -5
  55. ccxt/async_support/lbank.py +97 -2
  56. ccxt/async_support/okx.py +6 -5
  57. ccxt/async_support/phemex.py +4 -2
  58. ccxt/async_support/wavesexchange.py +13 -2
  59. ccxt/async_support/whitebit.py +5 -5
  60. ccxt/async_support/woo.py +1 -1
  61. ccxt/async_support/xt.py +32 -24
  62. ccxt/base/exchange.py +29 -6
  63. ccxt/base/types.py +12 -0
  64. ccxt/bequant.py +1 -1
  65. ccxt/bigone.py +1 -1
  66. ccxt/binance.py +6 -7
  67. ccxt/binancecoinm.py +1 -1
  68. ccxt/binanceus.py +1 -1
  69. ccxt/binanceusdm.py +1 -1
  70. ccxt/bingx.py +29 -29
  71. ccxt/bit2c.py +1 -1
  72. ccxt/bitbank.py +1 -1
  73. ccxt/bitbns.py +1 -1
  74. ccxt/bitfinex.py +1 -1
  75. ccxt/bitfinex2.py +1 -1
  76. ccxt/bitflyer.py +1 -1
  77. ccxt/bitget.py +6 -6
  78. ccxt/bithumb.py +1 -1
  79. ccxt/bitmart.py +7 -7
  80. ccxt/bitmex.py +1 -1
  81. ccxt/bitopro.py +1 -1
  82. ccxt/bitrue.py +1 -1
  83. ccxt/bitso.py +1 -1
  84. ccxt/bitstamp.py +1 -1
  85. ccxt/bitteam.py +1 -1
  86. ccxt/bitvavo.py +1 -1
  87. ccxt/bl3p.py +1 -1
  88. ccxt/blockchaincom.py +1 -1
  89. ccxt/blofin.py +1 -1
  90. ccxt/btcalpha.py +1 -1
  91. ccxt/btcbox.py +1 -1
  92. ccxt/btcmarkets.py +1 -1
  93. ccxt/btcturk.py +1 -1
  94. ccxt/bybit.py +10 -16
  95. ccxt/cex.py +36 -0
  96. ccxt/coinbase.py +89 -11
  97. ccxt/coinex.py +6 -8
  98. ccxt/digifinex.py +5 -5
  99. ccxt/exmo.py +1 -0
  100. ccxt/gate.py +26 -22
  101. ccxt/htx.py +5 -6
  102. ccxt/hyperliquid.py +31 -5
  103. ccxt/kucoin.py +5 -5
  104. ccxt/lbank.py +97 -2
  105. ccxt/okx.py +6 -5
  106. ccxt/phemex.py +4 -2
  107. ccxt/pro/__init__.py +1 -1
  108. ccxt/pro/binance.py +2 -2
  109. ccxt/pro/bybit.py +1 -1
  110. ccxt/pro/exmo.py +204 -4
  111. ccxt/pro/lbank.py +7 -4
  112. ccxt/pro/okx.py +1 -1
  113. ccxt/test/tests_helpers.py +3 -1
  114. ccxt/wavesexchange.py +13 -2
  115. ccxt/whitebit.py +5 -5
  116. ccxt/woo.py +1 -1
  117. ccxt/xt.py +32 -24
  118. ccxt-4.4.27.dist-info/METADATA +637 -0
  119. {ccxt-4.4.25.dist-info → ccxt-4.4.27.dist-info}/RECORD +122 -122
  120. ccxt-4.4.25.dist-info/METADATA +0 -636
  121. {ccxt-4.4.25.dist-info → ccxt-4.4.27.dist-info}/LICENSE.txt +0 -0
  122. {ccxt-4.4.25.dist-info → ccxt-4.4.27.dist-info}/WHEEL +0 -0
  123. {ccxt-4.4.25.dist-info → ccxt-4.4.27.dist-info}/top_level.txt +0 -0
ccxt/kucoin.py CHANGED
@@ -8,7 +8,7 @@ from ccxt.abstract.kucoin import ImplicitAPI
8
8
  import hashlib
9
9
  import math
10
10
  import json
11
- from ccxt.base.types import Account, Balances, Bool, Currencies, Currency, DepositAddress, Int, LedgerEntry, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, Transaction, TransferEntry
11
+ from ccxt.base.types import Account, Balances, BorrowInterest, Bool, Currencies, Currency, DepositAddress, Int, LedgerEntry, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, Transaction, TransferEntry
12
12
  from typing import List
13
13
  from ccxt.base.errors import ExchangeError
14
14
  from ccxt.base.errors import AuthenticationError
@@ -4153,7 +4153,7 @@ class kucoin(Exchange, ImplicitAPI):
4153
4153
  'info': info,
4154
4154
  }
4155
4155
 
4156
- def fetch_borrow_interest(self, code: Str = None, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
4156
+ def fetch_borrow_interest(self, code: Str = None, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[BorrowInterest]:
4157
4157
  """
4158
4158
  fetch the interest owed by the user for borrowing currency for margin trading
4159
4159
  :see: https://docs.kucoin.com/#get-repay-record
@@ -4248,7 +4248,7 @@ class kucoin(Exchange, ImplicitAPI):
4248
4248
  assets = self.safe_list(data, 'assets', []) if (marginMode == 'isolated') else self.safe_list(data, 'accounts', [])
4249
4249
  return self.parse_borrow_interests(assets, None)
4250
4250
 
4251
- def parse_borrow_interest(self, info: dict, market: Market = None):
4251
+ def parse_borrow_interest(self, info: dict, market: Market = None) -> BorrowInterest:
4252
4252
  #
4253
4253
  # Cross
4254
4254
  #
@@ -4311,15 +4311,15 @@ class kucoin(Exchange, ImplicitAPI):
4311
4311
  interest = self.safe_number(info, 'accruedInterest')
4312
4312
  currencyId = self.safe_string(info, 'currency')
4313
4313
  return {
4314
+ 'info': info,
4314
4315
  'symbol': symbol,
4315
- 'marginMode': marginMode,
4316
4316
  'currency': self.safe_currency_code(currencyId),
4317
4317
  'interest': interest,
4318
4318
  'interestRate': self.safe_number(info, 'dailyIntRate'),
4319
4319
  'amountBorrowed': amountBorrowed,
4320
+ 'marginMode': marginMode,
4320
4321
  'timestamp': timestamp, # create time
4321
4322
  'datetime': self.iso8601(timestamp),
4322
- 'info': info,
4323
4323
  }
4324
4324
 
4325
4325
  def fetch_borrow_rate_histories(self, codes=None, since: Int = None, limit: Int = None, params={}):
ccxt/lbank.py CHANGED
@@ -6,7 +6,7 @@
6
6
  from ccxt.base.exchange import Exchange
7
7
  from ccxt.abstract.lbank import ImplicitAPI
8
8
  import hashlib
9
- from ccxt.base.types import Balances, Currency, DepositAddress, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, TradingFees, Transaction
9
+ from ccxt.base.types import Balances, Currency, DepositAddress, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, FundingRate, FundingRates, Trade, TradingFeeInterface, TradingFees, Transaction
10
10
  from typing import List
11
11
  from ccxt.base.errors import ExchangeError
12
12
  from ccxt.base.errors import AuthenticationError
@@ -69,7 +69,7 @@ class lbank(Exchange, ImplicitAPI):
69
69
  'fetchFundingHistory': False,
70
70
  'fetchFundingRate': False,
71
71
  'fetchFundingRateHistory': False,
72
- 'fetchFundingRates': False,
72
+ 'fetchFundingRates': True,
73
73
  'fetchIndexOHLCV': False,
74
74
  'fetchIsolatedBorrowRate': False,
75
75
  'fetchIsolatedBorrowRates': False,
@@ -1132,6 +1132,101 @@ class lbank(Exchange, ImplicitAPI):
1132
1132
  return self.safe_balance(result)
1133
1133
  return None
1134
1134
 
1135
+ def parse_funding_rate(self, ticker, market: Market = None) -> FundingRate:
1136
+ # {
1137
+ # "symbol": "BTCUSDT",
1138
+ # "highestPrice": "69495.5",
1139
+ # "underlyingPrice": "68455.904",
1140
+ # "lowestPrice": "68182.1",
1141
+ # "openPrice": "68762.4",
1142
+ # "positionFeeRate": "0.0001",
1143
+ # "volume": "33534.2858",
1144
+ # "markedPrice": "68434.1",
1145
+ # "turnover": "1200636218.210558",
1146
+ # "positionFeeTime": "28800",
1147
+ # "lastPrice": "68427.3",
1148
+ # "nextFeeTime": "1730736000000",
1149
+ # "fundingRate": "0.0001",
1150
+ # }
1151
+ marketId = self.safe_string(ticker, 'symbol')
1152
+ symbol = self.safe_symbol(marketId, market)
1153
+ markPrice = self.safe_number(ticker, 'markedPrice')
1154
+ indexPrice = self.safe_number(ticker, 'underlyingPrice')
1155
+ fundingRate = self.safe_number(ticker, 'fundingRate')
1156
+ fundingTime = self.safe_integer(ticker, 'nextFeeTime')
1157
+ return {
1158
+ 'info': ticker,
1159
+ 'symbol': symbol,
1160
+ 'markPrice': markPrice,
1161
+ 'indexPrice': indexPrice,
1162
+ 'fundingRate': fundingRate,
1163
+ 'fundingTimestamp': fundingTime,
1164
+ 'fundingDatetime': self.iso8601(fundingTime),
1165
+ 'timestamp': None,
1166
+ 'datetime': None,
1167
+ 'nextFundingRate': None,
1168
+ 'nextFundingTimestamp': None,
1169
+ 'nextFundingDatetime': None,
1170
+ 'previousFundingRate': None,
1171
+ 'previousFundingTimestamp': None,
1172
+ 'previousFundingDatetime': None,
1173
+ 'interval': None,
1174
+ }
1175
+
1176
+ def fetch_funding_rate(self, symbol: str, params={}) -> FundingRate:
1177
+ """
1178
+ fetch the current funding rate
1179
+ :see: https://www.lbank.com/en-US/docs/contract.html#query-contract-market-list
1180
+ :param str symbol: unified market symbol
1181
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1182
+ :returns dict: a `funding rate structure <https://docs.ccxt.com/#/?id=funding-rate-structure>`
1183
+ """
1184
+ self.load_markets()
1185
+ market = self.market(symbol)
1186
+ responseForSwap = self.fetch_funding_rates([market['symbol']], params)
1187
+ return self.safe_value(responseForSwap, market['symbol'])
1188
+
1189
+ def fetch_funding_rates(self, symbols: Strings = None, params={}) -> FundingRates:
1190
+ """
1191
+ fetch the funding rate for multiple markets
1192
+ :see: https://www.lbank.com/en-US/docs/contract.html#query-contract-market-list
1193
+ :param str[]|None symbols: list of unified market symbols
1194
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1195
+ :returns dict: a dictionary of `funding rate structures <https://docs.ccxt.com/#/?id=funding-rates-structure>`, indexed by market symbols
1196
+ """
1197
+ self.load_markets()
1198
+ symbols = self.market_symbols(symbols)
1199
+ request: dict = {
1200
+ 'productGroup': 'SwapU',
1201
+ }
1202
+ response = self.contractPublicGetCfdOpenApiV1PubMarketData(self.extend(request, params))
1203
+ # {
1204
+ # "data": [
1205
+ # {
1206
+ # "symbol": "BTCUSDT",
1207
+ # "highestPrice": "69495.5",
1208
+ # "underlyingPrice": "68455.904",
1209
+ # "lowestPrice": "68182.1",
1210
+ # "openPrice": "68762.4",
1211
+ # "positionFeeRate": "0.0001",
1212
+ # "volume": "33534.2858",
1213
+ # "markedPrice": "68434.1",
1214
+ # "turnover": "1200636218.210558",
1215
+ # "positionFeeTime": "28800",
1216
+ # "lastPrice": "68427.3",
1217
+ # "nextFeeTime": "1730736000000",
1218
+ # "fundingRate": "0.0001",
1219
+ # }
1220
+ # ],
1221
+ # "error_code": "0",
1222
+ # "msg": "Success",
1223
+ # "result": "true",
1224
+ # "success": True,
1225
+ # }
1226
+ data = self.safe_list(response, 'data', [])
1227
+ result = self.parse_funding_rates(data)
1228
+ return self.filter_by_array(result, 'symbol', symbols)
1229
+
1135
1230
  def fetch_balance(self, params={}) -> Balances:
1136
1231
  """
1137
1232
  query for balance and get the amount of funds available for trading or funds locked in orders
ccxt/okx.py CHANGED
@@ -6,7 +6,7 @@
6
6
  from ccxt.base.exchange import Exchange
7
7
  from ccxt.abstract.okx import ImplicitAPI
8
8
  import hashlib
9
- from ccxt.base.types import Account, LongShortRatio, Balances, Conversion, CrossBorrowRate, CrossBorrowRates, Currencies, Currency, DepositAddress, Greeks, Int, LedgerEntry, Leverage, LeverageTier, MarginModification, Market, MarketInterface, Num, Option, OptionChain, Order, OrderBook, OrderRequest, CancellationRequest, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, FundingRate, Trade, TradingFeeInterface, Transaction, TransferEntry
9
+ from ccxt.base.types import Account, Balances, BorrowInterest, Conversion, CrossBorrowRate, CrossBorrowRates, Currencies, Currency, DepositAddress, Greeks, Int, LedgerEntry, Leverage, LeverageTier, LongShortRatio, MarginModification, Market, MarketInterface, Num, Option, OptionChain, Order, OrderBook, OrderRequest, CancellationRequest, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, FundingRate, Trade, TradingFeeInterface, Transaction, TransferEntry
10
10
  from typing import List
11
11
  from typing import Any
12
12
  from ccxt.base.errors import ExchangeError
@@ -421,6 +421,7 @@ class okx(Exchange, ImplicitAPI):
421
421
  # eth staking
422
422
  'finance/staking-defi/eth/balance': 5 / 3,
423
423
  'finance/staking-defi/eth/purchase-redeem-history': 5 / 3,
424
+ 'finance/staking-defi/eth/product-info': 3,
424
425
  # copytrading
425
426
  'copytrading/current-subpositions': 1,
426
427
  'copytrading/subpositions-history': 1,
@@ -6539,7 +6540,7 @@ class okx(Exchange, ImplicitAPI):
6539
6540
  })
6540
6541
  return tiers
6541
6542
 
6542
- def fetch_borrow_interest(self, code: Str = None, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
6543
+ def fetch_borrow_interest(self, code: Str = None, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[BorrowInterest]:
6543
6544
  """
6544
6545
  fetch the interest owed by the user for borrowing currency for margin trading
6545
6546
  :see: https://www.okx.com/docs-v5/en/#rest-api-account-get-interest-accrued-data
@@ -6595,21 +6596,21 @@ class okx(Exchange, ImplicitAPI):
6595
6596
  interest = self.parse_borrow_interests(data)
6596
6597
  return self.filter_by_currency_since_limit(interest, code, since, limit)
6597
6598
 
6598
- def parse_borrow_interest(self, info: dict, market: Market = None):
6599
+ def parse_borrow_interest(self, info: dict, market: Market = None) -> BorrowInterest:
6599
6600
  instId = self.safe_string(info, 'instId')
6600
6601
  if instId is not None:
6601
6602
  market = self.safe_market(instId, market)
6602
6603
  timestamp = self.safe_integer(info, 'ts')
6603
6604
  return {
6605
+ 'info': info,
6604
6606
  'symbol': self.safe_string(market, 'symbol'),
6605
- 'marginMode': self.safe_string(info, 'mgnMode'),
6606
6607
  'currency': self.safe_currency_code(self.safe_string(info, 'ccy')),
6607
6608
  'interest': self.safe_number(info, 'interest'),
6608
6609
  'interestRate': self.safe_number(info, 'interestRate'),
6609
6610
  'amountBorrowed': self.safe_number(info, 'liab'),
6611
+ 'marginMode': self.safe_string(info, 'mgnMode'),
6610
6612
  'timestamp': timestamp, # Interest accrued time
6611
6613
  'datetime': self.iso8601(timestamp),
6612
- 'info': info,
6613
6614
  }
6614
6615
 
6615
6616
  def borrow_cross_margin(self, code: str, amount: float, params={}):
ccxt/phemex.py CHANGED
@@ -121,7 +121,7 @@ class phemex(Exchange, ImplicitAPI):
121
121
  'private': 'https://{hostname}',
122
122
  },
123
123
  'www': 'https://phemex.com',
124
- 'doc': 'https://github.com/phemex/phemex-api-docs',
124
+ 'doc': 'https://phemex-docs.github.io/#overview',
125
125
  'fees': 'https://phemex.com/fees-conditions',
126
126
  'referral': {
127
127
  'url': 'https://phemex.com/register?referralCode=EDNVJ',
@@ -179,6 +179,7 @@ class phemex(Exchange, ImplicitAPI):
179
179
  'v2': {
180
180
  'get': {
181
181
  'public/products': 5,
182
+ 'public/products-plus': 5,
182
183
  'md/v2/orderbook': 5, # ?symbol=<symbol>&id=<id>
183
184
  'md/v2/trade': 5, # ?symbol=<symbol>&id=<id>
184
185
  'md/v2/ticker/24hr': 5, # ?symbol=<symbol>&id=<id>
@@ -746,13 +747,14 @@ class phemex(Exchange, ImplicitAPI):
746
747
  'max': self.parse_safe_number(self.safe_string(market, 'maxOrderValue')),
747
748
  },
748
749
  },
749
- 'created': None,
750
+ 'created': self.safe_integer(market, 'listTime'),
750
751
  'info': market,
751
752
  })
752
753
 
753
754
  def fetch_markets(self, params={}) -> List[Market]:
754
755
  """
755
756
  retrieves data on all markets for phemex
757
+ :see: https://phemex-docs.github.io/#query-product-information-3
756
758
  :param dict [params]: extra parameters specific to the exchange API endpoint
757
759
  :returns dict[]: an array of objects representing market data
758
760
  """
ccxt/pro/__init__.py CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # ----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.4.25'
7
+ __version__ = '4.4.27'
8
8
 
9
9
  # ----------------------------------------------------------------------------
10
10
 
ccxt/pro/binance.py CHANGED
@@ -1359,7 +1359,7 @@ class binance(ccxt.async_support.binance):
1359
1359
  filtered = self.filter_by_since_limit(candles, since, limit, 0, True)
1360
1360
  return self.create_ohlcv_object(symbol, timeframe, filtered)
1361
1361
 
1362
- async def un_watch_ohlcv_for_symbols(self, symbolsAndTimeframes: List[List[str]], params={}):
1362
+ async def un_watch_ohlcv_for_symbols(self, symbolsAndTimeframes: List[List[str]], params={}) -> Any:
1363
1363
  """
1364
1364
  unWatches historical candlestick data containing the open, high, low, and close price, and the volume of a market
1365
1365
  :see: https://binance-docs.github.io/apidocs/spot/en/#kline-candlestick-data
@@ -1819,7 +1819,7 @@ class binance(ccxt.async_support.binance):
1819
1819
  symbolsDefined = (symbols is not None)
1820
1820
  if symbolsDefined:
1821
1821
  firstMarket = self.market(symbols[0])
1822
- defaultMarket = 'swap' if (isMarkPrice) else 'spot'
1822
+ defaultMarket = 'swap' if (isMarkPrice) else None
1823
1823
  marketType, params = self.handle_market_type_and_params(methodName, firstMarket, params, defaultMarket)
1824
1824
  subType = None
1825
1825
  subType, params = self.handle_sub_type_and_params(methodName, firstMarket, params)
ccxt/pro/bybit.py CHANGED
@@ -651,7 +651,7 @@ class bybit(ccxt.async_support.bybit):
651
651
  filtered = self.filter_by_since_limit(stored, since, limit, 0, True)
652
652
  return self.create_ohlcv_object(symbol, timeframe, filtered)
653
653
 
654
- async def un_watch_ohlcv_for_symbols(self, symbolsAndTimeframes: List[List[str]], params={}):
654
+ async def un_watch_ohlcv_for_symbols(self, symbolsAndTimeframes: List[List[str]], params={}) -> Any:
655
655
  """
656
656
  unWatches historical candlestick data containing the open, high, low, and close price, and the volume of a market
657
657
  :see: https://bybit-exchange.github.io/docs/v5/websocket/public/kline
ccxt/pro/exmo.py CHANGED
@@ -6,7 +6,7 @@
6
6
  import ccxt.async_support
7
7
  from ccxt.async_support.base.ws.cache import ArrayCache, ArrayCacheBySymbolById
8
8
  import hashlib
9
- from ccxt.base.types import Balances, Int, OrderBook, Str, Strings, Ticker, Tickers, Trade
9
+ from ccxt.base.types import Balances, Int, Market, Order, OrderBook, Str, Strings, Ticker, Tickers, Trade
10
10
  from ccxt.async_support.base.ws.client import Client
11
11
  from typing import List
12
12
  from ccxt.base.errors import NotSupported
@@ -23,7 +23,7 @@ class exmo(ccxt.async_support.exmo):
23
23
  'watchTickers': True,
24
24
  'watchTrades': True,
25
25
  'watchMyTrades': True,
26
- 'watchOrders': False, # TODO
26
+ 'watchOrders': True,
27
27
  'watchOrderBook': True,
28
28
  'watchOHLCV': False,
29
29
  },
@@ -546,6 +546,206 @@ class exmo(ccxt.async_support.exmo):
546
546
  for i in range(0, len(deltas)):
547
547
  self.handle_delta(bookside, deltas[i])
548
548
 
549
+ async def watch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
550
+ """
551
+ :see: https://documenter.getpostman.com/view/10287440/SzYXWKPi#85f7bc03-b1c9-4cd2-bd22-8fd422272825
552
+ :see: https://documenter.getpostman.com/view/10287440/SzYXWKPi#95e4ed18-1791-4e6d-83ad-cbfe9be1051c
553
+ watches information on multiple orders made by the user
554
+ :param str symbol: unified market symbol of the market orders were made in
555
+ :param int [since]: the earliest time in ms to fetch orders for
556
+ :param int [limit]: the maximum number of order structures to retrieve
557
+ :param dict [params]: extra parameters specific to the exchange API endpoint
558
+ :returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
559
+ """
560
+ await self.load_markets()
561
+ await self.authenticate(params)
562
+ type, query = self.handle_market_type_and_params('watchOrders', None, params)
563
+ url = self.urls['api']['ws'][type]
564
+ messageHash = None
565
+ if symbol is None:
566
+ messageHash = 'orders:' + type
567
+ else:
568
+ market = self.market(symbol)
569
+ symbol = market['symbol']
570
+ messageHash = 'orders:' + market['symbol']
571
+ message: dict = {
572
+ 'method': 'subscribe',
573
+ 'topics': [
574
+ type + '/orders',
575
+ ],
576
+ 'id': self.request_id(),
577
+ }
578
+ request = self.deep_extend(message, query)
579
+ orders = await self.watch(url, messageHash, request, messageHash, request)
580
+ return self.filter_by_symbol_since_limit(orders, symbol, since, limit, True)
581
+
582
+ def handle_orders(self, client: Client, message):
583
+ #
584
+ # spot
585
+ # {
586
+ # "ts": 1574427585174,
587
+ # "event": "snapshot",
588
+ # "topic": "spot/orders",
589
+ # "data": [
590
+ # {
591
+ # "order_id": "14",
592
+ # "client_id":"100500",
593
+ # "created": "1574427585",
594
+ # "pair": "BTC_USD",
595
+ # "price": "7750",
596
+ # "quantity": "0.1",
597
+ # "amount": "775",
598
+ # "original_quantity": "0.1",
599
+ # "original_amount": "775",
600
+ # "type": "sell",
601
+ # "status": "open"
602
+ # }
603
+ # ]
604
+ # }
605
+ #
606
+ # margin
607
+ # {
608
+ # "ts":1624371281773,
609
+ # "event":"snapshot",
610
+ # "topic":"margin/orders",
611
+ # "data":[
612
+ # {
613
+ # "order_id":"692844278081168665",
614
+ # "created":"1624371250919761600",
615
+ # "type":"limit_buy",
616
+ # "previous_type":"limit_buy",
617
+ # "pair":"BTC_USD",
618
+ # "leverage":"2",
619
+ # "price":"10000",
620
+ # "stop_price":"0",
621
+ # "distance":"0",
622
+ # "trigger_price":"10000",
623
+ # "init_quantity":"0.1",
624
+ # "quantity":"0.1",
625
+ # "funding_currency":"USD",
626
+ # "funding_quantity":"1000",
627
+ # "funding_rate":"0",
628
+ # "client_id":"111111",
629
+ # "expire":0,
630
+ # "src":1,
631
+ # "comment":"comment1",
632
+ # "updated":1624371250938136600,
633
+ # "status":"active"
634
+ # }
635
+ # ]
636
+ # }
637
+ #
638
+ topic = self.safe_string(message, 'topic')
639
+ parts = topic.split('/')
640
+ type = self.safe_string(parts, 0)
641
+ messageHash = 'orders:' + type
642
+ event = self.safe_string(message, 'event')
643
+ if self.orders is None:
644
+ limit = self.safe_integer(self.options, 'ordersLimit', 1000)
645
+ self.orders = ArrayCacheBySymbolById(limit)
646
+ cachedOrders = self.orders
647
+ rawOrders = []
648
+ if event == 'snapshot':
649
+ rawOrders = self.safe_value(message, 'data', [])
650
+ elif event == 'update':
651
+ rawOrder = self.safe_dict(message, 'data', {})
652
+ rawOrders.append(rawOrder)
653
+ symbols: dict = {}
654
+ for j in range(0, len(rawOrders)):
655
+ order = self.parse_ws_order(rawOrders[j])
656
+ cachedOrders.append(order)
657
+ symbols[order['symbol']] = True
658
+ symbolKeys = list(symbols.keys())
659
+ for i in range(0, len(symbolKeys)):
660
+ symbol = symbolKeys[i]
661
+ symbolSpecificMessageHash = 'orders:' + symbol
662
+ client.resolve(cachedOrders, symbolSpecificMessageHash)
663
+ client.resolve(cachedOrders, messageHash)
664
+
665
+ def parse_ws_order(self, order: dict, market: Market = None) -> Order:
666
+ #
667
+ # {
668
+ # order_id: '43226756791',
669
+ # client_id: 0,
670
+ # created: '1730371416',
671
+ # type: 'market_buy',
672
+ # pair: 'TRX_USD',
673
+ # quantity: '0',
674
+ # original_quantity: '30',
675
+ # status: 'cancelled',
676
+ # last_trade_id: '726480870',
677
+ # last_trade_price: '0.17',
678
+ # last_trade_quantity: '30'
679
+ # }
680
+ #
681
+ id = self.safe_string(order, 'order_id')
682
+ timestamp = self.safe_timestamp(order, 'created')
683
+ orderType = self.safe_string(order, 'type')
684
+ side = self.parseSide(orderType)
685
+ marketId = self.safe_string(order, 'pair')
686
+ market = self.safe_market(marketId, market)
687
+ symbol = market['symbol']
688
+ amount = self.safe_string(order, 'quantity')
689
+ if amount is None:
690
+ amountField = 'in_amount' if (side == 'buy') else 'out_amount'
691
+ amount = self.safe_string(order, amountField)
692
+ price = self.safe_string(order, 'price')
693
+ clientOrderId = self.omit_zero(self.safe_string(order, 'client_id'))
694
+ triggerPrice = self.omit_zero(self.safe_string(order, 'stop_price'))
695
+ type = None
696
+ if (orderType != 'buy') and (orderType != 'sell'):
697
+ type = orderType
698
+ trades = None
699
+ if 'last_trade_id' in order:
700
+ trade = self.parse_ws_trade(order, market)
701
+ trades = [trade]
702
+ return self.safe_order({
703
+ 'id': id,
704
+ 'clientOrderId': clientOrderId,
705
+ 'datetime': self.iso8601(timestamp),
706
+ 'timestamp': timestamp,
707
+ 'lastTradeTimestamp': None,
708
+ 'status': self.parseStatus(self.safe_string(order, 'status')),
709
+ 'symbol': symbol,
710
+ 'type': type,
711
+ 'timeInForce': None,
712
+ 'postOnly': None,
713
+ 'side': side,
714
+ 'price': price,
715
+ 'stopPrice': triggerPrice,
716
+ 'triggerPrice': triggerPrice,
717
+ 'cost': None,
718
+ 'amount': self.safe_string(order, 'original_quantity'),
719
+ 'filled': None,
720
+ 'remaining': self.safe_string(order, 'quantity'),
721
+ 'average': None,
722
+ 'trades': trades,
723
+ 'fee': None,
724
+ 'info': order,
725
+ }, market)
726
+
727
+ def parse_ws_trade(self, trade: dict, market: Market = None) -> Trade:
728
+ id = self.safe_string(trade, 'order_id')
729
+ orderType = self.safe_string(trade, 'type')
730
+ side = self.parseSide(orderType)
731
+ marketId = self.safe_string(trade, 'pair')
732
+ market = self.safe_market(marketId, market)
733
+ symbol = market['symbol']
734
+ type = None
735
+ if (orderType != 'buy') and (orderType != 'sell'):
736
+ type = orderType
737
+ return self.safe_trade({
738
+ 'id': self.safe_string(trade, 'last_trade_id'),
739
+ 'symbol': symbol,
740
+ 'order': id,
741
+ 'type': type,
742
+ 'side': side,
743
+ 'price': self.safe_string(trade, 'last_trade_price'),
744
+ 'amount': self.safe_string(trade, 'last_trade_quantity'),
745
+ 'cost': None,
746
+ 'fee': None,
747
+ }, market)
748
+
549
749
  def handle_message(self, client: Client, message):
550
750
  #
551
751
  # {
@@ -585,8 +785,8 @@ class exmo(ccxt.async_support.exmo):
585
785
  'spot/trades': self.handle_trades,
586
786
  'margin/trades': self.handle_trades,
587
787
  'spot/order_book_updates': self.handle_order_book,
588
- # 'spot/orders': self.handleOrders,
589
- # 'margin/orders': self.handleOrders,
788
+ 'spot/orders': self.handle_orders,
789
+ 'margin/orders': self.handle_orders,
590
790
  'spot/user_trades': self.handle_my_trades,
591
791
  'margin/user_trades': self.handle_my_trades,
592
792
  }
ccxt/pro/lbank.py CHANGED
@@ -780,10 +780,13 @@ class lbank(ccxt.async_support.lbank):
780
780
  # {ping: 'a13a939c-5f25-4e06-9981-93cb3b890707', action: 'ping'}
781
781
  #
782
782
  pingId = self.safe_string(message, 'ping')
783
- await client.send({
784
- 'action': 'pong',
785
- 'pong': pingId,
786
- })
783
+ try:
784
+ await client.send({
785
+ 'action': 'pong',
786
+ 'pong': pingId,
787
+ })
788
+ except Exception as e:
789
+ self.on_error(client, e)
787
790
 
788
791
  def handle_message(self, client, message):
789
792
  status = self.safe_string(message, 'status')
ccxt/pro/okx.py CHANGED
@@ -930,7 +930,7 @@ class okx(ccxt.async_support.okx):
930
930
  filtered = self.filter_by_since_limit(candles, since, limit, 0, True)
931
931
  return self.create_ohlcv_object(symbol, timeframe, filtered)
932
932
 
933
- async def un_watch_ohlcv_for_symbols(self, symbolsAndTimeframes: List[List[str]], params={}):
933
+ async def un_watch_ohlcv_for_symbols(self, symbolsAndTimeframes: List[List[str]], params={}) -> Any:
934
934
  """
935
935
  unWatches historical candlestick data containing the open, high, low, and close price, and the volume of a market
936
936
  :param str[][] symbolsAndTimeframes: array of arrays containing unified symbols and timeframes to fetch OHLCV data for, example [['BTC/USDT', '1m'], ['LTC/USDT', '5m']]
@@ -69,7 +69,9 @@ parser.add_argument('--static', action='store_true', help='run static tests')
69
69
  parser.add_argument('--useProxy', action='store_true', help='run static tests')
70
70
  parser.add_argument('--idTests', action='store_true', help='run brokerId tests')
71
71
  parser.add_argument('--responseTests', action='store_true', help='run response tests')
72
- parser.add_argument('--requestTests', action='store_true', help='run response tests')
72
+ parser.add_argument('--response', action='store_true', help='run response tests')
73
+ parser.add_argument('--requestTests', action='store_true', help='run request tests')
74
+ parser.add_argument('--request', action='store_true', help='run request tests')
73
75
  parser.add_argument('--sync', action='store_true', help='is sync')
74
76
  parser.add_argument('--baseTests', action='store_true', help='is base tests')
75
77
  parser.add_argument('--exchangeTests', action='store_true', help='is exchange tests')
ccxt/wavesexchange.py CHANGED
@@ -137,7 +137,13 @@ class wavesexchange(Exchange, ImplicitAPI):
137
137
  'forward': 'https://wx.network/api/v1/forward/matcher',
138
138
  'market': 'https://wx.network/api/v1/forward/marketdata/api/v1',
139
139
  },
140
- 'doc': 'https://docs.wx.network',
140
+ 'doc': [
141
+ 'https://docs.wx.network',
142
+ 'https://docs.waves.tech',
143
+ 'https://api.wavesplatform.com/v0/docs/',
144
+ 'https://nodes.wavesnodes.com/api-docs/index.html',
145
+ 'https://matcher.waves.exchange/api-docs/index.html',
146
+ ],
141
147
  'www': 'https://wx.network',
142
148
  },
143
149
  'api': {
@@ -601,6 +607,7 @@ class wavesexchange(Exchange, ImplicitAPI):
601
607
  def fetch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
602
608
  """
603
609
  fetches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
610
+ :see: https://matcher.waves.exchange/api-docs/index.html#/markets/getOrderBook
604
611
  :param str symbol: unified symbol of the market to fetch the order book for
605
612
  :param int [limit]: the maximum amount of order book entries to return
606
613
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -721,6 +728,7 @@ class wavesexchange(Exchange, ImplicitAPI):
721
728
  def sign_in(self, params={}):
722
729
  """
723
730
  sign in, must be called prior to using other authenticated methods
731
+ :see: https://docs.wx.network/en/api/auth/oauth2-token
724
732
  :param dict [params]: extra parameters specific to the exchange API endpoint
725
733
  :returns: response from exchange
726
734
  """
@@ -831,6 +839,7 @@ class wavesexchange(Exchange, ImplicitAPI):
831
839
  def fetch_ticker(self, symbol: str, params={}) -> Ticker:
832
840
  """
833
841
  fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
842
+ :see: https://api.wavesplatform.com/v0/docs/#/pairs/getPairsListAll
834
843
  :param str symbol: unified symbol of the market to fetch the ticker for
835
844
  :param dict [params]: extra parameters specific to the exchange API endpoint
836
845
  :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
@@ -872,7 +881,7 @@ class wavesexchange(Exchange, ImplicitAPI):
872
881
  def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
873
882
  """
874
883
  fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
875
- :param str[]|None symbols: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
884
+ :param str[] [symbols]: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
876
885
  :param dict [params]: extra parameters specific to the exchange API endpoint
877
886
  :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
878
887
  """
@@ -911,6 +920,7 @@ class wavesexchange(Exchange, ImplicitAPI):
911
920
  def fetch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
912
921
  """
913
922
  fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
923
+ :see: https://api.wavesplatform.com/v0/docs/#/candles/getCandles
914
924
  :param str symbol: unified symbol of the market to fetch OHLCV data for
915
925
  :param str timeframe: the length of time each candle represents
916
926
  :param int [since]: timestamp in ms of the earliest candle to fetch
@@ -1216,6 +1226,7 @@ class wavesexchange(Exchange, ImplicitAPI):
1216
1226
  def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
1217
1227
  """
1218
1228
  create a trade order
1229
+ :see: https://matcher.waves.exchange/api-docs/index.html#/serialize/serializeOrder
1219
1230
  :param str symbol: unified symbol of the market to create an order in
1220
1231
  :param str type: 'market' or 'limit'
1221
1232
  :param str side: 'buy' or 'sell'