from __future__ import annotations

from typing import Any


def _meta(
    category: str,
    quality: str,
    frequency: str,
    risk: str,
    data_group: str,
    history_days: int,
    backtest_days: int,
    take_profit: float,
    stop_loss: float,
    **extra: Any,
) -> dict[str, Any]:
    return {
        "library": "curated",
        "category": category,
        "quality": quality,
        "frequency": frequency,
        "risk": risk,
        "data_group": data_group,
        "history_days": history_days,
        "backtest_days": backtest_days,
        "take_profit": take_profit,
        "stop_loss": stop_loss,
        **extra,
    }


ADVANCED_CURATED_STRATEGIES = [
    {
        "name": "中期动量·强者恒强",
        "description": "用60日至5日前的中期动量识别持续强势，同时剔除当日无法正常成交的涨停标的。",
        "regimes": ["repair", "fermentation", "climax", "divergence"],
        "formula": {
            "meta": _meta("动量反转", "A-", "每周", "中", "历史行情", 80, 10, 8, -5),
            "universe": {"exclude_st": True, "listed_days_min": 180},
            "filters": [
                {"field": "close", "op": "between", "value": [3, 100]},
                {"field": "momentum_60_5_rank", "op": ">=", "value": 0.90},
                {"field": "is_limit_up_today", "op": "==", "value": 0},
            ],
            "score": [
                {"field": "momentum_60_5", "weight": 0.55, "direction": "desc"},
                {"field": "relative_strength", "weight": 0.25, "direction": "desc"},
                {"field": "amount_billion", "weight": 0.20, "direction": "desc"},
            ],
            "limit": 25,
            "min_score": 0.50,
        },
    },
    {
        "name": "强者回调",
        "description": "在中期强势股池中寻找回踩20日线、短期超卖且近20日无跌停的牛回头候选。",
        "regimes": ["repair", "fermentation", "divergence"],
        "formula": {
            "meta": _meta("动量反转", "A-", "每日", "中", "历史行情", 80, 10, 8, -5),
            "universe": {"exclude_st": True, "listed_days_min": 180},
            "filters": [
                {"field": "momentum_60_5_rank", "op": ">=", "value": 0.70},
                {"field": "return_5d_rank", "op": "<=", "value": 0.20},
                {"field": "above_ma20", "op": "==", "value": 1},
                {"field": "rsi_6", "op": "<=", "value": 30},
                {"field": "no_limit_down_20d", "op": "==", "value": 1},
            ],
            "score": [
                {"field": "momentum_60_5", "weight": 0.42, "direction": "desc"},
                {"field": "return_5d", "weight": 0.33, "direction": "asc"},
                {"field": "amount_billion", "weight": 0.25, "direction": "desc"},
            ],
            "limit": 20,
            "min_score": 0.48,
        },
    },
    {
        "name": "超跌反转",
        "description": "筛选短期极端回撤、充分换手但尚未形成长期单边下跌的修复候选。",
        "regimes": ["ice", "repair"],
        "formula": {
            "meta": _meta("动量反转", "B+", "每日", "高", "行情与财务", 80, 5, 8, -5),
            "universe": {"exclude_st": True, "listed_days_min": 180},
            "filters": [
                {"field": "return_5d_rank", "op": "<=", "value": 0.05},
                {"field": "turnover_5d", "op": ">=", "value": 30},
                {"field": "return_60d", "op": ">=", "value": -40},
                {"field": "financial_risk", "op": "==", "value": 0},
                {"field": "is_limit_down_today", "op": "==", "value": 0},
            ],
            "score": [
                {"field": "return_5d", "weight": 0.45, "direction": "asc"},
                {"field": "turnover_5d", "weight": 0.30, "direction": "desc"},
                {"field": "amount_billion", "weight": 0.25, "direction": "desc"},
            ],
            "limit": 10,
            "min_score": 0.50,
        },
    },
    {
        "name": "相对强度新高",
        "description": "以个股相对沪深300的强度线识别弱市领涨和结构性抱团标的。",
        "regimes": ["ice", "repair", "fermentation", "divergence"],
        "formula": {
            "meta": _meta("动量反转", "A", "每周", "中", "行情与指数", 130, 20, 12, -7, requires_benchmark=True),
            "universe": {"exclude_st": True, "listed_days_min": 250},
            "filters": [
                {"field": "amount_billion", "op": ">=", "value": 1},
                {"field": "rs_high_120", "op": "==", "value": 1},
                {"field": "excess_return_60d", "op": ">=", "value": 10},
                {"field": "ma60_slope", "op": ">", "value": 0},
            ],
            "score": [
                {"field": "excess_return_60d", "weight": 0.50, "direction": "desc"},
                {"field": "ma60_slope", "weight": 0.25, "direction": "desc"},
                {"field": "amount_billion", "weight": 0.25, "direction": "desc"},
            ],
            "limit": 20,
            "min_score": 0.52,
        },
    },
    {
        "name": "均线多头排列",
        "description": "使用5、10、20、60日均线多头结构、20日线斜率和250日位置确认趋势。",
        "regimes": ["repair", "fermentation", "climax", "divergence"],
        "formula": {
            "meta": _meta("趋势追踪", "A-", "每周", "中低", "历史行情", 260, 20, 12, -7),
            "universe": {"exclude_st": True, "listed_days_min": 365},
            "filters": [
                {"field": "ma_bull_alignment", "op": "==", "value": 1},
                {"field": "ma20_slope_5d", "op": ">", "value": 0},
                {"field": "drawdown_from_high_250", "op": "<=", "value": 20},
            ],
            "score": [
                {"field": "ma20_slope_5d", "weight": 0.38, "direction": "desc"},
                {"field": "drawdown_from_high_250", "weight": 0.32, "direction": "asc"},
                {"field": "relative_strength", "weight": 0.30, "direction": "desc"},
            ],
            "limit": 30,
            "min_score": 0.50,
        },
    },
    {
        "name": "唐奇安通道突破",
        "description": "收盘突破前20日高点，并以突破幅度、量能和突破前振幅过滤假突破。",
        "regimes": ["repair", "fermentation", "divergence"],
        "formula": {
            "meta": _meta("趋势追踪", "A-", "每日", "中", "历史行情", 80, 20, 12, -7),
            "universe": {"exclude_st": True, "listed_days_min": 180},
            "filters": [
                {"field": "donchian_breakout_pct", "op": ">=", "value": 2},
                {"field": "volume_ratio_5d", "op": ">=", "value": 1.8},
                {"field": "range_20d", "op": "<=", "value": 35},
            ],
            "score": [
                {"field": "volume_ratio_5d", "weight": 0.40, "direction": "desc"},
                {"field": "donchian_breakout_pct", "weight": 0.35, "direction": "desc"},
                {"field": "range_20d", "weight": 0.25, "direction": "asc"},
            ],
            "limit": 15,
            "min_score": 0.52,
        },
    },
    {
        "name": "周线趋势·日线买点",
        "description": "周线MACD位于多头区间，日线金叉或回踩20日线收阳时确认多周期共振。",
        "regimes": ["repair", "fermentation", "divergence"],
        "formula": {
            "meta": _meta("趋势追踪", "A", "每周", "中低", "多周期行情", 180, 20, 12, -7),
            "universe": {"exclude_st": True, "listed_days_min": 365},
            "filters": [
                {"field": "weekly_trend_signal", "op": "==", "value": 1},
                {"field": "daily_buy_trigger", "op": "==", "value": 1},
                {"field": "weekly_amount_trend", "op": "==", "value": 1},
            ],
            "score": [
                {"field": "ma20_slope_5d", "weight": 0.35, "direction": "desc"},
                {"field": "relative_strength", "weight": 0.35, "direction": "desc"},
                {"field": "amount_billion", "weight": 0.30, "direction": "desc"},
            ],
            "limit": 20,
            "min_score": 0.52,
        },
    },
]

