# source: https://raw.githubusercontent.com/witooh/else/68abebdaa95ad34882d5a5036ccdf427b3d7bf59/user_data/strategies/TrendMomentum/TrendMomentum.py
"""
Github_witooh_else__TrendMomentum__20260306_110129 — EMA50/200 Cross, No RSI Exit (Round 15)

Strategy Concept:
  Return to the best-performing approach (Round 10's EMA50/200 cross) but
  remove the RSI overbought exit. The RSI exit was cutting winners short:
  in Round 10, 2 of 5 trades exited on RSI>85 at avg +34.66%.
  But after those RSI exits, BTC continued rallying — we missed the remaining gains.

  By removing RSI exit and relying only on:
  A. Death Cross (EMA50 < EMA200) — structural trend end
  B. Trailing Stop (15% after +40%) — protects massive parabolic gains

  We should capture more of each bull run, increasing avg trade profit.

  Additionally: use EMA50 Reclaim as a re-entry signal after corrections
  to catch more of the bull cycle.

Round 15 Design (1d timeframe, spot):
  Entry A: Golden Cross (EMA50 > EMA200), cross just happened + ST bullish
  Entry B: EMA50 Reclaim — price crosses above EMA50 while EMA50 > EMA200

  Exit A: Death Cross (EMA50 < EMA200)
  (RSI overbought exit REMOVED — let trailing stop handle parabolic tops)

  Stoploss: -22%
  Trailing: 15% trail after +40% profit

  Expected: Same 5 trades as Round 10, but higher avg profit per trade
  (no early RSI exits cutting winners short)
"""

import sys
from pathlib import Path

import pandas as pd
import talib.abstract as ta
from freqtrade.strategy import IStrategy

sys.path.insert(0, str(Path(__file__).parent.parent))
from indicators import calculate_supertrend


class Github_witooh_else__TrendMomentum__20260306_110129(IStrategy):
    INTERFACE_VERSION = 3

    timeframe = "1d"
    startup_candle_count = 220  # EMA200 needs 200 bars

    can_short = False

    stoploss = -0.22
    trailing_stop = True
    trailing_stop_positive = 0.15
    trailing_stop_positive_offset = 0.40
    trailing_only_offset_is_reached = True
    use_custom_stoploss = False

    # ROI disabled — rely on exit signals
    minimal_roi = {"0": 10.0}

    use_exit_signal = True
    exit_profit_only = False
    ignore_roi_if_entry_signal = False
    process_only_new_candles = True

    position_adjustment_enable = False

    st_period: int = 10
    st_multiplier: float = 3.0

    def populate_indicators(self, dataframe: pd.DataFrame, metadata: dict) -> pd.DataFrame:
        # --- Supertrend ---
        st, st_dir = calculate_supertrend(dataframe, self.st_period, self.st_multiplier)
        dataframe["supertrend"] = st
        dataframe["st_direction"] = st_dir

        # --- EMAs ---
        dataframe["ema50"] = ta.EMA(dataframe, timeperiod=50)
        dataframe["ema200"] = ta.EMA(dataframe, timeperiod=200)

        # EMA cross detection
        ema50_prev = dataframe["ema50"].shift(1)
        ema200_prev = dataframe["ema200"].shift(1)
        dataframe["golden_cross"] = (
            (dataframe["ema50"] > dataframe["ema200"])
            & (ema50_prev <= ema200_prev)
        )
        dataframe["death_cross"] = (
            (dataframe["ema50"] < dataframe["ema200"])
            & (ema50_prev >= ema200_prev)
        )

        # Price reclaims EMA50 from below (while EMA50 > EMA200)
        close_prev = dataframe["close"].shift(1)
        ema50_shifted = dataframe["ema50"].shift(1)
        dataframe["above_ema50_cross"] = (
            (dataframe["close"] > dataframe["ema50"])
            & (close_prev <= ema50_shifted)
            & (dataframe["ema50"] > dataframe["ema200"])
        )

        # --- RSI (kept for context but NOT used for exit) ---
        dataframe["rsi"] = ta.RSI(dataframe, timeperiod=14)
        dataframe["rsi_prev"] = dataframe["rsi"].shift(1)
        dataframe["rsi_recovery"] = (
            (dataframe["rsi"] > 48)
            & (dataframe["rsi_prev"] < 42)
        )

        return dataframe

    def populate_entry_trend(self, dataframe: pd.DataFrame, metadata: dict) -> pd.DataFrame:
        """
        Entry A: Golden Cross + ST bullish (structural trend begin)
        Entry B: EMA50 Reclaim — price crosses above EMA50 while macro bull
                 + RSI recovery from oversold (confirms real recovery, not noise)
        """
        entry_golden_cross = (
            dataframe["golden_cross"]
            & (dataframe["st_direction"] == 1)
            & (dataframe["volume"] > 0)
        )

        entry_ema50_reclaim = (
            dataframe["above_ema50_cross"]
            & dataframe["rsi_recovery"]
            & (dataframe["volume"] > 0)
        )

        dataframe.loc[entry_golden_cross, "enter_long"] = 1
        dataframe.loc[entry_golden_cross, "enter_tag"] = "golden_cross"

        dataframe.loc[entry_ema50_reclaim & ~entry_golden_cross, "enter_long"] = 1
        dataframe.loc[entry_ema50_reclaim & ~entry_golden_cross, "enter_tag"] = "ema50_reclaim"

        return dataframe

    def populate_exit_trend(self, dataframe: pd.DataFrame, metadata: dict) -> pd.DataFrame:
        """
        Exit A: Death Cross (EMA50 < EMA200) — structural bear begins
        Note: RSI overbought exit removed. Trailing stop handles parabolic tops.
        """
        exit_death_cross = dataframe["death_cross"]

        dataframe.loc[exit_death_cross, "exit_long"] = 1
        dataframe.loc[exit_death_cross, "exit_tag"] = "death_cross"

        return dataframe
