mirror of
https://github.com/NoFxAiOS/nofx.git
synced 2026-07-06 20:41:14 +08:00
- 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
58 lines
1.7 KiB
Go
58 lines
1.7 KiB
Go
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))
|
|
}
|
|
}
|