模块接口规格 · Contracts
⬡ claude-sonnet-4-6 · 2026-05-20
设计原则
契约驱动
模块之间只通过数据类型通信,不直接引用彼此的实现类。上游只关心输出字段是否符合约定,下游只关心输入字段是否存在。
短路优先
流水线中任一模块返回空值或明确的短路信号,后续模块不执行。避免弱信号进入执行层。
可插拔实现
每个模块位置(M1-M4)对应一个 ABC,注册表将算法名称映射到实现类。SystemConfig 中的
method 字段是路由键,不是代码引用。参数解耦
算法逻辑不在
__init__ 中接收参数,而是通过 configure(params: dict) 方法初始化。params 来自 SystemConfig,key 由算法自行定义。TrendResult 数据类型
M1 TrendModule 的输出,描述当前市场趋势状态。
| 字段 | 类型 | 是否必填 | 说明 |
|---|---|---|---|
direction | str | 必填 | 趋势方向:"bullish" / "bearish" / "ranging"。ranging 时触发短路,后续模块不执行。 |
stage | str | 必填 | 趋势阶段:"impulse" / "pullback" / "consolidation" |
extreme_price | float | 必填 | 本段趋势的极值价格(多头时为最高点,空头时为最低点) |
pullback_depth | float | 必填 | 当前回调深度(0.0 ~ 1.0,相对于趋势幅度)。仅描述数值,当前版本不用于过滤。 |
strength | float | None | 可选 | 趋势强度分值(0.0 ~ 1.0)。当前版本保留字段,不使用,后续用于影响仓位大小。 |
method | str | 必填 | 产生此结果的算法名称,如 "ema_group" |
params_hash | str | 必填 | 算法参数的哈希值,用于缓存 key 构建 |
strength 字段当前版本隐藏,置为 None。后续补回时影响仓位计算,届时由 PlanModule 读取。KeyLevel 数据类型
M2 KeyLevelModule 输出的单个关键位,实际输出为 List[KeyLevel]。
| 字段 | 类型 | 是否必填 | 说明 |
|---|---|---|---|
price | float | 必填 | 关键价格中轴 |
zone_low | float | 必填 | 区间下边界(用于图表填充矩形) |
zone_high | float | 必填 | 区间上边界 |
level_type | str | 必填 | "support" / "resistance" / "both" |
touch_count | int | 必填 | 历史触碰次数,越高越强 |
last_touch_time | int | 必填 | 最近一次触碰的 K 线收盘时间戳(ms) |
method | str | 必填 | 产生此关键位的算法名称 |
区间展示要求:KeyLevel 必须同时包含
zone_low 和 zone_high,图表层使用填充矩形展示,不画单条价格线。SignalResult 数据类型
M3 SignalModule 的输出,描述一个入场信号。
| 字段 | 类型 | 是否必填 | 说明 |
|---|---|---|---|
signal_type | str | 必填 | 信号类型,如 "golden_candle"、"pattern_signal" |
direction | str | 必填 | "long" / "short" |
entry_candle_time | int | 必填 | 触发信号的 K 线收盘时间戳(ms) |
entry_price_hint | float | 必填 | 建议入场价(参考值,PlanModule 可调整) |
key_level_ref | KeyLevel | 必填 | 触发此信号所依附的关键位 |
confidence | float | None | 可选 | 信号置信度(0.0~1.0)。当前版本保留字段,不使用 |
TradePlan 数据类型
M4 PlanModule 的输出,完整的交易计划。
| 字段 | 类型 | 是否必填 | 说明 |
|---|---|---|---|
symbol | str | 必填 | 交易对,如 "BTC/USDT:USDT" |
direction | str | 必填 | "long" / "short" |
entry_price | float | 必填 | 计划入场价 |
stop_loss | float | 必填 | 止损价 |
take_profit | float | 必填 | 止盈价 |
rr_ratio | float | 必填 | 盈亏比((tp-entry)/(entry-sl))。低于 min_rr_ratio 时短路。 |
position_size | float | 必填 | 仓位大小(USDT 计价) |
signal_ref | SignalResult | 必填 | 来源信号引用 |
created_at | int | 必填 | 计划生成时间戳(ms) |
TrendModule 抽象基类
M1 插槽的抽象基类,所有趋势算法必须继承此类。
from abc import ABC, abstractmethod
from .types import TrendResult
class TrendModule(ABC):
def configure(self, params: dict) -> None:
"""接收来自 SystemConfig 的参数字典,算法自行解析所需字段。"""
pass
@abstractmethod
def analyze(self, klines: list[dict], symbol: str, timeframe: str) -> TrendResult | None:
"""
分析 K 线序列,返回趋势判断结果。
返回 None 或 direction=="ranging" 时,流水线短路。
Args:
klines: K 线列表,每条格式 {time, open, high, low, close, volume}
symbol: 交易对
timeframe: 时间周期
"""
...
@property
@abstractmethod
def name(self) -> str:
"""算法注册名称,与方法注册表中的 key 一致。"""
...klines 列表中时间 t 的 K 线只包含 ≤t 时刻的数据(HistoricalDataFeed 保证此约束),算法实现不应假设能看到未来数据。KeyLevelModule 抽象基类
M2 插槽的抽象基类,所有关键位算法必须继承此类。
from abc import ABC, abstractmethod
from .types import KeyLevel
class KeyLevelModule(ABC):
def configure(self, params: dict) -> None:
pass
@abstractmethod
def identify(self, klines: list[dict], symbol: str, timeframe: str) -> list[KeyLevel]:
"""
识别关键价位区间列表。
返回空列表 [] 时,流水线短路。
返回的每个 KeyLevel 必须包含 zone_low 和 zone_high(区间,非单条线)。
"""
...
@property
@abstractmethod
def name(self) -> str: ...SignalModule 抽象基类
M3 插槽的抽象基类,所有信号算法必须继承此类。
from abc import ABC, abstractmethod
from .types import TrendResult, KeyLevel, SignalResult
class SignalModule(ABC):
def configure(self, params: dict) -> None:
pass
@abstractmethod
def detect(
self,
klines: list[dict],
trend: TrendResult,
key_levels: list[KeyLevel],
symbol: str,
) -> SignalResult | None:
"""
在给定趋势和关键位上下文中检测入场信号。
返回 None 时,流水线短路。
Args:
klines: K 线序列(最新一根为当前 K 线收盘)
trend: M1 输出的趋势判断
key_levels: M2 输出的关键位列表
"""
...
@property
@abstractmethod
def name(self) -> str: ...PlanModule 抽象基类
M4 插槽的抽象基类,所有交易计划算法必须继承此类。
from abc import ABC, abstractmethod
from .types import SignalResult, TradePlan
class PlanModule(ABC):
def configure(self, params: dict) -> None:
pass
@abstractmethod
def generate(
self,
signal: SignalResult,
account_balance: float,
min_rr_ratio: float,
) -> TradePlan | None:
"""
根据入场信号生成完整交易计划。
rr_ratio < min_rr_ratio 时返回 None(短路)。
Args:
signal: M3 输出的入场信号
account_balance: 当前账户余额(USDT),用于仓位计算
min_rr_ratio: 最小盈亏比阈值,来自 SystemConfig
"""
...
@property
@abstractmethod
def name(self) -> str: ...注册机制
注册表结构
每个模块插槽维护独立的注册表字典,key 为算法名称字符串,value 为实现类(类对象,非实例)。系统启动时扫描
alphaquant/modules/ 各子目录,自动注册所有实现类。SystemConfig 中的 trend_method(如 "ema_group")在运行时被用作路由 key,查表实例化对应类后调用 configure(params) 注入参数。新增算法的步骤
- 在对应模块子目录下新建实现文件,继承对应的 ABC
- 实现
name属性,返回唯一的算法注册名称(如"my_new_trend") - 实现核心抽象方法(
analyze/identify/detect/generate) - 在子目录的
__init__.py中导入该类,使注册扫描能发现它 - 在 SystemConfig 的 method 字段填写对应名称,参数写入 params 字典
方法目录(注册表总览)
| 插槽 | 注册名 | 中文名 | 状态 | 文档 |
|---|---|---|---|---|
| M1 TrendModule | naked_candle | 裸K趋势 | stable | m1_naked_candle.html |
| M1 TrendModule | ema_group | 均线组趋势 | stable | m1_ema_group.html |
| M1 TrendModule | vegas_tunnel | Vegas隧道 | draft | m1_vegas_tunnel.html |
| M1 TrendModule | trendline | 趋势线 | planned | — |
| M1 TrendModule | pattern_trend | 形态趋势 | planned | — |
| M2 KeyLevelModule | horizontal_swing | 水平关键位 | stable | m2_horizontal_swing.html |
| M2 KeyLevelModule | pattern_level | 形态关键位 | planned | — |
| M2 KeyLevelModule | specific_price | 特定价格 | planned | — |
| M3 SignalModule | golden_candle | 金K入场 | stable | m3_golden_candle.html |
| M3 SignalModule | pattern_signal | 形态信号 | draft | — |
| M3 SignalModule | ema_signal | 均线信号 | planned | — |
短路条件
流水线按 M1→M2→M3→M4 顺序执行,任一步短路后后续模块不再调用。短路不是错误,是正常的「无信号」状态。
| 模块 | 短路条件 | 原因 |
|---|---|---|
| M1 TrendModule | direction == "ranging" 或返回 None | 震荡市场下信号质量低,不值得继续分析 |
| M2 KeyLevelModule | 返回空列表 [] | 无关键位则 M3 无法判断价格是否进入有效区域 |
| M3 SignalModule | 返回 None | 当前 K 线无满足条件的入场形态 |
| M4 PlanModule | rr_ratio < min_rr_ratio 或返回 None | 盈亏比不足,不值得开仓;这是最后一道过滤门 |
短路信息记录在日志中,但不触发 Discord 通知。只有 M4 成功生成 TradePlan 才推送通知。