From dd6db430dd00247b312d086527636064c0785e1b Mon Sep 17 00:00:00 2001 From: nobody <878822589@qq.com> Date: Wed, 29 Oct 2025 12:23:29 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=BD=93API=20URL=E4=B8=BA=E7=A9=BA?= =?UTF-8?q?=E6=97=B6=E4=BD=BF=E7=94=A8=E9=BB=98=E8=AE=A4=E5=B8=81=E7=A7=8D?= =?UTF-8?q?=E5=88=97=E8=A1=A8=EF=BC=8C=E9=81=BF=E5=85=8D=E5=BE=AA=E7=8E=AF?= =?UTF-8?q?=E8=AF=B7=E6=B1=82=E5=A4=B1=E8=B4=A5=20-=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E9=BB=98=E8=AE=A4=E4=B8=BB=E6=B5=81=E5=B8=81=E7=A7=8D=E5=88=97?= =?UTF-8?q?=E8=A1=A8=EF=BC=88BTC=E3=80=81ETH=E3=80=81SOL=E3=80=81BNB?= =?UTF-8?q?=E3=80=81XRP=E3=80=81DOGE=E3=80=81ADA=E3=80=81HYPE=EF=BC=89=20-?= =?UTF-8?q?=20=E5=9C=A8GetCoinPool()=E4=B8=AD=E6=A3=80=E6=9F=A5coin=5Fpool?= =?UTF-8?q?=5Fapi=5Furl=EF=BC=8C=E4=B8=BA=E7=A9=BA=E6=97=B6=E7=9B=B4?= =?UTF-8?q?=E6=8E=A5=E8=BF=94=E5=9B=9E=E9=BB=98=E8=AE=A4=E5=88=97=E8=A1=A8?= =?UTF-8?q?=20-=20=E5=9C=A8GetOITopPositions()=E4=B8=AD=E6=A3=80=E6=9F=A5o?= =?UTF-8?q?i=5Ftop=5Fapi=5Furl=EF=BC=8C=E4=B8=BA=E7=A9=BA=E6=97=B6?= =?UTF-8?q?=E8=B7=B3=E8=BF=87OI=20Top=E6=95=B0=E6=8D=AE=20-=20=E6=9B=B4?= =?UTF-8?q?=E6=96=B0README=E6=96=87=E6=A1=A3=EF=BC=8C=E8=AF=B4=E6=98=8EAPI?= =?UTF-8?q?=20URL=E5=8F=AF=E9=80=89=E9=85=8D=E7=BD=AE=E5=92=8C=E9=BB=98?= =?UTF-8?q?=E8=AE=A4=E5=B8=81=E7=A7=8D=E5=88=97=E8=A1=A8=20-=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=EF=BC=9A=E9=81=BF=E5=85=8D=E7=A9=BAURL=E5=AF=BC?= =?UTF-8?q?=E8=87=B4=E7=9A=84=E5=BE=AA=E7=8E=AF=E8=AF=B7=E6=B1=82=E5=92=8C?= =?UTF-8?q?"unsupported=20protocol=20scheme"=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 7 +++++-- README.zh-CN.md | 7 +++++-- pool/coin_pool.go | 48 +++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 54 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 08dbd4ef..5c5fb6d0 100644 --- a/README.md +++ b/README.md @@ -250,8 +250,11 @@ 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) +- `coin_pool_api_url`: AI500 coin pool API (optional, if empty, uses default mainstream coins) +- `oi_top_api_url`: OI Top open interest API (optional, if empty, OI Top data is skipped) + +**Default Coin List** (used when APIs are not configured): +- BTC, ETH, SOL, BNB, XRP, DOGE, ADA, HYPE ### 5. Run the System diff --git a/README.zh-CN.md b/README.zh-CN.md index 4684f8d4..20c0f50a 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -250,8 +250,11 @@ 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(可选) +- `coin_pool_api_url`: AI500币种池API(可选,留空时使用默认主流币种) +- `oi_top_api_url`: OI Top持仓量API(可选,留空时跳过OI Top数据) + +**默认币种列表**(当API未配置时使用): +- BTC、ETH、SOL、BNB、XRP、DOGE、ADA、HYPE ### 5. 运行系统 diff --git a/pool/coin_pool.go b/pool/coin_pool.go index b88b865b..35c4bc64 100644 --- a/pool/coin_pool.go +++ b/pool/coin_pool.go @@ -8,9 +8,22 @@ 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 @@ -65,6 +78,12 @@ func SetOITopAPI(apiURL string) { // GetCoinPool 获取币种池列表(带重试和缓存机制) func GetCoinPool() ([]CoinInfo, error) { + // 检查API URL是否配置 + if strings.TrimSpace(coinPoolConfig.APIURL) == "" { + log.Printf("⚠️ 未配置币种池API URL,使用默认主流币种列表") + return convertSymbolsToCoins(defaultMainstreamCoins), nil + } + maxRetries := 3 var lastErr error @@ -99,8 +118,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 +341,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 +399,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 +439,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请求