# source: https://raw.githubusercontent.com/M4F-S/Claude-/a701e49a0cb2649c3589a70cbb9c1dcd9a2c59a7/freqtrade/user_data/strategies/BTCTrend.py
"""Github_M4F_S_Claude___BTCTrend__20260510_003653 — non-LLM baseline strategy.

EMA20/EMA50 crossover with an RSI gate. Pure indicators, no API calls. Used as
a baseline during the 14-day paper burn-in to compare against LLMScored.

Why a baseline matters: if LLMScored doesn't beat a 50-line EMA crossover after
two weeks, it's not earning its OpenRouter spend. This strategy is your control.
"""
from __future__ import annotations

import sys
from datetime import datetime
from pathlib import Path

import pandas as pd
from freqtrade.strategy import IStrategy
from pandas import DataFrame

sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
from risk_guard import guard_and_journal  # type: ignore  # noqa: E402


class Github_M4F_S_Claude___BTCTrend__20260510_003653(IStrategy):
    INTERFACE_VERSION = 3

    minimal_roi = {"0": 0.05, "120": 0.03, "240": 0.0}
    stoploss = -0.04
    trailing_stop = False
    timeframe = "1h"
    process_only_new_candles = True
    use_exit_signal = True
    exit_profit_only = False
    startup_candle_count = 50

    def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        dataframe["ema20"] = dataframe["close"].ewm(span=20, adjust=False).mean()
        dataframe["ema50"] = dataframe["close"].ewm(span=50, adjust=False).mean()
        delta = dataframe["close"].diff()
        gain = delta.clip(lower=0).rolling(14).mean()
        loss = (-delta.clip(upper=0)).rolling(14).mean()
        rs = gain / loss.replace({0: pd.NA})
        dataframe["rsi14"] = (100 - (100 / (1 + rs))).fillna(50)
        return dataframe

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

        # EMA20 crossing above EMA50 (golden-cross-ish on the bar timeframe) +
        # RSI not overbought + volume present.
        cross_up = (
            (dataframe["ema20"] > dataframe["ema50"])
            & (dataframe["ema20"].shift(1) <= dataframe["ema50"].shift(1))
        )
        gate = (dataframe["rsi14"] < 70) & (dataframe["volume"] > 0)
        dataframe.loc[cross_up & gate, "enter_long"] = 1
        dataframe.loc[cross_up & gate, "enter_tag"] = "ema20_cross_ema50"
        return dataframe

    def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        dataframe.loc[:, "exit_long"] = 0
        # Mirror exit: EMA20 crossing back below EMA50, OR RSI > 80
        cross_down = (
            (dataframe["ema20"] < dataframe["ema50"])
            & (dataframe["ema20"].shift(1) >= dataframe["ema50"].shift(1))
        )
        overbought = dataframe["rsi14"] > 80
        dataframe.loc[cross_down | overbought, "exit_long"] = 1
        return dataframe

    def confirm_trade_entry(
        self,
        pair: str,
        order_type: str,
        amount: float,
        rate: float,
        time_in_force: str,
        current_time: datetime,
        entry_tag: str | None,
        side: str,
        **kwargs,
    ) -> bool:
        proposal = {
            "symbol": pair,
            "action": "buy",
            "size_usd": amount * rate,
            "confidence": 0.5,
            "reason": entry_tag or "ema_cross",
            "side": side,
            "leverage": 1.0,
        }
        result = guard_and_journal(proposal)
        return bool(result["accepted"])
