mirror of
https://github.com/NoFxAiOS/nofx.git
synced 2026-07-16 17:12:25 +08:00
feat: cream terminal redesign, English-only UI, autopilot launch fixes
- Redesign dashboard into a cream-paper + vermilion IBM Plex Mono terminal (live L2 order book, cost/liq map, WS K-line, signal matrix, orchestration topology, risk radar, execution log, current positions, equity curve) - Convert all user-facing UI and backend strings/prompts from Chinese to English (multi-language retained, default English) - Add /api/statistics/full endpoint + full-stats frontend wiring - Fix Autopilot launch: reuse the existing trader instead of creating duplicates (eliminates repeat ~35s create cost and stale-trader 404s); launch sends 5m scan interval - Fix unreadable toasts: cream theme with high-contrast text + per-type accent - Silence background dashboard polls (getTraderConfig) to stop error-toast spam
This commit is contained in:
57
trader/auto_trader_force_test.go
Normal file
57
trader/auto_trader_force_test.go
Normal file
@@ -0,0 +1,57 @@
|
||||
package trader
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"nofx/kernel"
|
||||
"nofx/store"
|
||||
)
|
||||
|
||||
func baseForceTrader() *AutoTrader {
|
||||
cfg := store.GetDefaultStrategyConfig("en")
|
||||
cfg.CoinSource.SourceType = "vergex_signal"
|
||||
cfg.RiskControl.MaxPositions = 5
|
||||
cfg.RiskControl.AltcoinMaxLeverage = 10
|
||||
cfg.RiskControl.AltcoinMaxPositionValueRatio = 10
|
||||
at := &AutoTrader{config: AutoTraderConfig{StrategyConfig: &cfg}}
|
||||
at.strategyEngine = kernel.NewStrategyEngine(&cfg) // empty ranking cache
|
||||
return at
|
||||
}
|
||||
|
||||
func TestEnsureLongShortCoverageSafeModeSkips(t *testing.T) {
|
||||
at := baseForceTrader()
|
||||
at.safeMode = true
|
||||
out := at.ensureLongShortCoverage(nil, &kernel.Context{}, 100)
|
||||
if len(out) != 0 {
|
||||
t.Fatalf("safe mode must not force opens, got %d", len(out))
|
||||
}
|
||||
}
|
||||
|
||||
func TestEnsureLongShortCoverageNonVergexSkips(t *testing.T) {
|
||||
at := baseForceTrader()
|
||||
at.config.StrategyConfig.CoinSource.SourceType = "static"
|
||||
out := at.ensureLongShortCoverage(nil, &kernel.Context{}, 100)
|
||||
if len(out) != 0 {
|
||||
t.Fatalf("non-vergex source must not force opens, got %d", len(out))
|
||||
}
|
||||
}
|
||||
|
||||
func TestEnsureLongShortCoverageBothPresentNoop(t *testing.T) {
|
||||
at := baseForceTrader()
|
||||
in := []kernel.Decision{
|
||||
{Action: "open_long", Symbol: "xyz:AAPL"},
|
||||
{Action: "open_short", Symbol: "BTC"},
|
||||
}
|
||||
out := at.ensureLongShortCoverage(in, &kernel.Context{}, 100)
|
||||
if len(out) != 2 {
|
||||
t.Fatalf("both directions already present -> no force, got %d", len(out))
|
||||
}
|
||||
}
|
||||
|
||||
func TestEnsureLongShortCoverageNoCandidatesNoForce(t *testing.T) {
|
||||
at := baseForceTrader() // empty ranking cache -> no directional candidates
|
||||
out := at.ensureLongShortCoverage(nil, &kernel.Context{}, 100)
|
||||
if len(out) != 0 {
|
||||
t.Fatalf("no candidates available -> nothing to force, got %d", len(out))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user