From 2079096d57018915c36519818a287a902732bb65 Mon Sep 17 00:00:00 2001 From: raftersvk Date: Thu, 4 Nov 2021 13:26:22 +0100 Subject: [PATCH 1/6] ignore local files --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 1a4040ff0..b077ca99d 100644 --- a/.gitignore +++ b/.gitignore @@ -82,3 +82,5 @@ pyproject.yml setup.cfg setup.py setup.sh +user_data/strategies/MasterMoniGoManiHyperStrategy_SSL.py +user_data/strategies/MoniGoManiHyperStrategy_SSL.py From 015b73f97e0a1cd1893f384f58d6dedf7015bac4 Mon Sep 17 00:00:00 2001 From: raftersvk Date: Thu, 4 Nov 2021 14:46:32 +0100 Subject: [PATCH 2/6] new trend based on SSL + sideways based on 2 indicators --- .../MasterMoniGoManiHyperStrategy.py | 87 +++++++++++++++++-- 1 file changed, 79 insertions(+), 8 deletions(-) diff --git a/user_data/strategies/MasterMoniGoManiHyperStrategy.py b/user_data/strategies/MasterMoniGoManiHyperStrategy.py index bc9ad5302..d8e80cafa 100644 --- a/user_data/strategies/MasterMoniGoManiHyperStrategy.py +++ b/user_data/strategies/MasterMoniGoManiHyperStrategy.py @@ -15,7 +15,7 @@ import pandas as pd # noqa import talib.abstract as ta from numpy import timedelta64 -from pandas import DataFrame +from pandas import DataFrame, Series from scipy.interpolate import interp1d from yaml import full_load @@ -25,7 +25,10 @@ from freqtrade.misc import deep_merge_dicts, round_dict from freqtrade.optimize.space import Categorical, Dimension, Integer, SKDecimal from freqtrade.persistence import Trade -from freqtrade.strategy import IntParameter, IStrategy, merge_informative_pair, timeframe_to_minutes +from freqtrade.strategy import IntParameter, IStrategy, merge_informative_pair, timeframe_to_minutes,DecimalParameter + +import freqtrade.vendor.qtpylib.indicators as qtpylib +import pandas_ta as pta logger = logging.getLogger(__name__) @@ -205,6 +208,14 @@ class MasterMoniGoManiHyperStrategy(IStrategy, ABC): total_signals_possible[f'{space}_{trend}'] = 0 total_triggers_possible[f'{space}_{trend}'] = 0 + # CoreTrend Hyperoptable parameters + trend_ssl_period = IntParameter(3, 15, default=8, space='buy', optimize=False, load=False) + trend_ssl_atr_coef = DecimalParameter(0, 1, decimals=1, default=0.4, space='buy', optimize=False, load=False) + trend_ssl_mode = IntParameter(1, 17, default=1, space='buy', optimize=False, load=False) + trend_chop_sideway = IntParameter(40, 55, default=41, space='buy', optimize=False, load=False) + trend_bb_sideway = IntParameter(5, 15, default=9, space='buy', optimize=False, load=False) + + class HyperOpt: @staticmethod def generate_roi_table(params: Dict) -> Dict[int, float]: @@ -382,7 +393,7 @@ def populate_frequi_plots(weighted_signal_plots: dict) -> dict: framework_plots = { # Main Plots - Trend Indicator (SAR) 'main_plot': { - 'sar': {'color': '#2c05f6'} + #'sar': {'color': '#2c05f6'} }, # Sub Plots - Each dict defines one additional plot 'subplots': { @@ -390,9 +401,9 @@ def populate_frequi_plots(weighted_signal_plots: dict) -> dict: 'MoniGoMani Core Trend': { 'mgm_trend': {'color': '#7fba3c'} }, - 'Hilbert Transform (Trend vs Cycle)': { - 'ht_trendmode': {'color': '#6f1a7b'} - }, + #'Hilbert Transform (Trend vs Cycle)': { + # 'ht_trendmode': {'color': '#6f1a7b'} + #}, # Sub Plots - Final Buy + Sell Signals 'Buy + Sell Signals Firing': { 'buy': {'color': '#09d528'}, @@ -425,6 +436,10 @@ def _populate_core_trend(self, dataframe: DataFrame, metadata: dict) -> DataFram :return: a Dataframe with all core trend indicators for MoniGoMani """ + """ + # -------------------- + # Current Core Trend Detection + # -------------------- # Momentum Indicators # ------------------- # Hilbert Transform - Trend vs Cycle @@ -438,6 +453,19 @@ def _populate_core_trend(self, dataframe: DataFrame, metadata: dict) -> DataFram dataframe.loc[(dataframe['ht_trendmode'] == 1) & (dataframe['sar'] > dataframe['close']), 'trend'] = 'downwards' dataframe.loc[(dataframe['ht_trendmode'] == 0) | (dataframe['sar'] == dataframe['close']), 'trend'] = 'sideways' dataframe.loc[(dataframe['ht_trendmode'] == 1) & (dataframe['sar'] < dataframe['close']), 'trend'] = 'upwards' + """ + # -------------------- + # New Core Trend Detection + # -------------------- + #Upwards / Downwards movement detection + df_ssl = SSLChannels_ATR(dataframe,period=self.trend_ssl_period.value,coef=self.trend_ssl_atr_coef.value,mode=self.trend_ssl_mode.value) + dataframe = pd.concat([dataframe, df_ssl], axis=1) + dataframe['trend'] = np.where((dataframe[f'SSLATR_{self.trend_ssl_mode.value}_{self.trend_ssl_period.value}_{self.trend_ssl_atr_coef.value}_up'] < dataframe[f'SSLATR_{self.trend_ssl_mode.value}_{self.trend_ssl_period.value}_{self.trend_ssl_atr_coef.value}_down']) + , 'downwards', 'upwards') + #Sideway movement detection + dataframe['chop'] = pta.chop(dataframe["high"], dataframe["low"], dataframe["close"]) + bollinger = qtpylib.bollinger_bands(qtpylib.typical_price(dataframe), window=20, stds=2) + dataframe['trend'] = np.where((dataframe['chop'] > self.trend_chop_sideway.value) & ((((bollinger['upper'] - bollinger['lower']) / bollinger['upper']) * 100) < self.trend_bb_sideway.value),'sideways',dataframe['trend']) # Add DataFrame column for visualization in FreqUI when Dry/Live RunMode is detected if self.is_dry_live_run_detected is True: @@ -526,7 +554,7 @@ def _populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFram # Merge core trend to informative data frame informative = merge_informative_pair( - informative, core_trend[['date', 'ht_trendmode', 'sar', 'trend']].copy(), + informative, core_trend[['date', 'trend']].copy(), self.informative_timeframe, self.core_trend_timeframe, ffill=True) skip_columns = [f'{s}_{self.core_trend_timeframe}' for s in ['date', 'open', 'high', 'low', 'close', 'volume']] @@ -560,7 +588,7 @@ def _populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFram # Merge core trend to main data frame dataframe = merge_informative_pair( - dataframe, core_trend[['date', 'ht_trendmode', 'sar', 'trend', 'mgm_trend']].copy(), + dataframe, core_trend[['date', 'trend', 'mgm_trend']].copy(), self.timeframe, self.core_trend_timeframe, ffill=True) skip_columns = [f'{s}_{self.core_trend_timeframe}' for s in ['date', 'open', 'high', 'low', 'close', 'volume']] @@ -1421,3 +1449,46 @@ def init_hyperopt_epoch(self) -> None: separator_window = (self.separator / 1) - (1 / self.separator) self.separator_candle_weight_reducer = separator_window / self.get_param_value( 'sell___unclogger_trend_lookback_candles_window') +# --------------------------------------------------- +# Customized SSL Channel function with ATR coef +# --------------------------------------------------- +def SSLChannels_ATR(dataframe,period: int=7,coef: int=1,mode: int=1): + """ + SSL Channels with ATR: https://www.tradingview.com/script/SKHqWzql-SSL-ATR-channel/ + Credit to @JimmyNixx for python + """ + df = dataframe.copy() + + df['ATR'] = ta.ATR(df, timeperiod=int(period)) + + #MovingAverage mode + if mode == 1 : mamode = "dema" + elif mode == 2 : mamode = "fwma" + elif mode == 3 : mamode = "hma" + elif mode == 4 : mamode = "linreg" + elif mode == 5 : mamode = "midpoint" + elif mode == 6 : mamode = "pwma" + elif mode == 7 : mamode = "rma" + elif mode == 8 : mamode = "sinwma" + elif mode == 9 : mamode = "sma" + elif mode == 10 : mamode = "swma" + elif mode == 11 : mamode = "t3" + elif mode == 12 : mamode = "tema" + elif mode == 13 : mamode = "trima" + elif mode == 14 : mamode = "vidya" + elif mode == 15 : mamode = "wma" + elif mode == 16 : mamode = "zlma" + else : mamode = "ema" + + df['maHigh'] = pta.ma(mamode, dataframe['high'], length=period) + (df['ATR'] * coef) + df['maLow'] = pta.ma(mamode, dataframe['low'], length=period) - (df['ATR'] * coef) + + df['hlv'] = np.where(df['close'] > df['maHigh'], 1, np.where(df['close'] < df['maLow'], -1, np.NAN)) + df['hlv'] = df['hlv'].ffill() + + df[f'SSLATR_{mode}_{period}_{coef}_down'] = np.where(df['hlv'] < 0, df['maHigh'], df['maLow']) + df[f'SSLATR_{mode}_{period}_{coef}_up'] = np.where(df['hlv'] < 0, df['maLow'], df['maHigh']) + + return pd.concat([df[f'SSLATR_{mode}_{period}_{coef}_down'], df[f'SSLATR_{mode}_{period}_{coef}_up']], axis=1) +# --------------------------------------------------- + From 612dc9d44d89f1ca5748533bea293b98a99c940a Mon Sep 17 00:00:00 2001 From: raftersvk Date: Thu, 4 Nov 2021 14:56:44 +0100 Subject: [PATCH 3/6] chop indicator default value --- user_data/strategies/MasterMoniGoManiHyperStrategy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_data/strategies/MasterMoniGoManiHyperStrategy.py b/user_data/strategies/MasterMoniGoManiHyperStrategy.py index d8e80cafa..b9d83a18d 100644 --- a/user_data/strategies/MasterMoniGoManiHyperStrategy.py +++ b/user_data/strategies/MasterMoniGoManiHyperStrategy.py @@ -212,7 +212,7 @@ class MasterMoniGoManiHyperStrategy(IStrategy, ABC): trend_ssl_period = IntParameter(3, 15, default=8, space='buy', optimize=False, load=False) trend_ssl_atr_coef = DecimalParameter(0, 1, decimals=1, default=0.4, space='buy', optimize=False, load=False) trend_ssl_mode = IntParameter(1, 17, default=1, space='buy', optimize=False, load=False) - trend_chop_sideway = IntParameter(40, 55, default=41, space='buy', optimize=False, load=False) + trend_chop_sideway = IntParameter(40, 55, default=48, space='buy', optimize=False, load=False) trend_bb_sideway = IntParameter(5, 15, default=9, space='buy', optimize=False, load=False) From bb3c67d90c9be0888d90c04b64200ef574ccf465 Mon Sep 17 00:00:00 2001 From: raftersvk Date: Thu, 4 Nov 2021 22:13:34 +0100 Subject: [PATCH 4/6] default values for core trend 30m --- user_data/strategies/MasterMoniGoManiHyperStrategy.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/user_data/strategies/MasterMoniGoManiHyperStrategy.py b/user_data/strategies/MasterMoniGoManiHyperStrategy.py index b9d83a18d..91b66193a 100644 --- a/user_data/strategies/MasterMoniGoManiHyperStrategy.py +++ b/user_data/strategies/MasterMoniGoManiHyperStrategy.py @@ -209,12 +209,12 @@ class MasterMoniGoManiHyperStrategy(IStrategy, ABC): total_triggers_possible[f'{space}_{trend}'] = 0 # CoreTrend Hyperoptable parameters - trend_ssl_period = IntParameter(3, 15, default=8, space='buy', optimize=False, load=False) - trend_ssl_atr_coef = DecimalParameter(0, 1, decimals=1, default=0.4, space='buy', optimize=False, load=False) + trend_ssl_period = IntParameter(6, 15, default=10, space='buy', optimize=False, load=False) + trend_ssl_atr_coef = DecimalParameter(0, 1, decimals=1, default=0.3, space='buy', optimize=False, load=False) trend_ssl_mode = IntParameter(1, 17, default=1, space='buy', optimize=False, load=False) - trend_chop_sideway = IntParameter(40, 55, default=48, space='buy', optimize=False, load=False) - trend_bb_sideway = IntParameter(5, 15, default=9, space='buy', optimize=False, load=False) - + trend_chop_sideway = IntParameter(45, 55, default=50, space='buy', optimize=False, load=False) + trend_bb_sideway = IntParameter(5, 15, default=8, space='buy', optimize=False, load=False) + class HyperOpt: @staticmethod From 7088a5cc4926d62087957a9e03a2de4e42364c8e Mon Sep 17 00:00:00 2001 From: Rik Helsen Date: Sat, 6 Nov 2021 23:35:34 +0100 Subject: [PATCH 5/6] =?UTF-8?q?=E2=99=BB=20Refactored=20new=20`SSL`=20&=20?= =?UTF-8?q?`Chop`=20core=20trend=20detection?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MasterMoniGoManiHyperStrategy.py | 39 +++++++++++++------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/user_data/strategies/MasterMoniGoManiHyperStrategy.py b/user_data/strategies/MasterMoniGoManiHyperStrategy.py index 91b66193a..1d09d8400 100644 --- a/user_data/strategies/MasterMoniGoManiHyperStrategy.py +++ b/user_data/strategies/MasterMoniGoManiHyperStrategy.py @@ -214,7 +214,7 @@ class MasterMoniGoManiHyperStrategy(IStrategy, ABC): trend_ssl_mode = IntParameter(1, 17, default=1, space='buy', optimize=False, load=False) trend_chop_sideway = IntParameter(45, 55, default=50, space='buy', optimize=False, load=False) trend_bb_sideway = IntParameter(5, 15, default=8, space='buy', optimize=False, load=False) - + class HyperOpt: @staticmethod @@ -437,9 +437,9 @@ def _populate_core_trend(self, dataframe: DataFrame, metadata: dict) -> DataFram """ """ - # -------------------- + # ---------------------------- # Current Core Trend Detection - # -------------------- + # ---------------------------- # Momentum Indicators # ------------------- # Hilbert Transform - Trend vs Cycle @@ -453,19 +453,34 @@ def _populate_core_trend(self, dataframe: DataFrame, metadata: dict) -> DataFram dataframe.loc[(dataframe['ht_trendmode'] == 1) & (dataframe['sar'] > dataframe['close']), 'trend'] = 'downwards' dataframe.loc[(dataframe['ht_trendmode'] == 0) | (dataframe['sar'] == dataframe['close']), 'trend'] = 'sideways' dataframe.loc[(dataframe['ht_trendmode'] == 1) & (dataframe['sar'] < dataframe['close']), 'trend'] = 'upwards' - """ - # -------------------- + + # ------------------------ # New Core Trend Detection - # -------------------- - #Upwards / Downwards movement detection - df_ssl = SSLChannels_ATR(dataframe,period=self.trend_ssl_period.value,coef=self.trend_ssl_atr_coef.value,mode=self.trend_ssl_mode.value) + # ------------------------ + """ + # Upwards / Downwards movement detection + # -------------------------------------- + # SSL Channels + df_ssl = SSLChannels_ATR(dataframe, period=self.trend_ssl_period.value, + coef=self.trend_ssl_atr_coef.value, mode=self.trend_ssl_mode.value) dataframe = pd.concat([dataframe, df_ssl], axis=1) - dataframe['trend'] = np.where((dataframe[f'SSLATR_{self.trend_ssl_mode.value}_{self.trend_ssl_period.value}_{self.trend_ssl_atr_coef.value}_up'] < dataframe[f'SSLATR_{self.trend_ssl_mode.value}_{self.trend_ssl_period.value}_{self.trend_ssl_atr_coef.value}_down']) - , 'downwards', 'upwards') - #Sideway movement detection + + ssl_atr = f'SSLATR_{self.trend_ssl_mode.value}_{self.trend_ssl_period.value}_{self.trend_ssl_atr_coef.value}' + dataframe['trend'] = np.where(dataframe[f'{ssl_atr}_up'] < dataframe[f'{ssl_atr}_down'], 'downwards', 'upwards') + + # Sideways movement detection + # --------------------------- + # Choppiness Index dataframe['chop'] = pta.chop(dataframe["high"], dataframe["low"], dataframe["close"]) + + # Bollinger Bands bollinger = qtpylib.bollinger_bands(qtpylib.typical_price(dataframe), window=20, stds=2) - dataframe['trend'] = np.where((dataframe['chop'] > self.trend_chop_sideway.value) & ((((bollinger['upper'] - bollinger['lower']) / bollinger['upper']) * 100) < self.trend_bb_sideway.value),'sideways',dataframe['trend']) + + dataframe['trend'] = np.where( + (dataframe['chop'] > self.trend_chop_sideway.value) & + ((((bollinger['upper'] - bollinger['lower']) / bollinger['upper']) * 100) < self.trend_bb_sideway.value), + 'sideways', dataframe['trend'] + ) # Add DataFrame column for visualization in FreqUI when Dry/Live RunMode is detected if self.is_dry_live_run_detected is True: From 48a9c4d3900b10948ef43f70b0bc2b290028f4ed Mon Sep 17 00:00:00 2001 From: Rik Helsen Date: Sun, 7 Nov 2021 00:10:17 +0100 Subject: [PATCH 6/6] =?UTF-8?q?=E2=99=BB=20Refactored=20new=20`ssl=5Fchann?= =?UTF-8?q?els=5Fatr`=20function?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MasterMoniGoManiHyperStrategy.py | 66 +++++++++---------- 1 file changed, 30 insertions(+), 36 deletions(-) diff --git a/user_data/strategies/MasterMoniGoManiHyperStrategy.py b/user_data/strategies/MasterMoniGoManiHyperStrategy.py index 1d09d8400..bf195fb91 100644 --- a/user_data/strategies/MasterMoniGoManiHyperStrategy.py +++ b/user_data/strategies/MasterMoniGoManiHyperStrategy.py @@ -461,8 +461,8 @@ def _populate_core_trend(self, dataframe: DataFrame, metadata: dict) -> DataFram # Upwards / Downwards movement detection # -------------------------------------- # SSL Channels - df_ssl = SSLChannels_ATR(dataframe, period=self.trend_ssl_period.value, - coef=self.trend_ssl_atr_coef.value, mode=self.trend_ssl_mode.value) + df_ssl = ssl_channels_atr(dataframe, period=self.trend_ssl_period.value, + coef=self.trend_ssl_atr_coef.value, mode=self.trend_ssl_mode.value) dataframe = pd.concat([dataframe, df_ssl], axis=1) ssl_atr = f'SSLATR_{self.trend_ssl_mode.value}_{self.trend_ssl_period.value}_{self.trend_ssl_atr_coef.value}' @@ -1464,46 +1464,40 @@ def init_hyperopt_epoch(self) -> None: separator_window = (self.separator / 1) - (1 / self.separator) self.separator_candle_weight_reducer = separator_window / self.get_param_value( 'sell___unclogger_trend_lookback_candles_window') -# --------------------------------------------------- -# Customized SSL Channel function with ATR coef -# --------------------------------------------------- -def SSLChannels_ATR(dataframe,period: int=7,coef: int=1,mode: int=1): + + +def ssl_channels_atr(dataframe, period: int = 7, coef: int = 1, mode: int = 1): """ - SSL Channels with ATR: https://www.tradingview.com/script/SKHqWzql-SSL-ATR-channel/ - Credit to @JimmyNixx for python + Customized SSL Channel function with ATR Coefficient """ + ssl_atr = f'SSLATR_{mode}_{period}_{coef}' df = dataframe.copy() - df['ATR'] = ta.ATR(df, timeperiod=int(period)) - - #MovingAverage mode - if mode == 1 : mamode = "dema" - elif mode == 2 : mamode = "fwma" - elif mode == 3 : mamode = "hma" - elif mode == 4 : mamode = "linreg" - elif mode == 5 : mamode = "midpoint" - elif mode == 6 : mamode = "pwma" - elif mode == 7 : mamode = "rma" - elif mode == 8 : mamode = "sinwma" - elif mode == 9 : mamode = "sma" - elif mode == 10 : mamode = "swma" - elif mode == 11 : mamode = "t3" - elif mode == 12 : mamode = "tema" - elif mode == 13 : mamode = "trima" - elif mode == 14 : mamode = "vidya" - elif mode == 15 : mamode = "wma" - elif mode == 16 : mamode = "zlma" - else : mamode = "ema" - - df['maHigh'] = pta.ma(mamode, dataframe['high'], length=period) + (df['ATR'] * coef) - df['maLow'] = pta.ma(mamode, dataframe['low'], length=period) - (df['ATR'] * coef) - + # Moving Average modes + ma_modes = {1: 'dema', 2: 'fwma', 3: 'hma', 4: 'linreg', 5: 'midpoint', 6: 'pwma', 7: 'rma', 8: 'sinwma', 9: 'sma', + 10: 'swma', 11: 't3', 12: 'tema', 13: 'trima', 14: 'vidya', 15: 'wma', 16: 'zlma'} + + # Select the currently used Moving Average mode + ma_mode = 'ema' + for mode_key, ma_mode_value in ma_modes.items(): + if mode_key == mode: + ma_mode = ma_mode_value + break + + # Populate indicator data + # ----------------------- + # ATR + df['atr'] = ta.ATR(df, timeperiod=int(period)) + # Moving Average High/Low + df['maHigh'] = pta.ma(ma_mode, dataframe['high'], length=period) + (df['atr'] * coef) + df['maLow'] = pta.ma(ma_mode, dataframe['low'], length=period) - (df['atr'] * coef) + # HLV df['hlv'] = np.where(df['close'] > df['maHigh'], 1, np.where(df['close'] < df['maLow'], -1, np.NAN)) df['hlv'] = df['hlv'].ffill() + # SSL Down/Up + df[f'{ssl_atr}_down'] = np.where(df['hlv'] < 0, df['maHigh'], df['maLow']) + df[f'{ssl_atr}_up'] = np.where(df['hlv'] < 0, df['maLow'], df['maHigh']) - df[f'SSLATR_{mode}_{period}_{coef}_down'] = np.where(df['hlv'] < 0, df['maHigh'], df['maLow']) - df[f'SSLATR_{mode}_{period}_{coef}_up'] = np.where(df['hlv'] < 0, df['maLow'], df['maHigh']) - - return pd.concat([df[f'SSLATR_{mode}_{period}_{coef}_down'], df[f'SSLATR_{mode}_{period}_{coef}_up']], axis=1) + return pd.concat([df[f'{ssl_atr}_down'], df[f'{ssl_atr}_up']], axis=1) # ---------------------------------------------------