# source: https://raw.githubusercontent.com/ifashion101gm/auto-trade-system/951e809744da5c8230b6b57b44ffb9e67ba223ca/benchmark-bot/config/strategies/BenchmarkSampleStrategy.py
"""
Github_ifashion101gm_auto_trade_system__BenchmarkSampleStrategy__20260604_144038 — a deliberately simple, transparent baseline.

Purpose
-------
Provide a *reference* signal for the isolated benchmark bot so the production
auto-trade-system can be compared against a well-understood baseline. This is
NOT tuned for profit: it is an EMA(9/21) trend-cross on 5m candles with fixed
ROI / stop-loss, intended only to exercise the full paper-trading path
(data -> signal -> simulated order -> position -> exit) in dry-run mode.

Notes
-----
- Futures-aware (``can_short = True``).
- Indicators are computed with pandas ``.ewm()`` so the strategy loads without
  any TA-Lib / native dependency.
- All real exits are governed by ``minimal_roi`` / ``stoploss`` plus the EMA
  exit cross. There is no martingale, no averaging-down, no leverage override.
"""
from __future__ import annotations

from pandas import DataFrame
from freqtrade.strategy import IStrategy


class Github_ifashion101gm_auto_trade_system__BenchmarkSampleStrategy__20260604_144038(IStrategy):
    INTERFACE_VERSION = 3

    timeframe = "5m"

    # Allow shorts on futures. (Ignored automatically on spot markets.)
    can_short = True

    # Conservative, fixed exits. Kept in sync with benchmark-config.json.
    minimal_roi = {
        "0": 0.05,
        "60": 0.025,
        "120": 0.01,
        "240": 0,
    }
    stoploss = -0.05
    trailing_stop = False

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

    # Enough history to warm up the slow EMA before the first signal.
    startup_candle_count: int = 50

    # EMA periods (kept as class attributes for clarity / easy tweaking).
    ema_fast: int = 9
    ema_slow: int = 21

    def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        dataframe["ema_fast"] = (
            dataframe["close"].ewm(span=self.ema_fast, adjust=False).mean()
        )
        dataframe["ema_slow"] = (
            dataframe["close"].ewm(span=self.ema_slow, adjust=False).mean()
        )
        return dataframe

    def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        prev_fast = dataframe["ema_fast"].shift(1)
        prev_slow = dataframe["ema_slow"].shift(1)

        # Long when the fast EMA crosses ABOVE the slow EMA.
        long_cross = (dataframe["ema_fast"] > dataframe["ema_slow"]) & (
            prev_fast <= prev_slow
        )
        dataframe.loc[long_cross, "enter_long"] = 1

        # Short when the fast EMA crosses BELOW the slow EMA.
        short_cross = (dataframe["ema_fast"] < dataframe["ema_slow"]) & (
            prev_fast >= prev_slow
        )
        dataframe.loc[short_cross, "enter_short"] = 1

        return dataframe

    def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        prev_fast = dataframe["ema_fast"].shift(1)
        prev_slow = dataframe["ema_slow"].shift(1)

        # Exit a long on the opposite (bearish) cross.
        dataframe.loc[
            (dataframe["ema_fast"] < dataframe["ema_slow"]) & (prev_fast >= prev_slow),
            "exit_long",
        ] = 1
        # Exit a short on the (bullish) cross.
        dataframe.loc[
            (dataframe["ema_fast"] > dataframe["ema_slow"]) & (prev_fast <= prev_slow),
            "exit_short",
        ] = 1

        return dataframe
