Merge pull request #859 from freqtrade/readd_ticker_caching

Re-add ticker caching for rpc operations
This commit is contained in:
Michael Egger 2018-06-07 17:15:59 +02:00 committed by GitHub
commit 867145cd09
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 37 additions and 9 deletions

View File

@ -18,6 +18,8 @@ _API: ccxt.Exchange = None
_CONF: Dict = {} _CONF: Dict = {}
API_RETRY_COUNT = 4 API_RETRY_COUNT = 4
_CACHED_TICKER: Dict[str, Any] = {}
# Holds all open sell orders for dry_run # Holds all open sell orders for dry_run
_DRY_RUN_OPEN_ORDERS: Dict[str, Any] = {} _DRY_RUN_OPEN_ORDERS: Dict[str, Any] = {}
@ -264,17 +266,29 @@ def get_tickers() -> Dict:
raise OperationalException(e) raise OperationalException(e)
# TODO: remove refresh argument, keeping it to keep track of where it was intended to be used
@retrier @retrier
def get_ticker(pair: str, refresh: Optional[bool] = True) -> dict: def get_ticker(pair: str, refresh: Optional[bool] = True) -> dict:
try: global _CACHED_TICKER
return _API.fetch_ticker(pair) if refresh or pair not in _CACHED_TICKER.keys():
except (ccxt.NetworkError, ccxt.ExchangeError) as e: try:
raise TemporaryError( data = _API.fetch_ticker(pair)
'Could not load ticker history due to {}. Message: {}'.format( try:
e.__class__.__name__, e)) _CACHED_TICKER[pair] = {
except ccxt.BaseError as e: 'bid': float(data['bid']),
raise OperationalException(e) 'ask': float(data['ask']),
}
except KeyError as e:
logger.debug("Could not cache ticker data for %s", pair)
return data
except (ccxt.NetworkError, ccxt.ExchangeError) as e:
raise TemporaryError(
'Could not load ticker history due to {}. Message: {}'.format(
e.__class__.__name__, e))
except ccxt.BaseError as e:
raise OperationalException(e)
else:
logger.info("returning cached ticker-data for %s", pair)
return _CACHED_TICKER[pair]
@retrier @retrier

View File

@ -310,9 +310,19 @@ def test_get_ticker(default_conf, mocker):
# if not fetching a new result we should get the cached ticker # if not fetching a new result we should get the cached ticker
ticker = get_ticker(pair='ETH/BTC') ticker = get_ticker(pair='ETH/BTC')
assert api_mock.fetch_ticker.call_count == 1
assert ticker['bid'] == 0.5 assert ticker['bid'] == 0.5
assert ticker['ask'] == 1 assert ticker['ask'] == 1
assert 'ETH/BTC' in exchange._CACHED_TICKER
assert exchange._CACHED_TICKER['ETH/BTC']['bid'] == 0.5
assert exchange._CACHED_TICKER['ETH/BTC']['ask'] == 1
# Test caching
api_mock.fetch_ticker = MagicMock()
get_ticker(pair='ETH/BTC', refresh=False)
assert api_mock.fetch_ticker.call_count == 0
with pytest.raises(TemporaryError): # test retrier with pytest.raises(TemporaryError): # test retrier
api_mock.fetch_ticker = MagicMock(side_effect=ccxt.NetworkError) api_mock.fetch_ticker = MagicMock(side_effect=ccxt.NetworkError)
mocker.patch('freqtrade.exchange._API', api_mock) mocker.patch('freqtrade.exchange._API', api_mock)
@ -323,6 +333,10 @@ def test_get_ticker(default_conf, mocker):
mocker.patch('freqtrade.exchange._API', api_mock) mocker.patch('freqtrade.exchange._API', api_mock)
get_ticker(pair='ETH/BTC', refresh=True) get_ticker(pair='ETH/BTC', refresh=True)
api_mock.fetch_ticker = MagicMock(return_value={})
mocker.patch('freqtrade.exchange._API', api_mock)
get_ticker(pair='ETH/BTC', refresh=True)
def make_fetch_ohlcv_mock(data): def make_fetch_ohlcv_mock(data):
def fetch_ohlcv_mock(pair, timeframe, since): def fetch_ohlcv_mock(pair, timeframe, since):