use_sell_signal -> use_exit_signal
This commit is contained in:
parent
501f473164
commit
86cc911559
@ -115,10 +115,10 @@ Mandatory parameters are marked as **Required**, which means that they are requi
|
|||||||
| `ask_strategy.bid_last_balance` | Interpolate the selling price. More information [below](#sell-price-without-orderbook-enabled).
|
| `ask_strategy.bid_last_balance` | Interpolate the selling price. More information [below](#sell-price-without-orderbook-enabled).
|
||||||
| `ask_strategy.use_order_book` | Enable selling of open trades using [Order Book Asks](#sell-price-with-orderbook-enabled). <br> **Datatype:** Boolean
|
| `ask_strategy.use_order_book` | Enable selling of open trades using [Order Book Asks](#sell-price-with-orderbook-enabled). <br> **Datatype:** Boolean
|
||||||
| `ask_strategy.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 Asks](#sell-price-with-orderbook-enabled)<br>*Defaults to `1`.* <br> **Datatype:** Positive Integer
|
| `ask_strategy.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 Asks](#sell-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
|
||||||
| `sell_profit_only` | Wait until the bot reaches `sell_profit_offset` before taking a sell decision. [Strategy Override](#parameters-in-the-strategy). <br>*Defaults to `false`.* <br> **Datatype:** Boolean
|
| `sell_profit_only` | Wait until the bot reaches `sell_profit_offset` before taking a sell decision. [Strategy Override](#parameters-in-the-strategy). <br>*Defaults to `false`.* <br> **Datatype:** Boolean
|
||||||
| `sell_profit_offset` | Sell-signal is only active above this value. Only active in combination with `sell_profit_only=True`. [Strategy Override](#parameters-in-the-strategy). <br>*Defaults to `0.0`.* <br> **Datatype:** Float (as ratio)
|
| `sell_profit_offset` | Sell-signal is only active above this value. Only active in combination with `sell_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 (`"buy"`, `"sell"`, `"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 (`"buy"`, `"sell"`, `"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 buy and sell 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 buy and sell orders. [More information below](#understand-order_time_in_force). [Strategy Override](#parameters-in-the-strategy). <br> **Datatype:** Dict
|
||||||
@ -193,7 +193,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`
|
||||||
* `sell_profit_only`
|
* `sell_profit_only`
|
||||||
* `sell_profit_offset`
|
* `sell_profit_offset`
|
||||||
* `ignore_roi_if_buy_signal`
|
* `ignore_roi_if_buy_signal`
|
||||||
|
@ -89,7 +89,7 @@ For example you could implement a 1:2 risk-reward ROI with `custom_sell()`.
|
|||||||
Using custom_sell() 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_sell() 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 `sell_profit_only=True` while profit is below `sell_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 `sell_profit_only=True` while profit is below `sell_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:
|
||||||
|
|
||||||
|
@ -235,7 +235,7 @@ def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
|
|||||||
### Sell signal rules
|
### Sell signal rules
|
||||||
|
|
||||||
Edit the method `populate_sell_trend()` into your strategy file to update your sell strategy.
|
Edit the method `populate_sell_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 sell-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.
|
||||||
|
|
||||||
|
@ -150,9 +150,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."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -69,10 +69,10 @@ def process_deprecated_setting(config: Dict[str, Any],
|
|||||||
def process_temporary_deprecated_settings(config: Dict[str, Any]) -> None:
|
def process_temporary_deprecated_settings(config: Dict[str, Any]) -> None:
|
||||||
|
|
||||||
# Kept for future deprecated / moved settings
|
# Kept for future deprecated / moved settings
|
||||||
# check_conflicting_settings(config, 'ask_strategy', 'use_sell_signal',
|
# check_conflicting_settings(config, 'ask_strategy', 'use_exit_signal',
|
||||||
# 'experimental', 'use_sell_signal')
|
# 'experimental', 'use_exit_signal')
|
||||||
process_deprecated_setting(config, 'ask_strategy', 'use_sell_signal',
|
process_deprecated_setting(config, 'ask_strategy', 'use_exit_signal',
|
||||||
None, 'use_sell_signal')
|
None, 'use_exit_signal')
|
||||||
process_deprecated_setting(config, 'ask_strategy', 'sell_profit_only',
|
process_deprecated_setting(config, 'ask_strategy', 'sell_profit_only',
|
||||||
None, 'sell_profit_only')
|
None, 'sell_profit_only')
|
||||||
process_deprecated_setting(config, 'ask_strategy', 'sell_profit_offset',
|
process_deprecated_setting(config, 'ask_strategy', 'sell_profit_offset',
|
||||||
@ -83,8 +83,8 @@ def process_temporary_deprecated_settings(config: Dict[str, Any]) -> None:
|
|||||||
None, 'ignore_buying_expired_candle_after')
|
None, 'ignore_buying_expired_candle_after')
|
||||||
|
|
||||||
# Legacy way - having them in experimental ...
|
# Legacy way - having them in experimental ...
|
||||||
process_removed_setting(config, 'experimental', 'use_sell_signal',
|
process_removed_setting(config, 'experimental', 'use_exit_signal',
|
||||||
None, 'use_sell_signal')
|
None, 'use_exit_signal')
|
||||||
process_removed_setting(config, 'experimental', 'sell_profit_only',
|
process_removed_setting(config, 'experimental', 'sell_profit_only',
|
||||||
None, 'sell_profit_only')
|
None, 'sell_profit_only')
|
||||||
process_removed_setting(config, 'experimental', 'ignore_roi_if_buy_signal',
|
process_removed_setting(config, 'experimental', 'ignore_roi_if_buy_signal',
|
||||||
|
@ -147,7 +147,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'},
|
||||||
'sell_profit_only': {'type': 'boolean'},
|
'sell_profit_only': {'type': 'boolean'},
|
||||||
'sell_profit_offset': {'type': 'number'},
|
'sell_profit_offset': {'type': 'number'},
|
||||||
'ignore_roi_if_buy_signal': {'type': 'boolean'},
|
'ignore_roi_if_buy_signal': {'type': 'boolean'},
|
||||||
|
@ -864,7 +864,7 @@ class FreqtradeBot(LoggingMixin):
|
|||||||
exit_signal_type = "exit_short" if trade.is_short else "exit_long"
|
exit_signal_type = "exit_short" if trade.is_short else "exit_long"
|
||||||
|
|
||||||
# TODO-lev: change to use_exit_signal, ignore_roi_if_enter_signal
|
# TODO-lev: change to use_exit_signal, ignore_roi_if_enter_signal
|
||||||
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)
|
||||||
|
@ -113,10 +113,10 @@ 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
|
||||||
if 'ask_strategy' not in self.config:
|
if 'ask_strategy' not in self.config:
|
||||||
self.config['ask_strategy'] = {}
|
self.config['ask_strategy'] = {}
|
||||||
self.config['ask_strategy']['use_sell_signal'] = True
|
self.config['ask_strategy']['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
|
||||||
|
@ -459,7 +459,7 @@ def generate_strategy_stats(btdata: Dict[str, DataFrame],
|
|||||||
'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'],
|
||||||
'sell_profit_only': config['sell_profit_only'],
|
'sell_profit_only': config['sell_profit_only'],
|
||||||
'sell_profit_offset': config['sell_profit_offset'],
|
'sell_profit_offset': config['sell_profit_offset'],
|
||||||
'ignore_roi_if_buy_signal': config['ignore_roi_if_buy_signal'],
|
'ignore_roi_if_buy_signal': config['ignore_roi_if_buy_signal'],
|
||||||
|
@ -91,7 +91,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),
|
||||||
("sell_profit_only", False),
|
("sell_profit_only", False),
|
||||||
("ignore_roi_if_buy_signal", False),
|
("ignore_roi_if_buy_signal", False),
|
||||||
("sell_profit_offset", 0.0),
|
("sell_profit_offset", 0.0),
|
||||||
|
@ -101,7 +101,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
|
||||||
sell_profit_only: bool
|
sell_profit_only: bool
|
||||||
sell_profit_offset: float
|
sell_profit_offset: float
|
||||||
ignore_roi_if_buy_signal: bool
|
ignore_roi_if_buy_signal: bool
|
||||||
@ -793,7 +793,7 @@ class IStrategy(ABC, HyperStrategyMixin):
|
|||||||
if (self.sell_profit_only and current_profit <= self.sell_profit_offset):
|
if (self.sell_profit_only and current_profit <= self.sell_profit_offset):
|
||||||
# sell_profit_only and profit doesn't reach the offset - ignore sell signal
|
# sell_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_:
|
||||||
sell_signal = SellType.SELL_SIGNAL
|
sell_signal = SellType.SELL_SIGNAL
|
||||||
else:
|
else:
|
||||||
|
@ -62,7 +62,7 @@ class {{ strategy }}(IStrategy):
|
|||||||
process_only_new_candles = False
|
process_only_new_candles = False
|
||||||
|
|
||||||
# These values can be overridden in the "ask_strategy" section in the config.
|
# These values can be overridden in the "ask_strategy" section in the config.
|
||||||
use_sell_signal = True
|
use_exit_signal = True
|
||||||
sell_profit_only = False
|
sell_profit_only = False
|
||||||
ignore_roi_if_buy_signal = False
|
ignore_roi_if_buy_signal = False
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ class SampleShortStrategy(IStrategy):
|
|||||||
process_only_new_candles = False
|
process_only_new_candles = False
|
||||||
|
|
||||||
# These values can be overridden in the "ask_strategy" section in the config.
|
# These values can be overridden in the "ask_strategy" section in the config.
|
||||||
use_sell_signal = True
|
use_exit_signal = True
|
||||||
sell_profit_only = False
|
sell_profit_only = False
|
||||||
ignore_roi_if_buy_signal = False
|
ignore_roi_if_buy_signal = False
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ class SampleStrategy(IStrategy):
|
|||||||
process_only_new_candles = False
|
process_only_new_candles = False
|
||||||
|
|
||||||
# These values can be overridden in the "ask_strategy" section in the config.
|
# These values can be overridden in the "ask_strategy" section in the config.
|
||||||
use_sell_signal = True
|
use_exit_signal = True
|
||||||
sell_profit_only = False
|
sell_profit_only = False
|
||||||
ignore_roi_if_buy_signal = False
|
ignore_roi_if_buy_signal = False
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ class BTContainer(NamedTuple):
|
|||||||
trailing_only_offset_is_reached: bool = False
|
trailing_only_offset_is_reached: bool = False
|
||||||
trailing_stop_positive: Optional[float] = None
|
trailing_stop_positive: Optional[float] = None
|
||||||
trailing_stop_positive_offset: float = 0.0
|
trailing_stop_positive_offset: float = 0.0
|
||||||
use_sell_signal: bool = False
|
use_exit_signal: bool = False
|
||||||
use_custom_stoploss: bool = False
|
use_custom_stoploss: bool = False
|
||||||
leverage: float = 1.0
|
leverage: float = 1.0
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ tc0 = BTContainer(data=[
|
|||||||
[3, 5010, 5010, 4980, 5010, 6172, 0, 1],
|
[3, 5010, 5010, 4980, 5010, 6172, 0, 1],
|
||||||
[4, 5010, 5011, 4977, 4995, 6172, 0, 0],
|
[4, 5010, 5011, 4977, 4995, 6172, 0, 0],
|
||||||
[5, 4995, 4995, 4950, 4950, 6172, 0, 0]],
|
[5, 4995, 4995, 4950, 4950, 6172, 0, 0]],
|
||||||
stop_loss=-0.01, roi={"0": 1}, profit_perc=0.002, use_sell_signal=True,
|
stop_loss=-0.01, roi={"0": 1}, profit_perc=0.002, use_exit_signal=True,
|
||||||
trades=[BTrade(sell_reason=SellType.SELL_SIGNAL, open_tick=1, close_tick=4)]
|
trades=[BTrade(sell_reason=SellType.SELL_SIGNAL, open_tick=1, close_tick=4)]
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -390,7 +390,7 @@ tc24 = BTContainer(data=[
|
|||||||
[3, 5010, 5010, 4855, 5010, 6172, 0, 1], # Triggers stoploss + sellsignal
|
[3, 5010, 5010, 4855, 5010, 6172, 0, 1], # Triggers stoploss + sellsignal
|
||||||
[4, 5010, 5010, 4977, 4995, 6172, 0, 0],
|
[4, 5010, 5010, 4977, 4995, 6172, 0, 0],
|
||||||
[5, 4995, 4995, 4950, 4950, 6172, 0, 0]],
|
[5, 4995, 4995, 4950, 4950, 6172, 0, 0]],
|
||||||
stop_loss=-0.01, roi={"0": 1}, profit_perc=-0.01, use_sell_signal=True,
|
stop_loss=-0.01, roi={"0": 1}, profit_perc=-0.01, use_exit_signal=True,
|
||||||
trades=[BTrade(sell_reason=SellType.STOP_LOSS, open_tick=1, close_tick=3)]
|
trades=[BTrade(sell_reason=SellType.STOP_LOSS, open_tick=1, close_tick=3)]
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -405,7 +405,7 @@ tc25 = BTContainer(data=[
|
|||||||
[3, 5010, 5010, 4986, 5010, 6172, 0, 1],
|
[3, 5010, 5010, 4986, 5010, 6172, 0, 1],
|
||||||
[4, 5010, 5010, 4855, 4995, 6172, 0, 0], # Triggers stoploss + sellsignal acted on
|
[4, 5010, 5010, 4855, 4995, 6172, 0, 0], # Triggers stoploss + sellsignal acted on
|
||||||
[5, 4995, 4995, 4950, 4950, 6172, 0, 0]],
|
[5, 4995, 4995, 4950, 4950, 6172, 0, 0]],
|
||||||
stop_loss=-0.01, roi={"0": 1}, profit_perc=0.002, use_sell_signal=True,
|
stop_loss=-0.01, roi={"0": 1}, profit_perc=0.002, use_exit_signal=True,
|
||||||
trades=[BTrade(sell_reason=SellType.SELL_SIGNAL, open_tick=1, close_tick=4)]
|
trades=[BTrade(sell_reason=SellType.SELL_SIGNAL, open_tick=1, close_tick=4)]
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -420,7 +420,7 @@ tc26 = BTContainer(data=[
|
|||||||
[3, 5010, 5251, 4986, 5010, 6172, 0, 1], # Triggers ROI, sell-signal
|
[3, 5010, 5251, 4986, 5010, 6172, 0, 1], # Triggers ROI, sell-signal
|
||||||
[4, 5010, 5010, 4855, 4995, 6172, 0, 0],
|
[4, 5010, 5010, 4855, 4995, 6172, 0, 0],
|
||||||
[5, 4995, 4995, 4950, 4950, 6172, 0, 0]],
|
[5, 4995, 4995, 4950, 4950, 6172, 0, 0]],
|
||||||
stop_loss=-0.10, roi={"0": 0.05}, profit_perc=0.05, use_sell_signal=True,
|
stop_loss=-0.10, roi={"0": 0.05}, profit_perc=0.05, use_exit_signal=True,
|
||||||
trades=[BTrade(sell_reason=SellType.ROI, open_tick=1, close_tick=3)]
|
trades=[BTrade(sell_reason=SellType.ROI, open_tick=1, close_tick=3)]
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -434,7 +434,7 @@ tc27 = BTContainer(data=[
|
|||||||
[3, 5010, 5012, 4986, 5010, 6172, 0, 1], # sell-signal
|
[3, 5010, 5012, 4986, 5010, 6172, 0, 1], # sell-signal
|
||||||
[4, 5010, 5251, 4855, 4995, 6172, 0, 0], # Triggers ROI, sell-signal acted on
|
[4, 5010, 5251, 4855, 4995, 6172, 0, 0], # Triggers ROI, sell-signal acted on
|
||||||
[5, 4995, 4995, 4950, 4950, 6172, 0, 0]],
|
[5, 4995, 4995, 4950, 4950, 6172, 0, 0]],
|
||||||
stop_loss=-0.10, roi={"0": 0.05}, profit_perc=0.002, use_sell_signal=True,
|
stop_loss=-0.10, roi={"0": 0.05}, profit_perc=0.002, use_exit_signal=True,
|
||||||
trades=[BTrade(sell_reason=SellType.SELL_SIGNAL, open_tick=1, close_tick=4)]
|
trades=[BTrade(sell_reason=SellType.SELL_SIGNAL, open_tick=1, close_tick=4)]
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -546,7 +546,7 @@ tc34 = BTContainer(data=[
|
|||||||
[3, 5010, 5010, 4986, 5010, 6172, 0, 1],
|
[3, 5010, 5010, 4986, 5010, 6172, 0, 1],
|
||||||
[4, 5010, 5010, 4855, 4995, 6172, 0, 0], # Triggers stoploss + sellsignal acted on
|
[4, 5010, 5010, 4855, 4995, 6172, 0, 0], # Triggers stoploss + sellsignal acted on
|
||||||
[5, 4995, 4995, 4950, 4950, 6172, 0, 0]],
|
[5, 4995, 4995, 4950, 4950, 6172, 0, 0]],
|
||||||
stop_loss=-0.01, roi={"0": 1}, profit_perc=0.002 * 5.0, use_sell_signal=True,
|
stop_loss=-0.01, roi={"0": 1}, profit_perc=0.002 * 5.0, use_exit_signal=True,
|
||||||
leverage=5.0,
|
leverage=5.0,
|
||||||
trades=[BTrade(sell_reason=SellType.SELL_SIGNAL, open_tick=1, close_tick=4)]
|
trades=[BTrade(sell_reason=SellType.SELL_SIGNAL, open_tick=1, close_tick=4)]
|
||||||
)
|
)
|
||||||
@ -605,7 +605,7 @@ def test_backtest_results(default_conf, fee, mocker, caplog, data) -> None:
|
|||||||
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_sell_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)
|
||||||
|
@ -495,7 +495,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)
|
||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
@ -561,7 +561,7 @@ def test_backtest__enter_trade(default_conf, 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)
|
||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
@ -654,7 +654,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)
|
||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
@ -719,7 +719,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)
|
||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
@ -985,7 +985,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,
|
||||||
"sell_profit_only": False,
|
"sell_profit_only": False,
|
||||||
"sell_profit_offset": 0.0,
|
"sell_profit_offset": 0.0,
|
||||||
"ignore_roi_if_buy_signal": False,
|
"ignore_roi_if_buy_signal": False,
|
||||||
@ -1060,7 +1060,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,
|
||||||
"sell_profit_only": False,
|
"sell_profit_only": False,
|
||||||
"sell_profit_offset": 0.0,
|
"sell_profit_offset": 0.0,
|
||||||
"ignore_roi_if_buy_signal": False,
|
"ignore_roi_if_buy_signal": False,
|
||||||
@ -1172,7 +1172,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,
|
||||||
"sell_profit_only": False,
|
"sell_profit_only": False,
|
||||||
"sell_profit_offset": 0.0,
|
"sell_profit_offset": 0.0,
|
||||||
"ignore_roi_if_buy_signal": False,
|
"ignore_roi_if_buy_signal": False,
|
||||||
|
@ -285,27 +285,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_sell_profit_only(caplog, default_conf):
|
def test_strategy_override_use_sell_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)
|
||||||
|
|
||||||
@ -1118,8 +1118,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,
|
||||||
@ -1168,7 +1168,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),
|
||||||
])
|
])
|
||||||
|
@ -2098,14 +2098,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(
|
||||||
@ -3435,7 +3435,7 @@ def test_sell_profit_only(
|
|||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
)
|
)
|
||||||
default_conf_usdt.update({
|
default_conf_usdt.update({
|
||||||
'use_sell_signal': True,
|
'use_exit_signal': True,
|
||||||
'sell_profit_only': profit_only,
|
'sell_profit_only': profit_only,
|
||||||
'sell_profit_offset': 0.1,
|
'sell_profit_offset': 0.1,
|
||||||
})
|
})
|
||||||
|
10
tests/testdata/strategy_SampleStrategy.fthypt
vendored
10
tests/testdata/strategy_SampleStrategy.fthypt
vendored
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user