from functools import reduce import pandas as pd import talib.abstract as ta import freqtrade.vendor.qtpylib.indicators as qtpylib import technical.indicators as ftt from freqtrade.strategy.interface import IStrategy from pandas import DataFrame pd.options.mode.chained_assignment = None class ichiV1(IStrategy): buy_params = { "buy_trend_above_senkou_level": 1, "buy_trend_bullish_level": 6, "buy_fan_magnitude_shift_value": 3, "buy_min_fan_magnitude_gain": 1.002 # Good value (~70% win rate, many trades) # "buy_min_fan_magnitude_gain": 1.008 # Very safe value (~90% win rate, fewer trades) } sell_params = { "sell_trend_indicator": "trend_close_2h", } minimal_roi = { "0": 0.059, "10": 0.037, "41": 0.012, "114": 0, } stoploss = -0.275 timeframe = "5m" startup_candle_count = 96 process_only_new_candles = False trailing_stop = False use_sell_signal = True sell_profit_only = False ignore_roi_if_buy_signal = False plot_config = { "main_plot": { "senkou_a": { "color": "green", "fill_to": "senkou_b", "fill_label": "Ichimoku Cloud", "fill_color": "rgba(255,76,46,0.2)", }, "senkou_b": {}, "trend_close_5m": {"color": "#FF5733"}, "trend_close_15m": {"color": "#FF8333"}, "trend_close_30m": {"color": "#FFB533"}, "trend_close_1h": {"color": "#FFE633"}, "trend_close_2h": {"color": "#E3FF33"}, "trend_close_4h": {"color": "#C4FF33"}, "trend_close_6h": {"color": "#61FF33"}, "trend_close_8h": {"color": "#33FF7D"}, }, "subplots": { "fan_magnitude": {"fan_magnitude": {}}, "fan_magnitude_gain": {"fan_magnitude_gain": {}}, }, } def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: heikinashi = qtpylib.heikinashi(dataframe) dataframe["open"] = heikinashi["open"] dataframe["high"] = heikinashi["high"] dataframe["low"] = heikinashi["low"] for tf, period in zip( ["5m", "15m", "30m", "1h", "2h", "4h", "6h", "8h"], [0, 3, 6, 12, 24, 48, 72, 96], ): if period == 0: dataframe[f"trend_close_{tf}"] = dataframe["close"] dataframe[f"trend_open_{tf}"] = dataframe["open"] else: dataframe[f"trend_close_{tf}"] = ta.EMA(dataframe["close"], timeperiod=period) dataframe[f"trend_open_{tf}"] = ta.EMA(dataframe["open"], timeperiod=period) dataframe["fan_magnitude"] = dataframe["trend_close_1h"] / dataframe["trend_close_8h"] dataframe["fan_magnitude_gain"] = dataframe["fan_magnitude"] / dataframe["fan_magnitude"].shift(1) ichimoku = ftt.ichimoku( dataframe, conversion_line_period=20, base_line_periods=60, laggin_span=120, displacement=30, ) dataframe["chikou_span"] = ichimoku["chikou_span"] dataframe["tenkan_sen"] = ichimoku["tenkan_sen"] dataframe["kijun_sen"] = ichimoku["kijun_sen"] dataframe["senkou_a"] = ichimoku["senkou_span_a"] dataframe["senkou_b"] = ichimoku["senkou_span_b"] dataframe["leading_senkou_span_a"] = ichimoku["leading_senkou_span_a"] dataframe["leading_senkou_span_b"] = ichimoku["leading_senkou_span_b"] dataframe["cloud_green"] = ichimoku["cloud_green"] dataframe["cloud_red"] = ichimoku["cloud_red"] dataframe["atr"] = ta.ATR(dataframe) return dataframe def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: conditions = [] for i, tf in enumerate(["5m", "15m", "30m", "1h", "2h", "4h", "6h", "8h"], start=1): if self.buy_params["buy_trend_above_senkou_level"] >= i: conditions += [ dataframe[f"trend_close_{tf}"] > dataframe["senkou_a"], dataframe[f"trend_close_{tf}"] > dataframe["senkou_b"], ] for i, tf in enumerate(["5m", "15m", "30m", "1h", "2h", "4h", "6h", "8h"], start=1): if self.buy_params["buy_trend_bullish_level"] >= i: conditions.append(dataframe[f"trend_close_{tf}"] > dataframe[f"trend_open_{tf}"]) conditions += [ dataframe["fan_magnitude_gain"] >= self.buy_params["buy_min_fan_magnitude_gain"], dataframe["fan_magnitude"] > 1, ] conditions += [ dataframe["fan_magnitude"].shift(x + 1) < dataframe["fan_magnitude"] for x in range(self.buy_params["buy_fan_magnitude_shift_value"]) ] 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: conditions = [ qtpylib.crossed_below( dataframe["trend_close_5m"], dataframe[self.sell_params["sell_trend_indicator"]], ) ] if conditions: dataframe.loc[reduce(lambda x, y: x & y, conditions), "sell"] = 1 return dataframe