diff --git a/README.md b/README.md index 08dbd4ef..ad7e7046 100644 --- a/README.md +++ b/README.md @@ -250,8 +250,12 @@ Create `config.json` file (use `config.json.example` as template): - `binance_api_key/secret_key`: Each trader uses independent Binance account - `initial_balance`: Initial balance (for calculating P/L%) - `scan_interval_minutes`: Decision cycle (recommended 3-5 minutes) -- `coin_pool_api_url`: AI500 coin pool API (optional) -- `oi_top_api_url`: OI Top open interest API (optional) +- `use_default_coins`: **true** = Use default 8 mainstream coins | **false** = Use API coin pool (recommended for beginners: true) +- `coin_pool_api_url`: AI500 coin pool API (optional, ignored when use_default_coins=true) +- `oi_top_api_url`: OI Top open interest API (optional, if empty, OI Top data is skipped) + +**Default Coin List** (when `use_default_coins: true`): +- BTC, ETH, SOL, BNB, XRP, DOGE, ADA, HYPE ### 5. Run the System diff --git a/README.ru.md b/README.ru.md index ff43f489..f8f8e2b9 100644 --- a/README.ru.md +++ b/README.ru.md @@ -173,12 +173,27 @@ cd .. "initial_balance": 1000.0 } ], + "use_default_coins": false, "coin_pool_api_url": "http://x.x.x.x:xxx/api/ai500/list?auth=ВАШ_AUTH", "oi_top_api_url": "http://x.x.x.x:xxx/api/oi/top?auth=ВАШ_AUTH", "api_server_port": 8080 } ``` +**Примечания к конфигурации:** +- `traders`: Настройте 1-N трейдеров (один AI или соревнование нескольких AI) +- `id`: Уникальный идентификатор трейдера (используется для директории логов) +- `ai_model`: "qwen" или "deepseek" +- `binance_api_key/secret_key`: Каждый трейдер использует независимый аккаунт Binance +- `initial_balance`: Начальный баланс (для расчета P/L%) +- `scan_interval_minutes`: Цикл принятия решений (рекомендуется 3-5 минут) +- `use_default_coins`: **true** = Использовать 8 основных монет по умолчанию | **false** = Использовать API пул монет (рекомендуется для новичков: true) +- `coin_pool_api_url`: API пула монет AI500 (опционально, игнорируется при use_default_coins=true) +- `oi_top_api_url`: API открытого интереса OI Top (опционально, если пусто, данные OI Top пропускаются) + +**Список монет по умолчанию** (когда `use_default_coins: true`): +- BTC, ETH, SOL, BNB, XRP, DOGE, ADA, HYPE + ### 5. Запуск системы **Запуск backend (система AI торговли + API сервер):** diff --git a/README.uk.md b/README.uk.md index 5889a1b1..f9b08699 100644 --- a/README.uk.md +++ b/README.uk.md @@ -173,12 +173,27 @@ cd .. "initial_balance": 1000.0 } ], + "use_default_coins": false, "coin_pool_api_url": "http://x.x.x.x:xxx/api/ai500/list?auth=ВАШ_AUTH", "oi_top_api_url": "http://x.x.x.x:xxx/api/oi/top?auth=ВАШ_AUTH", "api_server_port": 8080 } ``` +**Примітки до конфігурації:** +- `traders`: Налаштуйте 1-N трейдерів (один AI або змагання кількох AI) +- `id`: Унікальний ідентифікатор трейдера (використовується для директорії логів) +- `ai_model`: "qwen" або "deepseek" +- `binance_api_key/secret_key`: Кожен трейдер використовує незалежний акаунт Binance +- `initial_balance`: Початковий баланс (для розрахунку P/L%) +- `scan_interval_minutes`: Цикл прийняття рішень (рекомендується 3-5 хвилин) +- `use_default_coins`: **true** = Використовувати 8 основних монет за замовчуванням | **false** = Використовувати API пул монет (рекомендується для новачків: true) +- `coin_pool_api_url`: API пулу монет AI500 (опціонально, ігнорується при use_default_coins=true) +- `oi_top_api_url`: API відкритого інтересу OI Top (опціонально, якщо порожньо, дані OI Top пропускаються) + +**Список монет за замовчуванням** (коли `use_default_coins: true`): +- BTC, ETH, SOL, BNB, XRP, DOGE, ADA, HYPE + ### 5. Запуск системи **Запуск backend (система AI торгівлі + API сервер):** diff --git a/README.zh-CN.md b/README.zh-CN.md index 4684f8d4..077fd6cc 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -250,8 +250,12 @@ cd .. - `binance_api_key/secret_key`: 每个trader使用独立的币安账户 - `initial_balance`: 初始余额(用于计算盈亏%) - `scan_interval_minutes`: 决策周期(建议3-5分钟) -- `coin_pool_api_url`: AI500币种池API(可选) -- `oi_top_api_url`: OI Top持仓量API(可选) +- `use_default_coins`: **true** = 使用默认8个主流币种 | **false** = 使用API币种池(新手推荐:true) +- `coin_pool_api_url`: AI500币种池API(可选,当use_default_coins=true时忽略) +- `oi_top_api_url`: OI Top持仓量API(可选,留空时跳过OI Top数据) + +**默认币种列表**(当 `use_default_coins: true` 时): +- BTC、ETH、SOL、BNB、XRP、DOGE、ADA、HYPE ### 5. 运行系统 diff --git a/config.json.example b/config.json.example index 4b29cbbf..3a6392a0 100644 --- a/config.json.example +++ b/config.json.example @@ -21,6 +21,7 @@ "scan_interval_minutes": 3 } ], + "use_default_coins": false, "coin_pool_api_url": "http://x.x.x.x:x/api/ai500/list?auth=", "oi_top_api_url": "http://x.x.x.x:x/api/oi/top?auth=", "api_server_port": 8080, diff --git a/config/config.go b/config/config.go index e427a226..489b0a83 100644 --- a/config/config.go +++ b/config/config.go @@ -23,6 +23,7 @@ type TraderConfig struct { // Config 总配置 type Config struct { Traders []TraderConfig `json:"traders"` + UseDefaultCoins bool `json:"use_default_coins"` // 是否使用默认主流币种列表 CoinPoolAPIURL string `json:"coin_pool_api_url"` OITopAPIURL string `json:"oi_top_api_url"` APIServerPort int `json:"api_server_port"` diff --git a/main.go b/main.go index c5791e88..b956209b 100644 --- a/main.go +++ b/main.go @@ -34,6 +34,12 @@ func main() { log.Printf("✓ 配置加载成功,共%d个trader参赛", len(cfg.Traders)) fmt.Println() + // 设置是否使用默认主流币种 + pool.SetUseDefaultCoins(cfg.UseDefaultCoins) + if cfg.UseDefaultCoins { + log.Printf("✓ 已启用默认主流币种列表(BTC、ETH、SOL、BNB、XRP、DOGE、ADA、HYPE)") + } + // 设置币种池API URL if cfg.CoinPoolAPIURL != "" { pool.SetCoinPoolAPI(cfg.CoinPoolAPIURL) diff --git a/pool/coin_pool.go b/pool/coin_pool.go index b88b865b..6675013c 100644 --- a/pool/coin_pool.go +++ b/pool/coin_pool.go @@ -8,20 +8,35 @@ import ( "net/http" "os" "path/filepath" + "strings" "time" ) +// defaultMainstreamCoins 默认主流币种池(当AI500和OI Top都失败时使用) +var defaultMainstreamCoins = []string{ + "BTCUSDT", + "ETHUSDT", + "SOLUSDT", + "BNBUSDT", + "XRPUSDT", + "DOGEUSDT", + "ADAUSDT", + "HYPEUSDT", +} + // CoinPoolConfig 币种池配置 type CoinPoolConfig struct { - APIURL string - Timeout time.Duration - CacheDir string + APIURL string + Timeout time.Duration + CacheDir string + UseDefaultCoins bool // 是否使用默认主流币种 } var coinPoolConfig = CoinPoolConfig{ - APIURL: "", - Timeout: 30 * time.Second, // 增加到30秒 - CacheDir: "coin_pool_cache", + APIURL: "", + Timeout: 30 * time.Second, // 增加到30秒 + CacheDir: "coin_pool_cache", + UseDefaultCoins: false, // 默认不使用 } // CoinPoolCache 币种池缓存 @@ -63,8 +78,25 @@ func SetOITopAPI(apiURL string) { oiTopConfig.APIURL = apiURL } +// SetUseDefaultCoins 设置是否使用默认主流币种 +func SetUseDefaultCoins(useDefault bool) { + coinPoolConfig.UseDefaultCoins = useDefault +} + // GetCoinPool 获取币种池列表(带重试和缓存机制) func GetCoinPool() ([]CoinInfo, error) { + // 优先检查是否启用默认币种列表 + if coinPoolConfig.UseDefaultCoins { + log.Printf("✓ 已启用默认主流币种列表") + return convertSymbolsToCoins(defaultMainstreamCoins), nil + } + + // 检查API URL是否配置 + if strings.TrimSpace(coinPoolConfig.APIURL) == "" { + log.Printf("⚠️ 未配置币种池API URL,使用默认主流币种列表") + return convertSymbolsToCoins(defaultMainstreamCoins), nil + } + maxRetries := 3 var lastErr error @@ -99,8 +131,9 @@ func GetCoinPool() ([]CoinInfo, error) { return cachedCoins, nil } - log.Printf("❌ 无法加载缓存数据: %v", err) - return nil, fmt.Errorf("获取币种池失败(API重试%d次后,缓存也不可用): %w", maxRetries, lastErr) + // 缓存也失败,使用默认主流币种 + log.Printf("⚠️ 无法加载缓存数据(最后错误: %v),使用默认主流币种列表", lastErr) + return convertSymbolsToCoins(defaultMainstreamCoins), nil } // fetchCoinPool 实际执行币种池请求 @@ -321,6 +354,19 @@ func endsWith(s, suffix string) bool { return s[len(s)-len(suffix):] == suffix } +// convertSymbolsToCoins 将币种符号列表转换为CoinInfo列表 +func convertSymbolsToCoins(symbols []string) []CoinInfo { + coins := make([]CoinInfo, 0, len(symbols)) + for _, symbol := range symbols { + coins = append(coins, CoinInfo{ + Pair: symbol, + Score: 0, + IsAvailable: true, + }) + } + return coins +} + // ========== OI Top(持仓量增长Top20)数据 ========== // OIPosition 持仓量数据 @@ -366,6 +412,12 @@ var oiTopConfig = struct { // GetOITopPositions 获取持仓量增长Top20数据(带重试和缓存) func GetOITopPositions() ([]OIPosition, error) { + // 检查API URL是否配置 + if strings.TrimSpace(oiTopConfig.APIURL) == "" { + log.Printf("⚠️ 未配置OI Top API URL,跳过OI Top数据获取") + return []OIPosition{}, nil // 返回空列表,不是错误 + } + maxRetries := 3 var lastErr error @@ -400,8 +452,9 @@ func GetOITopPositions() ([]OIPosition, error) { return cachedPositions, nil } - log.Printf("❌ 无法加载OI Top缓存数据: %v", err) - return nil, fmt.Errorf("获取OI Top数据失败(API重试%d次后,缓存也不可用): %w", maxRetries, lastErr) + // 缓存也失败,返回空列表(OI Top是可选的) + log.Printf("⚠️ 无法加载OI Top缓存数据(最后错误: %v),跳过OI Top数据", lastErr) + return []OIPosition{}, nil } // fetchOITop 实际执行OI Top请求