# source: https://raw.githubusercontent.com/Dmitry23051992/ai-trader/f71478dfbf515e15766ab8ce67273a8c95327e5f/templates/freqtrade_template.py
from freqtrade.strategy import IStrategy, IntParameter, DecimalParameter
from pandas import DataFrame
import talib.abstract as ta
import numpy as np


class Github_Dmitry23051992_ai_trader__freqtrade_template__20260708_070407(IStrategy):
    """
    Шаблон стратегии для генерации AI (v3 — качественный трендовый подход).

    ВАЖНО:
    - Используй сигнальные компоненты (trend_bull, mom_bull, adx_ok, vol_ok, rsi_ok, price_near_ema20).
    - Вход — только когда ВСЕ ключевые условия истинны (не по порогу суммы).
    - Выход — по развороту тренда/моментума или перекупленности.
    - Не менее 50 сделок, но не более 150 за 6 мес.

    Целевые метрики:
    - Win Rate 45-60%
    - Profit Factor > 1.3
    - Avg Profit > 0.3%
    - Max Drawdown < 15%
    """

    INTERFACE_VERSION = 3
    timeframe = "15m"

    # ROI — даём тренду время
    minimal_roi = {
        "0": 0.04,
        "90": 0.02,
        "180": 0.01,
    }

    stoploss = -0.04
    trailing_stop = True
    trailing_stop_positive = 0.01
    trailing_stop_positive_offset = 0.03
    trailing_only_offset_is_reached = True

    process_only_new_candles = True
    startup_candle_count = 200
    use_exit_signal = True
    exit_profit_only = False

    def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        # ── Обязательные индикаторы ──────────────────────────
        dataframe["ema12"] = ta.EMA(dataframe, timeperiod=12)
        dataframe["ema20"] = ta.EMA(dataframe, timeperiod=20)
        dataframe["ema50"] = ta.EMA(dataframe, timeperiod=50)
        dataframe["ema100"] = ta.EMA(dataframe, timeperiod=100)
        dataframe["ema200"] = ta.EMA(dataframe, timeperiod=200)

        macd = ta.MACD(dataframe, fastperiod=12, slowperiod=26, signalperiod=9)
        dataframe["macd"] = macd["macd"]
        dataframe["macd_signal"] = macd["macdsignal"]
        dataframe["macd_hist"] = macd["macdhist"]

        dataframe["rsi"] = ta.RSI(dataframe, timeperiod=14)

        bbands = ta.BBANDS(dataframe, timeperiod=20, nbdevup=2.0, nbdevdn=2.0)
        dataframe["bb_upper"] = bbands["upperband"]
        dataframe["bb_middle"] = bbands["middleband"]
        dataframe["bb_lower"] = bbands["lowerband"]

        dataframe["volume_ma20"] = dataframe["volume"].rolling(20).mean()
        dataframe["volume_ratio"] = dataframe["volume"] / dataframe["volume_ma20"]
        dataframe["adx"] = ta.ADX(dataframe, timeperiod=14)
        dataframe["atr"] = ta.ATR(dataframe, timeperiod=14)
        dataframe["atr_pct"] = dataframe["atr"] / dataframe["close"] * 100

        # ── Добавь СВОИ индикаторы здесь ─────────────────────
        # Например: дополнительный осциллятор, свечной паттерн,
        #           уровни поддержки/сопротивления, и т.д.

        # ============= СИГНАЛЬНЫЕ КОМПОНЕНТЫ =============
        # Тренд (цена > EMA200 и золотой крест)
        dataframe["trend_bull"] = (
            (dataframe["close"] > dataframe["ema200"]) &
            (dataframe["ema50"] > dataframe["ema200"])
        ).astype(int)

        # Моментум (быстрые EMA + MACD)
        dataframe["mom_bull"] = (
            (dataframe["ema12"] > dataframe["ema20"]) &
            (dataframe["macd"] > dataframe["macd_signal"])
        ).astype(int)

        # Сила тренда (ADX)
        dataframe["adx_ok"] = (dataframe["adx"] > 22).astype(int)

        # Объём
        dataframe["vol_ok"] = (dataframe["volume_ratio"] >= 0.9).astype(int)

        # RSI в рабочей зоне
        dataframe["rsi_ok"] = (
            (dataframe["rsi"] >= 40) & (dataframe["rsi"] <= 65)
        ).astype(int)

        # Цена у EMA20 (подтверждение момента)
        dataframe["price_near_ema20"] = (
            (dataframe["close"] >= dataframe["ema20"] * 0.98) &
            (dataframe["close"] <= dataframe["ema20"] * 1.03)
        ).astype(int)

        # ============= СКОРОВАЯ СИСТЕМА (0-10) =============
        score = 0
        score += dataframe["trend_bull"] * 3
        score += dataframe["mom_bull"] * 2
        score += dataframe["adx_ok"] * 2
        score += dataframe["vol_ok"] * 1
        score += dataframe["rsi_ok"] * 1
        score += dataframe["price_near_ema20"] * 1
        dataframe["buy_score"] = score

        return dataframe

    def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        dataframe["enter_long"] = 0

        # Вход: ВСЕ ключевые условия должны быть истинны
        entry = (
            (dataframe["trend_bull"] == 1) &
            (dataframe["mom_bull"] == 1) &
            (dataframe["adx_ok"] == 1) &
            (dataframe["vol_ok"] == 1) &
            (dataframe["rsi_ok"] == 1) &
            (dataframe["price_near_ema20"] == 1)
        )

        dataframe.loc[entry, "enter_long"] = 1
        return dataframe

    def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        dataframe["exit_long"] = 0

        # 1. Тренд развернулся
        trend_fail = (
            (dataframe["ema12"] < dataframe["ema50"]) &
            (dataframe["ema20"] < dataframe["ema50"])
        )

        # 2. Моментум сломался
        mom_fail = (
            (dataframe["macd"] < dataframe["macd_signal"]) &
            (dataframe["macd_hist"] < 0) &
            (dataframe["rsi"] < 50)
        )

        # 3. Перекуплен
        overbought = (dataframe["rsi"] > 82)

        # 4. Пробой EMA100
        breakdown = (
            (dataframe["close"] < dataframe["ema100"]) &
            (dataframe["macd_hist"] < 0) &
            (dataframe["rsi"] < 50)
        )

        dataframe.loc[
            trend_fail | mom_fail | overbought | breakdown,
            "exit_long"
        ] = 1

        return dataframe
