alphax/app/core/strategy_registry.py
2026-05-31 19:00:46 +08:00

216 lines
7.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Central registry for strategy identity and display metadata."""
from __future__ import annotations
from dataclasses import dataclass, field
MAIN_COMPOSITE_STRATEGY = "main_composite_v1"
BOX_RETEST_1H_STRATEGY = "box_retest_1h_v1"
BOX_RETEST_4H_STRATEGY = "box_retest_4h_v1"
VOLUME_IGNITION_1H_STRATEGY = "volume_ignition_1h_v1"
COMPRESSION_BREAKOUT_4H_STRATEGY = "compression_breakout_4h_v1"
INTRADAY_MOMENTUM_15M_STRATEGY = "intraday_momentum_15m_v1"
BREAKDOWN_RETEST_SHORT_1H_STRATEGY = "breakdown_retest_short_1h_v1"
@dataclass(frozen=True)
class StrategyDefinition:
strategy_code: str
strategy_name: str
description: str = ""
mode: str = "paper_only"
status: str = "active"
entry_gate_config: dict = field(default_factory=dict)
paper_config: dict = field(default_factory=dict)
STRATEGY_DEFINITIONS: dict[str, StrategyDefinition] = {
MAIN_COMPOSITE_STRATEGY: StrategyDefinition(
strategy_code=MAIN_COMPOSITE_STRATEGY,
strategy_name="综合确认策略",
description="迁移期兼容综合策略,承载现有综合筛选与确认逻辑;它与其他策略平等运行。",
mode="paper_enabled",
),
BOX_RETEST_1H_STRATEGY: StrategyDefinition(
strategy_code=BOX_RETEST_1H_STRATEGY,
strategy_name="1H箱体突破回踩",
description="小时级底部箱体突破后回踩箱体上沿或EMA承接的早期结构策略。",
mode="paper_only",
entry_gate_config={
"min_entry_score_buy_now": 1,
"min_entry_score_wait_pullback": 0,
"min_rr_buy_now": 1.2,
"max_wait_pullback_deviation_pct": 20,
"breakout_distance_wait_pct": 25,
"gain_24h_wait_pct": 12,
},
paper_config={
"entry_min_rr": 1.5,
"order_min_rr": 1.5,
"order_min_distance_to_entry_pct": 0,
"order_require_current_trigger": False,
"dynamic_leverage_enabled": True,
"dynamic_leverage_min": 3,
},
),
BOX_RETEST_4H_STRATEGY: StrategyDefinition(
strategy_code=BOX_RETEST_4H_STRATEGY,
strategy_name="4H箱体突破回踩",
description="底部箱体突破后回踩箱体上沿或EMA承接的结构策略。",
mode="paper_only",
entry_gate_config={
"min_entry_score_buy_now": 1,
"min_entry_score_wait_pullback": 0,
"min_rr_buy_now": 1.2,
"max_wait_pullback_deviation_pct": 20,
"breakout_distance_wait_pct": 25,
"gain_24h_wait_pct": 12,
},
paper_config={
"entry_min_rr": 1.5,
"order_min_rr": 1.5,
"order_min_distance_to_entry_pct": 0,
"order_require_current_trigger": False,
"dynamic_leverage_enabled": True,
"dynamic_leverage_min": 3,
},
),
VOLUME_IGNITION_1H_STRATEGY: StrategyDefinition(
strategy_code=VOLUME_IGNITION_1H_STRATEGY,
strategy_name="1H放量突破启动",
description="1H量价齐飞或连续放量后的启动策略适合捕捉日内到3天的第一段加速。",
mode="paper_only",
entry_gate_config={
"min_entry_score_buy_now": 2,
"min_entry_score_wait_pullback": 1,
"min_rr_buy_now": 1.25,
"breakout_distance_wait_pct": 12,
"gain_24h_wait_pct": 10,
},
paper_config={
"entry_min_rr": 1.5,
"order_min_rr": 1.5,
"order_min_distance_to_entry_pct": 0,
"order_require_current_trigger": True,
"dynamic_leverage_enabled": True,
"dynamic_leverage_min": 3,
},
),
COMPRESSION_BREAKOUT_4H_STRATEGY: StrategyDefinition(
strategy_code=COMPRESSION_BREAKOUT_4H_STRATEGY,
strategy_name="4H压缩蓄力突破",
description="4H静K蓄力、底部抬高或压缩放量后的突破策略偏向捕捉1周以内主升前段。",
mode="paper_only",
entry_gate_config={
"min_entry_score_buy_now": 2,
"min_entry_score_wait_pullback": 0,
"min_rr_buy_now": 1.3,
"max_wait_pullback_deviation_pct": 18,
"breakout_distance_wait_pct": 18,
"gain_24h_wait_pct": 12,
},
paper_config={
"entry_min_rr": 1.6,
"order_min_rr": 1.6,
"order_min_distance_to_entry_pct": 0,
"order_require_current_trigger": False,
"dynamic_leverage_enabled": True,
"dynamic_leverage_min": 3,
},
),
INTRADAY_MOMENTUM_15M_STRATEGY: StrategyDefinition(
strategy_code=INTRADAY_MOMENTUM_15M_STRATEGY,
strategy_name="15m日内动量延续",
description="短周期放量突破与1H背景共振的日内动量策略只做当前触发不做纯观察追高。",
mode="paper_only",
entry_gate_config={
"min_entry_score_buy_now": 3,
"min_entry_score_wait_pullback": 2,
"min_rr_buy_now": 1.4,
"breakout_distance_wait_pct": 8,
"gain_24h_wait_pct": 8,
},
paper_config={
"entry_min_rr": 1.6,
"order_min_rr": 1.6,
"order_min_distance_to_entry_pct": 0,
"order_require_current_trigger": True,
"dynamic_leverage_enabled": True,
"dynamic_leverage_min": 3,
},
),
BREAKDOWN_RETEST_SHORT_1H_STRATEGY: StrategyDefinition(
strategy_code=BREAKDOWN_RETEST_SHORT_1H_STRATEGY,
strategy_name="1H破位反抽做空",
description="箱体或关键均线破位后反抽失败的空头策略;只用于独立空头样本,不与多头突破策略共享入场门槛。",
mode="paper_only",
entry_gate_config={
"direction": "short",
"min_entry_score_buy_now": 2,
"min_entry_score_wait_pullback": 1,
"min_rr_buy_now": 1.5,
"breakdown_distance_wait_pct": 10,
"max_retest_deviation_pct": 8,
},
paper_config={
"entry_min_rr": 1.8,
"order_min_rr": 1.8,
"order_min_distance_to_entry_pct": 0,
"order_require_current_trigger": True,
"dynamic_leverage_enabled": True,
"dynamic_leverage_min": 2,
},
),
}
def normalize_strategy_code(strategy_code: str | None) -> str:
code = str(strategy_code or "").strip()
return code or MAIN_COMPOSITE_STRATEGY
def strategy_definition(strategy_code: str | None) -> StrategyDefinition:
code = normalize_strategy_code(strategy_code)
return STRATEGY_DEFINITIONS.get(
code,
StrategyDefinition(
strategy_code=code,
strategy_name=code,
description="未注册策略,请补充 strategy_registry。",
status="unknown",
),
)
def strategy_label(strategy_code: str | None) -> str:
return strategy_definition(strategy_code).strategy_name
def strategy_entry_gate_config(strategy_code: str | None) -> dict:
return dict(strategy_definition(strategy_code).entry_gate_config or {})
def strategy_paper_config(strategy_code: str | None) -> dict:
return dict(strategy_definition(strategy_code).paper_config or {})
def registered_strategy_codes() -> list[str]:
return list(STRATEGY_DEFINITIONS.keys())
def strategy_catalog_seed_rows(strategy_version: str = "") -> list[dict]:
rows = []
for item in STRATEGY_DEFINITIONS.values():
rows.append(
{
"strategy_code": item.strategy_code,
"strategy_name": item.strategy_name,
"strategy_version": strategy_version or "",
"status": item.status,
"mode": item.mode,
"description": item.description,
}
)
return rows