From 63a579dbab0eaafa0c699f01e6d266729575c5fa Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 11 Jan 2021 19:30:07 +0100 Subject: [PATCH] Add sell_profit_offset parameter Allows defining positive offsets before enabling the sell signal --- config_full.json.example | 1 + docs/configuration.md | 3 ++- freqtrade/constants.py | 1 + freqtrade/optimize/optimize_reports.py | 1 + freqtrade/resolvers/strategy_resolver.py | 1 + freqtrade/strategy/interface.py | 9 +++++---- 6 files changed, 11 insertions(+), 5 deletions(-) diff --git a/config_full.json.example b/config_full.json.example index db8debb2c..ef791d267 100644 --- a/config_full.json.example +++ b/config_full.json.example @@ -42,6 +42,7 @@ "order_book_max": 1, "use_sell_signal": true, "sell_profit_only": false, + "sell_profit_offset": 0.0, "ignore_roi_if_buy_signal": false }, "order_types": { diff --git a/docs/configuration.md b/docs/configuration.md index 13c7eb47b..926506f22 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -72,7 +72,8 @@ Mandatory parameters are marked as **Required**, which means that they are requi | `ask_strategy.order_book_min` | Bot will scan from the top min to max Order Book Asks searching for a profitable rate.
*Defaults to `1`.*
**Datatype:** Positive Integer | `ask_strategy.order_book_max` | Bot will scan from the top min to max Order Book Asks searching for a profitable rate.
*Defaults to `1`.*
**Datatype:** Positive Integer | `ask_strategy.use_sell_signal` | Use sell signals produced by the strategy in addition to the `minimal_roi`. [Strategy Override](#parameters-in-the-strategy).
*Defaults to `true`.*
**Datatype:** Boolean -| `ask_strategy.sell_profit_only` | Wait until the bot makes a positive profit before taking a sell decision. [Strategy Override](#parameters-in-the-strategy).
*Defaults to `false`.*
**Datatype:** Boolean +| `ask_strategy.sell_profit_only` | Wait until the bot reaches `ask_strategy.sell_profit_offset` before taking a sell decision. [Strategy Override](#parameters-in-the-strategy).
*Defaults to `false`.*
**Datatype:** Boolean +| `ask_strategy.sell_profit_offset` | Sell-signal is only active above this value. [Strategy Override](#parameters-in-the-strategy).
*Defaults to `0.0`.*
**Datatype:** Float (as ratio) | `ask_strategy.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).
*Defaults to `false`.*
**Datatype:** Boolean | `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).
**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).
**Datatype:** Dict diff --git a/freqtrade/constants.py b/freqtrade/constants.py index e7d7e80f6..d48ab635e 100644 --- a/freqtrade/constants.py +++ b/freqtrade/constants.py @@ -154,6 +154,7 @@ CONF_SCHEMA = { 'order_book_max': {'type': 'integer', 'minimum': 1, 'maximum': 50}, 'use_sell_signal': {'type': 'boolean'}, 'sell_profit_only': {'type': 'boolean'}, + 'sell_profit_offset': {'type': 'number', 'minimum': 0.0}, 'ignore_roi_if_buy_signal': {'type': 'boolean'} } }, diff --git a/freqtrade/optimize/optimize_reports.py b/freqtrade/optimize/optimize_reports.py index d029ecd13..6c70b7c84 100644 --- a/freqtrade/optimize/optimize_reports.py +++ b/freqtrade/optimize/optimize_reports.py @@ -299,6 +299,7 @@ def generate_backtest_stats(btdata: Dict[str, DataFrame], 'minimal_roi': config['minimal_roi'], 'use_sell_signal': config['ask_strategy']['use_sell_signal'], 'sell_profit_only': config['ask_strategy']['sell_profit_only'], + 'sell_profit_offset': config['ask_strategy']['sell_profit_offset'], 'ignore_roi_if_buy_signal': config['ask_strategy']['ignore_roi_if_buy_signal'], **daily_stats, } diff --git a/freqtrade/resolvers/strategy_resolver.py b/freqtrade/resolvers/strategy_resolver.py index 2b7a4f0c2..825e6572a 100644 --- a/freqtrade/resolvers/strategy_resolver.py +++ b/freqtrade/resolvers/strategy_resolver.py @@ -79,6 +79,7 @@ class StrategyResolver(IResolver): ("use_sell_signal", True, 'ask_strategy'), ("sell_profit_only", False, 'ask_strategy'), ("ignore_roi_if_buy_signal", False, 'ask_strategy'), + ("sell_profit_offset", 0.0, 'ask_strategy'), ("disable_dataframe_checks", False, None), ] for attribute, default, subkey in attributes: diff --git a/freqtrade/strategy/interface.py b/freqtrade/strategy/interface.py index 348e6a446..8546b1eda 100644 --- a/freqtrade/strategy/interface.py +++ b/freqtrade/strategy/interface.py @@ -505,18 +505,19 @@ class IStrategy(ABC): # Set current rate to high for backtesting sell current_rate = high or rate current_profit = trade.calc_profit_ratio(current_rate) - config_ask_strategy = self.config.get('ask_strategy', {}) + ask_strategy = self.config.get('ask_strategy', {}) # if buy signal and ignore_roi is set, we don't need to evaluate min_roi. - roi_reached = (not (buy and config_ask_strategy.get('ignore_roi_if_buy_signal', False)) + roi_reached = (not (buy and ask_strategy.get('ignore_roi_if_buy_signal', False)) and self.min_roi_reached(trade=trade, current_profit=current_profit, current_time=date)) - if config_ask_strategy.get('sell_profit_only', False) and trade.calc_profit(rate=rate) <= 0: + if (ask_strategy.get('sell_profit_only', False) + and trade.calc_profit(rate=rate) <= ask_strategy.get('sell_profit_offset', 0)): # Negative profits and sell_profit_only - ignore sell signal sell_signal = False else: - sell_signal = sell and not buy and config_ask_strategy.get('use_sell_signal', True) + sell_signal = sell and not buy and ask_strategy.get('use_sell_signal', True) # TODO: return here if sell-signal should be favored over ROI # Start evaluations