系统架构设计方案 v1.0
由 Claude Opus 4.7 生成 · 深度思考版本
一 · 整体分层与模块清单
L1
外部数据层
OKX REST / WebSocket
(CCXT 封装)
ExchangeAdapter — 按任务配置的交易对和周期周期性拉取,统一处理限频/重试/时区
L2
采集与配置层
TaskConfigService
MarketDataCollector
MarketDataStore
K线数据(OHLCV)+ 任务配置参数(交易对 / 周期 / 算法 / 仓位)
L3
分析计算层
TrendModule
KeyLevelModule
SignalModule
PlanModule
IndicatorLib
PatternLib
AlgoRegistry
趋势标签 + 均线快照 + 关键位区间列表 + 入场信号 + 完整交易计划
L4
编排调度层
PipelineOrchestrator
Scheduler
EventBus
事件驱动:kline.closed → 触发分析链 → 分发结果
L5
执行复盘层
ExecutionTracker
PositionMonitor
ReviewModule
TradeArchive
执行记录 + 持仓预警 + 复盘归档 + 统计数据
L6
输出展示层
ChartRenderer
WebUI
DiscordNotifier
APIGateway
持久化:TaskConfigStore · KlineCache · AnalysisCache · SignalLog · TradeLedger · ReviewArchive
二 · 模块职责边界
MarketDataCollector · K线采集程序
已上线
做
- 汇总所有运行中任务的 symbol×timeframe 集合(去重)
- 每根 K 线收盘后 +几秒延迟拉取最新 OHLCV
- 增量合并到 KlineCache,发布
kline.closed事件
不做
- 不计算任何指标
- 不判定信号或趋势
- 不直接调用下游模块
TrendModule · 趋势分析模块
已上线
做
- 运行配置算法(EMA 三均线默认,可插拔 MACD/SuperTrend)
- 输出趋势标签(涨/跌/震荡)+ 指标快照 + 预留 strength 字段
不做
- 不识别价位或形态
- 不决定做单方向(属 SignalModule)
KeyLevelModule · 关键位识别模块
已上线
做
- 扫描趋势+入场两个周期的 swing 高低点
- 按算法(Clustering/S-R Flip/Price Density)聚合为区间
- 输出
{center, low, high, type, touches, score}列表
不做
- 不判断当前价是否进入区间(属 SignalModule)
- 不绘图,不通知
SignalModule · 信号检测模块
规划中
做
- 检测最新 K 线是否落入关键位区间
- 识别配置的形态(Pin Bar/Engulfing 等)
- 按"做单方向"配置过滤,与趋势方向一致性校验
不做
- 不计算止损止盈(属 PlanModule)
- 不下单,不通知
PlanModule · 交易计划模块
规划中
做
- 由触发 K 线确定入场价 + 止损位(影线外侧 + buffer)
- 取下一个关键位为止盈目标,计算盈亏比
- 盈亏比未达阈值则丢弃;达标才输出完整计划
不做
- 不下单,不通知,不画图
- 暂不加权 confidence/pullback_depth(字段预留)
PipelineOrchestrator · 编排调度
做
- 消费
kline.closed事件,按依赖顺序展开分析链 - Trend ‖ KeyLevel → Signal → Plan → Chart + Discord + Ledger
- 单任务异常不阻塞其他任务
不做
- 不实现具体算法
- 不直接读交易所
三 · 依赖关系与数据流
用户配置任务
每根 K 线收盘后 · 定时触发
MarketDataCollector
← CCXT · OKX API · OHLCV
写入 KlineCache → 发布 kline.closed 事件
并行分析(PipelineOrchestrator)
TrendModule(趋势 TF)
KeyLevelModule(趋势 TF + 入场 TF)
SignalModule(入场 TF)
无信号 → 等待下一根 K 线
有信号
PlanModule
盈亏比不达标 → 丢弃
达标
并行输出
ChartRenderer
DiscordNotifier
TradeLedger(intended)
ExecutionTracker(auto_trade ? 下单 : 仅记录)
PositionMonitor · 持续监控
仓位关闭
ReviewModule → TradeArchive
四 · 同步 vs 异步
路径模式原因
Scheduler → Collector同步定时严格按 K 线收盘时刻触发
Collector → 分析链异步事件解耦,允许多消费者并行消费同一事件
Trend ‖ KeyLevel并行二者互不依赖,asyncio.gather 提速
Signal ← Trend, KeyLevel同步等待Signal 必须等两者都完成
Chart + Discord并行 fire-and-forgetI/O 慢,不阻塞主链
PositionMonitor独立协程长驻,与分析链完全解耦
五 · 关键设计决策
事件驱动 + 增量采集
Collector 完成一次 (symbol, tf) 写入后只发 1 个 kline.closed 事件;Orchestrator 内部按订阅了该 (symbol, tf) 的任务展开 N 个分析任务。同一任务的 trend 周期与 entry 周期独立触发:entry K 线收盘时复用最近的 trend 结果(AnalysisCache 缓存),trend 周期未收盘则不重算。
AnalysisCache 持久化(阻塞 SignalModule 开发的 P0 项)
| 缓存 | 介质 | Key 格式 | 用途 |
|---|---|---|---|
| KlineCache | Parquet + 内存 LRU | symbol/tf/月份 | 所有分析的源 |
| AnalysisCache | SQLite(必须持久化) | {task}:{module}:{tf}:{ts} | 回测 replay、模拟下单复现 |
| ChartCache | 文件系统 LRU | hash 文件名 | Discord 复用 PNG |
配置持久化三层
TaskConfigStore 用 SQLite + task_versions 表保留历史快照供回测复现;API Key/Secret 用 AES-GCM + env 主密钥加密落库,内存中只在 ExchangeAdapter 内解密;配置变更发 task.updated 事件,Scheduler 重算调度计划,Collector 重算采集集合。
算法可插拔(AlgoRegistry)
每个分析模块只依赖 AlgoRegistry.get(name) 取实现;新增算法 = 注册一个类,无需改 Orchestrator。任务配置存算法名 + 参数 dict,不存代码引用。支持同一任务多算法并行跑、结果并列展示(用户对比切换)。
关键位必须用填充矩形区间
KeyLevelModule 直接输出 {low, high} 边界,ChartRenderer 用填充矩形渲染(Flip 金色、支撑绿色、阻力红色),不转换为单条线。
六 · 核心数据结构
Task 配置
{
"id": "task_001", "version": 3, "status": "running | paused | archived",
"data": { "symbol": "BTC/USDT:USDT", "exchange": "okx", "trend_tf": "4h", "entry_tf": "15m", "window_size": 500 },
"trend": { "algo": "ema_triple", "params": { "p1": 21, "p2": 55, "p3": 144 } },
"keylevel":{ "algo": "sr_flip", "params": { "swing_lookback": 5, "cluster_tol_pct": 0.3, "min_touches": 2 } },
"signal": { "direction_mode": "with_trend", "pattern": "pin_bar",
"params": { "body_ratio_max": 0.33, "wick_multiple_min": 2.0 } },
"plan": { "position_mode": "fixed_amount", "position_value": 100, "min_rr": 2.0, "sl_buffer_ticks": 2 },
"execution":{ "auto_trade": false, "api_key_enc": "...", "api_secret_enc": "..." },
"notify": { "discord_webhook": "https://..." }
}
TrendSnapshot
{ "task_id":"...", "tf":"4h", "ts":1716000000000,
"label": "down | up | range",
"strength": 1.0, // 预留字段,当前固定 1.0
"indicators": { "ema21": 80500, "ema55": 81200, "ema144": 82800 } }
KeyLevelZone
{ "task_id":"...", "ts":1716000000000,
"zones": [
{ "id":"kl_xxx", "center":80489, "low":80350, "high":80620,
"type": "flip | support | resistance", "touches":11, "score":94.1 }
] }
Signal
{ "task_id":"...", "ts":..., "entry_tf":"15m",
"direction": "short | long", "pattern": "pin_bar",
"trigger_price": 80300, "matched_zone_id": "kl_xxx",
"trend_ref": { "label":"down", "strength": 1.0 } }
TradePlan
{ "task_id":"...", "signal_id":"...",
"entry":80300, "stop_loss":80920, "take_profit":76800,
"rr":5.6, "position_size":0.012, "leverage":5,
"confidence": null, // 预留,暂不启用
"pullback_depth": 0.38, // 照常计算,暂不加权
"reasoning": "Pin Bar at flip zone $80489, with-trend short, next zone $76800" }
Trade(贯穿执行 + 复盘)
{ "id":"...", "plan_id":"...",
"intended": { "entry":..., "sl":..., "tp":..., "size":... },
"actual": { "entry_price":..., "exit_price":..., "pnl":..., "exit_reason":"tp|sl|manual" },
"review": { "tech":"...", "sizing":"...", "psychology":"..." },
"status": "intended | open | closed | reviewed" }
七 · 技术选型
| 关注点 | 选型 | 理由 |
|---|---|---|
| 后端语言 | Python 3.11 + FastAPI + asyncio | CCXT/pandas/mplfinance 生态完整;项目已有 Python 历史 |
| 调度 | APScheduler + asyncio 长驻协程 | 单进程内一站式;多机可换 Celery Beat |
| 事件总线 | asyncio.Queue 起步 → Redis Streams 扩展 | 零依赖起步;扩展可水平拆分采集/分析/通知 |
| K 线存储 | Parquet 分片(symbol/tf/月) | 列存压缩高,时序友好,纯文件部署简单 |
| 元数据 / 配置 / 账本 | SQLite → PostgreSQL | 事务/备份/查询够用;成长后无缝迁移 |
| 图表 | lightweight-charts(交互看板)+ mplfinance(Discord PNG) | lightweight-charts 是 TradingView 开源版,性能最好 |
| Discord | 纯 Webhook 起步,discord.py Bot 扩展 | Webhook 最简,Bot 支持交互指令 |
| 前端 | React + Vite + TanStack Query | 任务管理 + 看板的交互需求,轻量方案 |
| 部署 | Docker Compose(Oracle 远端) | services: api / collector / orchestrator / monitor / web |
| 配置加密 | cryptography AES-GCM + env 主密钥 | 标准安全做法 |
八 · 目录结构
app/
├── adapters/ # ExchangeAdapter (CCXT)
├── config/ # TaskConfigService, TaskConfigStore
├── collector/ # MarketDataCollector, MarketDataStore
├── analysis/
│ ├── indicators/ # IndicatorLib
│ ├── patterns/ # PatternLib
│ ├── trend/ # TrendModule + algos
│ ├── keylevel/ # KeyLevelModule + clustering/sr_flip/density
│ ├── signal/ # SignalModule(规划中)
│ └── plan/ # PlanModule(规划中)
├── orchestrator/ # PipelineOrchestrator, Scheduler, EventBus
├── execution/ # ExecutionTracker, PositionMonitor
├── review/ # ReviewModule, TradeArchive
├── render/ # ChartRenderer
├── notify/ # DiscordNotifier
├── api/ # FastAPI 路由
├── web/ # React 前端
└── common/ # types, time utils, crypto, logging
data/
├── klines/ # Parquet
├── cache/ # AnalysisCache, ChartCache
├── db/ # SQLite
└── archive/ # 复盘归档
九 · 实施优先级
P0 立即
AnalysisCache 持久化(SQLite)—— 阻塞 SignalModule 和回测开发
EventBus + Orchestrator 骨架(现有模块从脚本串联变事件驱动)
TaskConfigService 完善 + API Key 加密存储
P1 主线
SignalModule(Pin Bar 起步)
PlanModule(含盈亏比过滤)
DiscordNotifier 完整消息模板
ChartRenderer 集成信号箭头 + 三色虚线
P2 闭环
ExecutionTracker(先手工模式,记录意图)
PositionMonitor + 预警推送
ReviewModule + TradeArchive
WebUI 看板交互(算法切换、历史复盘浏览)
P3 优化
趋势强度分值补回(TrendModule.strength 字段启用)
方法置信度 & 回调深度惩罚启用
回测引擎(复用 AnalysisCache replay)
十 · 待定事项
1
趋势强度分值:TrendModule 输出预留
strength: float,当前固定 1.0;PlanModule 仓位计算预留对 strength 的依赖位,后续回填。2
方法置信度 & 回调深度惩罚:TradePlan 预留
confidence 和 pullback_depth 字段,数值照常计算归档,暂不加权盈亏比。3
AnalysisCache 持久化方案必须先定(建议 SQLite + JSON value),再开发 SignalModule,这是 P0 阻塞项。
4
多算法并列展示:AlgoRegistry 需支持同 task 多算法并行跑、结果并列,供用户对比切换,设计时需预留此能力。