dev 2
This commit is contained in:
114
go-client/apps/zt/logic/config.go
Normal file
114
go-client/apps/zt/logic/config.go
Normal file
@@ -0,0 +1,114 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
QMTBaseURL string
|
||||
QMTToken string
|
||||
AccountType string
|
||||
AccountID string
|
||||
HostKey string
|
||||
APIHost string
|
||||
DataDir string
|
||||
HTTPTimeout time.Duration
|
||||
OrderTimeout time.Duration
|
||||
LoopInterval time.Duration
|
||||
OpenMoney float64
|
||||
MinCashRatio float64
|
||||
LossTriggerPct float64
|
||||
GridStepPct float64
|
||||
MinProfitPct float64
|
||||
AdoptExisting bool
|
||||
ReadyCacheStart int
|
||||
WatchTimeout time.Duration
|
||||
ReboundThreshold float64
|
||||
}
|
||||
|
||||
func LoadConfig() Config {
|
||||
cfg := Config{
|
||||
QMTBaseURL: env("QMT_BASE_URL", "http://127.0.0.1:10086"),
|
||||
QMTToken: env("QMT_TOKEN", "QMTbyYanweidong"),
|
||||
AccountType: env("QMT_ACCOUNT", "stock"),
|
||||
AccountID: env("ACCOUNT_ID", ""),
|
||||
HostKey: env("HOST_KEY", ""),
|
||||
APIHost: strings.TrimRight(env("API_HOST", "http://go.apinb.com"), "/"),
|
||||
DataDir: env("DATA_DIR", "D:/qmt_strategy_state"),
|
||||
HTTPTimeout: durationEnv("HTTP_TIMEOUT_SEC", 5) * time.Second,
|
||||
OrderTimeout: durationEnv("ORDER_TIMEOUT_SEC", 60) * time.Second,
|
||||
LoopInterval: durationEnv("LOOP_INTERVAL_SEC", 30) * time.Second,
|
||||
OpenMoney: floatEnv("OPEN_MONEY", 5000),
|
||||
MinCashRatio: floatEnv("MIN_CASH_RATIO", 0.1),
|
||||
LossTriggerPct: floatEnv("LOSS_TRIGGER_PCT", -30),
|
||||
GridStepPct: floatEnv("GRID_STEP_PCT", 1),
|
||||
MinProfitPct: floatEnv("MIN_PROFIT_PCT", 2),
|
||||
AdoptExisting: boolEnv("ADOPT_EXISTING_POSITIONS", true),
|
||||
ReadyCacheStart: intEnv("READY_CACHE_START", 925),
|
||||
WatchTimeout: durationEnv("WATCH_TIMEOUT_SEC", 300) * time.Second,
|
||||
ReboundThreshold: floatEnv("REBOUND_THRESHOLD", 0.61),
|
||||
}
|
||||
if strings.TrimSpace(cfg.AccountID) == "" {
|
||||
logf("ERROR", "ACCOUNT_ID 为空")
|
||||
os.Exit(1)
|
||||
}
|
||||
if cfg.MinCashRatio < 0 || cfg.MinCashRatio >= 1 {
|
||||
logf("ERROR", "MIN_CASH_RATIO 必须在 [0, 1)")
|
||||
os.Exit(1)
|
||||
}
|
||||
if cfg.OpenMoney <= 0 {
|
||||
logf("ERROR", "OPEN_MONEY 必须大于 0")
|
||||
os.Exit(1)
|
||||
}
|
||||
if err := os.MkdirAll(cfg.DataDir, 0o755); err != nil {
|
||||
logf("ERROR", "创建 DATA_DIR 失败: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
return cfg
|
||||
}
|
||||
|
||||
func env(key, fallback string) string {
|
||||
if v := strings.TrimSpace(os.Getenv(key)); v != "" {
|
||||
return v
|
||||
}
|
||||
return fallback
|
||||
}
|
||||
|
||||
func intEnv(key string, fallback int) int {
|
||||
v := strings.TrimSpace(os.Getenv(key))
|
||||
if v == "" {
|
||||
return fallback
|
||||
}
|
||||
n, err := strconv.Atoi(v)
|
||||
if err != nil {
|
||||
return fallback
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func floatEnv(key string, fallback float64) float64 {
|
||||
v := strings.TrimSpace(os.Getenv(key))
|
||||
if v == "" {
|
||||
return fallback
|
||||
}
|
||||
f, err := strconv.ParseFloat(v, 64)
|
||||
if err != nil {
|
||||
return fallback
|
||||
}
|
||||
return f
|
||||
}
|
||||
|
||||
func durationEnv(key string, fallbackSec int) time.Duration {
|
||||
return time.Duration(intEnv(key, fallbackSec))
|
||||
}
|
||||
|
||||
func boolEnv(key string, fallback bool) bool {
|
||||
v := strings.ToLower(strings.TrimSpace(os.Getenv(key)))
|
||||
if v == "" {
|
||||
return fallback
|
||||
}
|
||||
return v == "1" || v == "true" || v == "yes"
|
||||
}
|
||||
Reference in New Issue
Block a user