ADVANCED_CURATED_STRATEGIES.extend(
    [
        {
            "name": "空间板",
            "description": "识别当日新晋市场最高板，并要求所属方向具备足够的涨停支撑。",
            "regimes": ["repair", "fermentation"],
            "formula": {
                "meta": _meta("连板接力", "B+", "每日", "很高", "涨停结构", 80, 3, 8, -6),
                "universe": {"exclude_st": True, "listed_days_min": 120},
                "filters": [
                    {"field": "is_market_height", "op": "==", "value": 1},
                    {"field": "new_space_board", "op": "==", "value": 1},
                    {"field": "sector_limit_count", "op": ">=", "value": 3},
                ],
                "score": [
                    {"field": "limit_streak", "weight": 0.50, "direction": "desc"},
                    {"field": "sector_limit_count", "weight": 0.30, "direction": "desc"},
                    {"field": "amount_billion", "weight": 0.20, "direction": "desc"},
                ],
                "limit": 5,
                "min_score": 0.45,
            },
        },
        {
            "name": "龙头首阴",
            "description": "筛选三板以上强势股断板后的首次缩量阴线，并结合板块强度观察承接质量。",
            "regimes": ["fermentation", "climax"],
            "formula": {
                "meta": _meta("低吸反核", "B", "每日", "很高", "涨停结构", 80, 5, 8, -6),
                "universe": {"exclude_st": True, "listed_days_min": 120},
                "filters": [
                    {"field": "max_continuous_board_10d", "op": ">=", "value": 3},
                    {"field": "dragon_first_yin", "op": "==", "value": 1},
                    {"field": "yin_day_pct", "op": ">=", "value": -7},
                    {"field": "vol_vs_previous", "op": "<=", "value": 0.8},
                ],
                "score": [
                    {"field": "max_continuous_board_10d", "weight": 0.45, "direction": "desc"},
                    {"field": "vol_vs_previous", "weight": 0.30, "direction": "asc"},
                    {"field": "sector_strength", "weight": 0.25, "direction": "desc"},
                ],
                "limit": 5,
                "min_score": 0.48,
            },
        },
        {
            "name": "断板反包",
            "description": "连板断板后1至3日内，以涨停收复断板高点和量能确认N字反包。",
            "regimes": ["repair", "fermentation"],
            "formula": {
                "meta": _meta("低吸反核", "B+", "每日", "高", "涨停结构", 80, 3, 8, -6),
                "universe": {"exclude_st": True, "listed_days_min": 120},
                "filters": [
                    {"field": "broken_reversal", "op": "==", "value": 1},
                    {"field": "days_since_broken", "op": "between", "value": [1, 3]},
                    {"field": "close_above_broken_high", "op": "==", "value": 1},
                    {"field": "vol_vs_broken_day", "op": ">=", "value": 1},
                ],
                "score": [
                    {"field": "days_since_broken", "weight": 0.35, "direction": "asc"},
                    {"field": "vol_vs_broken_day", "weight": 0.35, "direction": "desc"},
                    {"field": "sector_strength", "weight": 0.30, "direction": "desc"},
                ],
                "limit": 5,
                "min_score": 0.46,
            },
        },
        {
            "name": "核按钮反核",
            "description": "近5日强势股盘中深水急杀后收回，并以长下影和非放量结构确认承接。",
            "regimes": ["repair", "fermentation"],
            "formula": {
                "meta": _meta("低吸反核", "B+", "每日", "很高", "历史行情", 80, 5, 8, -6),
                "universe": {"exclude_st": True, "listed_days_min": 120},
                "filters": [
                    {"field": "recent_limit_up_5d", "op": ">=", "value": 1},
                    {"field": "intraday_min_pct", "op": "<=", "value": -7},
                    {"field": "pct_chg", "op": ">=", "value": -3},
                    {"field": "lower_shadow_ratio", "op": ">=", "value": 2},
                    {"field": "vol_vs_previous", "op": "<=", "value": 1.1},
                ],
                "score": [
                    {"field": "lower_shadow_ratio", "weight": 0.42, "direction": "desc"},
                    {"field": "intraday_min_pct", "weight": 0.30, "direction": "asc"},
                    {"field": "sector_strength", "weight": 0.28, "direction": "desc"},
                ],
                "limit": 5,
                "min_score": 0.48,
            },
        },
    ]
)

