use_sell_signal -> use_exit_signal
This commit is contained in:
parent
5ce5c70be6
commit
4897731030
|
@ -15,7 +15,7 @@
|
||||||
"trailing_stop_positive": 0.005,
|
"trailing_stop_positive": 0.005,
|
||||||
"trailing_stop_positive_offset": 0.0051,
|
"trailing_stop_positive_offset": 0.0051,
|
||||||
"trailing_only_offset_is_reached": false,
|
"trailing_only_offset_is_reached": false,
|
||||||
"use_sell_signal": true,
|
"use_exit_signal": true,
|
||||||
"exit_profit_only": false,
|
"exit_profit_only": false,
|
||||||
"exit_profit_offset": 0.0,
|
"exit_profit_offset": 0.0,
|
||||||
"ignore_roi_if_buy_signal": false,
|
"ignore_roi_if_buy_signal": false,
|
||||||
|
|
|
@ -116,10 +116,10 @@ Mandatory parameters are marked as **Required**, which means that they are requi
|
||||||
| `exit_pricing.price_last_balance` | Interpolate the exiting price. More information [below](#exit-price-without-orderbook-enabled).
|
| `exit_pricing.price_last_balance` | Interpolate the exiting price. More information [below](#exit-price-without-orderbook-enabled).
|
||||||
| `exit_pricing.use_order_book` | Enable exiting of open trades using [Order Book Exit](#exit-price-with-orderbook-enabled). <br> *Defaults to `True`.*<br> **Datatype:** Boolean
|
| `exit_pricing.use_order_book` | Enable exiting of open trades using [Order Book Exit](#exit-price-with-orderbook-enabled). <br> *Defaults to `True`.*<br> **Datatype:** Boolean
|
||||||
| `exit_pricing.order_book_top` | Bot will use the top N rate in Order Book "price_side" to sell. I.e. a value of 2 will allow the bot to pick the 2nd ask rate in [Order Book Exit](#exit-price-with-orderbook-enabled)<br>*Defaults to `1`.* <br> **Datatype:** Positive Integer
|
| `exit_pricing.order_book_top` | Bot will use the top N rate in Order Book "price_side" to sell. I.e. a value of 2 will allow the bot to pick the 2nd ask rate in [Order Book Exit](#exit-price-with-orderbook-enabled)<br>*Defaults to `1`.* <br> **Datatype:** Positive Integer
|
||||||
| `use_sell_signal` | Use sell signals produced by the strategy in addition to the `minimal_roi`. [Strategy Override](#parameters-in-the-strategy). <br>*Defaults to `true`.* <br> **Datatype:** Boolean
|
| `use_exit_signal` | Use sell signals produced by the strategy in addition to the `minimal_roi`. [Strategy Override](#parameters-in-the-strategy). <br>*Defaults to `true`.* <br> **Datatype:** Boolean
|
||||||
| `exit_profit_only` | Wait until the bot reaches `exit_profit_offset` before taking an exit decision. [Strategy Override](#parameters-in-the-strategy). <br>*Defaults to `false`.* <br> **Datatype:** Boolean
|
| `exit_profit_only` | Wait until the bot reaches `exit_profit_offset` before taking an exit decision. [Strategy Override](#parameters-in-the-strategy). <br>*Defaults to `false`.* <br> **Datatype:** Boolean
|
||||||
| `exit_profit_offset` | Sell-signal is only active above this value. Only active in combination with `exit_profit_only=True`. [Strategy Override](#parameters-in-the-strategy). <br>*Defaults to `0.0`.* <br> **Datatype:** Float (as ratio)
|
| `exit_profit_offset` | Sell-signal is only active above this value. Only active in combination with `exit_profit_only=True`. [Strategy Override](#parameters-in-the-strategy). <br>*Defaults to `0.0`.* <br> **Datatype:** Float (as ratio)
|
||||||
| `ignore_roi_if_buy_signal` | Do not sell if the buy signal is still active. This setting takes preference over `minimal_roi` and `use_sell_signal`. [Strategy Override](#parameters-in-the-strategy). <br>*Defaults to `false`.* <br> **Datatype:** Boolean
|
| `ignore_roi_if_buy_signal` | Do not sell if the buy signal is still active. This setting takes preference over `minimal_roi` and `use_exit_signal`. [Strategy Override](#parameters-in-the-strategy). <br>*Defaults to `false`.* <br> **Datatype:** Boolean
|
||||||
| `ignore_buying_expired_candle_after` | Specifies the number of seconds until a buy signal is no longer used. <br> **Datatype:** Integer
|
| `ignore_buying_expired_candle_after` | Specifies the number of seconds until a buy signal is no longer used. <br> **Datatype:** Integer
|
||||||
| `order_types` | Configure order-types depending on the action (`"entry"`, `"exit"`, `"stoploss"`, `"stoploss_on_exchange"`). [More information below](#understand-order_types). [Strategy Override](#parameters-in-the-strategy).<br> **Datatype:** Dict
|
| `order_types` | Configure order-types depending on the action (`"entry"`, `"exit"`, `"stoploss"`, `"stoploss_on_exchange"`). [More information below](#understand-order_types). [Strategy Override](#parameters-in-the-strategy).<br> **Datatype:** Dict
|
||||||
| `order_time_in_force` | Configure time in force for entry and exit orders. [More information below](#understand-order_time_in_force). [Strategy Override](#parameters-in-the-strategy). <br> **Datatype:** Dict
|
| `order_time_in_force` | Configure time in force for entry and exit orders. [More information below](#understand-order_time_in_force). [Strategy Override](#parameters-in-the-strategy). <br> **Datatype:** Dict
|
||||||
|
@ -198,7 +198,7 @@ Values set in the configuration file always overwrite values set in the strategy
|
||||||
* `order_time_in_force`
|
* `order_time_in_force`
|
||||||
* `unfilledtimeout`
|
* `unfilledtimeout`
|
||||||
* `disable_dataframe_checks`
|
* `disable_dataframe_checks`
|
||||||
* `use_sell_signal`
|
- `use_exit_signal`
|
||||||
* `exit_profit_only`
|
* `exit_profit_only`
|
||||||
- `exit_profit_offset`
|
- `exit_profit_offset`
|
||||||
* `ignore_roi_if_buy_signal`
|
* `ignore_roi_if_buy_signal`
|
||||||
|
|
|
@ -91,7 +91,7 @@ For example you could implement a 1:2 risk-reward ROI with `custom_exit()`.
|
||||||
Using custom_exit() signals in place of stoploss though *is not recommended*. It is a inferior method to using `custom_stoploss()` in this regard - which also allows you to keep the stoploss on exchange.
|
Using custom_exit() signals in place of stoploss though *is not recommended*. It is a inferior method to using `custom_stoploss()` in this regard - which also allows you to keep the stoploss on exchange.
|
||||||
|
|
||||||
!!! Note
|
!!! Note
|
||||||
Returning a (none-empty) `string` or `True` from this method is equal to setting sell signal on a candle at specified time. This method is not called when sell signal is set already, or if sell signals are disabled (`use_sell_signal=False` or `exit_profit_only=True` while profit is below `exit_profit_offset`). `string` max length is 64 characters. Exceeding this limit will cause the message to be truncated to 64 characters.
|
Returning a (none-empty) `string` or `True` from this method is equal to setting sell signal on a candle at specified time. This method is not called when sell signal is set already, or if sell signals are disabled (`use_exit_signal=False` or `exit_profit_only=True` while profit is below `exit_profit_offset`). `string` max length is 64 characters. Exceeding this limit will cause the message to be truncated to 64 characters.
|
||||||
|
|
||||||
An example of how we can use different indicators depending on the current profit and also sell trades that were open longer than one day:
|
An example of how we can use different indicators depending on the current profit and also sell trades that were open longer than one day:
|
||||||
|
|
||||||
|
|
|
@ -264,7 +264,7 @@ def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFram
|
||||||
### Exit signal rules
|
### Exit signal rules
|
||||||
|
|
||||||
Edit the method `populate_exit_trend()` into your strategy file to update your sell strategy.
|
Edit the method `populate_exit_trend()` into your strategy file to update your sell strategy.
|
||||||
Please note that the sell-signal is only used if `use_sell_signal` is set to true in the configuration.
|
Please note that the exit-signal is only used if `use_exit_signal` is set to true in the configuration.
|
||||||
|
|
||||||
It's important to always return the dataframe without removing/modifying the columns `"open", "high", "low", "close", "volume"`, otherwise these fields would contain something unexpected.
|
It's important to always return the dataframe without removing/modifying the columns `"open", "high", "low", "close", "volume"`, otherwise these fields would contain something unexpected.
|
||||||
|
|
||||||
|
|
|
@ -154,9 +154,9 @@ def _validate_edge(conf: Dict[str, Any]) -> None:
|
||||||
if not conf.get('edge', {}).get('enabled'):
|
if not conf.get('edge', {}).get('enabled'):
|
||||||
return
|
return
|
||||||
|
|
||||||
if not conf.get('use_sell_signal', True):
|
if not conf.get('use_exit_signal', True):
|
||||||
raise OperationalException(
|
raise OperationalException(
|
||||||
"Edge requires `use_sell_signal` to be True, otherwise no sells will happen."
|
"Edge requires `use_exit_signal` to be True, otherwise no sells will happen."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -317,5 +317,6 @@ def _validate_pricing_rules(conf: Dict[str, Any]) -> None:
|
||||||
|
|
||||||
def _strategy_settings(conf: Dict[str, Any]) -> None:
|
def _strategy_settings(conf: Dict[str, Any]) -> None:
|
||||||
|
|
||||||
|
process_deprecated_setting(conf, None, 'use_sell_signal', None, 'use_exit_signal')
|
||||||
process_deprecated_setting(conf, None, 'sell_profit_only', None, 'exit_profit_only')
|
process_deprecated_setting(conf, None, 'sell_profit_only', None, 'exit_profit_only')
|
||||||
process_deprecated_setting(conf, None, 'sell_profit_offset', None, 'exit_profit_offset')
|
process_deprecated_setting(conf, None, 'sell_profit_offset', None, 'exit_profit_offset')
|
||||||
|
|
|
@ -149,7 +149,7 @@ CONF_SCHEMA = {
|
||||||
'trailing_stop_positive': {'type': 'number', 'minimum': 0, 'maximum': 1},
|
'trailing_stop_positive': {'type': 'number', 'minimum': 0, 'maximum': 1},
|
||||||
'trailing_stop_positive_offset': {'type': 'number', 'minimum': 0, 'maximum': 1},
|
'trailing_stop_positive_offset': {'type': 'number', 'minimum': 0, 'maximum': 1},
|
||||||
'trailing_only_offset_is_reached': {'type': 'boolean'},
|
'trailing_only_offset_is_reached': {'type': 'boolean'},
|
||||||
'use_sell_signal': {'type': 'boolean'},
|
'use_exit_signal': {'type': 'boolean'},
|
||||||
'exit_profit_only': {'type': 'boolean'},
|
'exit_profit_only': {'type': 'boolean'},
|
||||||
'exit_profit_offset': {'type': 'number'},
|
'exit_profit_offset': {'type': 'number'},
|
||||||
'ignore_roi_if_buy_signal': {'type': 'boolean'},
|
'ignore_roi_if_buy_signal': {'type': 'boolean'},
|
||||||
|
|
|
@ -926,7 +926,7 @@ class FreqtradeBot(LoggingMixin):
|
||||||
exit_tag = None
|
exit_tag = None
|
||||||
exit_signal_type = "exit_short" if trade.is_short else "exit_long"
|
exit_signal_type = "exit_short" if trade.is_short else "exit_long"
|
||||||
|
|
||||||
if (self.config.get('use_sell_signal', True) or
|
if (self.config.get('use_exit_signal', True) or
|
||||||
self.config.get('ignore_roi_if_buy_signal', False)):
|
self.config.get('ignore_roi_if_buy_signal', False)):
|
||||||
analyzed_df, _ = self.dataprovider.get_analyzed_dataframe(trade.pair,
|
analyzed_df, _ = self.dataprovider.get_analyzed_dataframe(trade.pair,
|
||||||
self.strategy.timeframe)
|
self.strategy.timeframe)
|
||||||
|
|
|
@ -114,8 +114,8 @@ class Hyperopt:
|
||||||
self.position_stacking = self.config.get('position_stacking', False)
|
self.position_stacking = self.config.get('position_stacking', False)
|
||||||
|
|
||||||
if HyperoptTools.has_space(self.config, 'sell'):
|
if HyperoptTools.has_space(self.config, 'sell'):
|
||||||
# Make sure use_sell_signal is enabled
|
# Make sure use_exit_signal is enabled
|
||||||
self.config['use_sell_signal'] = True
|
self.config['use_exit_signal'] = True
|
||||||
|
|
||||||
self.print_all = self.config.get('print_all', False)
|
self.print_all = self.config.get('print_all', False)
|
||||||
self.hyperopt_table_header = 0
|
self.hyperopt_table_header = 0
|
||||||
|
|
|
@ -460,7 +460,7 @@ def generate_strategy_stats(pairlist: List[str],
|
||||||
'trailing_only_offset_is_reached': config.get('trailing_only_offset_is_reached', False),
|
'trailing_only_offset_is_reached': config.get('trailing_only_offset_is_reached', False),
|
||||||
'use_custom_stoploss': config.get('use_custom_stoploss', False),
|
'use_custom_stoploss': config.get('use_custom_stoploss', False),
|
||||||
'minimal_roi': config['minimal_roi'],
|
'minimal_roi': config['minimal_roi'],
|
||||||
'use_sell_signal': config['use_sell_signal'],
|
'use_exit_signal': config['use_exit_signal'],
|
||||||
'exit_profit_only': config['exit_profit_only'],
|
'exit_profit_only': config['exit_profit_only'],
|
||||||
'exit_profit_offset': config['exit_profit_offset'],
|
'exit_profit_offset': config['exit_profit_offset'],
|
||||||
'ignore_roi_if_buy_signal': config['ignore_roi_if_buy_signal'],
|
'ignore_roi_if_buy_signal': config['ignore_roi_if_buy_signal'],
|
||||||
|
|
|
@ -85,7 +85,7 @@ class StrategyResolver(IResolver):
|
||||||
("protections", None),
|
("protections", None),
|
||||||
("startup_candle_count", None),
|
("startup_candle_count", None),
|
||||||
("unfilledtimeout", None),
|
("unfilledtimeout", None),
|
||||||
("use_sell_signal", True),
|
("use_exit_signal", True),
|
||||||
("exit_profit_only", False),
|
("exit_profit_only", False),
|
||||||
("ignore_roi_if_buy_signal", False),
|
("ignore_roi_if_buy_signal", False),
|
||||||
("exit_profit_offset", 0.0),
|
("exit_profit_offset", 0.0),
|
||||||
|
@ -188,12 +188,14 @@ class StrategyResolver(IResolver):
|
||||||
raise OperationalException(
|
raise OperationalException(
|
||||||
"Please migrate your implementation of `custom_sell` to `custom_exit`.")
|
"Please migrate your implementation of `custom_sell` to `custom_exit`.")
|
||||||
warn_deprecated_setting(strategy, 'sell_profit_only', 'exit_profit_only', True)
|
warn_deprecated_setting(strategy, 'sell_profit_only', 'exit_profit_only', True)
|
||||||
|
warn_deprecated_setting(strategy, 'sell_profit_offset', 'exit_profit_offset', True)
|
||||||
|
warn_deprecated_setting(strategy, 'use_sell_signal', 'use_exit_signal', True)
|
||||||
else:
|
else:
|
||||||
# TODO: Implementing one of the following methods should show a deprecation warning
|
# TODO: Implementing one of the following methods should show a deprecation warning
|
||||||
# buy_trend and sell_trend, custom_sell
|
# buy_trend and sell_trend, custom_sell
|
||||||
warn_deprecated_setting(strategy, 'sell_profit_only', 'exit_profit_only')
|
warn_deprecated_setting(strategy, 'sell_profit_only', 'exit_profit_only')
|
||||||
warn_deprecated_setting(strategy, 'sell_profit_offset', 'exit_profit_offset')
|
warn_deprecated_setting(strategy, 'sell_profit_offset', 'exit_profit_offset')
|
||||||
|
warn_deprecated_setting(strategy, 'use_sell_signal', 'use_exit_signal')
|
||||||
|
|
||||||
if (
|
if (
|
||||||
not check_override(strategy, IStrategy, 'populate_buy_trend')
|
not check_override(strategy, IStrategy, 'populate_buy_trend')
|
||||||
|
@ -267,7 +269,7 @@ class StrategyResolver(IResolver):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def warn_deprecated_setting(strategy: IStrategy, old: str, new: str, error: False):
|
def warn_deprecated_setting(strategy: IStrategy, old: str, new: str, error=False):
|
||||||
if hasattr(strategy, old):
|
if hasattr(strategy, old):
|
||||||
errormsg = f"DEPRECATED: Using '{old}' moved to '{new}'."
|
errormsg = f"DEPRECATED: Using '{old}' moved to '{new}'."
|
||||||
if error:
|
if error:
|
||||||
|
|
|
@ -90,7 +90,7 @@ class IStrategy(ABC, HyperStrategyMixin):
|
||||||
# run "populate_indicators" only for new candle
|
# run "populate_indicators" only for new candle
|
||||||
process_only_new_candles: bool = False
|
process_only_new_candles: bool = False
|
||||||
|
|
||||||
use_sell_signal: bool
|
use_exit_signal: bool
|
||||||
exit_profit_only: bool
|
exit_profit_only: bool
|
||||||
exit_profit_offset: float
|
exit_profit_offset: float
|
||||||
ignore_roi_if_buy_signal: bool
|
ignore_roi_if_buy_signal: bool
|
||||||
|
@ -884,7 +884,7 @@ class IStrategy(ABC, HyperStrategyMixin):
|
||||||
if (self.exit_profit_only and current_profit <= self.exit_profit_offset):
|
if (self.exit_profit_only and current_profit <= self.exit_profit_offset):
|
||||||
# exit_profit_only and profit doesn't reach the offset - ignore sell signal
|
# exit_profit_only and profit doesn't reach the offset - ignore sell signal
|
||||||
pass
|
pass
|
||||||
elif self.use_sell_signal and not enter:
|
elif self.use_exit_signal and not enter:
|
||||||
if exit_:
|
if exit_:
|
||||||
exit_signal = ExitType.EXIT_SIGNAL
|
exit_signal = ExitType.EXIT_SIGNAL
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -65,7 +65,7 @@ class {{ strategy }}(IStrategy):
|
||||||
process_only_new_candles = False
|
process_only_new_candles = False
|
||||||
|
|
||||||
# These values can be overridden in the config.
|
# These values can be overridden in the config.
|
||||||
use_sell_signal = True
|
use_exit_signal = True
|
||||||
exit_profit_only = False
|
exit_profit_only = False
|
||||||
ignore_roi_if_buy_signal = False
|
ignore_roi_if_buy_signal = False
|
||||||
|
|
||||||
|
|
|
@ -65,7 +65,7 @@ class SampleStrategy(IStrategy):
|
||||||
process_only_new_candles = False
|
process_only_new_candles = False
|
||||||
|
|
||||||
# These values can be overridden in the config.
|
# These values can be overridden in the config.
|
||||||
use_sell_signal = True
|
use_exit_signal = True
|
||||||
exit_profit_only = False
|
exit_profit_only = False
|
||||||
ignore_roi_if_buy_signal = False
|
ignore_roi_if_buy_signal = False
|
||||||
|
|
||||||
|
|
|
@ -821,7 +821,7 @@ def test_backtest_results(default_conf, fee, mocker, caplog, data: BTContainer)
|
||||||
if data.trailing_stop_positive is not None:
|
if data.trailing_stop_positive is not None:
|
||||||
default_conf["trailing_stop_positive"] = data.trailing_stop_positive
|
default_conf["trailing_stop_positive"] = data.trailing_stop_positive
|
||||||
default_conf["trailing_stop_positive_offset"] = data.trailing_stop_positive_offset
|
default_conf["trailing_stop_positive_offset"] = data.trailing_stop_positive_offset
|
||||||
default_conf["use_sell_signal"] = data.use_exit_signal
|
default_conf["use_exit_signal"] = data.use_exit_signal
|
||||||
|
|
||||||
mocker.patch("freqtrade.exchange.Exchange.get_fee", return_value=0.0)
|
mocker.patch("freqtrade.exchange.Exchange.get_fee", return_value=0.0)
|
||||||
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
||||||
|
|
|
@ -504,7 +504,7 @@ def test_backtesting_pairlist_list(default_conf, mocker, caplog, testdatadir, ti
|
||||||
|
|
||||||
|
|
||||||
def test_backtest__enter_trade(default_conf, fee, mocker) -> None:
|
def test_backtest__enter_trade(default_conf, fee, mocker) -> None:
|
||||||
default_conf['use_sell_signal'] = False
|
default_conf['use_exit_signal'] = False
|
||||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||||
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
||||||
mocker.patch("freqtrade.exchange.Exchange.get_max_pair_stake_amount", return_value=float('inf'))
|
mocker.patch("freqtrade.exchange.Exchange.get_max_pair_stake_amount", return_value=float('inf'))
|
||||||
|
@ -563,7 +563,7 @@ def test_backtest__enter_trade(default_conf, fee, mocker) -> None:
|
||||||
|
|
||||||
|
|
||||||
def test_backtest__enter_trade_futures(default_conf_usdt, fee, mocker) -> None:
|
def test_backtest__enter_trade_futures(default_conf_usdt, fee, mocker) -> None:
|
||||||
default_conf_usdt['use_sell_signal'] = False
|
default_conf_usdt['use_exit_signal'] = False
|
||||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||||
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
||||||
mocker.patch("freqtrade.exchange.Exchange.get_max_pair_stake_amount", return_value=float('inf'))
|
mocker.patch("freqtrade.exchange.Exchange.get_max_pair_stake_amount", return_value=float('inf'))
|
||||||
|
@ -645,7 +645,7 @@ def test_backtest__enter_trade_futures(default_conf_usdt, fee, mocker) -> None:
|
||||||
|
|
||||||
|
|
||||||
def test_backtest__get_sell_trade_entry(default_conf, fee, mocker) -> None:
|
def test_backtest__get_sell_trade_entry(default_conf, fee, mocker) -> None:
|
||||||
default_conf['use_sell_signal'] = False
|
default_conf['use_exit_signal'] = False
|
||||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||||
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
||||||
mocker.patch("freqtrade.exchange.Exchange.get_max_pair_stake_amount", return_value=float('inf'))
|
mocker.patch("freqtrade.exchange.Exchange.get_max_pair_stake_amount", return_value=float('inf'))
|
||||||
|
@ -740,7 +740,7 @@ def test_backtest__get_sell_trade_entry(default_conf, fee, mocker) -> None:
|
||||||
|
|
||||||
|
|
||||||
def test_backtest_one(default_conf, fee, mocker, testdatadir) -> None:
|
def test_backtest_one(default_conf, fee, mocker, testdatadir) -> None:
|
||||||
default_conf['use_sell_signal'] = False
|
default_conf['use_exit_signal'] = False
|
||||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||||
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
||||||
mocker.patch("freqtrade.exchange.Exchange.get_max_pair_stake_amount", return_value=float('inf'))
|
mocker.patch("freqtrade.exchange.Exchange.get_max_pair_stake_amount", return_value=float('inf'))
|
||||||
|
@ -807,7 +807,7 @@ def test_backtest_one(default_conf, fee, mocker, testdatadir) -> None:
|
||||||
|
|
||||||
|
|
||||||
def test_backtest_1min_timeframe(default_conf, fee, mocker, testdatadir) -> None:
|
def test_backtest_1min_timeframe(default_conf, fee, mocker, testdatadir) -> None:
|
||||||
default_conf['use_sell_signal'] = False
|
default_conf['use_exit_signal'] = False
|
||||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||||
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
||||||
mocker.patch("freqtrade.exchange.Exchange.get_max_pair_stake_amount", return_value=float('inf'))
|
mocker.patch("freqtrade.exchange.Exchange.get_max_pair_stake_amount", return_value=float('inf'))
|
||||||
|
@ -833,7 +833,7 @@ def test_backtest_1min_timeframe(default_conf, fee, mocker, testdatadir) -> None
|
||||||
|
|
||||||
|
|
||||||
def test_backtest_trim_no_data_left(default_conf, fee, mocker, testdatadir) -> None:
|
def test_backtest_trim_no_data_left(default_conf, fee, mocker, testdatadir) -> None:
|
||||||
default_conf['use_sell_signal'] = False
|
default_conf['use_exit_signal'] = False
|
||||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||||
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
||||||
mocker.patch("freqtrade.exchange.Exchange.get_max_pair_stake_amount", return_value=float('inf'))
|
mocker.patch("freqtrade.exchange.Exchange.get_max_pair_stake_amount", return_value=float('inf'))
|
||||||
|
@ -878,7 +878,7 @@ def test_processed(default_conf, mocker, testdatadir) -> None:
|
||||||
|
|
||||||
|
|
||||||
def test_backtest_dataprovider_analyzed_df(default_conf, fee, mocker, testdatadir) -> None:
|
def test_backtest_dataprovider_analyzed_df(default_conf, fee, mocker, testdatadir) -> None:
|
||||||
default_conf['use_sell_signal'] = False
|
default_conf['use_exit_signal'] = False
|
||||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||||
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
||||||
mocker.patch("freqtrade.exchange.Exchange.get_max_pair_stake_amount", return_value=100000)
|
mocker.patch("freqtrade.exchange.Exchange.get_max_pair_stake_amount", return_value=100000)
|
||||||
|
@ -1151,7 +1151,7 @@ def test_backtest_start_timerange(default_conf, mocker, caplog, testdatadir):
|
||||||
def test_backtest_start_multi_strat(default_conf, mocker, caplog, testdatadir):
|
def test_backtest_start_multi_strat(default_conf, mocker, caplog, testdatadir):
|
||||||
|
|
||||||
default_conf.update({
|
default_conf.update({
|
||||||
"use_sell_signal": True,
|
"use_exit_signal": True,
|
||||||
"exit_profit_only": False,
|
"exit_profit_only": False,
|
||||||
"exit_profit_offset": 0.0,
|
"exit_profit_offset": 0.0,
|
||||||
"ignore_roi_if_buy_signal": False,
|
"ignore_roi_if_buy_signal": False,
|
||||||
|
@ -1228,7 +1228,7 @@ def test_backtest_start_multi_strat(default_conf, mocker, caplog, testdatadir):
|
||||||
@pytest.mark.filterwarnings("ignore:deprecated")
|
@pytest.mark.filterwarnings("ignore:deprecated")
|
||||||
def test_backtest_start_multi_strat_nomock(default_conf, mocker, caplog, testdatadir, capsys):
|
def test_backtest_start_multi_strat_nomock(default_conf, mocker, caplog, testdatadir, capsys):
|
||||||
default_conf.update({
|
default_conf.update({
|
||||||
"use_sell_signal": True,
|
"use_exit_signal": True,
|
||||||
"exit_profit_only": False,
|
"exit_profit_only": False,
|
||||||
"exit_profit_offset": 0.0,
|
"exit_profit_offset": 0.0,
|
||||||
"ignore_roi_if_buy_signal": False,
|
"ignore_roi_if_buy_signal": False,
|
||||||
|
@ -1346,7 +1346,7 @@ def test_backtest_start_nomock_futures(default_conf_usdt, mocker,
|
||||||
default_conf_usdt.update({
|
default_conf_usdt.update({
|
||||||
"trading_mode": "futures",
|
"trading_mode": "futures",
|
||||||
"margin_mode": "isolated",
|
"margin_mode": "isolated",
|
||||||
"use_sell_signal": True,
|
"use_exit_signal": True,
|
||||||
"exit_profit_only": False,
|
"exit_profit_only": False,
|
||||||
"exit_profit_offset": 0.0,
|
"exit_profit_offset": 0.0,
|
||||||
"ignore_roi_if_buy_signal": False,
|
"ignore_roi_if_buy_signal": False,
|
||||||
|
@ -1450,7 +1450,7 @@ def test_backtest_start_multi_strat_nomock_detail(default_conf, mocker,
|
||||||
caplog, testdatadir, capsys):
|
caplog, testdatadir, capsys):
|
||||||
# Tests detail-data loading
|
# Tests detail-data loading
|
||||||
default_conf.update({
|
default_conf.update({
|
||||||
"use_sell_signal": True,
|
"use_exit_signal": True,
|
||||||
"exit_profit_only": False,
|
"exit_profit_only": False,
|
||||||
"exit_profit_offset": 0.0,
|
"exit_profit_offset": 0.0,
|
||||||
"ignore_roi_if_buy_signal": False,
|
"ignore_roi_if_buy_signal": False,
|
||||||
|
@ -1557,7 +1557,7 @@ def test_backtest_start_multi_strat_nomock_detail(default_conf, mocker,
|
||||||
def test_backtest_start_multi_strat_caching(default_conf, mocker, caplog, testdatadir, run_id,
|
def test_backtest_start_multi_strat_caching(default_conf, mocker, caplog, testdatadir, run_id,
|
||||||
start_delta, cache):
|
start_delta, cache):
|
||||||
default_conf.update({
|
default_conf.update({
|
||||||
"use_sell_signal": True,
|
"use_exit_signal": True,
|
||||||
"exit_profit_only": False,
|
"exit_profit_only": False,
|
||||||
"exit_profit_offset": 0.0,
|
"exit_profit_offset": 0.0,
|
||||||
"ignore_roi_if_buy_signal": False,
|
"ignore_roi_if_buy_signal": False,
|
||||||
|
|
|
@ -14,7 +14,7 @@ from tests.conftest import patch_exchange
|
||||||
|
|
||||||
|
|
||||||
def test_backtest_position_adjustment(default_conf, fee, mocker, testdatadir) -> None:
|
def test_backtest_position_adjustment(default_conf, fee, mocker, testdatadir) -> None:
|
||||||
default_conf['use_sell_signal'] = False
|
default_conf['use_exit_signal'] = False
|
||||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||||
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
||||||
mocker.patch("freqtrade.exchange.Exchange.get_max_pair_stake_amount", return_value=float('inf'))
|
mocker.patch("freqtrade.exchange.Exchange.get_max_pair_stake_amount", return_value=float('inf'))
|
||||||
|
|
|
@ -310,27 +310,27 @@ def test_strategy_override_order_tif(caplog, default_conf):
|
||||||
StrategyResolver.load_strategy(default_conf)
|
StrategyResolver.load_strategy(default_conf)
|
||||||
|
|
||||||
|
|
||||||
def test_strategy_override_use_sell_signal(caplog, default_conf):
|
def test_strategy_override_use_exit_signal(caplog, default_conf):
|
||||||
caplog.set_level(logging.INFO)
|
caplog.set_level(logging.INFO)
|
||||||
default_conf.update({
|
default_conf.update({
|
||||||
'strategy': CURRENT_TEST_STRATEGY,
|
'strategy': CURRENT_TEST_STRATEGY,
|
||||||
})
|
})
|
||||||
strategy = StrategyResolver.load_strategy(default_conf)
|
strategy = StrategyResolver.load_strategy(default_conf)
|
||||||
assert strategy.use_sell_signal
|
assert strategy.use_exit_signal
|
||||||
assert isinstance(strategy.use_sell_signal, bool)
|
assert isinstance(strategy.use_exit_signal, bool)
|
||||||
# must be inserted to configuration
|
# must be inserted to configuration
|
||||||
assert 'use_sell_signal' in default_conf
|
assert 'use_exit_signal' in default_conf
|
||||||
assert default_conf['use_sell_signal']
|
assert default_conf['use_exit_signal']
|
||||||
|
|
||||||
default_conf.update({
|
default_conf.update({
|
||||||
'strategy': CURRENT_TEST_STRATEGY,
|
'strategy': CURRENT_TEST_STRATEGY,
|
||||||
'use_sell_signal': False,
|
'use_exit_signal': False,
|
||||||
})
|
})
|
||||||
strategy = StrategyResolver.load_strategy(default_conf)
|
strategy = StrategyResolver.load_strategy(default_conf)
|
||||||
|
|
||||||
assert not strategy.use_sell_signal
|
assert not strategy.use_exit_signal
|
||||||
assert isinstance(strategy.use_sell_signal, bool)
|
assert isinstance(strategy.use_exit_signal, bool)
|
||||||
assert log_has("Override strategy 'use_sell_signal' with value in config file: False.", caplog)
|
assert log_has("Override strategy 'use_exit_signal' with value in config file: False.", caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_strategy_override_use_exit_profit_only(caplog, default_conf):
|
def test_strategy_override_use_exit_profit_only(caplog, default_conf):
|
||||||
|
|
|
@ -868,15 +868,15 @@ def test_validate_tsl(default_conf):
|
||||||
|
|
||||||
def test_validate_edge2(edge_conf):
|
def test_validate_edge2(edge_conf):
|
||||||
edge_conf.update({
|
edge_conf.update({
|
||||||
"use_sell_signal": True,
|
"use_exit_signal": True,
|
||||||
})
|
})
|
||||||
# Passes test
|
# Passes test
|
||||||
validate_config_consistency(edge_conf)
|
validate_config_consistency(edge_conf)
|
||||||
|
|
||||||
edge_conf.update({
|
edge_conf.update({
|
||||||
"use_sell_signal": False,
|
"use_exit_signal": False,
|
||||||
})
|
})
|
||||||
with pytest.raises(OperationalException, match="Edge requires `use_sell_signal` to be True, "
|
with pytest.raises(OperationalException, match="Edge requires `use_exit_signal` to be True, "
|
||||||
"otherwise no sells will happen."):
|
"otherwise no sells will happen."):
|
||||||
validate_config_consistency(edge_conf)
|
validate_config_consistency(edge_conf)
|
||||||
|
|
||||||
|
@ -1238,8 +1238,8 @@ def test_pairlist_resolving_fallback(mocker):
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("setting", [
|
@pytest.mark.parametrize("setting", [
|
||||||
("ask_strategy", "use_sell_signal", True,
|
("ask_strategy", "use_exit_signal", True,
|
||||||
None, "use_sell_signal", False),
|
None, "use_exit_signal", False),
|
||||||
("ask_strategy", "sell_profit_only", True,
|
("ask_strategy", "sell_profit_only", True,
|
||||||
None, "sell_profit_only", False),
|
None, "sell_profit_only", False),
|
||||||
("ask_strategy", "sell_profit_offset", 0.1,
|
("ask_strategy", "sell_profit_offset", 0.1,
|
||||||
|
@ -1288,7 +1288,7 @@ def test_process_temporary_deprecated_settings(mocker, default_conf, setting, ca
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("setting", [
|
@pytest.mark.parametrize("setting", [
|
||||||
("experimental", "use_sell_signal", False),
|
("experimental", "use_exit_signal", False),
|
||||||
("experimental", "sell_profit_only", True),
|
("experimental", "sell_profit_only", True),
|
||||||
("experimental", "ignore_roi_if_buy_signal", True),
|
("experimental", "ignore_roi_if_buy_signal", True),
|
||||||
])
|
])
|
||||||
|
|
|
@ -2273,14 +2273,14 @@ def test_handle_trade_roi(default_conf_usdt, ticker_usdt, limit_order_open, fee,
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("is_short", [False, True])
|
@pytest.mark.parametrize("is_short", [False, True])
|
||||||
def test_handle_trade_use_sell_signal(
|
def test_handle_trade_use_exit_signal(
|
||||||
default_conf_usdt, ticker_usdt, limit_order_open, fee, mocker, caplog, is_short
|
default_conf_usdt, ticker_usdt, limit_order_open, fee, mocker, caplog, is_short
|
||||||
) -> None:
|
) -> None:
|
||||||
|
|
||||||
enter_open_order = limit_order_open[exit_side(is_short)]
|
enter_open_order = limit_order_open[exit_side(is_short)]
|
||||||
exit_open_order = limit_order_open[enter_side(is_short)]
|
exit_open_order = limit_order_open[enter_side(is_short)]
|
||||||
|
|
||||||
# use_sell_signal is True buy default
|
# use_exit_signal is True buy default
|
||||||
caplog.set_level(logging.DEBUG)
|
caplog.set_level(logging.DEBUG)
|
||||||
patch_RPCManager(mocker)
|
patch_RPCManager(mocker)
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
|
@ -3657,7 +3657,7 @@ def test_exit_profit_only(
|
||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
)
|
)
|
||||||
default_conf_usdt.update({
|
default_conf_usdt.update({
|
||||||
'use_sell_signal': True,
|
'use_exit_signal': True,
|
||||||
'exit_profit_only': profit_only,
|
'exit_profit_only': profit_only,
|
||||||
'exit_profit_offset': 0.1,
|
'exit_profit_offset': 0.1,
|
||||||
})
|
})
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue