feat: 添加OKX行情接入+趋势检测+累积变动系统+界面重构
- 新增OKX WebSocket行情连接器,扩展4交易所价格监控 - 新增z-score趋势检测引擎(TrendDetector),识别价格异动/趋势启动 - 新增累积变动跟踪(CumulativeTracker),基于1min/5min多交易所共识 - 趋势事件和累积变动事件持久化到SQLite - 新增Binance/OKX动量检测字段,扩展前端动量卡片至15列 - 迁移至macOS(darwin-arm64),更新前端依赖 - Dashboard网格重构:非交易卡片置顶,交易卡片置底 - TrackedCoin添加OK字段,添加ExBinance/ExOKX常量 - 前端新增趋势检测卡片、趋势历史卡片、累积变动卡片 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
047571921e
commit
b7767c95ae
@@ -52,6 +52,17 @@ type Config struct {
|
||||
// Entry sanity check: reject if price moved beyond this % in the wrong direction
|
||||
ReversalTolerancePct float64
|
||||
|
||||
// Momentum scanning mode
|
||||
MomentumEnabled bool
|
||||
MomentumThresholdPct float64
|
||||
|
||||
// Trend detection mode
|
||||
TrendEnabled bool
|
||||
TrendBaselineWindow int // ticks for EMA volatility baseline (default: 600 = 30s)
|
||||
TrendAnomalyMul float64 // z-score multiplier for alert threshold (default: 3.0)
|
||||
TrendConfirmTicks int // ticks needed for state confirmation (default: 3)
|
||||
TrendAlertCooldown int64 // ms cooldown between alerts for same coin (default: 60000)
|
||||
|
||||
// Bitget API
|
||||
BitgetAPIKey string
|
||||
BitgetAPISecret string
|
||||
@@ -79,6 +90,17 @@ type jsonConfig struct {
|
||||
InitialCapital float64 `json:"initial_capital"`
|
||||
ExcludedCoins []string `json:"excluded_coins"`
|
||||
|
||||
// Momentum scanning
|
||||
MomentumEnabled bool `json:"momentum_enabled"`
|
||||
MomentumThresholdPct float64 `json:"momentum_threshold_pct"`
|
||||
|
||||
// Trend detection
|
||||
TrendEnabled bool `json:"trend_enabled"`
|
||||
TrendBaselineWindow int `json:"trend_baseline_window"`
|
||||
TrendAnomalyMul float64 `json:"trend_anomaly_mul"`
|
||||
TrendConfirmTicks int `json:"trend_confirm_ticks"`
|
||||
TrendAlertCooldown int64 `json:"trend_alert_cooldown_ms"`
|
||||
|
||||
// New: exchange fees
|
||||
TakerFeeBitget float64 `json:"taker_fee_bitget"`
|
||||
TakerFeeHyperLiquid float64 `json:"taker_fee_hyperliquid"`
|
||||
@@ -158,6 +180,17 @@ func LoadConfig() *Config {
|
||||
|
||||
ExcludedCoins: jsonCfg.ExcludedCoins,
|
||||
|
||||
// Momentum scanning
|
||||
MomentumEnabled: getBool("MOMENTUM_ENABLED", jsonCfg.MomentumEnabled),
|
||||
MomentumThresholdPct: getFloat("MOMENTUM_THRESHOLD_PCT", jsonCfg.MomentumThresholdPct),
|
||||
|
||||
// Trend detection
|
||||
TrendEnabled: getBool("TREND_ENABLED", jsonCfg.TrendEnabled),
|
||||
TrendBaselineWindow: int(getFloat("TREND_BASELINE_WINDOW", float64(jsonCfg.TrendBaselineWindow))),
|
||||
TrendAnomalyMul: getFloat("TREND_ANOMALY_MUL", jsonCfg.TrendAnomalyMul),
|
||||
TrendConfirmTicks: int(getFloat("TREND_CONFIRM_TICKS", float64(jsonCfg.TrendConfirmTicks))),
|
||||
TrendAlertCooldown: int64(getFloat("TREND_ALERT_COOLDOWN_MS", float64(jsonCfg.TrendAlertCooldown))),
|
||||
|
||||
BitgetAPIKey: getEnv("BITGET_API_KEY", ""),
|
||||
BitgetAPISecret: getEnv("BITGET_API_SECRET", ""),
|
||||
BitgetPassphrase: getEnv("BITGET_PASSPHRASE", ""),
|
||||
@@ -194,6 +227,15 @@ func loadJSONConfig() jsonConfig {
|
||||
// Scale-in parameters
|
||||
ScaleStepPct: 0.10, // 0.10% spread widening per scale level
|
||||
ScaleCooldownSec: 5, // 5 seconds between scales
|
||||
|
||||
// Momentum scanning
|
||||
MomentumThresholdPct: 0.25, // 0.25% change flags momentum
|
||||
|
||||
// Trend detection
|
||||
TrendBaselineWindow: 600, // ~30s at 50ms tick
|
||||
TrendAnomalyMul: 3.0, // 3 sigma z-score threshold
|
||||
TrendConfirmTicks: 3, // 3 consecutive ticks for confirmation
|
||||
TrendAlertCooldown: 60000, // 1 min cooldown
|
||||
}
|
||||
|
||||
data, err := os.ReadFile("config.json")
|
||||
@@ -267,11 +309,31 @@ func loadJSONConfig() jsonConfig {
|
||||
def.ExcludedCoins = cfg.ExcludedCoins
|
||||
}
|
||||
|
||||
if cfg.MomentumThresholdPct != 0 {
|
||||
def.MomentumThresholdPct = cfg.MomentumThresholdPct
|
||||
}
|
||||
|
||||
// Trend detection JSON overrides
|
||||
if cfg.TrendBaselineWindow != 0 {
|
||||
def.TrendBaselineWindow = cfg.TrendBaselineWindow
|
||||
}
|
||||
if cfg.TrendAnomalyMul != 0 {
|
||||
def.TrendAnomalyMul = cfg.TrendAnomalyMul
|
||||
}
|
||||
if cfg.TrendConfirmTicks != 0 {
|
||||
def.TrendConfirmTicks = cfg.TrendConfirmTicks
|
||||
}
|
||||
if cfg.TrendAlertCooldown != 0 {
|
||||
def.TrendAlertCooldown = cfg.TrendAlertCooldown
|
||||
}
|
||||
|
||||
// Boolean fields: zero default is false, so use OR logic
|
||||
// When JSON has true → true || false = true (override)
|
||||
// When JSON has false → false || false = false (keep default)
|
||||
def.TestMode = cfg.TestMode || def.TestMode
|
||||
def.TradeEnabled = cfg.TradeEnabled || def.TradeEnabled
|
||||
def.MomentumEnabled = cfg.MomentumEnabled || def.MomentumEnabled
|
||||
def.TrendEnabled = cfg.TrendEnabled || def.TrendEnabled
|
||||
|
||||
return def
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user