ADVANCED_CURATED_STRATEGIES.extend(
    [
        {
            "name": "景气-趋势-拥挤三维行业打分",
            "description": "以行业财务景气、价格趋势和交易拥挤度合成行业得分，再选取行业内动量与成交承载靠前的公司。",
            "regimes": ["ice", "repair", "fermentation", "climax", "divergence", "retreat"],
            "formula": {
                "meta": _meta(
                    "行业轮动", "A-", "双周", "中", "行业、财务与交易拥挤", 80, 20, 12, -7,
                    requires_fundamental=True,
                ),
                "universe": {"exclude_st": True, "listed_days_min": 180},
                "filters": [
                    {"field": "sector_composite_score", "op": ">=", "value": 0.58},
                    {"field": "sector_crowding_rank", "op": "<=", "value": 0.90},
                    {"field": "sector_stock_momentum_rank", "op": ">=", "value": 0.50},
                    {"field": "amount_billion", "op": ">=", "value": 1},
                ],
                "score": [
                    {"field": "sector_composite_score", "weight": 0.55, "direction": "desc"},
                    {"field": "sector_stock_momentum_rank", "weight": 0.25, "direction": "desc"},
                    {"field": "sector_crowding_rank", "weight": 0.20, "direction": "asc"},
                ],
                "limit": 12,
                "min_score": 0.50,
            },
        },
        {
            "name": "大小盘/成长价值风格切换(元策略)",
            "description": "比较大小盘与成长价值组合近20日相对表现，动态选择当前占优风格中的匹配标的。",
            "regimes": ["ice", "repair", "fermentation", "climax", "divergence", "retreat"],
            "formula": {
                "meta": _meta(
                    "元策略", "A-", "每周", "中低", "行情、估值与财务", 80, 20, 12, -7,
                    requires_fundamental=True, requires_valuation=True,
                ),
                "universe": {"exclude_st": True, "listed_days_min": 250},
                "filters": [
                    {"field": "style_fit_score", "op": ">=", "value": 0.65},
                    {"field": "amount_billion", "op": ">=", "value": 1},
                ],
                "score": [
                    {"field": "style_fit_score", "weight": 0.70, "direction": "desc"},
                    {"field": "relative_strength", "weight": 0.30, "direction": "desc"},
                ],
                "limit": 20,
                "min_score": 0.52,
            },
        },
        {
            "name": "业绩超预期漂移(SUE/PEAD)",
            "description": "以业绩预告和业绩快报的同报告期差异识别超预期事件，并限定在公告后的首个交易窗口。",
            "regimes": ["ice", "repair", "fermentation", "climax", "divergence", "retreat"],
            "formula": {
                "meta": _meta(
                    "业绩事件", "A-", "事件驱动", "中", "业绩预告与快报", 80, 20, 12, -7,
                    requires_earnings_events=True,
                ),
                "universe": {"exclude_st": True, "listed_days_min": 180},
                "filters": [
                    {"field": "earnings_surprise_pct", "op": ">=", "value": 10},
                    {"field": "revenue_yoy", "op": ">", "value": 0},
                    {"field": "earnings_event_quality", "op": "==", "value": 1},
                    {"field": "earnings_days_since_announce", "op": "between", "value": [1, 5]},
                ],
                "score": [
                    {"field": "earnings_surprise_pct", "weight": 0.60, "direction": "desc"},
                    {"field": "relative_strength", "weight": 0.25, "direction": "desc"},
                    {"field": "amount_billion", "weight": 0.15, "direction": "desc"},
                ],
                "limit": 15,
                "min_score": 0.50,
            },
        },
        {
            "name": "多因子综合打分(IC动态加权)",
            "description": "将价值、成长、质量、动量和交易情绪标准化，并按近期横截面有效性动态合成综合分。",
            "regimes": ["ice", "repair", "fermentation", "climax", "divergence", "retreat"],
            "formula": {
                "meta": _meta(
                    "多因子", "A-", "每周", "中", "行情、估值与财务", 260, 20, 12, -7,
                    requires_fundamental=True, requires_valuation=True,
                ),
                "universe": {"exclude_st": True, "listed_days_min": 250},
                "filters": [
                    {"field": "multi_factor_composite", "op": ">=", "value": 0.65},
                    {"field": "financial_risk", "op": "==", "value": 0},
                    {"field": "amount_billion", "op": ">=", "value": 1},
                ],
                "score": [
                    {"field": "multi_factor_composite", "weight": 0.75, "direction": "desc"},
                    {"field": "relative_strength", "weight": 0.15, "direction": "desc"},
                    {"field": "amount_billion", "weight": 0.10, "direction": "desc"},
                ],
                "limit": 30,
                "min_score": 0.55,
            },
        },
        {
            "name": "热度突增潜伏(另类数据)",
            "description": "从同花顺和东方财富人气榜中寻找排名快速跃升、但价格尚未明显兑现的观察候选。",
            "regimes": ["ice", "repair", "fermentation", "climax", "divergence", "retreat"],
            "formula": {
                "meta": _meta(
                    "热度观察", "B+", "每日", "高", "人气榜与行情", 80, 10, 10, -7,
                    requires_popularity=True, backtestable=False,
                ),
                "universe": {"exclude_st": True, "listed_days_min": 120},
                "filters": [
                    {"field": "popularity_score", "op": ">=", "value": 15},
                    {"field": "return_10d", "op": "<=", "value": 5},
                    {"field": "recent_limit_up_5d", "op": "==", "value": 0},
                    {"field": "amount_billion", "op": ">=", "value": 0.5},
                ],
                "score": [
                    {"field": "popularity_score", "weight": 0.50, "direction": "desc"},
                    {"field": "popularity_rank_change", "weight": 0.25, "direction": "desc"},
                    {"field": "popularity_dual_source", "weight": 0.10, "direction": "desc"},
                    {"field": "amount_billion", "weight": 0.15, "direction": "desc"},
                ],
                "limit": 10,
                "min_score": 0.48,
            },
        },
        {
            "name": "机构榜溢价",
            "description": "筛选龙虎榜机构专用席位低位净买入的公司，并以席位数量和成交承载确认信号。",
            "regimes": ["ice", "repair", "fermentation", "climax", "divergence", "retreat"],
            "formula": {
                "meta": _meta(
                    "资金席位", "B+", "每日", "中高", "龙虎榜机构席位", 80, 10, 10, -7,
                    requires_institutions=True,
                ),
                "universe": {"exclude_st": True, "listed_days_min": 180},
                "filters": [
                    {"field": "institution_net_buy_million", "op": ">=", "value": 30},
                    {"field": "institution_seat_count", "op": ">=", "value": 1},
                    {"field": "return_60d", "op": "<=", "value": 30},
                    {"field": "previous_limit_streak", "op": "<=", "value": 2},
                ],
                "score": [
                    {"field": "institution_net_buy_million", "weight": 0.55, "direction": "desc"},
                    {"field": "institution_seat_count", "weight": 0.15, "direction": "desc"},
                    {"field": "relative_position_60", "weight": 0.20, "direction": "asc"},
                    {"field": "amount_billion", "weight": 0.10, "direction": "desc"},
                ],
                "limit": 10,
                "min_score": 0.48,
            },
        },
    ]
)

