Implement caching in the correct place

This commit is contained in:
Matthias 2020-02-22 11:12:33 +01:00
parent f5b4a6d3d7
commit 97e6e5e976
2 changed files with 29 additions and 9 deletions

View File

@ -11,6 +11,7 @@ from threading import Lock
from typing import Any, Dict, List, Optional, Tuple
import arrow
from cachetools import TTLCache
from requests.exceptions import RequestException
from freqtrade import __version__, constants, persistence
@ -54,6 +55,9 @@ class FreqtradeBot:
self._heartbeat_msg = 0
self._sell_rate_cache = TTLCache(maxsize=100, ttl=5)
self._buy_rate_cache = TTLCache(maxsize=100, ttl=5)
self.heartbeat_interval = self.config.get('internals', {}).get('heartbeat_interval', 60)
self.strategy: IStrategy = StrategyResolver.load_strategy(self.config)
@ -234,11 +238,19 @@ class FreqtradeBot:
return trades_created
def get_buy_rate(self, pair: str, refresh: bool, tick: Dict = None) -> float:
def get_buy_rate(self, pair: str, refresh: bool) -> float:
"""
Calculates bid target between current ask price and last price
:param pair: Pair to get rate for
:param refresh: allow cached data
:return: float: Price
"""
if not refresh:
rate = self._sell_rate_cache.get(pair)
# Check if cache has been invalidated
if rate:
return rate
config_bid_strategy = self.config.get('bid_strategy', {})
if 'use_order_book' in config_bid_strategy and\
config_bid_strategy.get('use_order_book', False):
@ -251,11 +263,8 @@ class FreqtradeBot:
logger.info('...top %s order book buy rate %0.8f', order_book_top, order_book_rate)
used_rate = order_book_rate
else:
if not tick:
logger.info('Using Last Ask / Last Price')
ticker = self.exchange.fetch_ticker(pair)
else:
ticker = tick
logger.info('Using Last Ask / Last Price')
ticker = self.exchange.fetch_ticker(pair)
if ticker['ask'] < ticker['last']:
ticker_rate = ticker['ask']
else:
@ -263,6 +272,8 @@ class FreqtradeBot:
ticker_rate = ticker['ask'] + balance * (ticker['last'] - ticker['ask'])
used_rate = ticker_rate
self._buy_rate_cache[pair] = used_rate
return used_rate
def get_trade_stake_amount(self, pair: str) -> float:
@ -621,8 +632,16 @@ class FreqtradeBot:
The orderbook portion is only used for rpc messaging, which would otherwise fail
for BitMex (has no bid/ask in fetch_ticker)
or remain static in any other case since it's not updating.
:param pair: Pair to get rate for
:param refresh: allow cached data
:return: Bid rate
"""
if not refresh:
rate = self._sell_rate_cache.get(pair)
# Check if cache has been invalidated
if rate:
return rate
config_ask_strategy = self.config.get('ask_strategy', {})
if config_ask_strategy.get('use_order_book', False):
logger.debug('Using order book to get sell rate')
@ -632,6 +651,7 @@ class FreqtradeBot:
else:
rate = self.exchange.fetch_ticker(pair)['bid']
self._sell_rate_cache[pair] = rate
return rate
def handle_trade(self, trade: Trade) -> bool:

View File

@ -65,7 +65,7 @@ def test_rpc_trade_status(default_conf, ticker, fee, mocker) -> None:
'open_order': '(limit buy rem=0.00000000)'
} == results[0]
mocker.patch('freqtrade.exchange.Exchange.fetch_ticker',
mocker.patch('freqtrade.freqtradebot.FreqtradeBot.get_sell_rate',
MagicMock(side_effect=DependencyException(f"Pair 'ETH/BTC' not available")))
results = rpc._rpc_trade_status()
assert isnan(results[0]['current_profit'])
@ -132,7 +132,7 @@ def test_rpc_status_table(default_conf, ticker, fee, mocker) -> None:
assert 'ETH/BTC' in result[0][1]
assert '-0.59% (-0.09)' == result[0][3]
mocker.patch('freqtrade.exchange.Exchange.fetch_ticker',
mocker.patch('freqtrade.freqtradebot.FreqtradeBot.get_sell_rate',
MagicMock(side_effect=DependencyException(f"Pair 'ETH/BTC' not available")))
result, headers = rpc._rpc_status_table(default_conf['stake_currency'], 'USD')
assert 'instantly' == result[0][2]
@ -256,7 +256,7 @@ def test_rpc_trade_statistics(default_conf, ticker, ticker_sell_up, fee,
assert prec_satoshi(stats['best_rate'], 6.2)
# Test non-available pair
mocker.patch('freqtrade.exchange.Exchange.fetch_ticker',
mocker.patch('freqtrade.freqtradebot.FreqtradeBot.get_sell_rate',
MagicMock(side_effect=DependencyException(f"Pair 'ETH/BTC' not available")))
stats = rpc._rpc_trade_statistics(stake_currency, fiat_display_currency)
assert stats['trade_count'] == 2