Implement generic solution for l2 limited limit
This commit is contained in:
parent
886abe36c9
commit
077374ac42
@ -20,20 +20,9 @@ class Binance(Exchange):
|
|||||||
"order_time_in_force": ['gtc', 'fok', 'ioc'],
|
"order_time_in_force": ['gtc', 'fok', 'ioc'],
|
||||||
"trades_pagination": "id",
|
"trades_pagination": "id",
|
||||||
"trades_pagination_arg": "fromId",
|
"trades_pagination_arg": "fromId",
|
||||||
|
"l2_limit_range": [5, 10, 20, 50, 100, 500, 1000],
|
||||||
}
|
}
|
||||||
|
|
||||||
def fetch_l2_order_book(self, pair: str, limit: int = 100) -> dict:
|
|
||||||
"""
|
|
||||||
get order book level 2 from exchange
|
|
||||||
|
|
||||||
20180619: binance support limits but only on specific range
|
|
||||||
"""
|
|
||||||
limit_range = [5, 10, 20, 50, 100, 500, 1000]
|
|
||||||
# get next-higher step in the limit_range list
|
|
||||||
limit = min(list(filter(lambda x: limit <= x, limit_range)))
|
|
||||||
|
|
||||||
return super().fetch_l2_order_book(pair, limit)
|
|
||||||
|
|
||||||
def stoploss_adjust(self, stop_loss: float, order: Dict) -> bool:
|
def stoploss_adjust(self, stop_loss: float, order: Dict) -> bool:
|
||||||
"""
|
"""
|
||||||
Verify stop_loss against stoploss-order value (limit or price)
|
Verify stop_loss against stoploss-order value (limit or price)
|
||||||
|
@ -53,7 +53,7 @@ class Exchange:
|
|||||||
"ohlcv_partial_candle": True,
|
"ohlcv_partial_candle": True,
|
||||||
"trades_pagination": "time", # Possible are "time" or "id"
|
"trades_pagination": "time", # Possible are "time" or "id"
|
||||||
"trades_pagination_arg": "since",
|
"trades_pagination_arg": "since",
|
||||||
|
"l2_limit_range": None,
|
||||||
}
|
}
|
||||||
_ft_has: Dict = {}
|
_ft_has: Dict = {}
|
||||||
|
|
||||||
@ -1069,6 +1069,16 @@ class Exchange:
|
|||||||
return self.fetch_stoploss_order(order_id, pair)
|
return self.fetch_stoploss_order(order_id, pair)
|
||||||
return self.fetch_order(order_id, pair)
|
return self.fetch_order(order_id, pair)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_next_limit_in_list(limit: int, limit_range: Optional[List[int]]):
|
||||||
|
"""
|
||||||
|
Get next greater limit
|
||||||
|
"""
|
||||||
|
if not limit_range:
|
||||||
|
return limit
|
||||||
|
|
||||||
|
return min(list(filter(lambda x: limit <= x, limit_range)))
|
||||||
|
|
||||||
@retrier
|
@retrier
|
||||||
def fetch_l2_order_book(self, pair: str, limit: int = 100) -> dict:
|
def fetch_l2_order_book(self, pair: str, limit: int = 100) -> dict:
|
||||||
"""
|
"""
|
||||||
@ -1077,9 +1087,10 @@ class Exchange:
|
|||||||
Returns a dict in the format
|
Returns a dict in the format
|
||||||
{'asks': [price, volume], 'bids': [price, volume]}
|
{'asks': [price, volume], 'bids': [price, volume]}
|
||||||
"""
|
"""
|
||||||
|
limit1 = self.get_next_limit_in_list(limit, self._ft_has['l2_limit_range'])
|
||||||
try:
|
try:
|
||||||
|
|
||||||
return self._api.fetch_l2_order_book(pair, limit)
|
return self._api.fetch_l2_order_book(pair, limit1)
|
||||||
except ccxt.NotSupported as e:
|
except ccxt.NotSupported as e:
|
||||||
raise OperationalException(
|
raise OperationalException(
|
||||||
f'Exchange {self._api.name} does not support fetching order book.'
|
f'Exchange {self._api.name} does not support fetching order book.'
|
||||||
|
@ -1438,6 +1438,25 @@ def test_refresh_latest_ohlcv_inv_result(default_conf, mocker, caplog):
|
|||||||
assert log_has("Async code raised an exception: TypeError", caplog)
|
assert log_has("Async code raised an exception: TypeError", caplog)
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_next_limit_in_list():
|
||||||
|
limit_range = [5, 10, 20, 50, 100, 500, 1000]
|
||||||
|
assert Exchange.get_next_limit_in_list(1, limit_range) == 5
|
||||||
|
assert Exchange.get_next_limit_in_list(5, limit_range) == 5
|
||||||
|
assert Exchange.get_next_limit_in_list(6, limit_range) == 10
|
||||||
|
assert Exchange.get_next_limit_in_list(9, limit_range) == 10
|
||||||
|
assert Exchange.get_next_limit_in_list(10, limit_range) == 10
|
||||||
|
assert Exchange.get_next_limit_in_list(11, limit_range) == 20
|
||||||
|
assert Exchange.get_next_limit_in_list(19, limit_range) == 20
|
||||||
|
assert Exchange.get_next_limit_in_list(21, limit_range) == 50
|
||||||
|
assert Exchange.get_next_limit_in_list(51, limit_range) == 100
|
||||||
|
assert Exchange.get_next_limit_in_list(1000, limit_range) == 1000
|
||||||
|
# assert Exchange.get_next_limit_in_list(1001, limit_range) == 1001
|
||||||
|
|
||||||
|
assert Exchange.get_next_limit_in_list(21, None) == 21
|
||||||
|
assert Exchange.get_next_limit_in_list(100, None) == 100
|
||||||
|
assert Exchange.get_next_limit_in_list(1000, None) == 1000
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("exchange_name", EXCHANGES)
|
@pytest.mark.parametrize("exchange_name", EXCHANGES)
|
||||||
def test_fetch_l2_order_book(default_conf, mocker, order_book_l2, exchange_name):
|
def test_fetch_l2_order_book(default_conf, mocker, order_book_l2, exchange_name):
|
||||||
default_conf['exchange']['name'] = exchange_name
|
default_conf['exchange']['name'] = exchange_name
|
||||||
@ -1450,6 +1469,20 @@ def test_fetch_l2_order_book(default_conf, mocker, order_book_l2, exchange_name)
|
|||||||
assert 'asks' in order_book
|
assert 'asks' in order_book
|
||||||
assert len(order_book['bids']) == 10
|
assert len(order_book['bids']) == 10
|
||||||
assert len(order_book['asks']) == 10
|
assert len(order_book['asks']) == 10
|
||||||
|
assert api_mock.fetch_l2_order_book.call_args_list[0][0][0] == 'ETH/BTC'
|
||||||
|
assert api_mock.fetch_l2_order_book.call_args_list[0][0][1] == 10
|
||||||
|
|
||||||
|
for val in [1, 5, 12, 20, 50, 100]:
|
||||||
|
api_mock.fetch_l2_order_book.reset_mock()
|
||||||
|
|
||||||
|
order_book = exchange.fetch_l2_order_book(pair='ETH/BTC', limit=val)
|
||||||
|
assert api_mock.fetch_l2_order_book.call_args_list[0][0][0] == 'ETH/BTC'
|
||||||
|
# Not all exchanges support all limits for orderbook
|
||||||
|
if not exchange._ft_has['l2_limit_range'] or val in exchange._ft_has['l2_limit_range']:
|
||||||
|
assert api_mock.fetch_l2_order_book.call_args_list[0][0][1] == val
|
||||||
|
else:
|
||||||
|
next_limit = exchange.get_next_limit_in_list(val, exchange._ft_has['l2_limit_range'])
|
||||||
|
assert api_mock.fetch_l2_order_book.call_args_list[0][0][1] == next_limit
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("exchange_name", EXCHANGES)
|
@pytest.mark.parametrize("exchange_name", EXCHANGES)
|
||||||
|
Loading…
Reference in New Issue
Block a user