# source: https://raw.githubusercontent.com/DoudGeorges/freqtrade-bot/66ceed9f2fee7361aa9fe5e15b049435b134b837/user_data/strategies/ichiV1.py
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 Github_DoudGeorges_freqtrade_bot__ichiV1__20250906_043548(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
