From 6bfc37309e6c14d03a747616883444736f8bf1a4 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 16 Mar 2019 13:24:10 +0100 Subject: [PATCH 1/3] refactor getting sell/current rate for telegram and selling fix #1658 --- freqtrade/freqtradebot.py | 24 ++++++++++++++++++++++-- freqtrade/rpc/rpc.py | 12 ++++++------ 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 8b9594047..6ba59bea4 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -579,6 +579,25 @@ class FreqtradeBot(object): f"(from {order_amount} to {real_amount}) from Trades") return real_amount + def get_sell_rate(self, pair: str, refresh: bool) -> float: + """ + Get sell rate - either using get-ticker bid or first bid based on orderbook + The orderbook portion is only used for rpc messaging, which would otherwise fail + for BitMex (has no bid/ask in get_ticker) + or remain static in any other case since it's not updating. + :return: Bid 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') + + order_book = self.exchange.get_order_book(pair, 1) + rate = order_book['asks'][0][0] + + else: + rate = self.exchange.get_ticker(pair, refresh)['bid'] + return rate + def handle_trade(self, trade: Trade) -> bool: """ Sells the current pair if the threshold is reached and updates the trade record. @@ -615,7 +634,7 @@ class FreqtradeBot(object): else: logger.debug('checking sell') - sell_rate = self.exchange.get_ticker(trade.pair)['bid'] + sell_rate = self.get_sell_rate(trade.pair, True) if self.check_sell(trade, sell_rate, buy, sell): return True @@ -858,7 +877,8 @@ class FreqtradeBot(object): """ profit_rate = trade.close_rate if trade.close_rate else trade.close_rate_requested profit_trade = trade.calc_profit(rate=profit_rate) - current_rate = self.exchange.get_ticker(trade.pair)['bid'] + # Use cached ticker here - it was updated seconds ago. + current_rate = self.get_sell_rate(trade.pair, False) profit_percent = trade.calc_profit_percent(profit_rate) gain = "profit" if profit_percent > 0 else "loss" diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index af64c3d67..ffbc8d334 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -94,7 +94,7 @@ class RPC(object): order = self._freqtrade.exchange.get_order(trade.open_order_id, trade.pair) # calculate profit and send message to user try: - current_rate = self._freqtrade.exchange.get_ticker(trade.pair, False)['bid'] + current_rate = self._freqtrade.get_sell_rate(trade.pair, False) except DependencyException: current_rate = NAN current_profit = trade.calc_profit_percent(current_rate) @@ -125,7 +125,7 @@ class RPC(object): for trade in trades: # calculate profit and send message to user try: - current_rate = self._freqtrade.exchange.get_ticker(trade.pair, False)['bid'] + current_rate = self._freqtrade.get_sell_rate(trade.pair, False) except DependencyException: current_rate = NAN trade_perc = (100 * trade.calc_profit_percent(current_rate)) @@ -213,7 +213,7 @@ class RPC(object): else: # Get current rate try: - current_rate = self._freqtrade.exchange.get_ticker(trade.pair, False)['bid'] + current_rate = self._freqtrade.get_sell_rate(trade.pair, False) except DependencyException: current_rate = NAN profit_percent = trade.calc_profit_percent(rate=current_rate) @@ -280,9 +280,9 @@ class RPC(object): else: try: if coin == 'USDT': - rate = 1.0 / self._freqtrade.exchange.get_ticker('BTC/USDT', False)['bid'] + rate = 1.0 / self._freqtrade.get_sell_rate('BTC/USDT', False) else: - rate = self._freqtrade.exchange.get_ticker(coin + '/BTC', False)['bid'] + rate = self._freqtrade.get_sell_rate(coin + '/BTC', False) except (TemporaryError, DependencyException): continue est_btc: float = rate * balance['total'] @@ -356,7 +356,7 @@ class RPC(object): return # Get current rate and execute sell - current_rate = self._freqtrade.exchange.get_ticker(trade.pair, False)['bid'] + current_rate = self._freqtrade.get_sell_rate(trade.pair, False) self._freqtrade.execute_sell(trade, current_rate, SellType.FORCE_SELL) # ---- EOF def _exec_forcesell ---- From 29aa1598273b7e7ea64abbbba78fc02cb8b95c43 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 16 Mar 2019 13:32:26 +0100 Subject: [PATCH 2/3] Add test for get_sell_rate --- freqtrade/tests/test_freqtradebot.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/freqtrade/tests/test_freqtradebot.py b/freqtrade/tests/test_freqtradebot.py index fc7c48663..950662bfb 100644 --- a/freqtrade/tests/test_freqtradebot.py +++ b/freqtrade/tests/test_freqtradebot.py @@ -2962,6 +2962,31 @@ def test_order_book_ask_strategy(default_conf, limit_buy_order, limit_sell_order assert freqtrade.handle_trade(trade) is True +def test_get_sell_rate(default_conf, mocker, ticker, order_book_l2) -> None: + + mocker.patch.multiple( + 'freqtrade.exchange.Exchange', + get_order_book=order_book_l2, + get_ticker=ticker, + ) + pair = "ETH/BTC" + + # Test regular mode + ft = get_patched_freqtradebot(mocker, default_conf) + rate = ft.get_sell_rate(pair, True) + assert isinstance(rate, float) + assert rate == 0.00001098 + + # Test orderbook mode + default_conf['ask_strategy']['use_order_book'] = True + default_conf['ask_strategy']['order_book_min'] = 1 + default_conf['ask_strategy']['order_book_max'] = 2 + ft = get_patched_freqtradebot(mocker, default_conf) + rate = ft.get_sell_rate(pair, True) + assert isinstance(rate, float) + assert rate == 0.043949 + + def test_startup_messages(default_conf, mocker): default_conf['pairlist'] = {'method': 'VolumePairList', 'config': {'number_assets': 20} From a0e6cd93b62595b71a2edcc8c2b6ebfd7df5229f Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 17 Mar 2019 11:27:01 +0100 Subject: [PATCH 3/3] Use bids, not asks for sell-rate detection --- freqtrade/freqtradebot.py | 2 +- freqtrade/tests/test_freqtradebot.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 6ba59bea4..cfff46fea 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -592,7 +592,7 @@ class FreqtradeBot(object): logger.debug('Using order book to get sell rate') order_book = self.exchange.get_order_book(pair, 1) - rate = order_book['asks'][0][0] + rate = order_book['bids'][0][0] else: rate = self.exchange.get_ticker(pair, refresh)['bid'] diff --git a/freqtrade/tests/test_freqtradebot.py b/freqtrade/tests/test_freqtradebot.py index 950662bfb..e4f0415f7 100644 --- a/freqtrade/tests/test_freqtradebot.py +++ b/freqtrade/tests/test_freqtradebot.py @@ -2984,7 +2984,7 @@ def test_get_sell_rate(default_conf, mocker, ticker, order_book_l2) -> None: ft = get_patched_freqtradebot(mocker, default_conf) rate = ft.get_sell_rate(pair, True) assert isinstance(rate, float) - assert rate == 0.043949 + assert rate == 0.043936 def test_startup_messages(default_conf, mocker):