Merge pull request #114 from Icyoung/dev

[Dev] 还原config配置、部署优化
This commit is contained in:
tinkle-community
2025-10-31 15:50:23 +08:00
committed by GitHub
9 changed files with 208 additions and 37 deletions

View File

@@ -10,9 +10,9 @@
## 配置方式 ## 配置方式
~~在 `config.json` 中添加使用自定义 API 的 trader~~ `config.json` 中添加使用自定义 API 的 trader~~已弃用~~
*注意现在通过Web界面配置自定义API不再使用config.json文件* *注意现在通过Web界面配置自定义API和交易员config.json仅保留基础设置*
```json ```json
{ {

View File

@@ -49,13 +49,13 @@ docker compose --version # Docker 24+ includes this, no separate installation n
### Step 1: Prepare Configuration File ### Step 1: Prepare Configuration File
```bash ```bash
# ~~Copy configuration template~~ # Copy configuration template
# ~~cp config.example.jsonc config.json~~ cp config.example.jsonc config.json
# ~~Edit configuration file with your API keys~~ # Edit configuration file with your API keys
# ~~nano config.json # or use any other editor~~ nano config.json # or use any other editor
⚠️ **Note**: Configuration is now done through the web interface, no longer using JSON files. ⚠️ **Note**: Basic config.json is still needed for some settings, but ~~trader configurations~~ are now done through the web interface.
``` ```
**Required fields:** **Required fields:**

View File

@@ -156,7 +156,7 @@ A Binance-compatible decentralized perpetual futures exchange!
``` ```
nofx/ nofx/
├── main.go # Program entry (multi-trader manager) ├── main.go # Program entry (multi-trader manager)
├── ~~config.json~~ # ~~Configuration file (API keys, multi-trader config)~~ (Deprecated: Use web interface) ├── config.json # Configuration file (API keys, ~~multi-trader config~~) (Trader config via web interface)
├── api/ # HTTP API service ├── api/ # HTTP API service
│ └── server.go # Gin framework, RESTful API │ └── server.go # Gin framework, RESTful API
@@ -251,15 +251,16 @@ Before using this system, you need a Binance Futures account. **Use our referral
Docker automatically handles all dependencies (Go, Node.js, TA-Lib, SQLite) and environment setup. Docker automatically handles all dependencies (Go, Node.js, TA-Lib, SQLite) and environment setup.
#### ~~Step 1: Prepare Configuration~~ (Deprecated) #### Step 1: Prepare Configuration
```bash ```bash
# ~~Copy configuration template~~ # Copy configuration template
# ~~cp config.example.jsonc config.json~~ cp config.example.jsonc config.json
# ~~Edit and fill in your API keys~~ # Edit and fill in your API keys
# ~~nano config.json # or use any editor~~ nano config.json # or use any editor
``` ```
**Note**: Configuration is now done through the web interface, not JSON files.
**Note**: Basic config.json is still needed for some settings, but ~~trader configurations~~ are now done through the web interface.
#### Step 2: One-Click Start #### Step 2: One-Click Start
```bash ```bash

View File

@@ -150,7 +150,7 @@ NOFX现已支持**三大交易所**Binance、Hyperliquid和Aster DEX
``` ```
nofx/ nofx/
├── main.go # 程序入口多trader管理器 ├── main.go # 程序入口多trader管理器
├── ~~config.json~~ # ~~配置文件API密钥、多trader配置~~ (已弃用:使用Web界面) ├── config.json # 配置文件API密钥、~~多trader配置~~(交易员配置通过Web界面)
├── api/ # HTTP API服务 ├── api/ # HTTP API服务
│ └── server.go # Gin框架RESTful API │ └── server.go # Gin框架RESTful API
@@ -245,15 +245,16 @@ nofx/
Docker会自动处理所有依赖GoNode.jsTA-Lib和环境配置完美适合新手 Docker会自动处理所有依赖GoNode.jsTA-Lib和环境配置完美适合新手
#### ~~步骤1准备配置文件~~ (已弃用) #### 步骤1准备配置文件
```bash ```bash
# ~~复制配置文件模板~~ # 复制配置文件模板
# ~~cp config.example.jsonc config.json~~ cp config.example.jsonc config.json
# ~~编辑并填入你的API密钥~~ # 编辑并填入你的API密钥
# ~~nano config.json # 或使用其他编辑器~~ nano config.json # 或使用其他编辑器
``` ```
**注意**: 现在通过Web界面进行配置不再使用JSON文件
**注意**: 基础config.json仍需要一些设置~~交易员配置~~现在通过Web界面进行
#### 步骤2一键启动 #### 步骤2一键启动
```bash ```bash

25
config.json.example Normal file
View File

@@ -0,0 +1,25 @@
{
"admin_mode": true,
"leverage": {
"btc_eth_leverage": 5,
"altcoin_leverage": 5
},
"use_default_coins": true,
"default_coins": [
"BTCUSDT",
"ETHUSDT",
"SOLUSDT",
"BNBUSDT",
"XRPUSDT",
"DOGEUSDT",
"ADAUSDT",
"HYPEUSDT"
],
"coin_pool_api_url": "",
"oi_top_api_url": "",
"api_server_port": 8080,
"max_daily_loss": 10.0,
"max_drawdown": 20.0,
"stop_trading_minutes": 60,
"jwt_secret": "Qk0kAa+d0iIEzXVHXbNbm+UaN3RNabmWtH8rDWZ5OPf+4GX8pBflAHodfpbipVMyrw1fsDanHsNBjhgbDeK9Jg=="
}

View File

@@ -209,15 +209,20 @@ func (d *Database) initDefaultData() error {
} }
} }
// 初始化系统配置 // 初始化系统配置 - 创建所有字段设置默认值后续由config.json同步更新
systemConfigs := map[string]string{ systemConfigs := map[string]string{
"api_server_port": "8080", "admin_mode": "true", // 默认开启管理员模式,便于首次使用
"use_default_coins": "true", "api_server_port": "8080", // 默认API端口
"coin_pool_api_url": "", "use_default_coins": "true", // 默认使用内置币种列表
"oi_top_api_url": "", "default_coins": `["BTCUSDT","ETHUSDT","SOLUSDT","BNBUSDT","XRPUSDT","DOGEUSDT","ADAUSDT","HYPEUSDT"]`, // 默认币种列表JSON格式
"max_daily_loss": "10.0", "coin_pool_api_url": "", // 币种池API URL默认为空
"max_drawdown": "20.0", "oi_top_api_url": "", // 持仓量API URL默认为空
"stop_trading_minutes": "60", "max_daily_loss": "10.0", // 最大日损失百分比
"max_drawdown": "20.0", // 最大回撤百分比
"stop_trading_minutes": "60", // 停止交易时间(分钟)
"btc_eth_leverage": "5", // BTC/ETH杠杆倍数
"altcoin_leverage": "5", // 山寨币杠杆倍数
"jwt_secret": "", // JWT密钥默认为空由config.json或系统生成
} }
for key, value := range systemConfigs { for key, value := range systemConfigs {

View File

@@ -10,6 +10,7 @@ services:
- "${NOFX_BACKEND_PORT:-8080}:8080" - "${NOFX_BACKEND_PORT:-8080}:8080"
volumes: volumes:
- ./config.json:/app/config.json:ro - ./config.json:/app/config.json:ro
- ./config.db:/app/config.db
- ./decision_logs:/app/decision_logs - ./decision_logs:/app/decision_logs
- /etc/localtime:/etc/localtime:ro # Sync host time - /etc/localtime:/etc/localtime:ro # Sync host time
environment: environment:

95
main.go
View File

@@ -1,6 +1,7 @@
package main package main
import ( import (
"encoding/json"
"fmt" "fmt"
"log" "log"
"nofx/api" "nofx/api"
@@ -15,6 +16,95 @@ import (
"syscall" "syscall"
) )
// LeverageConfig 杠杆配置
type LeverageConfig struct {
BTCETHLeverage int `json:"btc_eth_leverage"`
AltcoinLeverage int `json:"altcoin_leverage"`
}
// ConfigFile 配置文件结构,只包含需要同步到数据库的字段
type ConfigFile struct {
AdminMode bool `json:"admin_mode"`
APIServerPort int `json:"api_server_port"`
UseDefaultCoins bool `json:"use_default_coins"`
DefaultCoins []string `json:"default_coins"`
CoinPoolAPIURL string `json:"coin_pool_api_url"`
OITopAPIURL string `json:"oi_top_api_url"`
MaxDailyLoss float64 `json:"max_daily_loss"`
MaxDrawdown float64 `json:"max_drawdown"`
StopTradingMinutes int `json:"stop_trading_minutes"`
Leverage LeverageConfig `json:"leverage"`
JWTSecret string `json:"jwt_secret"`
}
// syncConfigToDatabase 从config.json读取配置并同步到数据库
func syncConfigToDatabase(database *config.Database) error {
// 检查config.json是否存在
if _, err := os.Stat("config.json"); os.IsNotExist(err) {
log.Printf("📄 config.json不存在跳过同步")
return nil
}
// 读取config.json
data, err := os.ReadFile("config.json")
if err != nil {
return fmt.Errorf("读取config.json失败: %w", err)
}
// 解析JSON
var configFile ConfigFile
if err := json.Unmarshal(data, &configFile); err != nil {
return fmt.Errorf("解析config.json失败: %w", err)
}
log.Printf("🔄 开始同步config.json到数据库...")
// 同步各配置项到数据库
configs := map[string]string{
"admin_mode": fmt.Sprintf("%t", configFile.AdminMode),
"api_server_port": strconv.Itoa(configFile.APIServerPort),
"use_default_coins": fmt.Sprintf("%t", configFile.UseDefaultCoins),
"coin_pool_api_url": configFile.CoinPoolAPIURL,
"oi_top_api_url": configFile.OITopAPIURL,
"max_daily_loss": fmt.Sprintf("%.1f", configFile.MaxDailyLoss),
"max_drawdown": fmt.Sprintf("%.1f", configFile.MaxDrawdown),
"stop_trading_minutes": strconv.Itoa(configFile.StopTradingMinutes),
}
// 同步default_coins转换为JSON字符串存储
if len(configFile.DefaultCoins) > 0 {
defaultCoinsJSON, err := json.Marshal(configFile.DefaultCoins)
if err == nil {
configs["default_coins"] = string(defaultCoinsJSON)
}
}
// 同步杠杆配置
if configFile.Leverage.BTCETHLeverage > 0 {
configs["btc_eth_leverage"] = strconv.Itoa(configFile.Leverage.BTCETHLeverage)
}
if configFile.Leverage.AltcoinLeverage > 0 {
configs["altcoin_leverage"] = strconv.Itoa(configFile.Leverage.AltcoinLeverage)
}
// 如果JWT密钥不为空也同步
if configFile.JWTSecret != "" {
configs["jwt_secret"] = configFile.JWTSecret
}
// 更新数据库配置
for key, value := range configs {
if err := database.SetSystemConfig(key, value); err != nil {
log.Printf("⚠️ 更新配置 %s 失败: %v", key, err)
} else {
log.Printf("✓ 同步配置: %s = %s", key, value)
}
}
log.Printf("✅ config.json同步完成")
return nil
}
func main() { func main() {
fmt.Println("╔════════════════════════════════════════════════════════════╗") fmt.Println("╔════════════════════════════════════════════════════════════╗")
fmt.Println("║ 🤖 AI多模型交易系统 - 支持 DeepSeek & Qwen ║") fmt.Println("║ 🤖 AI多模型交易系统 - 支持 DeepSeek & Qwen ║")
@@ -34,6 +124,11 @@ func main() {
} }
defer database.Close() defer database.Close()
// 同步config.json到数据库
if err := syncConfigToDatabase(database); err != nil {
log.Printf("⚠️ 同步config.json到数据库失败: %v", err)
}
// 获取系统配置 // 获取系统配置
useDefaultCoinsStr, _ := database.GetSystemConfig("use_default_coins") useDefaultCoinsStr, _ := database.GetSystemConfig("use_default_coins")
useDefaultCoins := useDefaultCoinsStr == "true" useDefaultCoins := useDefaultCoinsStr == "true"

View File

@@ -70,18 +70,54 @@ check_env() {
if [ ! -f ".env" ]; then if [ ! -f ".env" ]; then
print_warning ".env 不存在,从模板复制..." print_warning ".env 不存在,从模板复制..."
cp .env.example .env cp .env.example .env
print_info "请编辑 .env 填入你的环境变量配置" print_info "✓ 已使用默认环境变量创建 .env"
print_info "运行: nano .env 或使用其他编辑器" print_info "💡 如需修改端口等设置,可编辑 .env 文件"
exit 1
fi fi
print_success "环境变量文件存在" print_success "环境变量文件存在"
} }
# ------------------------------------------------------------------------ # ------------------------------------------------------------------------
# Validation: Database File (trading.db) # Validation: Configuration File (config.json) - BASIC SETTINGS ONLY
# ------------------------------------------------------------------------
check_config() {
if [ ! -f "config.json" ]; then
print_warning "config.json 不存在,从模板复制..."
cp config.json.example config.json
print_info "✓ 已使用默认配置创建 config.json"
print_info "💡 如需修改基础设置杠杆大小、开仓币种、管理员模式、JWT密钥等可编辑 config.json"
print_info "💡 模型/交易所/交易员配置请使用Web界面"
fi
print_success "配置文件存在"
}
# ------------------------------------------------------------------------
# Utility: Read Environment Variables
# ------------------------------------------------------------------------
read_env_vars() {
if [ -f ".env" ]; then
# 读取端口配置,设置默认值
NOFX_FRONTEND_PORT=$(grep "^NOFX_FRONTEND_PORT=" .env 2>/dev/null | cut -d'=' -f2 || echo "3000")
NOFX_BACKEND_PORT=$(grep "^NOFX_BACKEND_PORT=" .env 2>/dev/null | cut -d'=' -f2 || echo "8080")
# 去除可能的引号和空格
NOFX_FRONTEND_PORT=$(echo "$NOFX_FRONTEND_PORT" | tr -d '"'"'" | tr -d ' ')
NOFX_BACKEND_PORT=$(echo "$NOFX_BACKEND_PORT" | tr -d '"'"'" | tr -d ' ')
# 如果为空则使用默认值
NOFX_FRONTEND_PORT=${NOFX_FRONTEND_PORT:-3000}
NOFX_BACKEND_PORT=${NOFX_BACKEND_PORT:-8080}
else
# 如果.env不存在使用默认端口
NOFX_FRONTEND_PORT=3000
NOFX_BACKEND_PORT=8080
fi
}
# ------------------------------------------------------------------------
# Validation: Database File (config.db)
# ------------------------------------------------------------------------ # ------------------------------------------------------------------------
check_database() { check_database() {
if [ ! -f "trading.db" ]; then if [ ! -f "config.db" ]; then
print_info "数据库文件不存在,系统将在启动时自动创建" print_info "数据库文件不存在,系统将在启动时自动创建"
else else
print_success "数据库文件存在" print_success "数据库文件存在"
@@ -123,6 +159,9 @@ check_database() {
start() { start() {
print_info "正在启动 NOFX AI Trading System..." print_info "正在启动 NOFX AI Trading System..."
# 读取环境变量
read_env_vars
# Auto-build frontend if missing or forced # Auto-build frontend if missing or forced
# if [ ! -d "web/dist" ] || [ "$1" == "--build" ]; then # if [ ! -d "web/dist" ] || [ "$1" == "--build" ]; then
# build_frontend # build_frontend
@@ -138,8 +177,8 @@ start() {
fi fi
print_success "服务已启动!" print_success "服务已启动!"
print_info "Web 界面: http://localhost:3000" print_info "Web 界面: http://localhost:${NOFX_FRONTEND_PORT}"
print_info "API 端点: http://localhost:8080" print_info "API 端点: http://localhost:${NOFX_BACKEND_PORT}"
print_info "" print_info ""
print_info "查看日志: ./start.sh logs" print_info "查看日志: ./start.sh logs"
print_info "停止服务: ./start.sh stop" print_info "停止服务: ./start.sh stop"
@@ -178,11 +217,14 @@ logs() {
# Monitoring: Status # Monitoring: Status
# ------------------------------------------------------------------------ # ------------------------------------------------------------------------
status() { status() {
# 读取环境变量
read_env_vars
print_info "服务状态:" print_info "服务状态:"
$COMPOSE_CMD ps $COMPOSE_CMD ps
echo "" echo ""
print_info "健康检查:" print_info "健康检查:"
curl -s http://localhost:8080/health | jq '.' || echo "后端未响应" curl -s "http://localhost:${NOFX_BACKEND_PORT}/health" | jq '.' || echo "后端未响应"
} }
# ------------------------------------------------------------------------ # ------------------------------------------------------------------------
@@ -243,6 +285,7 @@ main() {
case "${1:-start}" in case "${1:-start}" in
start) start)
check_env check_env
check_config
check_database check_database
start "$2" start "$2"
;; ;;