334 lines
16 KiB
Python
334 lines
16 KiB
Python
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": "选择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,
|
|
},
|
|
},
|
|
]
|
|
)
|