From 2d4cd262626ffad756f94d75b78dbe274a4d4bc7 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 5 Sep 2021 15:57:51 +0200 Subject: [PATCH] Convert ReinforcedScalp to parametrized strategy --- .../ReinforcedSmoothScalp_hyperopt.py | 153 ------------------ .../berlinguyinca/ReinforcedSmoothScalp.py | 105 ++++++++---- 2 files changed, 70 insertions(+), 188 deletions(-) delete mode 100644 user_data/hyperopts/ReinforcedSmoothScalp_hyperopt.py diff --git a/user_data/hyperopts/ReinforcedSmoothScalp_hyperopt.py b/user_data/hyperopts/ReinforcedSmoothScalp_hyperopt.py deleted file mode 100644 index f205d8c..0000000 --- a/user_data/hyperopts/ReinforcedSmoothScalp_hyperopt.py +++ /dev/null @@ -1,153 +0,0 @@ -# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement - -from functools import reduce -from typing import Any, Callable, Dict, List - -import talib.abstract as ta -from pandas import DataFrame -from skopt.space import Categorical, Dimension, Integer - -import freqtrade.vendor.qtpylib.indicators as qtpylib -from freqtrade.optimize.hyperopt_interface import IHyperOpt - - -class ReinforcedSmoothScalp(IHyperOpt): - """ - Default hyperopt provided by the Freqtrade bot. - You can override it with your own Hyperopt - """ - - @staticmethod - def buy_strategy_generator(params: Dict[str, Any]) -> Callable: - """ - Define the buy strategy parameters to be used by Hyperopt. - """ - def populate_buy_trend(dataframe: DataFrame, metadata: dict) -> DataFrame: - """ - Buy strategy Hyperopt will build and use. - """ - conditions = [] - - # GUARDS AND TRENDS - if 'mfi-enabled' in params and params['mfi-enabled']: - conditions.append(dataframe['mfi'] < params['mfi-value']) - if 'fastd-enabled' in params and params['fastd-enabled']: - conditions.append(dataframe['fastd'] < params['fastd-value']) - if 'adx-enabled' in params and params['adx-enabled']: - conditions.append(dataframe['adx'] > params['adx-value']) - # if 'rsi-enabled' in params and params['rsi-enabled']: - # conditions.append(dataframe['rsi'] < params['rsi-value']) - if 'fastk-enabled' in params and params['fastk-enabled']: - conditions.append(dataframe['fastk'] < params['fastk-value']) - # TRIGGERS - # if 'trigger' in params: - # if params['trigger'] == 'bb_lower': - # conditions.append(dataframe['close'] < dataframe['bb_lowerband']) - # if params['trigger'] == 'macd_cross_signal': - # conditions.append(qtpylib.crossed_above( - # dataframe['macd'], dataframe['macdsignal'] - # )) - # if params['trigger'] == 'sar_reversal': - # conditions.append(qtpylib.crossed_above( - # dataframe['close'], dataframe['sar'] - # )) - - # Check that volume is not 0 - conditions.append(dataframe['volume'] > 0) - - if conditions: - dataframe.loc[ - reduce(lambda x, y: x & y, conditions), - 'buy'] = 1 - - return dataframe - - return populate_buy_trend - - @staticmethod - def indicator_space() -> List[Dimension]: - """ - Define your Hyperopt space for searching buy strategy parameters. - """ - return [ - Integer(10, 25, name='mfi-value'), - Integer(15, 45, name='fastd-value'), - Integer(15, 45, name='fastk-value'), - Integer(20, 50, name='adx-value'), - # Integer(20, 40, name='rsi-value'), - Categorical([True, False], name='mfi-enabled'), - Categorical([True, False], name='fastd-enabled'), - Categorical([True, False], name='adx-enabled'), - Categorical([True, False], name='fastk-enabled'), - # Categorical([True, False], name='rsi-enabled'), - # Categorical(['bb_lower', 'macd_cross_signal', 'sar_reversal'], name='trigger') - ] - - @staticmethod - def sell_strategy_generator(params: Dict[str, Any]) -> Callable: - """ - Define the sell strategy parameters to be used by Hyperopt. - """ - def populate_sell_trend(dataframe: DataFrame, metadata: dict) -> DataFrame: - """ - Sell strategy Hyperopt will build and use. - """ - conditions = [] - - # GUARDS AND TRENDS - if 'sell-mfi-enabled' in params and params['sell-mfi-enabled']: - conditions.append(dataframe['mfi'] > params['sell-mfi-value']) - if 'sell-fastd-enabled' in params and params['sell-fastd-enabled']: - conditions.append(dataframe['fastd'] > params['sell-fastd-value']) - if 'sell-adx-enabled' in params and params['sell-adx-enabled']: - conditions.append(dataframe['adx'] < params['sell-adx-value']) - if 'sell-fastk-enabled' in params and params['sell-fastk-enabled']: - conditions.append(dataframe['fastk'] > params['sell-fastk-value']) - if 'sell-cci-enabled' in params and params['sell-cci-enabled']: - conditions.append(dataframe['cci'] > params['sell-cci-value']) - - # TRIGGERS - # if 'sell-trigger' in params: - # if params['sell-trigger'] == 'sell-bb_upper': - # conditions.append(dataframe['close'] > dataframe['bb_upperband']) - # if params['sell-trigger'] == 'sell-macd_cross_signal': - # conditions.append(qtpylib.crossed_above( - # dataframe['macdsignal'], dataframe['macd'] - # )) - # if params['sell-trigger'] == 'sell-sar_reversal': - # conditions.append(qtpylib.crossed_above( - # dataframe['sar'], dataframe['close'] - # )) - - # Check that volume is not 0 - conditions.append(dataframe['volume'] > 0) - - if conditions: - dataframe.loc[ - reduce(lambda x, y: x & y, conditions), - 'sell'] = 1 - - return dataframe - - return populate_sell_trend - - @staticmethod - def sell_indicator_space() -> List[Dimension]: - """ - Define your Hyperopt space for searching sell strategy parameters. - """ - return [ - Integer(75, 100, name='sell-mfi-value'), - Integer(50, 100, name='sell-fastd-value'), - Integer(50, 100, name='sell-fastk-value'), - Integer(50, 100, name='sell-adx-value'), - Integer(100, 200, name='sell-cci-value'), - Categorical([True, False], name='sell-mfi-enabled'), - Categorical([True, False], name='sell-fastd-enabled'), - Categorical([True, False], name='sell-adx-enabled'), - Categorical([True, False], name='sell-cci-enabled'), - Categorical([True, False], name='sell-fastk-enabled'), - # Categorical(['sell-bb_upper', - # 'sell-macd_cross_signal', - # 'sell-sar_reversal'], name='sell-trigger') - ] diff --git a/user_data/strategies/berlinguyinca/ReinforcedSmoothScalp.py b/user_data/strategies/berlinguyinca/ReinforcedSmoothScalp.py index a3bbe79..ec5ed37 100644 --- a/user_data/strategies/berlinguyinca/ReinforcedSmoothScalp.py +++ b/user_data/strategies/berlinguyinca/ReinforcedSmoothScalp.py @@ -1,6 +1,8 @@ # --- Do not remove these libs --- -from freqtrade.strategy.interface import IStrategy +from functools import reduce +from freqtrade.strategy import IStrategy from freqtrade.strategy import timeframe_to_minutes +from freqtrade.strategy import BooleanParameter, IntParameter from pandas import DataFrame from technical.util import resample_to_interval, resampled_merge import numpy # noqa @@ -33,6 +35,27 @@ class ReinforcedSmoothScalp(IStrategy): # resample factor to establish our general trend. Basically don't buy if a trend is not given resample_factor = 5 + buy_adx = IntParameter(20, 50, default=32, space='buy') + buy_fastd = IntParameter(15, 45, default=30, space='buy') + buy_fastk = IntParameter(15, 45, default=26, space='buy') + buy_mfi = IntParameter(10, 25, default=22, space='buy') + buy_adx_enabled = BooleanParameter(default=True, space='buy') + buy_fastd_enabled = BooleanParameter(default=True, space='buy') + buy_fastk_enabled = BooleanParameter(default=False, space='buy') + buy_mfi_enabled = BooleanParameter(default=True, space='buy') + + sell_adx = IntParameter(50, 100, default=53, space='sell') + sell_cci = IntParameter(100, 200, default=183, space='sell') + sell_fastd = IntParameter(50, 100, default=79, space='sell') + sell_fastk = IntParameter(50, 100, default=70, space='sell') + sell_mfi = IntParameter(75, 100, default=92, space='sell') + + sell_adx_enabled = BooleanParameter(default=False, space='sell') + sell_cci_enabled = BooleanParameter(default=True, space='sell') + sell_fastd_enabled = BooleanParameter(default=True, space='sell') + sell_fastk_enabled = BooleanParameter(default=True, space='sell') + sell_mfi_enabled = BooleanParameter(default=False, space='sell') + def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: tf_res = timeframe_to_minutes(self.timeframe) * 5 df_res = resample_to_interval(dataframe, tf_res) @@ -60,43 +83,55 @@ class ReinforcedSmoothScalp(IStrategy): return dataframe def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: - dataframe.loc[ - ( - ( - (dataframe['open'] < dataframe['ema_low']) & - (dataframe['adx'] > 30) & - (dataframe['mfi'] < 30) & - ( - (dataframe['fastk'] < 30) & - (dataframe['fastd'] < 30) & - (qtpylib.crossed_above(dataframe['fastk'], dataframe['fastd'])) - ) & - (dataframe['resample_sma'] < dataframe['close']) - ) - # | - # # try to get some sure things independent of resample - # ((dataframe['rsi'] - dataframe['mfi']) < 10) & - # (dataframe['mfi'] < 30) & - # (dataframe['cci'] < -200) - ), - 'buy'] = 1 + + conditions = [] + if self.buy_mfi_enabled.value: + conditions.append(dataframe['mfi'] < self.buy_mfi.value) + if self.buy_fastd_enabled.value: + conditions.append(dataframe['fastd'] < self.buy_fastd.value) + if self.buy_fastk_enabled.value: + conditions.append(dataframe['fastk'] < self.buy_fastk.value) + if self.buy_adx_enabled.value: + conditions.append(dataframe['adx'] > self.buy_adx.value) + + # Some static conditions which always apply + conditions.append(qtpylib.crossed_above(dataframe['fastk'], dataframe['fastd'])) + conditions.append(dataframe['resample_sma'] < dataframe['close']) + + # Check that volume is not 0 + conditions.append(dataframe['volume'] > 0) + + if conditions: + dataframe.loc[ + reduce(lambda x, y: x & y, conditions), + 'buy'] = 1 + return dataframe def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: - dataframe.loc[ - ( - ( - ( - (dataframe['open'] >= dataframe['ema_high']) - ) | - ( - (qtpylib.crossed_above(dataframe['fastk'], 70)) | - (qtpylib.crossed_above(dataframe['fastd'], 70)) + conditions = [] + + # Some static conditions which always apply + conditions.append(dataframe['open'] > dataframe['ema_high']) + + if self.sell_mfi_enabled.value: + conditions.append(dataframe['mfi'] > self.sell_mfi.value) + if self.sell_fastd_enabled.value: + conditions.append(dataframe['fastd'] > self.sell_fastd.value) + if self.sell_fastk_enabled.value: + conditions.append(dataframe['fastk'] > self.sell_fastk.value) + if self.sell_adx_enabled.value: + conditions.append(dataframe['adx'] < self.sell_adx.value) + if self.sell_cci_enabled.value: + conditions.append(dataframe['cci'] > self.sell_cci.value) + + # Check that volume is not 0 + conditions.append(dataframe['volume'] > 0) + + if conditions: + dataframe.loc[ + reduce(lambda x, y: x & y, conditions), + 'sell'] = 1 - ) - ) & (dataframe['cci'] > 100) - ) - , - 'sell'] = 1 return dataframe