From 018c6200578ac8702a40c53cf0142291d85908d6 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 26 Feb 2022 08:19:45 +0100 Subject: [PATCH] Fix 0 Division error on exchanges without average closes #6461 --- freqtrade/persistence/models.py | 1 + freqtrade/rpc/telegram.py | 21 +++++++++++++-------- tests/rpc/test_rpc.py | 4 ++-- tests/rpc/test_rpc_telegram.py | 4 +++- 4 files changed, 19 insertions(+), 11 deletions(-) diff --git a/freqtrade/persistence/models.py b/freqtrade/persistence/models.py index e674890d3..559c7e94a 100644 --- a/freqtrade/persistence/models.py +++ b/freqtrade/persistence/models.py @@ -195,6 +195,7 @@ class Order(_DECL_BASE): return { 'amount': self.amount, 'average': round(self.average, 8) if self.average else 0, + 'safe_price': self.safe_price, 'cost': self.cost if self.cost else 0, 'filled': self.filled, 'ft_order_side': self.ft_order_side, diff --git a/freqtrade/rpc/telegram.py b/freqtrade/rpc/telegram.py index da613fab8..eb9dd94e3 100644 --- a/freqtrade/rpc/telegram.py +++ b/freqtrade/rpc/telegram.py @@ -370,15 +370,18 @@ class Telegram(RPCHandler): else: return "\N{CROSS MARK}" - def _prepare_entry_details(self, filled_orders, base_currency, is_open): + def _prepare_entry_details(self, filled_orders: List, base_currency: str, is_open: bool): """ Prepare details of trade with entry adjustment enabled """ - lines = [] + lines: List[str] = [] + if len(filled_orders) > 0: + first_avg = filled_orders[0]["safe_price"] + for x, order in enumerate(filled_orders): cur_entry_datetime = arrow.get(order["order_filled_date"]) cur_entry_amount = order["amount"] - cur_entry_average = order["average"] + cur_entry_average = order["safe_price"] lines.append(" ") if x == 0: lines.append("*Entry #{}:*".format(x+1)) @@ -389,12 +392,14 @@ class Telegram(RPCHandler): sumA = 0 sumB = 0 for y in range(x): - sumA += (filled_orders[y]["amount"] * filled_orders[y]["average"]) + sumA += (filled_orders[y]["amount"] * filled_orders[y]["safe_price"]) sumB += filled_orders[y]["amount"] - prev_avg_price = sumA/sumB - price_to_1st_entry = ((cur_entry_average - filled_orders[0]["average"]) - / filled_orders[0]["average"]) - minus_on_entry = (cur_entry_average - prev_avg_price)/prev_avg_price + prev_avg_price = sumA / sumB + price_to_1st_entry = ((cur_entry_average - first_avg) / first_avg) + minus_on_entry = 0 + if prev_avg_price: + minus_on_entry = (cur_entry_average - prev_avg_price) / prev_avg_price + dur_entry = cur_entry_datetime - arrow.get(filled_orders[x-1]["order_filled_date"]) days = dur_entry.days hours, remainder = divmod(dur_entry.seconds, 3600) diff --git a/tests/rpc/test_rpc.py b/tests/rpc/test_rpc.py index e7b09ab74..dd6c969ed 100644 --- a/tests/rpc/test_rpc.py +++ b/tests/rpc/test_rpc.py @@ -110,7 +110,7 @@ def test_rpc_trade_status(default_conf, ticker, fee, mocker) -> None: 'open_order': None, 'exchange': 'binance', 'filled_entry_orders': [{ - 'amount': 91.07468123, 'average': 1.098e-05, + 'amount': 91.07468123, 'average': 1.098e-05, 'safe_price': 1.098e-05, 'cost': 0.0009999999999054, 'filled': 91.07468123, 'ft_order_side': 'buy', 'order_date': ANY, 'order_timestamp': ANY, 'order_filled_date': ANY, 'order_filled_timestamp': ANY, 'order_type': 'limit', 'price': 1.098e-05, @@ -185,7 +185,7 @@ def test_rpc_trade_status(default_conf, ticker, fee, mocker) -> None: 'open_order': None, 'exchange': 'binance', 'filled_entry_orders': [{ - 'amount': 91.07468123, 'average': 1.098e-05, + 'amount': 91.07468123, 'average': 1.098e-05, 'safe_price': 1.098e-05, 'cost': 0.0009999999999054, 'filled': 91.07468123, 'ft_order_side': 'buy', 'order_date': ANY, 'order_timestamp': ANY, 'order_filled_date': ANY, 'order_filled_timestamp': ANY, 'order_type': 'limit', 'price': 1.098e-05, diff --git a/tests/rpc/test_rpc_telegram.py b/tests/rpc/test_rpc_telegram.py index 5894b9a0f..ccf61f91b 100644 --- a/tests/rpc/test_rpc_telegram.py +++ b/tests/rpc/test_rpc_telegram.py @@ -236,6 +236,8 @@ def test_telegram_status_multi_entry(default_conf, update, mocker, fee) -> None: create_mock_trades(fee) trades = Trade.get_open_trades() trade = trades[0] + # Average may be empty on some exchanges + trade.orders[0].average = 0 trade.orders.append(Order( order_id='5412vbb', ft_order_side='buy', @@ -246,7 +248,7 @@ def test_telegram_status_multi_entry(default_conf, update, mocker, fee) -> None: order_type="market", side="buy", price=trade.open_rate * 0.95, - average=trade.open_rate * 0.95, + average=0, filled=trade.amount, remaining=0, cost=trade.amount,