# source: https://raw.githubusercontent.com/owenops61-byte/claude_project/8640552e7e28b766d9322d503a8fffeb50d26b57/freqtrade/strategies/SampleStrategy.py
"""
临时占位策略 - 仅用于验证 Freqtrade 环境是否可用
后续会替换为 AICommitteeStrategy（接入 5 人 AI 委员会）

交易逻辑：
- RSI < 30 + MACD 金叉 → 做多
- RSI > 70 + MACD 死叉 → 做空
- 硬止损 2.5%（即杠杆前敞口的 2.5%，相当于本金的 5%）
- ROI 目标 1.5%（杠杆前 = 本金 30%）
- 20x 杠杆，单笔保证金 50 USDT
"""
from datetime import datetime
from typing import Optional

import pandas as pd
import talib.abstract as ta

from freqtrade.strategy import (
    IStrategy,
    informative,
    merge_informative_pair,
)


class Github_owenops61_byte_claude_project__SampleStrategy__20260413_025027(IStrategy):
    INTERFACE_VERSION = 3

    # ============ 基础配置 ============
    timeframe = "15m"
    can_short = True  # 支持做空
    process_only_new_candles = True

    # ============ 风控（硬规则） ============
    # 止盈表：持有时间越长要求 ROI 越低
    minimal_roi = {
        "0": 0.015,    # 开单立即：1.5% 止盈（保证金层面即 30%）
        "30": 0.01,    # 30 分钟后：1%
        "60": 0.005,   # 60 分钟后：0.5%
        "120": 0,      # 2 小时后：保本出
    }

    # 硬止损：2.5% 敞口损失 = 50% 保证金损失 = 5% 本金损失
    stoploss = -0.025

    # 追踪止损
    trailing_stop = True
    trailing_stop_positive = 0.005  # 达到 0.5% 盈利时启动追踪
    trailing_stop_positive_offset = 0.012  # 追踪距离 1.2%
    trailing_only_offset_is_reached = True

    # 订单类型
    order_types = {
        "entry": "limit",
        "exit": "limit",
        "stoploss": "market",
        "stoploss_on_exchange": True,  # 止损挂在交易所侧，避免本地进程挂掉
        "stoploss_on_exchange_interval": 60,
    }

    # 保护机制
    protections = [
        {
            "method": "StoplossGuard",
            "lookback_period_candles": 24,  # 过去 24 根 15m K 线（6 小时）
            "trade_limit": 2,  # 2 次止损
            "stop_duration_candles": 12,  # 停 3 小时
            "only_per_pair": False,
        },
        {
            "method": "CooldownPeriod",
            "stop_duration_candles": 4,  # 每笔交易后冷却 1 小时
        },
        {
            "method": "MaxDrawdown",
            "lookback_period_candles": 48,
            "trade_limit": 10,
            "stop_duration_candles": 48,
            "max_allowed_drawdown": 0.10,  # 回撤 10% 停机
        },
    ]

    # 启动时间（给数据加载留时间）
    startup_candle_count: int = 100

    # 杠杆配置（交易所侧）
    def leverage(
        self,
        pair: str,
        current_time: datetime,
        current_rate: float,
        proposed_leverage: float,
        max_leverage: float,
        entry_tag: Optional[str],
        side: str,
        **kwargs,
    ) -> float:
        return 20.0  # 强制 20x

    # ============ 指标计算 ============
    def populate_indicators(self, dataframe: pd.DataFrame, metadata: dict) -> pd.DataFrame:
        # MACD
        macd = ta.MACD(dataframe, fastperiod=12, slowperiod=26, signalperiod=9)
        dataframe["macd"] = macd["macd"]
        dataframe["macdsignal"] = macd["macdsignal"]
        dataframe["macdhist"] = macd["macdhist"]

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

        # EMA
        dataframe["ema9"] = ta.EMA(dataframe, timeperiod=9)
        dataframe["ema21"] = ta.EMA(dataframe, timeperiod=21)
        dataframe["ema50"] = ta.EMA(dataframe, timeperiod=50)

        # ATR
        dataframe["atr"] = ta.ATR(dataframe, timeperiod=14)

        return dataframe

    # ============ 入场信号 ============
    def populate_entry_trend(self, dataframe: pd.DataFrame, metadata: dict) -> pd.DataFrame:
        # 做多条件：RSI 从超卖反弹 + MACD 金叉 + 价格在 EMA50 上方
        dataframe.loc[
            (
                (dataframe["rsi"] > 30)
                & (dataframe["rsi"].shift(1) <= 30)  # 刚从超卖反弹
                & (dataframe["macd"] > dataframe["macdsignal"])
                & (dataframe["macd"].shift(1) <= dataframe["macdsignal"].shift(1))  # 金叉
                & (dataframe["close"] > dataframe["ema50"])  # 趋势向上
                & (dataframe["volume"] > 0)
            ),
            "enter_long",
        ] = 1

        # 做空条件：RSI 从超买回落 + MACD 死叉 + 价格在 EMA50 下方
        dataframe.loc[
            (
                (dataframe["rsi"] < 70)
                & (dataframe["rsi"].shift(1) >= 70)  # 刚从超买回落
                & (dataframe["macd"] < dataframe["macdsignal"])
                & (dataframe["macd"].shift(1) >= dataframe["macdsignal"].shift(1))  # 死叉
                & (dataframe["close"] < dataframe["ema50"])  # 趋势向下
                & (dataframe["volume"] > 0)
            ),
            "enter_short",
        ] = 1

        return dataframe

    # ============ 出场信号 ============
    def populate_exit_trend(self, dataframe: pd.DataFrame, metadata: dict) -> pd.DataFrame:
        # 做多平仓：RSI 进入超买区间或 MACD 死叉
        dataframe.loc[
            (dataframe["rsi"] > 75) | (dataframe["macd"] < dataframe["macdsignal"]),
            "exit_long",
        ] = 1

        # 做空平仓：RSI 进入超卖区间或 MACD 金叉
        dataframe.loc[
            (dataframe["rsi"] < 25) | (dataframe["macd"] > dataframe["macdsignal"]),
            "exit_short",
        ] = 1

        return dataframe
