mirror of
https://github.com/NoFxAiOS/nofx.git
synced 2026-07-05 20:11:13 +08:00
- Remove system_config, beta_codes, signal_source tables and related code - Simplify config.go to only read from .env (APIServerPort, JWTSecret, RegistrationEnabled) - Remove GetCustomCoins, use all USDT perpetual contracts for WSMonitor - Add trader_equity_snapshots table for equity tracking - Remove signal source modal from frontend AITradersPage - Fix WSMonitor nil panic by restoring initialization in main.go
158 lines
4.3 KiB
Go
158 lines
4.3 KiB
Go
package main
|
||
|
||
import (
|
||
"nofx/api"
|
||
"nofx/auth"
|
||
"nofx/backtest"
|
||
"nofx/config"
|
||
"nofx/crypto"
|
||
"nofx/logger"
|
||
"nofx/manager"
|
||
"nofx/market"
|
||
"nofx/mcp"
|
||
"nofx/store"
|
||
"os"
|
||
"os/signal"
|
||
"syscall"
|
||
|
||
"github.com/joho/godotenv"
|
||
)
|
||
|
||
func main() {
|
||
// 加载 .env 环境变量
|
||
_ = godotenv.Load()
|
||
|
||
// 初始化日志
|
||
logger.Init(nil)
|
||
|
||
logger.Info("╔════════════════════════════════════════════════════════════╗")
|
||
logger.Info("║ 🤖 AI多模型交易系统 - 支持 DeepSeek & Qwen ║")
|
||
logger.Info("╚════════════════════════════════════════════════════════════╝")
|
||
|
||
// 初始化全局配置(从 .env 加载)
|
||
config.Init()
|
||
cfg := config.Get()
|
||
logger.Info("✅ 配置加载完成")
|
||
|
||
// 初始化数据库
|
||
dbPath := "data.db"
|
||
if len(os.Args) > 1 {
|
||
dbPath = os.Args[1]
|
||
}
|
||
|
||
logger.Infof("📋 初始化数据库: %s", dbPath)
|
||
st, err := store.New(dbPath)
|
||
if err != nil {
|
||
logger.Fatalf("❌ 初始化数据库失败: %v", err)
|
||
}
|
||
defer st.Close()
|
||
backtest.UseDatabase(st.DB())
|
||
|
||
// 初始化加密服务
|
||
logger.Info("🔐 初始化加密服务...")
|
||
cryptoService, err := crypto.NewCryptoService()
|
||
if err != nil {
|
||
logger.Fatalf("❌ 初始化加密服务失败: %v", err)
|
||
}
|
||
encryptFunc := func(plaintext string) string {
|
||
if plaintext == "" {
|
||
return plaintext
|
||
}
|
||
encrypted, err := cryptoService.EncryptForStorage(plaintext)
|
||
if err != nil {
|
||
logger.Warnf("⚠️ 加密失败: %v", err)
|
||
return plaintext
|
||
}
|
||
return encrypted
|
||
}
|
||
decryptFunc := func(encrypted string) string {
|
||
if encrypted == "" {
|
||
return encrypted
|
||
}
|
||
if !cryptoService.IsEncryptedStorageValue(encrypted) {
|
||
return encrypted
|
||
}
|
||
decrypted, err := cryptoService.DecryptFromStorage(encrypted)
|
||
if err != nil {
|
||
logger.Warnf("⚠️ 解密失败: %v", err)
|
||
return encrypted
|
||
}
|
||
return decrypted
|
||
}
|
||
st.SetCryptoFuncs(encryptFunc, decryptFunc)
|
||
logger.Info("✅ 加密服务初始化成功")
|
||
|
||
// 设置 JWT 密钥
|
||
auth.SetJWTSecret(cfg.JWTSecret)
|
||
logger.Info("🔑 JWT 密钥已设置")
|
||
|
||
// 创建 TraderManager 与 BacktestManager
|
||
traderManager := manager.NewTraderManager()
|
||
mcpClient := newSharedMCPClient()
|
||
backtestManager := backtest.NewManager(mcpClient)
|
||
if err := backtestManager.RestoreRuns(); err != nil {
|
||
logger.Warnf("⚠️ 恢复历史回测失败: %v", err)
|
||
}
|
||
|
||
// 从数据库加载所有交易员到内存
|
||
if err := traderManager.LoadTradersFromStore(st); err != nil {
|
||
logger.Fatalf("❌ 加载交易员失败: %v", err)
|
||
}
|
||
|
||
// 显示加载的交易员信息
|
||
traders, err := st.Trader().List("default")
|
||
if err != nil {
|
||
logger.Fatalf("❌ 获取交易员列表失败: %v", err)
|
||
}
|
||
|
||
logger.Info("🤖 数据库中的AI交易员配置:")
|
||
if len(traders) == 0 {
|
||
logger.Info(" (无交易员配置,请通过Web管理界面创建)")
|
||
} else {
|
||
for _, t := range traders {
|
||
status := "❌ 已停止"
|
||
if t.IsRunning {
|
||
status = "✅ 运行中"
|
||
}
|
||
logger.Infof(" • %s [%s] %s - AI模型: %s, 交易所: %s",
|
||
t.Name, t.ID[:8], status, t.AIModelID, t.ExchangeID)
|
||
}
|
||
}
|
||
|
||
// 启动 WebSocket 行情监控(获取所有 USDT 永续合约的行情数据)
|
||
go market.NewWSMonitor(150).Start(nil)
|
||
logger.Info("📊 WebSocket 行情监控已启动")
|
||
|
||
// 启动API服务器
|
||
server := api.NewServer(traderManager, st, cryptoService, backtestManager, cfg.APIServerPort)
|
||
go func() {
|
||
if err := server.Start(); err != nil {
|
||
logger.Fatalf("❌ API服务器启动失败: %v", err)
|
||
}
|
||
}()
|
||
|
||
// 等待中断信号
|
||
quit := make(chan os.Signal, 1)
|
||
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
|
||
|
||
logger.Info("✅ 系统启动完成,等待交易指令...")
|
||
logger.Info("📌 提示: 使用 Ctrl+C 停止系统")
|
||
|
||
<-quit
|
||
logger.Info("📴 收到停止信号,正在关闭系统...")
|
||
|
||
// 停止所有交易员
|
||
traderManager.StopAll()
|
||
logger.Info("✅ 系统已安全关闭")
|
||
}
|
||
|
||
// newSharedMCPClient 创建共享的 MCP AI 客户端(用于回测)
|
||
func newSharedMCPClient() mcp.AIClient {
|
||
apiKey := os.Getenv("DEEPSEEK_API_KEY")
|
||
if apiKey == "" {
|
||
logger.Warn("⚠️ DEEPSEEK_API_KEY 未设置,AI 功能将不可用")
|
||
return nil
|
||
}
|
||
return mcp.NewDeepSeekClient()
|
||
}
|