Move get_buy_rate to exchange class

This commit is contained in:
Matthias
2021-06-02 11:30:19 +02:00
parent 4e1425023e
commit 12916243ec
4 changed files with 95 additions and 92 deletions

View File

@@ -22,8 +22,8 @@ from pandas import DataFrame
from freqtrade.constants import DEFAULT_AMOUNT_RESERVE_PERCENT, ListPairsWithTimeframes
from freqtrade.data.converter import ohlcv_to_dataframe, trades_dict_to_list
from freqtrade.exceptions import (DDosProtection, ExchangeError, InsufficientFundsError,
InvalidOrderException, OperationalException, RetryableOrderError,
TemporaryError)
InvalidOrderException, OperationalException, PricingError,
RetryableOrderError, TemporaryError)
from freqtrade.exchange.common import (API_FETCH_ORDER_RETRY_COUNT, BAD_EXCHANGES,
EXCHANGE_HAS_OPTIONAL, EXCHANGE_HAS_REQUIRED, retrier,
retrier_async)
@@ -88,6 +88,7 @@ class Exchange:
# Cache for 10 minutes ...
self._fetch_tickers_cache: TTLCache = TTLCache(maxsize=1, ttl=60 * 10)
self._buy_rate_cache: TTLCache = TTLCache(maxsize=100, ttl=1800)
# Holds candles
self._klines: Dict[Tuple[str, str], DataFrame] = {}
@@ -911,6 +912,52 @@ class Exchange:
except ccxt.BaseError as e:
raise OperationalException(e) from e
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
:raises PricingError if orderbook price could not be determined.
"""
if not refresh:
rate = self._buy_rate_cache.get(pair)
# Check if cache has been invalidated
if rate:
logger.debug(f"Using cached buy rate for {pair}.")
return rate
bid_strategy = self._config.get('bid_strategy', {})
if 'use_order_book' in bid_strategy and bid_strategy.get('use_order_book', False):
order_book_top = bid_strategy.get('order_book_top', 1)
order_book = self.fetch_l2_order_book(pair, order_book_top)
logger.debug('order_book %s', order_book)
# top 1 = index 0
try:
rate_from_l2 = order_book[f"{bid_strategy['price_side']}s"][order_book_top - 1][0]
except (IndexError, KeyError) as e:
logger.warning(
"Buy Price from orderbook could not be determined."
f"Orderbook: {order_book}"
)
raise PricingError from e
logger.info(f"Buy price from orderbook {bid_strategy['price_side'].capitalize()} side "
f"- top {order_book_top} order book buy rate {rate_from_l2:.8f}")
used_rate = rate_from_l2
else:
logger.info(f"Using Last {bid_strategy['price_side'].capitalize()} / Last Price")
ticker = self.fetch_ticker(pair)
ticker_rate = ticker[bid_strategy['price_side']]
if ticker['last'] and ticker_rate > ticker['last']:
balance = bid_strategy['ask_last_balance']
ticker_rate = ticker_rate + balance * (ticker['last'] - ticker_rate)
used_rate = ticker_rate
self._buy_rate_cache[pair] = used_rate
return used_rate
# Fee handling
@retrier