From 5783a44c862a1f5aa15b7d8dacce81d7f793d662 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 12 May 2024 16:43:43 +0200 Subject: [PATCH] ruff format: template directory --- .../templates/FreqaiExampleHybridStrategy.py | 130 ++++++++-------- freqtrade/templates/FreqaiExampleStrategy.py | 37 ++--- freqtrade/templates/sample_hyperopt_loss.py | 20 ++- freqtrade/templates/sample_strategy.py | 139 +++++++++--------- 4 files changed, 167 insertions(+), 159 deletions(-) diff --git a/freqtrade/templates/FreqaiExampleHybridStrategy.py b/freqtrade/templates/FreqaiExampleHybridStrategy.py index 5df03bd5d..6f7e5cac7 100644 --- a/freqtrade/templates/FreqaiExampleHybridStrategy.py +++ b/freqtrade/templates/FreqaiExampleHybridStrategy.py @@ -61,27 +61,28 @@ class FreqaiExampleHybridStrategy(IStrategy): """ minimal_roi = { + # "120": 0.0, # exit after 120 minutes at break even "60": 0.01, "30": 0.02, "0": 0.04 } plot_config = { - 'main_plot': { - 'tema': {}, + "main_plot": { + "tema": {}, }, - 'subplots': { + "subplots": { "MACD": { - 'macd': {'color': 'blue'}, - 'macdsignal': {'color': 'orange'}, + "macd": {"color": "blue"}, + "macdsignal": {"color": "orange"}, }, "RSI": { - 'rsi': {'color': 'red'}, + "rsi": {"color": "red"}, }, "Up_or_down": { - '&s-up_or_down': {'color': 'green'}, - } - } + "&s-up_or_down": {"color": "green"}, + }, + }, } process_only_new_candles = True @@ -91,13 +92,14 @@ class FreqaiExampleHybridStrategy(IStrategy): can_short = True # Hyperoptable parameters - buy_rsi = IntParameter(low=1, high=50, default=30, space='buy', optimize=True, load=True) - sell_rsi = IntParameter(low=50, high=100, default=70, space='sell', optimize=True, load=True) - short_rsi = IntParameter(low=51, high=100, default=70, space='sell', optimize=True, load=True) - exit_short_rsi = IntParameter(low=1, high=50, default=30, space='buy', optimize=True, load=True) + buy_rsi = IntParameter(low=1, high=50, default=30, space="buy", optimize=True, load=True) + sell_rsi = IntParameter(low=50, high=100, default=70, space="sell", optimize=True, load=True) + short_rsi = IntParameter(low=51, high=100, default=70, space="sell", optimize=True, load=True) + exit_short_rsi = IntParameter(low=1, high=50, default=30, space="buy", optimize=True, load=True) - def feature_engineering_expand_all(self, dataframe: DataFrame, period: int, - metadata: Dict, **kwargs) -> DataFrame: + def feature_engineering_expand_all( + self, dataframe: DataFrame, period: int, metadata: Dict, **kwargs + ) -> DataFrame: """ *Only functional with FreqAI enabled strategies* This function will automatically expand the defined features on the config defined @@ -136,12 +138,9 @@ class FreqaiExampleHybridStrategy(IStrategy): dataframe["bb_upperband-period"] = bollinger["upper"] dataframe["%-bb_width-period"] = ( - dataframe["bb_upperband-period"] - - dataframe["bb_lowerband-period"] + dataframe["bb_upperband-period"] - dataframe["bb_lowerband-period"] ) / dataframe["bb_middleband-period"] - dataframe["%-close-bb_lower-period"] = ( - dataframe["close"] / dataframe["bb_lowerband-period"] - ) + dataframe["%-close-bb_lower-period"] = dataframe["close"] / dataframe["bb_lowerband-period"] dataframe["%-roc-period"] = ta.ROC(dataframe, timeperiod=period) @@ -152,7 +151,8 @@ class FreqaiExampleHybridStrategy(IStrategy): return dataframe def feature_engineering_expand_basic( - self, dataframe: DataFrame, metadata: Dict, **kwargs) -> DataFrame: + self, dataframe: DataFrame, metadata: Dict, **kwargs + ) -> DataFrame: """ *Only functional with FreqAI enabled strategies* This function will automatically expand the defined features on the config defined @@ -185,7 +185,8 @@ class FreqaiExampleHybridStrategy(IStrategy): return dataframe def feature_engineering_standard( - self, dataframe: DataFrame, metadata: Dict, **kwargs) -> DataFrame: + self, dataframe: DataFrame, metadata: Dict, **kwargs + ) -> DataFrame: """ *Only functional with FreqAI enabled strategies* This optional function will be called once with the dataframe of the base timeframe. @@ -226,13 +227,13 @@ class FreqaiExampleHybridStrategy(IStrategy): usage example: dataframe["&-target"] = dataframe["close"].shift(-1) / dataframe["close"] """ self.freqai.class_names = ["down", "up"] - dataframe['&s-up_or_down'] = np.where(dataframe["close"].shift(-50) > - dataframe["close"], 'up', 'down') + dataframe["&s-up_or_down"] = np.where( + dataframe["close"].shift(-50) > dataframe["close"], "up", "down" + ) return dataframe def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: # noqa: C901 - # User creates their own custom strat here. Present example is a supertrend # based strategy. @@ -240,78 +241,81 @@ class FreqaiExampleHybridStrategy(IStrategy): # TA indicators to combine with the Freqai targets # RSI - dataframe['rsi'] = ta.RSI(dataframe) + dataframe["rsi"] = ta.RSI(dataframe) # Bollinger Bands bollinger = qtpylib.bollinger_bands(qtpylib.typical_price(dataframe), window=20, stds=2) - dataframe['bb_lowerband'] = bollinger['lower'] - dataframe['bb_middleband'] = bollinger['mid'] - dataframe['bb_upperband'] = bollinger['upper'] - dataframe["bb_percent"] = ( - (dataframe["close"] - dataframe["bb_lowerband"]) / - (dataframe["bb_upperband"] - dataframe["bb_lowerband"]) - ) - dataframe["bb_width"] = ( - (dataframe["bb_upperband"] - dataframe["bb_lowerband"]) / dataframe["bb_middleband"] + dataframe["bb_lowerband"] = bollinger["lower"] + dataframe["bb_middleband"] = bollinger["mid"] + dataframe["bb_upperband"] = bollinger["upper"] + dataframe["bb_percent"] = (dataframe["close"] - dataframe["bb_lowerband"]) / ( + dataframe["bb_upperband"] - dataframe["bb_lowerband"] ) + dataframe["bb_width"] = (dataframe["bb_upperband"] - dataframe["bb_lowerband"]) / dataframe[ + "bb_middleband" + ] # TEMA - Triple Exponential Moving Average - dataframe['tema'] = ta.TEMA(dataframe, timeperiod=9) + dataframe["tema"] = ta.TEMA(dataframe, timeperiod=9) return dataframe def populate_entry_trend(self, df: DataFrame, metadata: dict) -> DataFrame: - df.loc[ ( # Signal: RSI crosses above 30 - (qtpylib.crossed_above(df['rsi'], self.buy_rsi.value)) & - (df['tema'] <= df['bb_middleband']) & # Guard: tema below BB middle - (df['tema'] > df['tema'].shift(1)) & # Guard: tema is raising - (df['volume'] > 0) & # Make sure Volume is not 0 - (df['do_predict'] == 1) & # Make sure Freqai is confident in the prediction + (qtpylib.crossed_above(df["rsi"], self.buy_rsi.value)) + & (df["tema"] <= df["bb_middleband"]) # Guard: tema below BB middle + & (df["tema"] > df["tema"].shift(1)) # Guard: tema is raising + & (df["volume"] > 0) # Make sure Volume is not 0 + & (df["do_predict"] == 1) # Make sure Freqai is confident in the prediction + & # Only enter trade if Freqai thinks the trend is in this direction - (df['&s-up_or_down'] == 'up') + (df["&s-up_or_down"] == "up") ), - 'enter_long'] = 1 + "enter_long", + ] = 1 df.loc[ ( # Signal: RSI crosses above 70 - (qtpylib.crossed_above(df['rsi'], self.short_rsi.value)) & - (df['tema'] > df['bb_middleband']) & # Guard: tema above BB middle - (df['tema'] < df['tema'].shift(1)) & # Guard: tema is falling - (df['volume'] > 0) & # Make sure Volume is not 0 - (df['do_predict'] == 1) & # Make sure Freqai is confident in the prediction + (qtpylib.crossed_above(df["rsi"], self.short_rsi.value)) + & (df["tema"] > df["bb_middleband"]) # Guard: tema above BB middle + & (df["tema"] < df["tema"].shift(1)) # Guard: tema is falling + & (df["volume"] > 0) # Make sure Volume is not 0 + & (df["do_predict"] == 1) # Make sure Freqai is confident in the prediction + & # Only enter trade if Freqai thinks the trend is in this direction - (df['&s-up_or_down'] == 'down') + (df["&s-up_or_down"] == "down") ), - 'enter_short'] = 1 + "enter_short", + ] = 1 return df def populate_exit_trend(self, df: DataFrame, metadata: dict) -> DataFrame: - df.loc[ ( # Signal: RSI crosses above 70 - (qtpylib.crossed_above(df['rsi'], self.sell_rsi.value)) & - (df['tema'] > df['bb_middleband']) & # Guard: tema above BB middle - (df['tema'] < df['tema'].shift(1)) & # Guard: tema is falling - (df['volume'] > 0) # Make sure Volume is not 0 + (qtpylib.crossed_above(df["rsi"], self.sell_rsi.value)) + & (df["tema"] > df["bb_middleband"]) # Guard: tema above BB middle + & (df["tema"] < df["tema"].shift(1)) # Guard: tema is falling + & (df["volume"] > 0) # Make sure Volume is not 0 ), - - 'exit_long'] = 1 + "exit_long", + ] = 1 df.loc[ ( # Signal: RSI crosses above 30 - (qtpylib.crossed_above(df['rsi'], self.exit_short_rsi.value)) & + (qtpylib.crossed_above(df["rsi"], self.exit_short_rsi.value)) + & # Guard: tema below BB middle - (df['tema'] <= df['bb_middleband']) & - (df['tema'] > df['tema'].shift(1)) & # Guard: tema is raising - (df['volume'] > 0) # Make sure Volume is not 0 + (df["tema"] <= df["bb_middleband"]) + & (df["tema"] > df["tema"].shift(1)) # Guard: tema is raising + & (df["volume"] > 0) # Make sure Volume is not 0 ), - 'exit_short'] = 1 + "exit_short", + ] = 1 return df diff --git a/freqtrade/templates/FreqaiExampleStrategy.py b/freqtrade/templates/FreqaiExampleStrategy.py index 93b916e38..a16775163 100644 --- a/freqtrade/templates/FreqaiExampleStrategy.py +++ b/freqtrade/templates/FreqaiExampleStrategy.py @@ -45,8 +45,9 @@ class FreqaiExampleStrategy(IStrategy): startup_candle_count: int = 40 can_short = True - def feature_engineering_expand_all(self, dataframe: DataFrame, period: int, - metadata: Dict, **kwargs) -> DataFrame: + def feature_engineering_expand_all( + self, dataframe: DataFrame, period: int, metadata: Dict, **kwargs + ) -> DataFrame: """ *Only functional with FreqAI enabled strategies* This function will automatically expand the defined features on the config defined @@ -89,12 +90,9 @@ class FreqaiExampleStrategy(IStrategy): dataframe["bb_upperband-period"] = bollinger["upper"] dataframe["%-bb_width-period"] = ( - dataframe["bb_upperband-period"] - - dataframe["bb_lowerband-period"] + dataframe["bb_upperband-period"] - dataframe["bb_lowerband-period"] ) / dataframe["bb_middleband-period"] - dataframe["%-close-bb_lower-period"] = ( - dataframe["close"] / dataframe["bb_lowerband-period"] - ) + dataframe["%-close-bb_lower-period"] = dataframe["close"] / dataframe["bb_lowerband-period"] dataframe["%-roc-period"] = ta.ROC(dataframe, timeperiod=period) @@ -105,7 +103,8 @@ class FreqaiExampleStrategy(IStrategy): return dataframe def feature_engineering_expand_basic( - self, dataframe: DataFrame, metadata: Dict, **kwargs) -> DataFrame: + self, dataframe: DataFrame, metadata: Dict, **kwargs + ) -> DataFrame: """ *Only functional with FreqAI enabled strategies* This function will automatically expand the defined features on the config defined @@ -142,7 +141,8 @@ class FreqaiExampleStrategy(IStrategy): return dataframe def feature_engineering_standard( - self, dataframe: DataFrame, metadata: Dict, **kwargs) -> DataFrame: + self, dataframe: DataFrame, metadata: Dict, **kwargs + ) -> DataFrame: """ *Only functional with FreqAI enabled strategies* This optional function will be called once with the dataframe of the base timeframe. @@ -197,7 +197,7 @@ class FreqaiExampleStrategy(IStrategy): .mean() / dataframe["close"] - 1 - ) + ) # Classifiers are typically set up with strings as targets: # df['&s-up_or_down'] = np.where( df["close"].shift(-100) > @@ -224,7 +224,6 @@ class FreqaiExampleStrategy(IStrategy): return dataframe def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: - # All indicators must be populated by feature_engineering_*() functions # the model will return all labels created by user in `set_freqai_targets()` @@ -237,11 +236,10 @@ class FreqaiExampleStrategy(IStrategy): return dataframe def populate_entry_trend(self, df: DataFrame, metadata: dict) -> DataFrame: - enter_long_conditions = [ df["do_predict"] == 1, df["&-s_close"] > 0.01, - ] + ] if enter_long_conditions: df.loc[ @@ -251,7 +249,7 @@ class FreqaiExampleStrategy(IStrategy): enter_short_conditions = [ df["do_predict"] == 1, df["&-s_close"] < -0.01, - ] + ] if enter_short_conditions: df.loc[ @@ -261,17 +259,11 @@ class FreqaiExampleStrategy(IStrategy): return df def populate_exit_trend(self, df: DataFrame, metadata: dict) -> DataFrame: - exit_long_conditions = [ - df["do_predict"] == 1, - df["&-s_close"] < 0 - ] + exit_long_conditions = [df["do_predict"] == 1, df["&-s_close"] < 0] if exit_long_conditions: df.loc[reduce(lambda x, y: x & y, exit_long_conditions), "exit_long"] = 1 - exit_short_conditions = [ - df["do_predict"] == 1, - df["&-s_close"] > 0 - ] + exit_short_conditions = [df["do_predict"] == 1, df["&-s_close"] > 0] if exit_short_conditions: df.loc[reduce(lambda x, y: x & y, exit_short_conditions), "exit_short"] = 1 @@ -289,7 +281,6 @@ class FreqaiExampleStrategy(IStrategy): side: str, **kwargs, ) -> bool: - df, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe) last_candle = df.iloc[-1].squeeze() diff --git a/freqtrade/templates/sample_hyperopt_loss.py b/freqtrade/templates/sample_hyperopt_loss.py index 5eab92a0c..4e4afed24 100644 --- a/freqtrade/templates/sample_hyperopt_loss.py +++ b/freqtrade/templates/sample_hyperopt_loss.py @@ -35,17 +35,23 @@ class SampleHyperOptLoss(IHyperOptLoss): """ @staticmethod - def hyperopt_loss_function(results: DataFrame, trade_count: int, - min_date: datetime, max_date: datetime, - config: Config, processed: Dict[str, DataFrame], - *args, **kwargs) -> float: + def hyperopt_loss_function( + results: DataFrame, + trade_count: int, + min_date: datetime, + max_date: datetime, + config: Config, + processed: Dict[str, DataFrame], + *args, + **kwargs, + ) -> float: """ Objective function, returns smaller number for better results """ - total_profit = results['profit_ratio'].sum() - trade_duration = results['trade_duration'].mean() + total_profit = results["profit_ratio"].sum() + trade_duration = results["trade_duration"].mean() - trade_loss = 1 - 0.25 * exp(-(trade_count - TARGET_TRADES) ** 2 / 10 ** 5.8) + trade_loss = 1 - 0.25 * exp(-((trade_count - TARGET_TRADES) ** 2) / 10**5.8) profit_loss = max(0, 1 - total_profit / EXPECTED_MAX_PROFIT) duration_loss = 0.4 * min(trade_duration / MAX_ACCEPTED_TRADE_DURATION, 1) result = trade_loss + profit_loss + duration_loss diff --git a/freqtrade/templates/sample_strategy.py b/freqtrade/templates/sample_strategy.py index dec547715..076569420 100644 --- a/freqtrade/templates/sample_strategy.py +++ b/freqtrade/templates/sample_strategy.py @@ -7,8 +7,13 @@ import pandas as pd # noqa from pandas import DataFrame from typing import Optional, Union -from freqtrade.strategy import (BooleanParameter, CategoricalParameter, DecimalParameter, - IStrategy, IntParameter) +from freqtrade.strategy import ( + BooleanParameter, + CategoricalParameter, + DecimalParameter, + IStrategy, + IntParameter, +) # -------------------------------- # Add your lib to import here @@ -34,6 +39,7 @@ class SampleStrategy(IStrategy): You should keep: - timeframe, minimal_roi, stoploss, trailing_* """ + # Strategy interface version - allow new iterations of the strategy interface. # Check the documentation or the Sample strategy to get the latest version. INTERFACE_VERSION = 3 @@ -44,6 +50,7 @@ class SampleStrategy(IStrategy): # Minimal ROI designed for the strategy. # This attribute will be overridden if the config file contains "minimal_roi". minimal_roi = { + # "120": 0.0, # exit after 120 minutes at break even "60": 0.01, "30": 0.02, "0": 0.04 @@ -60,7 +67,7 @@ class SampleStrategy(IStrategy): # trailing_stop_positive_offset = 0.0 # Disabled / not configured # Optimal timeframe for the strategy. - timeframe = '5m' + timeframe = "5m" # Run "populate_indicators()" only for new candle. process_only_new_candles = True @@ -71,42 +78,39 @@ class SampleStrategy(IStrategy): ignore_roi_if_entry_signal = False # Hyperoptable parameters - buy_rsi = IntParameter(low=1, high=50, default=30, space='buy', optimize=True, load=True) - sell_rsi = IntParameter(low=50, high=100, default=70, space='sell', optimize=True, load=True) - short_rsi = IntParameter(low=51, high=100, default=70, space='sell', optimize=True, load=True) - exit_short_rsi = IntParameter(low=1, high=50, default=30, space='buy', optimize=True, load=True) + buy_rsi = IntParameter(low=1, high=50, default=30, space="buy", optimize=True, load=True) + sell_rsi = IntParameter(low=50, high=100, default=70, space="sell", optimize=True, load=True) + short_rsi = IntParameter(low=51, high=100, default=70, space="sell", optimize=True, load=True) + exit_short_rsi = IntParameter(low=1, high=50, default=30, space="buy", optimize=True, load=True) # Number of candles the strategy requires before producing valid signals startup_candle_count: int = 200 # Optional order type mapping. order_types = { - 'entry': 'limit', - 'exit': 'limit', - 'stoploss': 'market', - 'stoploss_on_exchange': False + "entry": "limit", + "exit": "limit", + "stoploss": "market", + "stoploss_on_exchange": False, } # Optional order time in force. - order_time_in_force = { - 'entry': 'GTC', - 'exit': 'GTC' - } + order_time_in_force = {"entry": "GTC", "exit": "GTC"} plot_config = { - 'main_plot': { - 'tema': {}, - 'sar': {'color': 'white'}, + "main_plot": { + "tema": {}, + "sar": {"color": "white"}, }, - 'subplots': { + "subplots": { "MACD": { - 'macd': {'color': 'blue'}, - 'macdsignal': {'color': 'orange'}, + "macd": {"color": "blue"}, + "macdsignal": {"color": "orange"}, }, "RSI": { - 'rsi': {'color': 'red'}, - } - } + "rsi": {"color": "red"}, + }, + }, } def informative_pairs(self): @@ -138,7 +142,7 @@ class SampleStrategy(IStrategy): # ------------------------------------ # ADX - dataframe['adx'] = ta.ADX(dataframe) + dataframe["adx"] = ta.ADX(dataframe) # # Plus Directional Indicator / Movement # dataframe['plus_dm'] = ta.PLUS_DM(dataframe) @@ -177,7 +181,7 @@ class SampleStrategy(IStrategy): # dataframe['cci'] = ta.CCI(dataframe) # RSI - dataframe['rsi'] = ta.RSI(dataframe) + dataframe["rsi"] = ta.RSI(dataframe) # # Inverse Fisher transform on RSI: values [-1.0, 1.0] (https://goo.gl/2JGGoy) # rsi = 0.1 * (dataframe['rsi'] - 50) @@ -193,8 +197,8 @@ class SampleStrategy(IStrategy): # Stochastic Fast stoch_fast = ta.STOCHF(dataframe) - dataframe['fastd'] = stoch_fast['fastd'] - dataframe['fastk'] = stoch_fast['fastk'] + dataframe["fastd"] = stoch_fast["fastd"] + dataframe["fastk"] = stoch_fast["fastk"] # # Stochastic RSI # Please read https://github.com/freqtrade/freqtrade/issues/2961 before using this. @@ -205,12 +209,12 @@ class SampleStrategy(IStrategy): # MACD macd = ta.MACD(dataframe) - dataframe['macd'] = macd['macd'] - dataframe['macdsignal'] = macd['macdsignal'] - dataframe['macdhist'] = macd['macdhist'] + dataframe["macd"] = macd["macd"] + dataframe["macdsignal"] = macd["macdsignal"] + dataframe["macdhist"] = macd["macdhist"] # MFI - dataframe['mfi'] = ta.MFI(dataframe) + dataframe["mfi"] = ta.MFI(dataframe) # # ROC # dataframe['roc'] = ta.ROC(dataframe) @@ -220,16 +224,15 @@ class SampleStrategy(IStrategy): # Bollinger Bands bollinger = qtpylib.bollinger_bands(qtpylib.typical_price(dataframe), window=20, stds=2) - dataframe['bb_lowerband'] = bollinger['lower'] - dataframe['bb_middleband'] = bollinger['mid'] - dataframe['bb_upperband'] = bollinger['upper'] - dataframe["bb_percent"] = ( - (dataframe["close"] - dataframe["bb_lowerband"]) / - (dataframe["bb_upperband"] - dataframe["bb_lowerband"]) - ) - dataframe["bb_width"] = ( - (dataframe["bb_upperband"] - dataframe["bb_lowerband"]) / dataframe["bb_middleband"] + dataframe["bb_lowerband"] = bollinger["lower"] + dataframe["bb_middleband"] = bollinger["mid"] + dataframe["bb_upperband"] = bollinger["upper"] + dataframe["bb_percent"] = (dataframe["close"] - dataframe["bb_lowerband"]) / ( + dataframe["bb_upperband"] - dataframe["bb_lowerband"] ) + dataframe["bb_width"] = (dataframe["bb_upperband"] - dataframe["bb_lowerband"]) / dataframe[ + "bb_middleband" + ] # Bollinger Bands - Weighted (EMA based instead of SMA) # weighted_bollinger = qtpylib.weighted_bollinger_bands( @@ -264,17 +267,17 @@ class SampleStrategy(IStrategy): # dataframe['sma100'] = ta.SMA(dataframe, timeperiod=100) # Parabolic SAR - dataframe['sar'] = ta.SAR(dataframe) + dataframe["sar"] = ta.SAR(dataframe) # TEMA - Triple Exponential Moving Average - dataframe['tema'] = ta.TEMA(dataframe, timeperiod=9) + dataframe["tema"] = ta.TEMA(dataframe, timeperiod=9) # Cycle Indicator # ------------------------------------ # Hilbert Transform Indicator - SineWave hilbert = ta.HT_SINE(dataframe) - dataframe['htsine'] = hilbert['sine'] - dataframe['htleadsine'] = hilbert['leadsine'] + dataframe["htsine"] = hilbert["sine"] + dataframe["htleadsine"] = hilbert["leadsine"] # Pattern Recognition - Bullish candlestick patterns # ------------------------------------ @@ -353,22 +356,24 @@ class SampleStrategy(IStrategy): dataframe.loc[ ( # Signal: RSI crosses above 30 - (qtpylib.crossed_above(dataframe['rsi'], self.buy_rsi.value)) & - (dataframe['tema'] <= dataframe['bb_middleband']) & # Guard: tema below BB middle - (dataframe['tema'] > dataframe['tema'].shift(1)) & # Guard: tema is raising - (dataframe['volume'] > 0) # Make sure Volume is not 0 + (qtpylib.crossed_above(dataframe["rsi"], self.buy_rsi.value)) + & (dataframe["tema"] <= dataframe["bb_middleband"]) # Guard: tema below BB middle + & (dataframe["tema"] > dataframe["tema"].shift(1)) # Guard: tema is raising + & (dataframe["volume"] > 0) # Make sure Volume is not 0 ), - 'enter_long'] = 1 + "enter_long", + ] = 1 dataframe.loc[ ( # Signal: RSI crosses above 70 - (qtpylib.crossed_above(dataframe['rsi'], self.short_rsi.value)) & - (dataframe['tema'] > dataframe['bb_middleband']) & # Guard: tema above BB middle - (dataframe['tema'] < dataframe['tema'].shift(1)) & # Guard: tema is falling - (dataframe['volume'] > 0) # Make sure Volume is not 0 + (qtpylib.crossed_above(dataframe["rsi"], self.short_rsi.value)) + & (dataframe["tema"] > dataframe["bb_middleband"]) # Guard: tema above BB middle + & (dataframe["tema"] < dataframe["tema"].shift(1)) # Guard: tema is falling + & (dataframe["volume"] > 0) # Make sure Volume is not 0 ), - 'enter_short'] = 1 + "enter_short", + ] = 1 return dataframe @@ -382,23 +387,25 @@ class SampleStrategy(IStrategy): dataframe.loc[ ( # Signal: RSI crosses above 70 - (qtpylib.crossed_above(dataframe['rsi'], self.sell_rsi.value)) & - (dataframe['tema'] > dataframe['bb_middleband']) & # Guard: tema above BB middle - (dataframe['tema'] < dataframe['tema'].shift(1)) & # Guard: tema is falling - (dataframe['volume'] > 0) # Make sure Volume is not 0 + (qtpylib.crossed_above(dataframe["rsi"], self.sell_rsi.value)) + & (dataframe["tema"] > dataframe["bb_middleband"]) # Guard: tema above BB middle + & (dataframe["tema"] < dataframe["tema"].shift(1)) # Guard: tema is falling + & (dataframe["volume"] > 0) # Make sure Volume is not 0 ), - - 'exit_long'] = 1 + "exit_long", + ] = 1 dataframe.loc[ ( # Signal: RSI crosses above 30 - (qtpylib.crossed_above(dataframe['rsi'], self.exit_short_rsi.value)) & + (qtpylib.crossed_above(dataframe["rsi"], self.exit_short_rsi.value)) + & # Guard: tema below BB middle - (dataframe['tema'] <= dataframe['bb_middleband']) & - (dataframe['tema'] > dataframe['tema'].shift(1)) & # Guard: tema is raising - (dataframe['volume'] > 0) # Make sure Volume is not 0 + (dataframe["tema"] <= dataframe["bb_middleband"]) + & (dataframe["tema"] > dataframe["tema"].shift(1)) # Guard: tema is raising + & (dataframe["volume"] > 0) # Make sure Volume is not 0 ), - 'exit_short'] = 1 + "exit_short", + ] = 1 return dataframe