- 系统架构总览:技术栈、目录结构、数据流向 - 指标引擎详解:16个指标完整原理与参数(含源码行号) - 信号评分引擎:多指标共振评分机制、动态阈值、案例分析 - 大周期偏向判定:assessBigTimeframeBias 完整说明 - EWO转换检测机制:evaluateEwoTurnForUser 逐步流程 - 飞书通知格式规范:三类通知完整格式模板 - 类型系统参考:所有 TypeScript 类型完整文档 - 数据库与存储:MySQL 表结构、缓存机制、维护指南 - 部署运维指南:Docker Compose、Nginx、飞书配置 - 开发历史与TODO:功能状态表、优先级路线图 - 优化建议汇总:9项优化建议含源码位置和预期效果
6.4 KiB
6.4 KiB
tradehk 信号评分引擎
返回:tradehk 文档中心 源函数:
generateSignal()—client/src/lib/indicators.ts第 454-747 行
概述
generateSignal 是 tradehk 的核心信号生成函数。它采用多指标共振评分机制:对每根已收线的 K 线,计算各指标的多空得分,根据总分判断信号类型(BUY/SELL/NEUTRAL)和强度(STRONG/MODERATE/WEAK)。
函数签名
generateSignal(
candles: Candle[], // K线数组(至少需要35根)
symbol: string, // 交易对(如 "BTCUSDT")
interval: TimeInterval, // 时间周期(如 "10m")
params?: IndicatorParams // 可选指标参数
) → TradingSignal | null
评分机制
常开指标评分表
| 指标 | 触发条件 | 分值 | 方向 |
|---|---|---|---|
| EWO | 上穿零轴(红→绿) | +2 | 多头 |
| EWO | 下穿零轴(绿→红) | +2 | 空头 |
| EWO | 在零轴上方(未穿越) | +1 | 多头 |
| EWO | 在零轴下方(未穿越) | +1 | 空头 |
| MACD | 金叉(MACD上穿信号线) | +2 | 多头 |
| MACD | 死叉(MACD下穿信号线) | +2 | 空头 |
| MACD柱 | 柱状图>0且扩大 | +1 | 多头 |
| MACD柱 | 柱状图<0且扩大 | +1 | 空头 |
| AO | 上穿零轴 | +1 | 多头 |
| AO | 下穿零轴 | +1 | 空头 |
| MA排列 | 价格>MA10>MA100 | +1 | 多头 |
| MA排列 | 价格<MA10<MA100 | +1 | 空头 |
常开指标最高可得分:多头最高 7 分(EWO穿越2 + MACD金叉2 + MACD柱1 + AO穿越1 + MA排列1)
可选指标评分表
| 指标 | 触发条件 | 分值 | 方向 | 开关 |
|---|---|---|---|---|
| RSI | RSI < 超卖线(默认30) | +1 | 多头 | signalUseRsi |
| RSI | RSI > 超买线(默认70) | +1 | 空头 | signalUseRsi |
| RSI | 从超卖区回升穿越30 | +1 | 多头 | signalUseRsi |
| RSI | 从超买区回落穿越70 | +1 | 空头 | signalUseRsi |
| KDJ | 低位金叉(K<30时K上穿D) | +2 | 多头 | signalUseKdj |
| KDJ | 普通金叉 | +1 | 多头 | signalUseKdj |
| KDJ | 高位死叉(K>70时K下穿D) | +2 | 空头 | signalUseKdj |
| KDJ | 普通死叉 | +1 | 空头 | signalUseKdj |
| Stoch | K<20且D<20 | +1 | 多头 | signalUseStoch |
| Stoch | K>80且D>80 | +1 | 空头 | signalUseStoch |
| 布林带 | 价格触及下轨 | +1 | 多头 | signalUseBollinger |
| 布林带 | 价格触及上轨 | +1 | 空头 | signalUseBollinger |
| SuperTrend | 方向由空转多 | +2 | 多头 | signalUseSuperTrend |
| SuperTrend | 多头趋势中 | +1 | 多头 | signalUseSuperTrend |
| SuperTrend | 方向由多转空 | +2 | 空头 | signalUseSuperTrend |
| SuperTrend | 空头趋势中 | +1 | 空头 | signalUseSuperTrend |
| DMI/ADX | ADX>25时+DI上穿-DI | +2 | 多头 | signalUseDmi |
| DMI/ADX | ADX>25时+DI>-DI | +1 | 多头 | signalUseDmi |
| DMI/ADX | ADX>25时-DI上穿+DI | +2 | 空头 | signalUseDmi |
| DMI/ADX | ADX>25时-DI>+DI | +1 | 空头 | signalUseDmi |
强度判定阈值(动态)
强度阈值根据已启用的可选指标数量动态调整,避免指标越多越容易触发强信号:
activeOptionalCount = 已启用的可选指标组数(0-6)
strongThreshold = 5 + floor(activeOptionalCount × 0.5)
moderateThreshold = 3 + floor(activeOptionalCount × 0.3)
| 启用可选指标数 | STRONG 阈值 | MODERATE 阈值 |
|---|---|---|
| 0(仅常开) | 5 分 | 3 分 |
| 2 个可选 | 6 分 | 3 分 |
| 4 个可选 | 7 分 | 4 分 |
| 6 个可选(全开) | 8 分 | 4 分 |
信号类型判定
if (bullishCount > bearishCount):
type = BUY
if bullishCount >= strongThreshold: strength = STRONG
elif bullishCount >= moderateThreshold: strength = MODERATE
else: strength = WEAK
elif (bearishCount > bullishCount):
type = SELL
(同上逻辑)
else:
return null(多空平衡,不产生信号)
输出结构(TradingSignal)
{
id: string, // nanoid 生成的唯一 ID
timestamp: number, // 信号时间戳(毫秒)
symbol: string, // 交易对
interval: TimeInterval, // K线周期
type: 'BUY' | 'SELL', // 信号方向
strength: 'STRONG' | 'MODERATE' | 'WEAK', // 信号强度
price: number, // 当前收盘价
indicators: { // 当前指标值快照
ma10, ma100, ewo, macd, macdSignal, macdHistogram, ao
},
reasons: string[], // 触发原因列表(中文)
isActive: boolean // 是否活跃
}
实际案例分析
案例:2026-03-06 BTC/10m EWO 红→绿
输入:
- EWO 前值:-29.048617(红色)
- EWO 当前:+33.320837(绿色)
- 假设 MACD 金叉、AO 上穿、MA 多头排列
评分计算:
EWO 穿越:+2(bullishCount)
MACD 金叉:+2
MACD 柱扩大:+1
AO 上穿:+1
MA 多头排列:+1
bullishCount = 7
强度判定(仅常开指标,strongThreshold=5):
7 >= 5 → STRONG(强信号)
案例:2026-03-06 SOL/10m EWO 红→绿
输入:
- EWO 前值:-0.037316(红色)
- EWO 当前:+0.006745(绿色)
- 穿越幅度极小(0.044061)
问题:当前系统对 BTC(穿越幅度62.37)和 SOL(穿越幅度0.044)给出相同的 +2 分,无法区分信号质量。
优化方案:→ EWO 阈值过滤完整流程
关键设计决策
为什么 EWO 穿越给 +2 而不是 +1?
EWO 是 tradehk 的核心指标,代表中短期动量的根本转变。穿越零轴意味着 EMA5 和 EMA35 的关系发生逆转,是趋势转换的重要信号,因此权重高于其他指标。
为什么动态阈值?
固定阈值在只开 2 个指标时太难触发,开 6 个指标时又太容易触发。动态阈值确保无论用户开了多少指标,信号质量保持一致。
为什么 ADX > 25 才计算 DMI?
ADX < 25 表示市场处于震荡状态,DMI 的 +DI/-DI 交叉在震荡市中产生大量假信号。只在强趋势(ADX > 25)时才使用 DMI,可以显著提高信号质量。