get fees for both sides in one request

Co-Authored-By: மனோஜ்குமார் பழனிச்சாமி <smartmanoj42857@gmail.com>
This commit is contained in:
Kavinkumar 2022-03-19 14:40:16 +05:30
parent 13ff413e4f
commit 127fba021b
4 changed files with 38 additions and 12 deletions

View File

@ -1114,7 +1114,8 @@ class Exchange:
except ccxt.BaseError as e: except ccxt.BaseError as e:
raise OperationalException(e) from e raise OperationalException(e) from e
def get_rate(self, pair: str, refresh: bool, side: str) -> float: def get_rate(self, pair: str, refresh: bool, side: str,
order_book: Optional[dict] = None, ticker: Optional[dict] = None) -> float:
""" """
Calculates bid/ask target Calculates bid/ask target
bid rate - between current ask price and last price bid rate - between current ask price and last price
@ -1141,23 +1142,25 @@ class Exchange:
if conf_strategy.get('use_order_book', False) and ('use_order_book' in conf_strategy): if conf_strategy.get('use_order_book', False) and ('use_order_book' in conf_strategy):
order_book_top = conf_strategy.get('order_book_top', 1) order_book_top = conf_strategy.get('order_book_top', 1)
order_book = self.fetch_l2_order_book(pair, order_book_top) if order_book is None:
order_book = self.fetch_l2_order_book(pair, order_book_top)
logger.debug('order_book %s', order_book) logger.debug('order_book %s', order_book)
# top 1 = index 0 # top 1 = index 0
try: try:
rate = order_book[f"{conf_strategy['price_side']}s"][order_book_top - 1][0] rate = order_book[f"{conf_strategy['price_side']}s"][order_book_top - 1][0]
except (IndexError, KeyError) as e: except (IndexError, KeyError) as e:
logger.warning( logger.warning(
f"{name} Price at location {order_book_top} from orderbook could not be " f"{pair} - {name} Price at location {order_book_top} from orderbook "
f"determined. Orderbook: {order_book}" f"could not be determined. Orderbook: {order_book}"
) )
raise PricingError from e raise PricingError from e
price_side = {conf_strategy['price_side'].capitalize()} price_side = {conf_strategy['price_side'].capitalize()}
logger.debug(f"{name} price from orderbook {price_side}" logger.debug(f"{pair} - {name} price from orderbook {price_side}"
f"side - top {order_book_top} order book {side} rate {rate:.8f}") f"side - top {order_book_top} order book {side} rate {rate:.8f}")
else: else:
logger.debug(f"Using Last {conf_strategy['price_side'].capitalize()} / Last Price") logger.debug(f"Using Last {conf_strategy['price_side'].capitalize()} / Last Price")
ticker = self.fetch_ticker(pair) if ticker is None:
ticker = self.fetch_ticker(pair)
ticker_rate = ticker[conf_strategy['price_side']] ticker_rate = ticker[conf_strategy['price_side']]
if ticker['last'] and ticker_rate: if ticker['last'] and ticker_rate:
if side == 'buy' and ticker_rate > ticker['last']: if side == 'buy' and ticker_rate > ticker['last']:
@ -1174,6 +1177,28 @@ class Exchange:
return rate return rate
def get_rates(self, pair: str, refresh: bool) -> Tuple[float, float]:
buy_rate = sell_rate = None
if not refresh:
buy_rate, sell_rate = self._buy_rate_cache.get(pair), self._sell_rate_cache.get(pair)
bid_strategy = self._config.get('bid_strategy', {})
ask_strategy = self._config.get('ask_strategy', {})
order_book = ticker = None
if bid_strategy.get('use_order_book', False) and ('use_order_book' in bid_strategy):
order_book_top = max(bid_strategy.get('order_book_top', 1),
ask_strategy.get('order_book_top', 1))
order_book = self.fetch_l2_order_book(pair, order_book_top)
if not buy_rate:
buy_rate = self.get_rate(pair, refresh, 'buy', order_book=order_book)
else:
ticker = self.fetch_ticker(pair)
if not buy_rate:
buy_rate = self.get_rate(pair, refresh, 'buy', ticker=ticker)
if not sell_rate:
sell_rate = self.get_rate(pair, refresh, 'sell', order_book=order_book, ticker=ticker)
return buy_rate, sell_rate
# Fee handling # Fee handling
@retrier @retrier

View File

@ -452,8 +452,7 @@ class FreqtradeBot(LoggingMixin):
If the strategy triggers the adjustment, a new order gets issued. If the strategy triggers the adjustment, a new order gets issued.
Once that completes, the existing trade is modified to match new data. Once that completes, the existing trade is modified to match new data.
""" """
current_entry_rate = self.exchange.get_rate(trade.pair, refresh=True, side="buy") current_entry_rate, current_exit_rate = self.exchange.get_rates(trade.pair, True)
current_exit_rate = current_entry_rate
current_rate = current_entry_rate # backward compatibilty current_rate = current_entry_rate # backward compatibilty
current_profit = trade.calc_profit_ratio(current_rate) current_profit = trade.calc_profit_ratio(current_rate)

View File

@ -2055,7 +2055,7 @@ def test_get_sell_rate_orderbook_exception(default_conf, mocker, caplog):
exchange = get_patched_exchange(mocker, default_conf) exchange = get_patched_exchange(mocker, default_conf)
with pytest.raises(PricingError): with pytest.raises(PricingError):
exchange.get_rate(pair, refresh=True, side="sell") exchange.get_rate(pair, refresh=True, side="sell")
assert log_has_re(r"Sell Price at location 1 from orderbook could not be determined\..*", assert log_has_re(rf"{pair} - Sell Price at location 1 from orderbook could not be determined\..*",
caplog) caplog)

View File

@ -3961,7 +3961,7 @@ def test_order_book_bid_strategy1(mocker, default_conf_usdt, order_book_l2, exce
with pytest.raises(PricingError): with pytest.raises(PricingError):
freqtrade.exchange.get_rate('ETH/USDT', refresh=True, side="buy") freqtrade.exchange.get_rate('ETH/USDT', refresh=True, side="buy")
assert log_has_re( assert log_has_re(
r'Buy Price at location 1 from orderbook could not be determined.', caplog) r'ETH/USDT - Buy Price at location 1 from orderbook could not be determined.', caplog)
else: else:
assert freqtrade.exchange.get_rate('ETH/USDT', refresh=True, side="buy") == 0.043935 assert freqtrade.exchange.get_rate('ETH/USDT', refresh=True, side="buy") == 0.043935
assert ticker_usdt_mock.call_count == 0 assert ticker_usdt_mock.call_count == 0
@ -4035,8 +4035,10 @@ def test_order_book_ask_strategy(
return_value={'bids': [[]], 'asks': [[]]}) return_value={'bids': [[]], 'asks': [[]]})
with pytest.raises(PricingError): with pytest.raises(PricingError):
freqtrade.handle_trade(trade) freqtrade.handle_trade(trade)
assert log_has_re(r'Sell Price at location 1 from orderbook could not be determined\..*', pair = limit_buy_order_usdt['symbol']
caplog) assert log_has_re(
rf"{pair} - Sell Price at location 1 from orderbook could not be determined\..*",
caplog)
def test_startup_state(default_conf_usdt, mocker): def test_startup_state(default_conf_usdt, mocker):