Files
nofx/config/config.go
T
tinkle-community 5aa50d35d7 Initial commit: NOFX AI Trading System
- Multi-AI competition mode (Qwen vs DeepSeek)
- Binance Futures integration
- AI self-learning mechanism
- Professional web dashboard
- Complete risk management system
2025-10-28 15:47:34 +08:00

104 lines
3.0 KiB
Go

package config
import (
"encoding/json"
"fmt"
"os"
"time"
)
// TraderConfig 单个trader的配置
type TraderConfig struct {
ID string `json:"id"`
Name string `json:"name"`
AIModel string `json:"ai_model"` // "qwen" or "deepseek"
BinanceAPIKey string `json:"binance_api_key"`
BinanceSecretKey string `json:"binance_secret_key"`
QwenKey string `json:"qwen_key,omitempty"`
DeepSeekKey string `json:"deepseek_key,omitempty"`
InitialBalance float64 `json:"initial_balance"`
ScanIntervalMinutes int `json:"scan_interval_minutes"`
}
// Config 总配置
type Config struct {
Traders []TraderConfig `json:"traders"`
CoinPoolAPIURL string `json:"coin_pool_api_url"`
OITopAPIURL string `json:"oi_top_api_url"`
APIServerPort int `json:"api_server_port"`
MaxDailyLoss float64 `json:"max_daily_loss"`
MaxDrawdown float64 `json:"max_drawdown"`
StopTradingMinutes int `json:"stop_trading_minutes"`
}
// LoadConfig 从文件加载配置
func LoadConfig(filename string) (*Config, error) {
data, err := os.ReadFile(filename)
if err != nil {
return nil, fmt.Errorf("读取配置文件失败: %w", err)
}
var config Config
if err := json.Unmarshal(data, &config); err != nil {
return nil, fmt.Errorf("解析配置文件失败: %w", err)
}
// 验证配置
if err := config.Validate(); err != nil {
return nil, fmt.Errorf("配置验证失败: %w", err)
}
return &config, nil
}
// Validate 验证配置有效性
func (c *Config) Validate() error {
if len(c.Traders) == 0 {
return fmt.Errorf("至少需要配置一个trader")
}
traderIDs := make(map[string]bool)
for i, trader := range c.Traders {
if trader.ID == "" {
return fmt.Errorf("trader[%d]: ID不能为空", i)
}
if traderIDs[trader.ID] {
return fmt.Errorf("trader[%d]: ID '%s' 重复", i, trader.ID)
}
traderIDs[trader.ID] = true
if trader.Name == "" {
return fmt.Errorf("trader[%d]: Name不能为空", i)
}
if trader.AIModel != "qwen" && trader.AIModel != "deepseek" {
return fmt.Errorf("trader[%d]: ai_model必须是 'qwen' 或 'deepseek'", i)
}
if trader.BinanceAPIKey == "" || trader.BinanceSecretKey == "" {
return fmt.Errorf("trader[%d]: 币安API密钥不能为空", i)
}
if trader.AIModel == "qwen" && trader.QwenKey == "" {
return fmt.Errorf("trader[%d]: 使用Qwen时必须配置qwen_key", i)
}
if trader.AIModel == "deepseek" && trader.DeepSeekKey == "" {
return fmt.Errorf("trader[%d]: 使用DeepSeek时必须配置deepseek_key", i)
}
if trader.InitialBalance <= 0 {
return fmt.Errorf("trader[%d]: initial_balance必须大于0", i)
}
if trader.ScanIntervalMinutes <= 0 {
trader.ScanIntervalMinutes = 3 // 默认3分钟
}
}
if c.APIServerPort <= 0 {
c.APIServerPort = 8080 // 默认8080端口
}
return nil
}
// GetScanInterval 获取扫描间隔
func (tc *TraderConfig) GetScanInterval() time.Duration {
return time.Duration(tc.ScanIntervalMinutes) * time.Minute
}