diff --git a/user_data/strategies/Strategy001_custom_sell.py b/user_data/strategies/Strategy001_custom_sell.py new file mode 100644 index 0000000..231d085 --- /dev/null +++ b/user_data/strategies/Strategy001_custom_sell.py @@ -0,0 +1,141 @@ + +# --- Do not remove these libs --- +from freqtrade.strategy.interface import IStrategy +from typing import Dict, List +from functools import reduce +from pandas import DataFrame +# -------------------------------- + +import talib.abstract as ta +import freqtrade.vendor.qtpylib.indicators as qtpylib + +class Strategy001_custom_sell(IStrategy): + + """ + Strategy 001_custom_sell + author@: Gerald Lonlas, froggleston + github@: https://github.com/freqtrade/freqtrade-strategies + + How to use it? + > python3 ./freqtrade/main.py -s Strategy001_custom_sell + """ + + # Minimal ROI designed for the strategy. + # This attribute will be overridden if the config file contains "minimal_roi" + minimal_roi = { + "60": 0.01, + "30": 0.03, + "20": 0.04, + "0": 0.05 + } + + # Optimal stoploss designed for the strategy + # This attribute will be overridden if the config file contains "stoploss" + stoploss = -0.10 + + # Optimal timeframe for the strategy + timeframe = '5m' + + # trailing stoploss + trailing_stop = False + trailing_stop_positive = 0.01 + trailing_stop_positive_offset = 0.02 + + # run "populate_indicators" only for new candle + process_only_new_candles = False + + # Experimental settings (configuration will overide these if set) + use_sell_signal = True + sell_profit_only = True + ignore_roi_if_buy_signal = False + + # Optional order type mapping + order_types = { + 'buy': 'limit', + 'sell': 'limit', + 'stoploss': 'market', + 'stoploss_on_exchange': False + } + + def informative_pairs(self): + """ + Define additional, informative pair/interval combinations to be cached from the exchange. + These pair/interval combinations are non-tradeable, unless they are part + of the whitelist as well. + For more information, please consult the documentation + :return: List of tuples in the format (pair, interval) + Sample: return [("ETH/USDT", "5m"), + ("BTC/USDT", "15m"), + ] + """ + return [] + + def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Adds several different TA indicators to the given DataFrame + + Performance Note: For the best performance be frugal on the number of indicators + you are using. Let uncomment only the indicator you are using in your strategies + or your hyperopt configuration, otherwise you will waste your memory and CPU usage. + """ + + dataframe['ema20'] = ta.EMA(dataframe, timeperiod=20) + dataframe['ema50'] = ta.EMA(dataframe, timeperiod=50) + dataframe['ema100'] = ta.EMA(dataframe, timeperiod=100) + + heikinashi = qtpylib.heikinashi(dataframe) + dataframe['ha_open'] = heikinashi['open'] + dataframe['ha_close'] = heikinashi['close'] + + dataframe['rsi'] = ta.RSI(dataframe, 14) + + return dataframe + + def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Based on TA indicators, populates the buy signal for the given dataframe + :param dataframe: DataFrame + :return: DataFrame with buy column + """ + dataframe.loc[ + ( + qtpylib.crossed_above(dataframe['ema20'], dataframe['ema50']) & + (dataframe['ha_close'] > dataframe['ema20']) & + (dataframe['ha_open'] < dataframe['ha_close']) # green bar + ), + 'buy'] = 1 + + return dataframe + + def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Based on TA indicators, populates the sell signal for the given dataframe + :param dataframe: DataFrame + :return: DataFrame with buy column + """ + dataframe.loc[ + ( + qtpylib.crossed_above(dataframe['ema50'], dataframe['ema100']) & + (dataframe['ha_close'] < dataframe['ema20']) & + (dataframe['ha_open'] > dataframe['ha_close']) # red bar + ), + 'sell'] = 1 + return dataframe + + def custom_sell(self, pair: str, trade: 'Trade', current_time: 'datetime', current_rate: float, current_profit: float, **kwargs): + """ + Sell only when matching some criteria other than those used to generate the sell signal + :return: str sell_reason, if any, otherwise None + """ + # get dataframe + dataframe, _ = self.dp.get_analyzed_dataframe(pair=pair, timeframe=self.timeframe) + + # get the current candle + current_candle = dataframe.iloc[-1].squeeze() + + # if RSI greater than 70 and profit is positive, then sell + if (current_candle['rsi'] > 70) and (current_profit > 0): + return "rsi_profit_sell" + + # else, hold + return None \ No newline at end of file