ADVANCED_CURATED_STRATEGIES.extend(
    [
        {
            "name": "行业动量轮动",
            "description": "选择20日涨幅居前的行业，并在行业内部保留趋势与成交承载更强的前排公司。",
            "regimes": ["ice", "repair", "fermentation", "climax", "divergence", "retreat"],
            "formula": {
                "meta": _meta("行业轮动", "A-", "双周", "中", "行业与历史行情", 80, 20, 12, -7),
                "universe": {"exclude_st": True, "listed_days_min": 180},
                "filters": [
                    {"field": "sector_momentum_rank", "op": ">=", "value": 0.90},
                    {"field": "sector_stock_momentum_rank", "op": ">=", "value": 0.80},
                    {"field": "amount_billion", "op": ">=", "value": 1},
                ],
                "score": [
                    {"field": "sector_return_20d", "weight": 0.38, "direction": "desc"},
                    {"field": "return_20d", "weight": 0.32, "direction": "desc"},
                    {"field": "total_mv_billion", "weight": 0.18, "direction": "desc"},
                    {"field": "amount_billion", "weight": 0.12, "direction": "desc"},
                ],
                "limit": 12,
                "min_score": 0.48,
            },
        },
        {
            "name": "主力资金行业流入",
            "description": "寻找近5日主力资金持续净流入、行业涨幅尚未充分兑现的板块前排。",
            "regimes": ["ice", "repair", "fermentation", "climax", "divergence", "retreat"],
            "formula": {
                "meta": _meta(
                    "行业轮动", "B+", "每周", "中高", "行业与资金流", 80, 10, 10, -7,
                    requires_moneyflow_history=True,
                ),
                "universe": {"exclude_st": True, "listed_days_min": 180},
                "filters": [
                    {"field": "sector_flow_rank", "op": ">=", "value": 0.85},
                    {"field": "sector_net_flow_5d_million", "op": ">", "value": 0},
                    {"field": "sector_return_5d", "op": "<=", "value": 8},
                    {"field": "flow_to_circ_mv_5d", "op": ">", "value": 0},
                    {"field": "amount_billion", "op": ">=", "value": 1},
                ],
                "score": [
                    {"field": "flow_to_circ_mv_5d", "weight": 0.42, "direction": "desc"},
                    {"field": "sector_net_flow_5d_million", "weight": 0.30, "direction": "desc"},
                    {"field": "sector_return_5d", "weight": 0.16, "direction": "asc"},
                    {"field": "amount_billion", "weight": 0.12, "direction": "desc"},
                ],
                "limit": 15,
                "min_score": 0.48,
            },
        },
    ]
)
