Skip to content

Commit

Permalink
Merge pull request freqtrade#4734 from freqtrade/get_tickers_ccache
Browse files Browse the repository at this point in the history
/balance should use cached tickers when possible
  • Loading branch information
xmatthias authored Apr 14, 2021
2 parents 82d6641 + ba38e39 commit 6beb1c2
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 3 deletions.
18 changes: 16 additions & 2 deletions freqtrade/exchange/exchange.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
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
Expand Down Expand Up @@ -84,6 +85,9 @@ def __init__(self, config: Dict[str, Any], validate: bool = True) -> None:
# 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] = {}

Expand Down Expand Up @@ -693,9 +697,19 @@ def get_balances(self) -> dict:
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. '
Expand Down
2 changes: 1 addition & 1 deletion freqtrade/rpc/rpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,7 @@ def _rpc_balance(self, stake_currency: str, fiat_display_currency: str) -> Dict:
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.')

Expand Down
10 changes: 10 additions & 0 deletions tests/exchange/test_exchange.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
2 changes: 2 additions & 0 deletions tests/rpc/test_rpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down

0 comments on commit 6beb1c2

Please sign in to comment.