package config import ( "fmt" "os" "path/filepath" "strings" "time" "gopkg.in/yaml.v3" ) var ( Global *GlobalConfig Account *AccountConfig HttpTimeOut time.Duration = 5 * time.Second ) type GlobalConfig struct { QMTBaseURL string `yaml:"qmt_base_url"` QMTToken string `yaml:"qmt_token"` APIHost string `yaml:"api_host"` QMTDataDir string `yaml:"qmt_data_dir"` Hosts map[string]string `yaml:"hosts"` } type AccountConfig struct { AccountID string `yaml:"account_id"` HostKey string `yaml:"host_key"` OrderTimeoutSec int `yaml:"order_timeout_seconds"` BuyValue float64 `yaml:"buy_value"` MinCashRatio float64 `yaml:"min_cash_ratio"` LossTriggerPct float64 `yaml:"loss_trigger_pct"` GridStepPct float64 `yaml:"grid_step_pct"` MinProfitPct float64 `yaml:"min_profit_pct"` WatchTimeoutSec int `yaml:"watch_timeout_seconds"` ReboundThreshold float64 `yaml:"rebound_threshold"` } // Load 根据 global.yaml 中的 hosts 映射加载当前计算机的账户配置。 func Load(etcDir string) error { var global GlobalConfig if err := readYAML(filepath.Join(etcDir, "global.yaml"), &global); err != nil { return err } hostname, err := os.Hostname() if err != nil { return fmt.Errorf("读取计算机名失败: %w", err) } if global.QMTBaseURL == "" || global.APIHost == "" || global.QMTDataDir == "." { return fmt.Errorf("Global 配置缺少必要参数") } if err := os.MkdirAll(global.QMTDataDir, 0o755); err != nil { return fmt.Errorf("创建目录 %s 失败: %w", global.QMTDataDir, err) } accountFile := hostAccountFile(global.Hosts, hostname) if accountFile == "" { return fmt.Errorf("global.yaml 未配置计算机 %q", hostname) } if filepath.Ext(accountFile) == "" { accountFile += ".yaml" } var account AccountConfig if err := readYAML(filepath.Join(etcDir, accountFile), &account); err != nil { return err } if account.BuyValue <= 0 || account.GridStepPct <= 0 { return fmt.Errorf("buy_value、grid_step_pct 和超时时间必须大于 0") } Global = &global Account = &account return nil } func readYAML(path string, dest any) error { raw, err := os.ReadFile(path) if err != nil { return fmt.Errorf("读取配置 %s 失败: %w", path, err) } if err := yaml.Unmarshal(raw, dest); err != nil { return fmt.Errorf("解析配置 %s 失败: %w", path, err) } return nil } func hostAccountFile(hosts map[string]string, hostname string) string { for host, file := range hosts { if strings.EqualFold(strings.TrimSpace(host), strings.TrimSpace(hostname)) { return strings.TrimSpace(file) } } return "" }