"""
策略抽象基类。

所有策略必须继承 BaseStrategy，实现 generate_signals(factor_df) → pd.Series。
"""

from abc import ABC, abstractmethod

import pandas as pd


class BaseStrategy(ABC):
    """
    回测策略基类。

    属性:
        name: 策略名称
        category: 'trend' | 'mean_revert' | 'rotation'
    """

    name: str = ""
    category: str = ""

    @abstractmethod
    def generate_signals(self, factor_df: pd.DataFrame) -> pd.Series:
        """
        因子 → 交易信号。

        参数:
            factor_df: 因子 DataFrame，index=trade_date，columns=因子名

        返回:
            pd.Series，index 与 factor_df 对齐：
            1=买入, 0=平仓/无操作
            （只做多，不做空）
        """
        ...

    def get_params(self) -> dict:
        """返回策略当前参数（供 Optuna 优化用）。"""
        return {
            k: v for k, v in self.__dict__.items()
            if not k.startswith("_") and k not in ("name", "category")
        }

    def set_params(self, **kwargs) -> None:
        """设置策略参数。"""
        for k, v in kwargs.items():
            if hasattr(self, k):
                setattr(self, k, v)

    def __repr__(self) -> str:
        return f"{self.__class__.__name__}(name='{self.name}')"
