系统架构设计方案 · 通用框架版
⬡ claude-opus-4-7 · 2026-05-20
零 · 框架化与可插拔设计
什么定义「一个交易系统」
一个交易系统由五个配置项唯一确定:三个主方法 + 两个时间周期。满足任一差异即视为不同系统:
| 设计维度 | 配置项 | 差异即不同系统的条件 |
|---|---|---|
| 方法可插拔 | M1 趋势主方法(裸K / 均线EMA / Vegas隧道 / 趋势线 / 形态) M2 关键位主方法(水平 / 形态 / 特定价格) M3 信号主方法(金K / 形态 / 均线) |
三者任一不同 → 不同系统 |
| 框架化 | 趋势周期(trend_timeframe) 交易周期(main_timeframe) |
方法完全相同但周期不同 → 也是不同系统 |
框架本身不内置任何方法论——「4H趋势+1H信号+EMA」是一套系统,「4H趋势+1H信号+裸K」是另一套,「1D趋势+4H信号+EMA」又是一套,三者可以在同一框架下并行运行。
多对多并行关系
框架在两个维度同时支持多对多:
- 每个交易系统可以同时跟踪多个交易对(系统A 同时监控 BTC、ETH、SOL)
- 每个交易对可以同时被多个交易系统覆盖(BTC 同时跑系统A、B、C)
去重共享计算的条件
当同一交易对被多套系统覆盖时,按缓存 key 判断是否可以复用结果:
| 数据类型 | 缓存 Key | 共享条件 |
|---|---|---|
| K 线数据 | (symbol, timeframe) |
同交易对 + 同周期,始终共享,无论方法是否相同 |
| M1 趋势结果 | (symbol, tf, method, params_hash) |
方法 + 参数完全相同才共享 |
| M2 关键位结果 | (symbol, tf, method, params_hash, close_time) |
方法 + 参数相同,且基于同一根收盘 K 线 |
| M3 信号 / M4 计划 | 不缓存 | 每根 K 线实时独立计算,不跨系统共享 |
示例:BTC/USDT 同时运行系统A(EMA趋势 + 水平关键位)和系统C(EMA趋势 + 形态关键位),两者共享 BTC/USDT 4H K 线和 M1 EMA 趋势结果;但 M2 关键位各算各的(水平 ≠ 形态);M3 信号各自独立识别。
一 · 架构总览
L0
宿主运行层
MultiSystemRunner
RiskController 暂缓
RevengeController 暂缓
协调所有交易系统并行运行 · 统一执行账户级风控 · 跨系统复仇配额管理
L1
共享数据层
MarketDataHub
TrendResultCache
KeyLevelCache
SymbolStrategyRegistry
多系统共享行情和分析结果 · 相同计算只发生一次 · 以交易对为路由入口
L2
系统接口层
SystemConfig Schema
PluginInterface 契约
每个交易系统通过配置清单声明自己使用哪些模块实现、哪种方法、哪些参数
L3
流水线模块层
M1 TrendModule
M2 KeyLevelModule
M3 SignalModule
M4 PlanModule
← 短路流水线
短路流水线 · 任一步不达标立即终止 · 模块可整体替换实现,只要遵守接口契约
L4
执行监控层
M5A OrderManager
M5B PositionMonitor
下单执行与持仓追踪 · WebSocket 事件驱动(非定时轮询)· 幂等处理
L5
输出层
M5C ReviewLogger
Notifier
这是一套框架级架构,而非单一交易系统的实例。L0 MultiSystemRunner 作为宿主,统筹多套交易系统在同一账户并行运行;L1 共享数据层实现去重计算,多套系统订阅同一份行情和分析结果;L2 系统接口层定义插槽契约,具体的交易方法论通过配置清单注入;L3 流水线模块层承载可替换的核心算法,实行短路机制;L4 执行监控层通过 CCXT WebSocket 推送驱动,实现毫秒级持仓追踪;L5 输出层负责归档和通知,不参与主链路决策。
二 · 模块说明
| 模块 | 层次 | 职责 | 边界约束 | 可插拔 |
|---|---|---|---|---|
| MultiSystemRunner | L0 | 宿主运行器,协调所有已注册交易系统并行运行;分发行情事件、执行统一风控、管理资金分配 | 不持有任何具体交易逻辑;各系统故障不互相影响 | 否 |
| RiskController | L0 | 账户级熔断:单交易对每日亏损上限 + 全账户每日亏损上限;触达后冻结开新仓 | 暂缓实现;架构已明确,后续补充 | 否 |
| RevengeController | L0 | 跨系统复仇配额管理:同一信号事件(同交易对+同方向+关键位重叠±0.4%+时间差≤4小时)最多允许 N 次复仇,配额跨系统共享 | 暂缓实现;先到先得原则,日亏损上限触达时自动冻结 | 否 |
| MarketDataHub | L1 | 启动时收集所有系统注册的交易对,合并去重后统一拉取 K 线;每个交易对每个周期只拉一份,多个系统订阅同一份数据 | 只写缓存,不做分析;写入时加写锁 | 否 |
| TrendResultCache | L1 | 缓存趋势分析结果;key=(symbol, timeframe, method, params_hash),每种方法+周期只算一次,各系统按需取用 | 写入时加写锁,读时加读锁(多读单写);新 K 线收盘时失效 | 否 |
| KeyLevelCache | L1 | 缓存关键位识别结果;key=(symbol, timeframe, method, params_hash, source_close_time);新 K 线收盘时旧条目失效,保留 1 根供回放 | 读写锁;信号探测读前校验 source_close_time 一致性 | 否 |
| SymbolStrategyRegistry | L1 | 以交易对为路由入口,记录哪个交易对激活哪些系统模板;运营时可随时启停某交易对的某套策略,无需改代码 | 只负责路由映射,不参与计算 | 否 |
| SystemConfig (M0) | L2 | 系统定义 Schema,在运行前固化所有配置(exchange, symbols, trend_timeframe, main_timeframe, kline_window, trend_method_main, signal_types, min_rr_ratio, auto_trade, discord_webhook);下游模块从中读取参数 | 只读,不可在运行时修改 | 否 |
| M1 TrendModule | L3 | 趋势判断;输出 direction(涨势/跌势/震荡)/ stage / extreme_price / pullback_depth;震荡时触发短路,顺势系统停止后续计算 | 只读 K 线缓存,不写;实现可替换(均线/裸K/形态/趋势线) | ✓ 模块级 |
| M2 KeyLevelModule | L3 | 关键位识别;输出 key_levels 列表;key_levels 为空时触发短路 | 只读 K 线缓存;实现可替换(多周期扫描/单周期/人工标注) | ✓ 模块级 |
| M3 SignalModule | L3 | 入场信号识别;消费趋势结果和关键位列表,检测价格是否在关键区出现合格形态;无合格信号时短路 | 不判断盈亏比,不管仓位;实现可替换(PinBar/突破/量能) | ✓ 模块级 |
| M4 PlanModule | L3 | 交易计划生成;计算入场价/止损位/止盈目标/盈亏比/仓位;盈亏比不足时短路,不往下传 | 不检测信号形态;止盈策略可替换(关键位/等距/跟踪均线) | ✓ 方法级 |
| M5A OrderManager | L4 | 下单管理;FILLED→移交持仓监控;EXPIRED/CANCELLED→记录结束;auto_trade=False 时只记录计划和推送通知,不发送真实订单 | 幂等处理(order_id+event_type 去重) | 否 |
| M5B PositionMonitor | L4 | 持仓监控;CCXT WebSocket 推送驱动;检查止盈/止损/移损触发;浮亏不加仓硬规则强制拦截 | 只处理已成交订单的持仓;不触发新信号 | 否 |
| M5C ReviewLogger | L5 | 复盘归档;平仓后记录 TradePlan + 实际执行结果;提供胜率/盈亏统计;统计维度可按系统扩展 | 只做归档和读取,不影响主链路 | 否 |
三 · 模块依赖关系图
共享数据层(每次 K 线收盘只算一次)
MarketDataHub行情数据中心
→
TrendResultCache趋势结果缓存
→
KeyLevelCache关键位缓存
路由到各系统
SymbolStrategyRegistry交易对策略路由
激活对应系统
并行运行 · 读缓存,互不依赖
M1 TrendModule趋势分析
M2 KeyLevelModule关键位识别
两者就绪 · 无震荡
M3 SignalModule信号检测
有信号 · Signal
M4 PlanModule计划生成
RR 达标 · TradePlan
同时输出
M5A OrderManager下单执行
auto_trade=True 时
NotifierDiscord 通知
signal_fired 事件
成交后追踪
M5B PositionMonitor持仓监控
止盈 / 止损命中
平仓后
M5C ReviewLogger复盘归档
NotifierDiscord 通知
position_closed 事件
RiskController账户风控
在 PlanModule 输出 TradePlan 前拦截校验 · 日亏损上限触达时阻止开新仓 · 暂缓实现
- M1 TrendModule 和 M2 KeyLevelModule 从缓存读取,并行运行,互不依赖;M3 需等两者都就绪
- 共享数据层(MarketDataHub / TrendResultCache / KeyLevelCache)统一在市场扫描轨道中更新,主链路只读不写
- MultiSystemRunner 协调多套系统并发,每套系统有独立的流水线实例,共享同一份缓存数据
四 · 三条并行轨道
市场扫描
trend_timeframe + main_timeframe
收盘时定时触发
收盘时定时触发
定时调度器K 线收盘检测
MarketDataHub拉取 K 线(去重)
TrendResultCache更新趋势缓存
KeyLevelCache更新关键位缓存
写完释放写锁
信号探测轨道可读缓存了
信号探测
main_timeframe 每根
K 线收盘时事件驱动
K 线收盘时事件驱动
K 线收盘事件校验缓存时间戳
读缓存(并行)
M1趋势
M2关键位
M3 SignalModule信号检测
有信号
M4 PlanModule生成计划
RR 达标
M5A OrderManager下单执行
持仓追踪
CCXT WebSocket 推送驱动
交易所主动推送,非轮询
交易所主动推送,非轮询
WebSocket 推送order_filled / update
M5A OrderManager订单状态处理
成交 → 移交持仓
M5B PositionMonitor止损 / 止盈 / 移损
平仓命中
M5C ReviewLogger归档交易记录
NotifierDiscord 推送
- 读写锁隔离:市场扫描写缓存时加写锁;信号探测读缓存时加读锁(多读单写);写完前,信号探测挂起等待
- 时间戳一致性:信号探测读取前校验
trend.source_close_time == key_level.source_close_time,不一致则跳过本次并记录日志 - WebSocket 幂等:同一笔成交可能触发多个事件,M5A/M5B 以
order_id + event_type作为幂等键去重,同一 key 只处理一次
六 · 关键设计决策
短路流水线——为什么任一步不通过就立即停止
传统做法是让所有模块都跑完再判断。短路的意义在于:前一步不通过,后一步没必要计算——节省计算资源,也确保不会在弱信号上勉强生成计划。
震荡行情直接在 M1 短路,不触发后续任何计算;无关键位在 M2 短路,不做信号识别;盈亏比不足在 M4 短路,不下单。整条链路的行为完全可预测,调试时也更容易定位到底在哪一步停住。
共享数据层——为什么多系统要去重计算而不是各算各的
如果每套系统独立拉行情、独立计算趋势和关键位,N 套系统就有 N 倍的 API 请求和 N 倍的计算量。当多套系统使用相同的方法+参数时,这些计算完全是重复工作。
BTC/USDT 4H 的 EMA 趋势只需要算一次,系统A、系统C 都取同一份结果。KeyLevelCache 的 params_hash 机制确保不同参数的系统不会互相污染,各取各的缓存。
三轨道分离——为什么市场扫描/信号探测/持仓追踪要独立运行
三条轨道的触发频率和响应时间要求差异巨大。市场扫描是分钟级(K 线收盘才触发),可以稍慢;信号探测需要在 K 线收盘后快速计算;持仓追踪需要毫秒级响应(止损止盈不能延迟)。
如果混在一起,持仓追踪会被市场扫描的写锁阻塞,可能错过止损时机。分离后三者完全异步,持仓追踪由 WebSocket 推送驱动,不受其他轨道影响。
接口契约驱动——为什么模块之间只看输入/输出字段
框架不假设 TrendModule 内部如何实现,只规定它必须输出
direction(涨势/跌势/震荡)等字段。这样,把均线实现换成裸K实现,M3 SignalModule 完全不需要感知——它只看 M1 输出的 direction 字段。
契约驱动使得模块可以独立开发、独立测试、独立升级。三层可插拔(模块级/方法级/参数级)都建立在这个基础上。算法规格书(如 M1_Trend_Sanbuqu.md)专门负责描述"如何填充框架要求的输出字段"。
风控与系统正交——为什么账户级风控不放在各系统内
如果每套系统各自管理自己的风控,会出现两个问题:一是各系统可能绕过风控(忘记实现或实现有 Bug);二是各系统的风控配额是独立的,多套系统同时在同一个账户开仓,累计风险可能超过预期。
账户级风控由 MultiSystemRunner 统一执行,各系统无法绕过。全账户日亏损上限是一个硬约束,不论哪个系统触发,整个账户的新开仓权限都会冻结。
复仇协调器跨系统设计——为什么同一关键位的复仇配额要跨系统共享
"复仇"指的是在同一个关键位亏损后再次入场的行为。如果系统A和系统C各有独立的复仇配额,在同一个关键位同一个方向亏损后,两套系统都可以各自复仇一次,相当于变相放大了在同一位置的风险敞口。
同一信号事件判定(同交易对+同方向+关键位重叠±0.4%+时间差≤4小时),跨系统共享配额,先到先得。这样无论有多少套系统在跑,在同一个位置的复仇次数始终受到约束。
七 · 与单系统(AlphaQuant-Bot)架构差异
| 维度 | 通用框架(Framework) | 单系统(AlphaQuant-Bot) |
|---|---|---|
| 定位 | 通用运行时,不持有任何具体交易方法论;是所有交易系统的宿主 | 特定交易系统(日内交易三步曲)的单一实例 |
| 系统数量 | 支持多套系统在同一账户并行运行(系统A/B/C 同时跑) | 单系统,只有一套策略参数 |
| 交易对 | 多交易对,按 SymbolStrategyRegistry 路由;BTC 可激活多套系统 | 配置文件中声明一个或少量交易对,无动态路由 |
| 数据共享 | MarketDataHub + TrendResultCache + KeyLevelCache 去重共享,N 系统 = 1 份计算 | KlineCache 只供单系统使用,无跨系统共享机制 |
| 风控层次 | 账户级风控由 MultiSystemRunner 统一执行:熔断、复仇配额、浮亏不加仓、当日强平 | 无账户级风控;只有 PlanModule 的盈亏比门槛和单笔风险比例 |
| 可插拔性 | 三层可插拔:模块级(整体替换实现类)/ 方法级(多算法组合)/ 参数级 | 参数级可配置(EMA 周期、信号类型等);模块实现固定不可替换 |
| 持仓监控触发 | CCXT WebSocket 推送驱动(事件驱动,毫秒级);与市场扫描轨道完全分离 | EventBus 内部事件驱动;持仓监控与主链路在同一运行时 |
| 调度机制 | 三条完全独立的异步并行轨道;市场扫描与信号探测分别独立调度,互不阻塞 | Scheduler 统一定时轮询;内部通过 EventBus 解耦,但仍在同一运行时 |
| 文档体系 | 三层:框架文档(接口协议)→ 算法规格书(M1_Trend_Sanbuqu.md 等)→ 系统配置(JSON) | 单层:系统架构文档 + TaskConfig 参数配置;无算法规格书概念 |
| 扩展方式 | 注册新系统只需提交一份 SystemConfig 配置清单,7 步完成接入,无需改框架代码 | 新策略需修改系统代码本身,无标准化的注册和接入流程 |