feat: 重构为三所价差异动监控系统

删除 HyperLiquid + 全部交易功能,构建自适应 surge 检测器。
- 新增 surge_detector.go: 每币独立滚动窗口基线,检测三所价差异常飙升
- 新增 SpreadCard/SurgeCard 前端组件
- 保留 momentum/trend/cumulative/trend_filter 扫描功能
- 更新文档和配置以反映新系统

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
jackyu66git
2026-05-08 02:01:18 +08:00
co-authored by Claude Opus 4.6
parent 559d7bb870
commit d38782490c
36 changed files with 1201 additions and 6374 deletions
+11 -14
View File
@@ -199,14 +199,11 @@ func (td *TrendDetector) Tick() {
defer td.mu.Unlock()
for _, entry := range entries {
// Collect 60s changes from all 4 exchanges
// Collect 60s changes from all 3 exchanges
var changes []exchangeChange
if entry.BG60s != 0 {
changes = append(changes, exchangeChange{name: ExBitget, change: entry.BG60s})
}
if entry.HL60s != 0 {
changes = append(changes, exchangeChange{name: ExHyperLiquid, change: entry.HL60s})
}
if entry.BN60s != 0 {
changes = append(changes, exchangeChange{name: ExBinance, change: entry.BN60s})
}
@@ -214,8 +211,8 @@ func (td *TrendDetector) Tick() {
changes = append(changes, exchangeChange{name: ExOKX, change: entry.OKX60s})
}
if len(changes) < 3 {
continue // need at least 3 exchanges for reliable detection
if len(changes) < 2 {
continue // need at least 2 exchanges for reliable detection
}
// Compute aggregate stats
@@ -287,7 +284,7 @@ func (td *TrendDetector) Tick() {
cs.confirmCount = 1
cs.misalignCount = 0
td.recordEvent(entry.Coin, "idle", "alert", string(majorityDir),
zScore, cs.volatility, entry.BG60s, entry.HL60s, entry.BN60s, entry.OKX60s,
zScore, cs.volatility, entry.BG60s, 0, entry.BN60s, entry.OKX60s,
majorityCount, len(changes))
}
@@ -301,7 +298,7 @@ func (td *TrendDetector) Tick() {
cs.confirmedAt = now
cs.stateSince = now
td.recordEvent(entry.Coin, "alert", "confirmed", string(cs.direction),
zScore, cs.volatility, entry.BG60s, entry.HL60s, entry.BN60s, entry.OKX60s,
zScore, cs.volatility, entry.BG60s, 0, entry.BN60s, entry.OKX60s,
majorityCount, len(changes))
}
} else {
@@ -313,7 +310,7 @@ func (td *TrendDetector) Tick() {
cs.confirmCount = 0
cs.misalignCount = 0
td.recordEvent(entry.Coin, "alert", "idle", string(cs.direction),
zScore, cs.volatility, entry.BG60s, entry.HL60s, entry.BN60s, entry.OKX60s,
zScore, cs.volatility, entry.BG60s, 0, entry.BN60s, entry.OKX60s,
majorityCount, len(changes))
}
}
@@ -325,7 +322,7 @@ func (td *TrendDetector) Tick() {
cs.state = TrendExhausting
cs.stateSince = now
td.recordEvent(entry.Coin, "confirmed", "exhausting", string(cs.direction),
zScore, cs.volatility, entry.BG60s, entry.HL60s, entry.BN60s, entry.OKX60s,
zScore, cs.volatility, entry.BG60s, 0, entry.BN60s, entry.OKX60s,
majorityCount, len(changes))
}
@@ -337,7 +334,7 @@ func (td *TrendDetector) Tick() {
cs.confirmCount = 0
cs.misalignCount = 0
td.recordEvent(entry.Coin, "exhausting", "idle", string(cs.direction),
zScore, cs.volatility, entry.BG60s, entry.HL60s, entry.BN60s, entry.OKX60s,
zScore, cs.volatility, entry.BG60s, 0, entry.BN60s, entry.OKX60s,
majorityCount, len(changes))
}
// Also immediately go to idle if below threshold
@@ -347,7 +344,7 @@ func (td *TrendDetector) Tick() {
cs.confirmCount = 0
cs.misalignCount = 0
td.recordEvent(entry.Coin, "exhausting", "idle", string(cs.direction),
zScore, cs.volatility, entry.BG60s, entry.HL60s, entry.BN60s, entry.OKX60s,
zScore, cs.volatility, entry.BG60s, 0, entry.BN60s, entry.OKX60s,
majorityCount, len(changes))
}
}
@@ -391,13 +388,13 @@ func (td *TrendDetector) Snapshot() []TrendEntry {
if me, ok := entryMap[coin]; ok {
entry.BGChange = me.BG15s
entry.HLChange = me.HL15s
entry.HLChange = 0
entry.BNChange = me.BN15s
entry.OKXChange = me.OKX15s
// Count how many exchanges agree with the trend direction
agree := 0
changes := []float64{entry.BGChange, entry.HLChange, entry.BNChange, entry.OKXChange}
changes := []float64{entry.BGChange, entry.BNChange, entry.OKXChange}
for _, c := range changes {
if cs.direction == TrendUp && c > 0.001 {
agree++