SellCheckTuple -> ExitCheckTuple
This commit is contained in:
parent
19692ff4e8
commit
2124438202
@ -29,7 +29,7 @@ from freqtrade.plugins.pairlistmanager import PairListManager
|
|||||||
from freqtrade.plugins.protectionmanager import ProtectionManager
|
from freqtrade.plugins.protectionmanager import ProtectionManager
|
||||||
from freqtrade.resolvers import ExchangeResolver, StrategyResolver
|
from freqtrade.resolvers import ExchangeResolver, StrategyResolver
|
||||||
from freqtrade.rpc import RPCManager
|
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.strategy.strategy_wrapper import strategy_safe_wrapper
|
||||||
from freqtrade.wallets import Wallets
|
from freqtrade.wallets import Wallets
|
||||||
|
|
||||||
@ -914,7 +914,7 @@ class FreqtradeBot(LoggingMixin):
|
|||||||
trade.stoploss_order_id = None
|
trade.stoploss_order_id = None
|
||||||
logger.error(f'Unable to place a stoploss order on exchange. {e}')
|
logger.error(f'Unable to place a stoploss order on exchange. {e}')
|
||||||
logger.warning('Exiting the trade forcefully')
|
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))
|
exit_type=ExitType.EMERGENCY_SELL))
|
||||||
|
|
||||||
except ExchangeError:
|
except ExchangeError:
|
||||||
@ -1030,7 +1030,7 @@ class FreqtradeBot(LoggingMixin):
|
|||||||
"""
|
"""
|
||||||
Check and execute trade exit
|
Check and execute trade exit
|
||||||
"""
|
"""
|
||||||
should_exit: SellCheckTuple = self.strategy.should_exit(
|
should_exit: ExitCheckTuple = self.strategy.should_exit(
|
||||||
trade,
|
trade,
|
||||||
exit_rate,
|
exit_rate,
|
||||||
datetime.now(timezone.utc),
|
datetime.now(timezone.utc),
|
||||||
@ -1102,7 +1102,7 @@ class FreqtradeBot(LoggingMixin):
|
|||||||
try:
|
try:
|
||||||
self.execute_trade_exit(
|
self.execute_trade_exit(
|
||||||
trade, order.get('price'),
|
trade, order.get('price'),
|
||||||
exit_reason=SellCheckTuple(exit_type=ExitType.EMERGENCY_SELL))
|
exit_reason=ExitCheckTuple(exit_type=ExitType.EMERGENCY_SELL))
|
||||||
except DependencyException as exception:
|
except DependencyException as exception:
|
||||||
logger.warning(
|
logger.warning(
|
||||||
f'Unable to emergency sell trade {trade.pair}: {exception}')
|
f'Unable to emergency sell trade {trade.pair}: {exception}')
|
||||||
@ -1266,7 +1266,7 @@ class FreqtradeBot(LoggingMixin):
|
|||||||
self,
|
self,
|
||||||
trade: Trade,
|
trade: Trade,
|
||||||
limit: float,
|
limit: float,
|
||||||
exit_reason: SellCheckTuple,
|
exit_reason: ExitCheckTuple,
|
||||||
*,
|
*,
|
||||||
exit_tag: Optional[str] = None,
|
exit_tag: Optional[str] = None,
|
||||||
ordertype: Optional[str] = None,
|
ordertype: Optional[str] = None,
|
||||||
|
@ -28,7 +28,7 @@ from freqtrade.persistence import LocalTrade, PairLocks, Trade
|
|||||||
from freqtrade.plugins.pairlistmanager import PairListManager
|
from freqtrade.plugins.pairlistmanager import PairListManager
|
||||||
from freqtrade.plugins.protectionmanager import ProtectionManager
|
from freqtrade.plugins.protectionmanager import ProtectionManager
|
||||||
from freqtrade.resolvers import ExchangeResolver, StrategyResolver
|
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.strategy.strategy_wrapper import strategy_safe_wrapper
|
||||||
from freqtrade.wallets import Wallets
|
from freqtrade.wallets import Wallets
|
||||||
|
|
||||||
@ -308,7 +308,7 @@ class Backtesting:
|
|||||||
processed[pair] = pair_data = None
|
processed[pair] = pair_data = None
|
||||||
return data
|
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:
|
trade_dur: int) -> float:
|
||||||
"""
|
"""
|
||||||
Get close rate for backtesting result
|
Get close rate for backtesting result
|
||||||
|
@ -26,7 +26,7 @@ from freqtrade.persistence import PairLocks, Trade
|
|||||||
from freqtrade.persistence.models import PairLock
|
from freqtrade.persistence.models import PairLock
|
||||||
from freqtrade.plugins.pairlist.pairlist_helpers import expand_pairlist
|
from freqtrade.plugins.pairlist.pairlist_helpers import expand_pairlist
|
||||||
from freqtrade.rpc.fiat_convert import CryptoToFiatConverter
|
from freqtrade.rpc.fiat_convert import CryptoToFiatConverter
|
||||||
from freqtrade.strategy.interface import SellCheckTuple
|
from freqtrade.strategy.interface import ExitCheckTuple
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@ -672,7 +672,7 @@ class RPC:
|
|||||||
closing_side = "buy" if trade.is_short else "sell"
|
closing_side = "buy" if trade.is_short else "sell"
|
||||||
current_rate = self._freqtrade.exchange.get_rate(
|
current_rate = self._freqtrade.exchange.get_rate(
|
||||||
trade.pair, refresh=False, side=closing_side)
|
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(
|
order_type = ordertype or self._freqtrade.strategy.order_types.get(
|
||||||
"forcesell", self._freqtrade.strategy.order_types["sell"])
|
"forcesell", self._freqtrade.strategy.order_types["sell"])
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ logger = logging.getLogger(__name__)
|
|||||||
CUSTOM_SELL_MAX_LENGTH = 64
|
CUSTOM_SELL_MAX_LENGTH = 64
|
||||||
|
|
||||||
|
|
||||||
class SellCheckTuple:
|
class ExitCheckTuple:
|
||||||
"""
|
"""
|
||||||
NamedTuple for Sell type + reason
|
NamedTuple for Sell type + reason
|
||||||
"""
|
"""
|
||||||
@ -756,7 +756,7 @@ class IStrategy(ABC, HyperStrategyMixin):
|
|||||||
def should_exit(self, trade: Trade, rate: float, date: datetime, *,
|
def should_exit(self, trade: Trade, rate: float, date: datetime, *,
|
||||||
enter: bool, exit_: bool,
|
enter: bool, exit_: bool,
|
||||||
low: float = None, high: float = None,
|
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
|
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.
|
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. "
|
logger.debug(f"{trade.pair} - Sell signal received. "
|
||||||
f"exit_type=ExitType.{exit_signal.name}" +
|
f"exit_type=ExitType.{exit_signal.name}" +
|
||||||
(f", custom_reason={custom_reason}" if custom_reason else ""))
|
(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:
|
# Sequence:
|
||||||
# Exit-signal
|
# Exit-signal
|
||||||
@ -823,7 +823,7 @@ class IStrategy(ABC, HyperStrategyMixin):
|
|||||||
# Stoploss
|
# Stoploss
|
||||||
if roi_reached and stoplossflag.exit_type != ExitType.STOP_LOSS:
|
if roi_reached and stoplossflag.exit_type != ExitType.STOP_LOSS:
|
||||||
logger.debug(f"{trade.pair} - Required profit reached. exit_type=ExitType.ROI")
|
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:
|
if stoplossflag.sell_flag:
|
||||||
|
|
||||||
@ -832,12 +832,12 @@ class IStrategy(ABC, HyperStrategyMixin):
|
|||||||
|
|
||||||
# This one is noisy, commented out...
|
# This one is noisy, commented out...
|
||||||
# logger.debug(f"{trade.pair} - No exit signal.")
|
# 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,
|
def stop_loss_reached(self, current_rate: float, trade: Trade,
|
||||||
current_time: datetime, current_profit: float,
|
current_time: datetime, current_profit: float,
|
||||||
force_stoploss: float, low: float = None,
|
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,
|
Based on current profit of the trade and configured (trailing) stoploss,
|
||||||
decides to exit or not
|
decides to exit or not
|
||||||
@ -915,9 +915,9 @@ class IStrategy(ABC, HyperStrategyMixin):
|
|||||||
logger.debug(f"{trade.pair} - Trailing stop saved "
|
logger.debug(f"{trade.pair} - Trailing stop saved "
|
||||||
f"{new_stoploss:.6f}")
|
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]]:
|
def min_roi_reached_entry(self, trade_dur: int) -> Tuple[Optional[int], Optional[float]]:
|
||||||
"""
|
"""
|
||||||
|
@ -18,7 +18,7 @@ from freqtrade.persistence import PairLocks, Trade
|
|||||||
from freqtrade.resolvers import StrategyResolver
|
from freqtrade.resolvers import StrategyResolver
|
||||||
from freqtrade.strategy.hyper import (BaseParameter, BooleanParameter, CategoricalParameter,
|
from freqtrade.strategy.hyper import (BaseParameter, BooleanParameter, CategoricalParameter,
|
||||||
DecimalParameter, IntParameter, RealParameter)
|
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 freqtrade.strategy.strategy_wrapper import strategy_safe_wrapper
|
||||||
from tests.conftest import CURRENT_TEST_STRATEGY, TRADE_SIDES, log_has, log_has_re
|
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,
|
sl_flag = strategy.stop_loss_reached(current_rate=trade.open_rate * (1 + profit), trade=trade,
|
||||||
current_time=now, current_profit=profit,
|
current_time=now, current_profit=profit,
|
||||||
force_stoploss=0, high=None)
|
force_stoploss=0, high=None)
|
||||||
assert isinstance(sl_flag, SellCheckTuple)
|
assert isinstance(sl_flag, ExitCheckTuple)
|
||||||
assert sl_flag.exit_type == expected
|
assert sl_flag.exit_type == expected
|
||||||
if expected == ExitType.NONE:
|
if expected == ExitType.NONE:
|
||||||
assert sl_flag.sell_flag is False
|
assert sl_flag.sell_flag is False
|
||||||
|
@ -19,7 +19,7 @@ from freqtrade.exceptions import (DependencyException, ExchangeError, Insufficie
|
|||||||
from freqtrade.freqtradebot import FreqtradeBot
|
from freqtrade.freqtradebot import FreqtradeBot
|
||||||
from freqtrade.persistence import Order, PairLocks, Trade
|
from freqtrade.persistence import Order, PairLocks, Trade
|
||||||
from freqtrade.persistence.models import PairLock
|
from freqtrade.persistence.models import PairLock
|
||||||
from freqtrade.strategy.interface import SellCheckTuple
|
from freqtrade.strategy.interface import ExitCheckTuple
|
||||||
from freqtrade.worker import Worker
|
from freqtrade.worker import Worker
|
||||||
from tests.conftest import (create_mock_trades, get_patched_freqtradebot, get_patched_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,
|
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(
|
freqtrade.execute_trade_exit(
|
||||||
trade=trade,
|
trade=trade,
|
||||||
limit=(ticker_usdt_sell_down()['ask'] if is_short else ticker_usdt_sell_up()['bid']),
|
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 rpc_mock.call_count == 0
|
||||||
assert freqtrade.strategy.confirm_trade_exit.call_count == 1
|
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(
|
freqtrade.execute_trade_exit(
|
||||||
trade=trade,
|
trade=trade,
|
||||||
limit=(ticker_usdt_sell_down()['ask'] if is_short else ticker_usdt_sell_up()['bid']),
|
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
|
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(
|
freqtrade.execute_trade_exit(
|
||||||
trade=trade, limit=(ticker_usdt_sell_up if is_short else ticker_usdt_sell_down)()['bid'],
|
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
|
assert rpc_mock.call_count == 2
|
||||||
last_msg = rpc_mock.call_args_list[-1][0][0]
|
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(
|
freqtrade.execute_trade_exit(
|
||||||
trade=trade,
|
trade=trade,
|
||||||
limit=ticker_usdt_sell_up()['ask' if is_short else 'bid'],
|
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
|
# 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
|
trade.stop_loss = 2.0 * 1.01 if is_short else 2.0 * 0.99
|
||||||
freqtrade.execute_trade_exit(
|
freqtrade.execute_trade_exit(
|
||||||
trade=trade, limit=(ticker_usdt_sell_up if is_short else ticker_usdt_sell_down())['bid'],
|
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
|
assert rpc_mock.call_count == 2
|
||||||
last_msg = rpc_mock.call_args_list[-1][0][0]
|
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"
|
trade.stoploss_order_id = "abcd"
|
||||||
|
|
||||||
freqtrade.execute_trade_exit(trade=trade, limit=1234,
|
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 create_order_mock.call_count == 2
|
||||||
assert log_has('Could not cancel stoploss order abcd', caplog)
|
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(
|
freqtrade.execute_trade_exit(
|
||||||
trade=trade,
|
trade=trade,
|
||||||
limit=ticker_usdt_sell_up()['ask' if is_short else 'bid'],
|
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()
|
trade = Trade.query.first()
|
||||||
@ -3328,7 +3328,7 @@ def test_execute_trade_exit_market_order(
|
|||||||
freqtrade.execute_trade_exit(
|
freqtrade.execute_trade_exit(
|
||||||
trade=trade,
|
trade=trade,
|
||||||
limit=ticker_usdt_sell_up()['ask' if is_short else 'bid'],
|
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
|
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
|
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(
|
assert not freqtrade.execute_trade_exit(
|
||||||
trade=trade,
|
trade=trade,
|
||||||
limit=ticker_usdt_sell_up()['ask' if is_short else 'bid'],
|
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:
|
if exit_type == ExitType.EXIT_SIGNAL.value:
|
||||||
freqtrade.strategy.min_roi_reached = MagicMock(return_value=False)
|
freqtrade.strategy.min_roi_reached = MagicMock(return_value=False)
|
||||||
else:
|
else:
|
||||||
freqtrade.strategy.stop_loss_reached = MagicMock(return_value=SellCheckTuple(
|
freqtrade.strategy.stop_loss_reached = MagicMock(return_value=ExitCheckTuple(
|
||||||
exit_type=ExitType.NONE))
|
exit_type=ExitType.NONE))
|
||||||
freqtrade.enter_positions()
|
freqtrade.enter_positions()
|
||||||
|
|
||||||
@ -3561,7 +3561,7 @@ def test_locked_pairs(default_conf_usdt, ticker_usdt, fee,
|
|||||||
freqtrade.execute_trade_exit(
|
freqtrade.execute_trade_exit(
|
||||||
trade=trade,
|
trade=trade,
|
||||||
limit=ticker_usdt_sell_down()['ask' if is_short else 'bid'],
|
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'])
|
trade.close(ticker_usdt_sell_down()['bid'])
|
||||||
assert freqtrade.strategy.is_pair_locked(trade.pair)
|
assert freqtrade.strategy.is_pair_locked(trade.pair)
|
||||||
@ -4920,7 +4920,7 @@ def test_update_funding_fees(
|
|||||||
trade=trade,
|
trade=trade,
|
||||||
# The values of the next 2 params are irrelevant for this test
|
# The values of the next 2 params are irrelevant for this test
|
||||||
limit=ticker_usdt_sell_up()['bid'],
|
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(
|
assert trade.funding_fees == pytest.approx(sum(
|
||||||
trade.amount *
|
trade.amount *
|
||||||
|
@ -5,7 +5,7 @@ import pytest
|
|||||||
from freqtrade.enums import ExitType
|
from freqtrade.enums import ExitType
|
||||||
from freqtrade.persistence import Trade
|
from freqtrade.persistence import Trade
|
||||||
from freqtrade.rpc.rpc import RPC
|
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
|
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])
|
side_effect=[stoploss_order_closed, stoploss_order_open, stoploss_order_open])
|
||||||
# Sell 3rd trade (not called for the first trade)
|
# Sell 3rd trade (not called for the first trade)
|
||||||
should_sell_mock = MagicMock(side_effect=[
|
should_sell_mock = MagicMock(side_effect=[
|
||||||
SellCheckTuple(exit_type=ExitType.NONE),
|
ExitCheckTuple(exit_type=ExitType.NONE),
|
||||||
SellCheckTuple(exit_type=ExitType.EXIT_SIGNAL)]
|
ExitCheckTuple(exit_type=ExitType.EXIT_SIGNAL)]
|
||||||
)
|
)
|
||||||
cancel_order_mock = MagicMock()
|
cancel_order_mock = MagicMock()
|
||||||
mocker.patch('freqtrade.exchange.Binance.stoploss', stoploss)
|
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(),
|
_notify_exit=MagicMock(),
|
||||||
)
|
)
|
||||||
should_sell_mock = MagicMock(side_effect=[
|
should_sell_mock = MagicMock(side_effect=[
|
||||||
SellCheckTuple(exit_type=ExitType.NONE),
|
ExitCheckTuple(exit_type=ExitType.NONE),
|
||||||
SellCheckTuple(exit_type=ExitType.EXIT_SIGNAL),
|
ExitCheckTuple(exit_type=ExitType.EXIT_SIGNAL),
|
||||||
SellCheckTuple(exit_type=ExitType.NONE),
|
ExitCheckTuple(exit_type=ExitType.NONE),
|
||||||
SellCheckTuple(exit_type=ExitType.NONE),
|
ExitCheckTuple(exit_type=ExitType.NONE),
|
||||||
SellCheckTuple(exit_type=ExitType.NONE)]
|
ExitCheckTuple(exit_type=ExitType.NONE)]
|
||||||
)
|
)
|
||||||
mocker.patch("freqtrade.strategy.interface.IStrategy.should_exit", should_sell_mock)
|
mocker.patch("freqtrade.strategy.interface.IStrategy.should_exit", should_sell_mock)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user