SellCheckTuple -> ExitCheckTuple

This commit is contained in:
Sam Germain 2022-01-04 23:03:58 -06:00
parent 19692ff4e8
commit 2124438202
7 changed files with 40 additions and 40 deletions

View File

@ -29,7 +29,7 @@ from freqtrade.plugins.pairlistmanager import PairListManager
from freqtrade.plugins.protectionmanager import ProtectionManager
from freqtrade.resolvers import ExchangeResolver, StrategyResolver
from freqtrade.rpc import RPCManager
from freqtrade.strategy.interface import IStrategy, SellCheckTuple
from freqtrade.strategy.interface import IStrategy, ExitCheckTuple
from freqtrade.strategy.strategy_wrapper import strategy_safe_wrapper
from freqtrade.wallets import Wallets
@ -914,7 +914,7 @@ class FreqtradeBot(LoggingMixin):
trade.stoploss_order_id = None
logger.error(f'Unable to place a stoploss order on exchange. {e}')
logger.warning('Exiting the trade forcefully')
self.execute_trade_exit(trade, trade.stop_loss, exit_reason=SellCheckTuple(
self.execute_trade_exit(trade, trade.stop_loss, exit_reason=ExitCheckTuple(
exit_type=ExitType.EMERGENCY_SELL))
except ExchangeError:
@ -1030,7 +1030,7 @@ class FreqtradeBot(LoggingMixin):
"""
Check and execute trade exit
"""
should_exit: SellCheckTuple = self.strategy.should_exit(
should_exit: ExitCheckTuple = self.strategy.should_exit(
trade,
exit_rate,
datetime.now(timezone.utc),
@ -1102,7 +1102,7 @@ class FreqtradeBot(LoggingMixin):
try:
self.execute_trade_exit(
trade, order.get('price'),
exit_reason=SellCheckTuple(exit_type=ExitType.EMERGENCY_SELL))
exit_reason=ExitCheckTuple(exit_type=ExitType.EMERGENCY_SELL))
except DependencyException as exception:
logger.warning(
f'Unable to emergency sell trade {trade.pair}: {exception}')
@ -1266,7 +1266,7 @@ class FreqtradeBot(LoggingMixin):
self,
trade: Trade,
limit: float,
exit_reason: SellCheckTuple,
exit_reason: ExitCheckTuple,
*,
exit_tag: Optional[str] = None,
ordertype: Optional[str] = None,

View File

@ -28,7 +28,7 @@ from freqtrade.persistence import LocalTrade, PairLocks, Trade
from freqtrade.plugins.pairlistmanager import PairListManager
from freqtrade.plugins.protectionmanager import ProtectionManager
from freqtrade.resolvers import ExchangeResolver, StrategyResolver
from freqtrade.strategy.interface import IStrategy, SellCheckTuple
from freqtrade.strategy.interface import IStrategy, ExitCheckTuple
from freqtrade.strategy.strategy_wrapper import strategy_safe_wrapper
from freqtrade.wallets import Wallets
@ -308,7 +308,7 @@ class Backtesting:
processed[pair] = pair_data = None
return data
def _get_close_rate(self, sell_row: Tuple, trade: LocalTrade, sell: SellCheckTuple,
def _get_close_rate(self, sell_row: Tuple, trade: LocalTrade, sell: ExitCheckTuple,
trade_dur: int) -> float:
"""
Get close rate for backtesting result

View File

@ -26,7 +26,7 @@ from freqtrade.persistence import PairLocks, Trade
from freqtrade.persistence.models import PairLock
from freqtrade.plugins.pairlist.pairlist_helpers import expand_pairlist
from freqtrade.rpc.fiat_convert import CryptoToFiatConverter
from freqtrade.strategy.interface import SellCheckTuple
from freqtrade.strategy.interface import ExitCheckTuple
logger = logging.getLogger(__name__)
@ -672,7 +672,7 @@ class RPC:
closing_side = "buy" if trade.is_short else "sell"
current_rate = self._freqtrade.exchange.get_rate(
trade.pair, refresh=False, side=closing_side)
exit_reason = SellCheckTuple(exit_type=ExitType.FORCE_SELL)
exit_reason = ExitCheckTuple(exit_type=ExitType.FORCE_SELL)
order_type = ordertype or self._freqtrade.strategy.order_types.get(
"forcesell", self._freqtrade.strategy.order_types["sell"])

View File

@ -30,7 +30,7 @@ logger = logging.getLogger(__name__)
CUSTOM_SELL_MAX_LENGTH = 64
class SellCheckTuple:
class ExitCheckTuple:
"""
NamedTuple for Sell type + reason
"""
@ -756,7 +756,7 @@ class IStrategy(ABC, HyperStrategyMixin):
def should_exit(self, trade: Trade, rate: float, date: datetime, *,
enter: bool, exit_: bool,
low: float = None, high: float = None,
force_stoploss: float = 0) -> SellCheckTuple:
force_stoploss: float = 0) -> ExitCheckTuple:
"""
This function evaluates if one of the conditions required to trigger an exit order
has been reached, which can either be a stop-loss, ROI or exit-signal.
@ -815,7 +815,7 @@ class IStrategy(ABC, HyperStrategyMixin):
logger.debug(f"{trade.pair} - Sell signal received. "
f"exit_type=ExitType.{exit_signal.name}" +
(f", custom_reason={custom_reason}" if custom_reason else ""))
return SellCheckTuple(exit_type=exit_signal, exit_reason=custom_reason)
return ExitCheckTuple(exit_type=exit_signal, exit_reason=custom_reason)
# Sequence:
# Exit-signal
@ -823,7 +823,7 @@ class IStrategy(ABC, HyperStrategyMixin):
# Stoploss
if roi_reached and stoplossflag.exit_type != ExitType.STOP_LOSS:
logger.debug(f"{trade.pair} - Required profit reached. exit_type=ExitType.ROI")
return SellCheckTuple(exit_type=ExitType.ROI)
return ExitCheckTuple(exit_type=ExitType.ROI)
if stoplossflag.sell_flag:
@ -832,12 +832,12 @@ class IStrategy(ABC, HyperStrategyMixin):
# This one is noisy, commented out...
# logger.debug(f"{trade.pair} - No exit signal.")
return SellCheckTuple(exit_type=ExitType.NONE)
return ExitCheckTuple(exit_type=ExitType.NONE)
def stop_loss_reached(self, current_rate: float, trade: Trade,
current_time: datetime, current_profit: float,
force_stoploss: float, low: float = None,
high: float = None) -> SellCheckTuple:
high: float = None) -> ExitCheckTuple:
"""
Based on current profit of the trade and configured (trailing) stoploss,
decides to exit or not
@ -915,9 +915,9 @@ class IStrategy(ABC, HyperStrategyMixin):
logger.debug(f"{trade.pair} - Trailing stop saved "
f"{new_stoploss:.6f}")
return SellCheckTuple(exit_type=exit_type)
return ExitCheckTuple(exit_type=exit_type)
return SellCheckTuple(exit_type=ExitType.NONE)
return ExitCheckTuple(exit_type=ExitType.NONE)
def min_roi_reached_entry(self, trade_dur: int) -> Tuple[Optional[int], Optional[float]]:
"""

View File

@ -18,7 +18,7 @@ from freqtrade.persistence import PairLocks, Trade
from freqtrade.resolvers import StrategyResolver
from freqtrade.strategy.hyper import (BaseParameter, BooleanParameter, CategoricalParameter,
DecimalParameter, IntParameter, RealParameter)
from freqtrade.strategy.interface import SellCheckTuple
from freqtrade.strategy.interface import ExitCheckTuple
from freqtrade.strategy.strategy_wrapper import strategy_safe_wrapper
from tests.conftest import CURRENT_TEST_STRATEGY, TRADE_SIDES, log_has, log_has_re
@ -439,7 +439,7 @@ def test_stop_loss_reached(default_conf, fee, profit, adjusted, expected, traili
sl_flag = strategy.stop_loss_reached(current_rate=trade.open_rate * (1 + profit), trade=trade,
current_time=now, current_profit=profit,
force_stoploss=0, high=None)
assert isinstance(sl_flag, SellCheckTuple)
assert isinstance(sl_flag, ExitCheckTuple)
assert sl_flag.exit_type == expected
if expected == ExitType.NONE:
assert sl_flag.sell_flag is False

View File

@ -19,7 +19,7 @@ from freqtrade.exceptions import (DependencyException, ExchangeError, Insufficie
from freqtrade.freqtradebot import FreqtradeBot
from freqtrade.persistence import Order, PairLocks, Trade
from freqtrade.persistence.models import PairLock
from freqtrade.strategy.interface import SellCheckTuple
from freqtrade.strategy.interface import ExitCheckTuple
from freqtrade.worker import Worker
from tests.conftest import (create_mock_trades, get_patched_freqtradebot, get_patched_worker,
log_has, log_has_re, patch_edge, patch_exchange, patch_get_signal,
@ -2855,7 +2855,7 @@ def test_execute_trade_exit_up(default_conf_usdt, ticker_usdt, fee, ticker_usdt_
freqtrade.execute_trade_exit(
trade=trade,
limit=(ticker_usdt_sell_down()['ask'] if is_short else ticker_usdt_sell_up()['bid']),
exit_reason=SellCheckTuple(exit_type=ExitType.ROI)
exit_reason=ExitCheckTuple(exit_type=ExitType.ROI)
)
assert rpc_mock.call_count == 0
assert freqtrade.strategy.confirm_trade_exit.call_count == 1
@ -2867,7 +2867,7 @@ def test_execute_trade_exit_up(default_conf_usdt, ticker_usdt, fee, ticker_usdt_
freqtrade.execute_trade_exit(
trade=trade,
limit=(ticker_usdt_sell_down()['ask'] if is_short else ticker_usdt_sell_up()['bid']),
exit_reason=SellCheckTuple(exit_type=ExitType.ROI)
exit_reason=ExitCheckTuple(exit_type=ExitType.ROI)
)
assert freqtrade.strategy.confirm_trade_exit.call_count == 1
@ -2928,7 +2928,7 @@ def test_execute_trade_exit_down(default_conf_usdt, ticker_usdt, fee, ticker_usd
)
freqtrade.execute_trade_exit(
trade=trade, limit=(ticker_usdt_sell_up if is_short else ticker_usdt_sell_down)()['bid'],
exit_reason=SellCheckTuple(exit_type=ExitType.STOP_LOSS))
exit_reason=ExitCheckTuple(exit_type=ExitType.STOP_LOSS))
assert rpc_mock.call_count == 2
last_msg = rpc_mock.call_args_list[-1][0][0]
@ -3003,7 +3003,7 @@ def test_execute_trade_exit_custom_exit_price(
freqtrade.execute_trade_exit(
trade=trade,
limit=ticker_usdt_sell_up()['ask' if is_short else 'bid'],
exit_reason=SellCheckTuple(exit_type=ExitType.EXIT_SIGNAL)
exit_reason=ExitCheckTuple(exit_type=ExitType.EXIT_SIGNAL)
)
# Sell price must be different to default bid price
@ -3074,7 +3074,7 @@ def test_execute_trade_exit_down_stoploss_on_exchange_dry_run(
trade.stop_loss = 2.0 * 1.01 if is_short else 2.0 * 0.99
freqtrade.execute_trade_exit(
trade=trade, limit=(ticker_usdt_sell_up if is_short else ticker_usdt_sell_down())['bid'],
exit_reason=SellCheckTuple(exit_type=ExitType.STOP_LOSS))
exit_reason=ExitCheckTuple(exit_type=ExitType.STOP_LOSS))
assert rpc_mock.call_count == 2
last_msg = rpc_mock.call_args_list[-1][0][0]
@ -3134,7 +3134,7 @@ def test_execute_trade_exit_sloe_cancel_exception(
trade.stoploss_order_id = "abcd"
freqtrade.execute_trade_exit(trade=trade, limit=1234,
exit_reason=SellCheckTuple(exit_type=ExitType.STOP_LOSS))
exit_reason=ExitCheckTuple(exit_type=ExitType.STOP_LOSS))
assert create_order_mock.call_count == 2
assert log_has('Could not cancel stoploss order abcd', caplog)
@ -3189,7 +3189,7 @@ def test_execute_trade_exit_with_stoploss_on_exchange(
freqtrade.execute_trade_exit(
trade=trade,
limit=ticker_usdt_sell_up()['ask' if is_short else 'bid'],
exit_reason=SellCheckTuple(exit_type=ExitType.STOP_LOSS)
exit_reason=ExitCheckTuple(exit_type=ExitType.STOP_LOSS)
)
trade = Trade.query.first()
@ -3328,7 +3328,7 @@ def test_execute_trade_exit_market_order(
freqtrade.execute_trade_exit(
trade=trade,
limit=ticker_usdt_sell_up()['ask' if is_short else 'bid'],
exit_reason=SellCheckTuple(exit_type=ExitType.ROI)
exit_reason=ExitCheckTuple(exit_type=ExitType.ROI)
)
assert not trade.is_open
@ -3392,7 +3392,7 @@ def test_execute_trade_exit_insufficient_funds_error(default_conf_usdt, ticker_u
fetch_ticker=ticker_usdt_sell_up
)
exit_reason = SellCheckTuple(exit_type=ExitType.ROI)
exit_reason = ExitCheckTuple(exit_type=ExitType.ROI)
assert not freqtrade.execute_trade_exit(
trade=trade,
limit=ticker_usdt_sell_up()['ask' if is_short else 'bid'],
@ -3444,7 +3444,7 @@ def test_sell_profit_only(
if exit_type == ExitType.EXIT_SIGNAL.value:
freqtrade.strategy.min_roi_reached = MagicMock(return_value=False)
else:
freqtrade.strategy.stop_loss_reached = MagicMock(return_value=SellCheckTuple(
freqtrade.strategy.stop_loss_reached = MagicMock(return_value=ExitCheckTuple(
exit_type=ExitType.NONE))
freqtrade.enter_positions()
@ -3561,7 +3561,7 @@ def test_locked_pairs(default_conf_usdt, ticker_usdt, fee,
freqtrade.execute_trade_exit(
trade=trade,
limit=ticker_usdt_sell_down()['ask' if is_short else 'bid'],
exit_reason=SellCheckTuple(exit_type=ExitType.STOP_LOSS)
exit_reason=ExitCheckTuple(exit_type=ExitType.STOP_LOSS)
)
trade.close(ticker_usdt_sell_down()['bid'])
assert freqtrade.strategy.is_pair_locked(trade.pair)
@ -4920,7 +4920,7 @@ def test_update_funding_fees(
trade=trade,
# The values of the next 2 params are irrelevant for this test
limit=ticker_usdt_sell_up()['bid'],
exit_reason=SellCheckTuple(exit_type=ExitType.ROI)
exit_reason=ExitCheckTuple(exit_type=ExitType.ROI)
)
assert trade.funding_fees == pytest.approx(sum(
trade.amount *

View File

@ -5,7 +5,7 @@ import pytest
from freqtrade.enums import ExitType
from freqtrade.persistence import Trade
from freqtrade.rpc.rpc import RPC
from freqtrade.strategy.interface import SellCheckTuple
from freqtrade.strategy.interface import ExitCheckTuple
from tests.conftest import get_patched_freqtradebot, patch_get_signal
@ -52,8 +52,8 @@ def test_may_execute_exit_stoploss_on_exchange_multi(default_conf, ticker, fee,
side_effect=[stoploss_order_closed, stoploss_order_open, stoploss_order_open])
# Sell 3rd trade (not called for the first trade)
should_sell_mock = MagicMock(side_effect=[
SellCheckTuple(exit_type=ExitType.NONE),
SellCheckTuple(exit_type=ExitType.EXIT_SIGNAL)]
ExitCheckTuple(exit_type=ExitType.NONE),
ExitCheckTuple(exit_type=ExitType.EXIT_SIGNAL)]
)
cancel_order_mock = MagicMock()
mocker.patch('freqtrade.exchange.Binance.stoploss', stoploss)
@ -157,11 +157,11 @@ def test_forcebuy_last_unlimited(default_conf, ticker, fee, limit_buy_order, moc
_notify_exit=MagicMock(),
)
should_sell_mock = MagicMock(side_effect=[
SellCheckTuple(exit_type=ExitType.NONE),
SellCheckTuple(exit_type=ExitType.EXIT_SIGNAL),
SellCheckTuple(exit_type=ExitType.NONE),
SellCheckTuple(exit_type=ExitType.NONE),
SellCheckTuple(exit_type=ExitType.NONE)]
ExitCheckTuple(exit_type=ExitType.NONE),
ExitCheckTuple(exit_type=ExitType.EXIT_SIGNAL),
ExitCheckTuple(exit_type=ExitType.NONE),
ExitCheckTuple(exit_type=ExitType.NONE),
ExitCheckTuple(exit_type=ExitType.NONE)]
)
mocker.patch("freqtrade.strategy.interface.IStrategy.should_exit", should_sell_mock)