Merge pull request #4734 from freqtrade/get_tickers_ccache
/balance should use cached tickers when possible
This commit is contained in:
commit
6beb1c223f
@ -14,6 +14,7 @@ from typing import Any, Dict, List, Optional, Tuple
|
||||
import arrow
|
||||
import ccxt
|
||||
import ccxt.async_support as ccxt_async
|
||||
from cachetools import TTLCache
|
||||
from ccxt.base.decimal_to_precision import (ROUND_DOWN, ROUND_UP, TICK_SIZE, TRUNCATE,
|
||||
decimal_to_precision)
|
||||
from pandas import DataFrame
|
||||
@ -84,6 +85,9 @@ class Exchange:
|
||||
# Timestamp of last markets refresh
|
||||
self._last_markets_refresh: int = 0
|
||||
|
||||
# Cache for 10 minutes ...
|
||||
self._fetch_tickers_cache: TTLCache = TTLCache(maxsize=1, ttl=60 * 10)
|
||||
|
||||
# Holds candles
|
||||
self._klines: Dict[Tuple[str, str], DataFrame] = {}
|
||||
|
||||
@ -693,9 +697,19 @@ class Exchange:
|
||||
raise OperationalException(e) from e
|
||||
|
||||
@retrier
|
||||
def get_tickers(self) -> Dict:
|
||||
def get_tickers(self, cached: bool = False) -> Dict:
|
||||
"""
|
||||
:param cached: Allow cached result
|
||||
:return: fetch_tickers result
|
||||
"""
|
||||
if cached:
|
||||
tickers = self._fetch_tickers_cache.get('fetch_tickers')
|
||||
if tickers:
|
||||
return tickers
|
||||
try:
|
||||
return self._api.fetch_tickers()
|
||||
tickers = self._api.fetch_tickers()
|
||||
self._fetch_tickers_cache['fetch_tickers'] = tickers
|
||||
return tickers
|
||||
except ccxt.NotSupported as e:
|
||||
raise OperationalException(
|
||||
f'Exchange {self._api.name} does not support fetching tickers in batch. '
|
||||
|
@ -442,7 +442,7 @@ class RPC:
|
||||
output = []
|
||||
total = 0.0
|
||||
try:
|
||||
tickers = self._freqtrade.exchange.get_tickers()
|
||||
tickers = self._freqtrade.exchange.get_tickers(cached=True)
|
||||
except (ExchangeError):
|
||||
raise RPCException('Error getting current tickers.')
|
||||
|
||||
|
@ -1319,6 +1319,16 @@ def test_get_tickers(default_conf, mocker, exchange_name):
|
||||
assert tickers['ETH/BTC']['ask'] == 1
|
||||
assert tickers['BCH/BTC']['bid'] == 0.6
|
||||
assert tickers['BCH/BTC']['ask'] == 0.5
|
||||
assert api_mock.fetch_tickers.call_count == 1
|
||||
|
||||
api_mock.fetch_tickers.reset_mock()
|
||||
|
||||
# Cached ticker should not call api again
|
||||
tickers2 = exchange.get_tickers(cached=True)
|
||||
assert tickers2 == tickers
|
||||
assert api_mock.fetch_tickers.call_count == 0
|
||||
tickers2 = exchange.get_tickers(cached=False)
|
||||
assert api_mock.fetch_tickers.call_count == 1
|
||||
|
||||
ccxt_exceptionhandlers(mocker, default_conf, api_mock, exchange_name,
|
||||
"get_tickers", "fetch_tickers")
|
||||
|
@ -569,6 +569,8 @@ def test_rpc_balance_handle(default_conf, mocker, tickers):
|
||||
result = rpc._rpc_balance(default_conf['stake_currency'], default_conf['fiat_display_currency'])
|
||||
assert prec_satoshi(result['total'], 12.309096315)
|
||||
assert prec_satoshi(result['value'], 184636.44472997)
|
||||
assert tickers.call_count == 1
|
||||
assert tickers.call_args_list[0][1]['cached'] is True
|
||||
assert 'USD' == result['symbol']
|
||||
assert result['currencies'] == [
|
||||
{'currency': 'BTC',
|
||||
|
Loading…
Reference in New Issue
Block a user