diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index f9bb8e77d..8ba1dcecc 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -434,11 +434,11 @@ class FreqtradeBot(LoggingMixin): if self._check_depth_of_market_buy(pair, bid_check_dom): # TODO-lev: pass in "enter" as side. - return self.execute_entry(pair, stake_amount, buy_tag=enter_tag) + return self.execute_entry(pair, stake_amount, enter_tag=enter_tag) else: return False - return self.execute_entry(pair, stake_amount, buy_tag=enter_tag) + return self.execute_entry(pair, stake_amount, enter_tag=enter_tag) else: return False diff --git a/freqtrade/strategy/interface.py b/freqtrade/strategy/interface.py index 5fc975ef7..e89811bd0 100644 --- a/freqtrade/strategy/interface.py +++ b/freqtrade/strategy/interface.py @@ -596,11 +596,11 @@ class IStrategy(ABC, HyperStrategyMixin): return False, False if is_short: - enter = latest.get(SignalType.ENTER_SHORT, 0) == 1 - exit_ = latest.get(SignalType.EXIT_SHORT, 0) == 1 + enter = latest.get(SignalType.ENTER_SHORT.value, 0) == 1 + exit_ = latest.get(SignalType.EXIT_SHORT.value, 0) == 1 else: - enter = latest[SignalType.ENTER_LONG] == 1 - exit_ = latest.get(SignalType.EXIT_LONG, 0) == 1 + enter = latest[SignalType.ENTER_LONG.value] == 1 + exit_ = latest.get(SignalType.EXIT_LONG.value, 0) == 1 logger.debug(f"exit-trigger: {latest['date']} (pair={pair}) " f"enter={enter} exit={exit_}") diff --git a/tests/optimize/test_backtesting.py b/tests/optimize/test_backtesting.py index bdb491441..3e3b16371 100644 --- a/tests/optimize/test_backtesting.py +++ b/tests/optimize/test_backtesting.py @@ -570,47 +570,54 @@ def test_backtest__get_sell_trade_entry(default_conf, fee, mocker) -> None: pair = 'UNITTEST/BTC' row = [ pd.Timestamp(year=2020, month=1, day=1, hour=4, minute=55, tzinfo=timezone.utc), - 1, # Buy 200, # Open - 201, # Close - 0, # Sell - 195, # Low 201.5, # High - '', # Buy Signal Name + 195, # Low + 201, # Close + 1, # enter_long + 0, # exit_long + 0, # enter_short + 0, # exit_hsort + '', # Long Signal Name + '', # Short Signal Name ] - trade = backtesting._enter_trade(pair, row=row) + trade = backtesting._enter_trade(pair, row=row, direction='long') assert isinstance(trade, LocalTrade) row_sell = [ pd.Timestamp(year=2020, month=1, day=1, hour=5, minute=0, tzinfo=timezone.utc), - 0, # Buy 200, # Open - 201, # Close - 0, # Sell - 195, # Low 210.5, # High - '', # Buy Signal Name + 195, # Low + 201, # Close + 0, # enter_long + 0, # exit_long + 0, # enter_short + 0, # exit_short + '', # long Signal Name + '', # Short Signal Name ] row_detail = pd.DataFrame( [ [ pd.Timestamp(year=2020, month=1, day=1, hour=5, minute=0, tzinfo=timezone.utc), - 1, 200, 199, 0, 197, 200.1, '', + 200, 200.1, 197, 199, 1, 0, 0, 0, '', '', ], [ pd.Timestamp(year=2020, month=1, day=1, hour=5, minute=1, tzinfo=timezone.utc), - 0, 199, 199.5, 0, 199, 199.7, '', + 199, 199.7, 199, 199.5, 0, 0, 0, 0, '', '' ], [ pd.Timestamp(year=2020, month=1, day=1, hour=5, minute=2, tzinfo=timezone.utc), - 0, 199.5, 200.5, 0, 199, 200.8, '', + 199.5, 200.8, 199, 200.9, 0, 0, 0, 0, '', '' ], [ pd.Timestamp(year=2020, month=1, day=1, hour=5, minute=3, tzinfo=timezone.utc), - 0, 200.5, 210.5, 0, 193, 210.5, '', # ROI sell (?) + 200.5, 210.5, 193, 210.5, 0, 0, 0, 0, '', '' # ROI sell (?) ], [ pd.Timestamp(year=2020, month=1, day=1, hour=5, minute=4, tzinfo=timezone.utc), - 0, 200, 199, 0, 193, 200.1, '', + 200, 200.1, 193, 199, 0, 0, 0, 0, '', '' ], - ], columns=["date", "buy", "open", "close", "sell", "low", "high", "buy_tag"] + ], columns=['date', 'open', 'high', 'low', 'close', 'enter_long', 'exit_long', + 'enter_short', 'exit_short', 'long_tag', 'short_tag'] ) # No data available. @@ -620,11 +627,12 @@ def test_backtest__get_sell_trade_entry(default_conf, fee, mocker) -> None: assert res.close_date_utc == datetime(2020, 1, 1, 5, 0, tzinfo=timezone.utc) # Enter new trade - trade = backtesting._enter_trade(pair, row=row) + trade = backtesting._enter_trade(pair, row=row, direction='long') assert isinstance(trade, LocalTrade) # Assign empty ... no result. backtesting.detail_data[pair] = pd.DataFrame( - [], columns=["date", "buy", "open", "close", "sell", "low", "high", "buy_tag"]) + [], columns=['date', 'open', 'high', 'low', 'close', 'enter_long', 'exit_long', + 'enter_short', 'exit_short', 'long_tag', 'short_tag']) res = backtesting._get_sell_trade_entry(trade, row) assert res is None diff --git a/tests/strategy/test_interface.py b/tests/strategy/test_interface.py index 39f0b8009..6f2adad33 100644 --- a/tests/strategy/test_interface.py +++ b/tests/strategy/test_interface.py @@ -31,28 +31,56 @@ _STRATEGY = StrategyTestV2(config={}) _STRATEGY.dp = DataProvider({}, None, None) -def test_returns_latest_signal(default_conf, ohlcv_history): +def test_returns_latest_signal(ohlcv_history): ohlcv_history.loc[1, 'date'] = arrow.utcnow() # Take a copy to correctly modify the call mocked_history = ohlcv_history.copy() - mocked_history['sell'] = 0 - mocked_history['buy'] = 0 - mocked_history.loc[1, 'sell'] = 1 + mocked_history['enter_long'] = 0 + mocked_history['exit_long'] = 0 + mocked_history['enter_short'] = 0 + mocked_history['exit_short'] = 0 + mocked_history.loc[1, 'exit_long'] = 1 - assert _STRATEGY.get_signal('ETH/BTC', '5m', mocked_history) == (False, True, None) - mocked_history.loc[1, 'sell'] = 0 - mocked_history.loc[1, 'buy'] = 1 + assert _STRATEGY.get_entry_signal('ETH/BTC', '5m', mocked_history) == (None, None) + assert _STRATEGY.get_exit_signal('ETH/BTC', '5m', mocked_history) == (False, True) + assert _STRATEGY.get_exit_signal('ETH/BTC', '5m', mocked_history, True) == (False, False) + mocked_history.loc[1, 'exit_long'] = 0 + mocked_history.loc[1, 'enter_long'] = 1 - assert _STRATEGY.get_signal('ETH/BTC', '5m', mocked_history) == (True, False, None) - mocked_history.loc[1, 'sell'] = 0 - mocked_history.loc[1, 'buy'] = 0 + assert _STRATEGY.get_entry_signal('ETH/BTC', '5m', mocked_history + ) == (SignalDirection.LONG, None) + assert _STRATEGY.get_exit_signal('ETH/BTC', '5m', mocked_history) == (True, False) + assert _STRATEGY.get_exit_signal('ETH/BTC', '5m', mocked_history, True) == (False, False) + mocked_history.loc[1, 'exit_long'] = 0 + mocked_history.loc[1, 'enter_long'] = 0 - assert _STRATEGY.get_signal('ETH/BTC', '5m', mocked_history) == (False, False, None) - mocked_history.loc[1, 'sell'] = 0 - mocked_history.loc[1, 'buy'] = 1 + assert _STRATEGY.get_entry_signal('ETH/BTC', '5m', mocked_history) == (None, None) + assert _STRATEGY.get_exit_signal('ETH/BTC', '5m', mocked_history) == (False, False) + assert _STRATEGY.get_exit_signal('ETH/BTC', '5m', mocked_history, True) == (False, False) + mocked_history.loc[1, 'exit_long'] = 0 + mocked_history.loc[1, 'enter_long'] = 1 mocked_history.loc[1, 'buy_tag'] = 'buy_signal_01' - assert _STRATEGY.get_signal('ETH/BTC', '5m', mocked_history) == (True, False, 'buy_signal_01') + assert _STRATEGY.get_entry_signal( + 'ETH/BTC', '5m', mocked_history) == (SignalDirection.LONG, 'buy_signal_01') + assert _STRATEGY.get_exit_signal('ETH/BTC', '5m', mocked_history) == (True, False) + assert _STRATEGY.get_exit_signal('ETH/BTC', '5m', mocked_history, True) == (False, False) + + mocked_history.loc[1, 'exit_long'] = 0 + mocked_history.loc[1, 'enter_long'] = 0 + mocked_history.loc[1, 'enter_short'] = 1 + mocked_history.loc[1, 'exit_short'] = 0 + assert _STRATEGY.get_entry_signal( + 'ETH/BTC', '5m', mocked_history) == (SignalDirection.SHORT, None) + assert _STRATEGY.get_exit_signal('ETH/BTC', '5m', mocked_history) == (False, False) + assert _STRATEGY.get_exit_signal('ETH/BTC', '5m', mocked_history, True) == (True, False) + + mocked_history.loc[1, 'enter_short'] = 0 + mocked_history.loc[1, 'exit_short'] = 1 + assert _STRATEGY.get_entry_signal( + 'ETH/BTC', '5m', mocked_history) == (None, None) + assert _STRATEGY.get_exit_signal('ETH/BTC', '5m', mocked_history) == (False, False) + assert _STRATEGY.get_exit_signal('ETH/BTC', '5m', mocked_history, True) == (False, True) def test_analyze_pair_empty(default_conf, mocker, caplog, ohlcv_history):