# 配置架构验证文档 ## 📋 验证目标 确认: 1. ✅ **所有用户下的账户都使用全局策略配置** 2. ✅ **普通用户无法通过自己的配置直接影响核心策略参数** --- ## 🏗️ 配置架构设计 ### 1. 配置层级 ``` ┌─────────────────────────────────────────────────────────┐ │ 全局策略账号 (account_id=1, 默认) │ │ - 存储所有核心策略参数 │ │ - 例如:ATR_STOP_LOSS_MULTIPLIER, ATR_TAKE_PROFIT_... │ └─────────────────────────────────────────────────────────┘ ↓ 读取 ┌─────────────────────────────────────────────────────────┐ │ 用户账户 (account_id=2, 3, 4...) │ │ - 存储风险旋钮(每个账户独立) │ │ - 例如:MAX_POSITION_PERCENT, AUTO_TRADE_ENABLED... │ └─────────────────────────────────────────────────────────┘ ``` ### 2. 配置读取逻辑 **位置**:`backend/config_manager.py` 的 `get_trading_config()` 方法 ```python def eff_get(key: str, default: Any): """ 策略核心:默认从全局账号读取(GLOBAL_STRATEGY_ACCOUNT_ID)。 风险旋钮:从当前账号读取。 """ # API key/secret/testnet 永远按账号读取 if key in RISK_KNOBS_KEYS or global_mgr is None: return self.get(key, default) # 从当前账号读取 try: # 从全局账号读取 return global_mgr.get(key, default) except Exception: return self.get(key, default) ``` **风险旋钮列表**(`RISK_KNOBS_KEYS`): - `MIN_MARGIN_USDT` - `MIN_POSITION_PERCENT` - `MAX_POSITION_PERCENT` - `MAX_TOTAL_POSITION_PERCENT` - `AUTO_TRADE_ENABLED` - `MAX_OPEN_POSITIONS` - `MAX_DAILY_ENTRIES` **核心策略参数**(从全局账号读取): - `ATR_STOP_LOSS_MULTIPLIER` - `ATR_TAKE_PROFIT_MULTIPLIER` - `RISK_REWARD_RATIO` - `USE_FIXED_RISK_SIZING` - `FIXED_RISK_PERCENT` - `USE_DYNAMIC_ATR_MULTIPLIER` - `MIN_SIGNAL_STRENGTH` - `SCAN_INTERVAL` - `TOP_N_SYMBOLS` - ... 等等所有非风险旋钮的配置 --- ## 🔒 权限控制 ### 1. 后端API权限控制 **位置**:`backend/api/routes/config.py` #### GET `/api/config` - 获取配置列表 ```python # 普通用户:只展示风险旋钮 + 账号密钥 # 管理员:若当前不是"全局策略账号",同样只展示风险旋钮 is_admin = (user.get("role") or "user") == "admin" gid = _global_strategy_account_id() if (not is_admin) or (is_admin and int(account_id) != int(gid)): allowed = set(USER_RISK_KNOBS) | {"BINANCE_API_KEY", "BINANCE_API_SECRET", "USE_TESTNET"} result = {k: v for k, v in result.items() if k in allowed} ``` **验证**: - ✅ 普通用户只能看到 `USER_RISK_KNOBS` + API密钥 - ✅ 管理员在非全局策略账号时,也只能看到风险旋钮 - ✅ 只有管理员在全局策略账号时,才能看到所有配置 #### PUT `/api/config/{key}` - 更新单个配置 ```python # 管理员:若不是全局策略账号,则禁止修改策略核心 if (user.get("role") or "user") == "admin": gid = _global_strategy_account_id() if int(account_id) != int(gid): if key not in (USER_RISK_KNOBS | {"BINANCE_API_KEY", "BINANCE_API_SECRET", "USE_TESTNET"}): raise HTTPException(status_code=403, detail=f"该配置由全局策略账号 #{gid} 统一管理") # 产品模式:普通用户只能改"风险旋钮"与账号私有密钥/测试网 if (user.get("role") or "user") != "admin": if key not in (USER_RISK_KNOBS | {"BINANCE_API_KEY", "BINANCE_API_SECRET", "USE_TESTNET"}): raise HTTPException(status_code=403, detail="该配置由平台统一管理(仅管理员可修改)") ``` **验证**: - ✅ 普通用户尝试修改核心策略参数会返回 403 错误 - ✅ 管理员在非全局策略账号时,也无法修改核心策略参数 - ✅ 只有管理员在全局策略账号时,才能修改核心策略参数 #### POST `/api/config/batch` - 批量更新配置 ```python for item in configs: # 管理员:若不是全局策略账号,则批量只允许风险旋钮/密钥 if (user.get("role") or "user") == "admin": gid = _global_strategy_account_id() if int(account_id) != int(gid): if item.key not in (USER_RISK_KNOBS | {"BINANCE_API_KEY", "BINANCE_API_SECRET", "USE_TESTNET"}): errors.append(f"{item.key}: 该配置由全局策略账号 #{gid} 统一管理,请切换账号修改") continue # 产品模式:普通用户只能改"风险旋钮"与账号私有密钥/测试网 if (user.get("role") or "user") != "admin": if item.key not in (USER_RISK_KNOBS | {"BINANCE_API_KEY", "BINANCE_API_SECRET", "USE_TESTNET"}): errors.append(f"{item.key}: 该配置由平台统一管理(仅管理员可修改)") continue ``` **验证**: - ✅ 普通用户批量更新时,核心策略参数会被过滤并返回错误 - ✅ 管理员在非全局策略账号时,核心策略参数也会被过滤 --- ## ✅ 验证结果 ### 1. 所有账户使用全局策略配置 ✅ **验证点**: - `config_manager.py` 的 `get_trading_config()` 方法中,所有非风险旋钮的配置都通过 `eff_get()` 从全局账号读取 - 即使普通用户在自己的账户中设置了核心策略参数,也不会生效(因为读取时从全局账号读取) **代码位置**: - `backend/config_manager.py:509-522` **结论**:✅ **所有账户都使用全局策略配置** --- ### 2. 普通用户无法修改核心策略参数 ✅ **验证点**: - **前端限制**:普通用户在配置页面只能看到风险旋钮(通过API过滤) - **后端限制**: - GET `/api/config`:只返回风险旋钮 - PUT `/api/config/{key}`:尝试修改核心参数返回 403 - POST `/api/config/batch`:核心参数被过滤并返回错误 **代码位置**: - `backend/api/routes/config.py:273-280` (GET) - `backend/api/routes/config.py:645-655` (PUT) - `backend/api/routes/config.py:765-776` (POST) **结论**:✅ **普通用户无法通过自己的配置直接影响核心策略参数** --- ## 📊 配置分类总结 ### 风险旋钮(每个账户独立) - `MIN_MARGIN_USDT` - 最小保证金(USDT) - `MIN_POSITION_PERCENT` - 最小仓位占比 - `MAX_POSITION_PERCENT` - 最大仓位占比 - `MAX_TOTAL_POSITION_PERCENT` - 总仓位占比上限 - `AUTO_TRADE_ENABLED` - 自动交易开关 - `MAX_OPEN_POSITIONS` - 同时持仓数量上限 - `MAX_DAILY_ENTRIES` - 每日最多开仓次数 ### 核心策略参数(全局统一) - `ATR_STOP_LOSS_MULTIPLIER` - ATR止损倍数 - `ATR_TAKE_PROFIT_MULTIPLIER` - ATR止盈倍数 - `RISK_REWARD_RATIO` - 盈亏比 - `USE_FIXED_RISK_SIZING` - 使用固定风险百分比 - `FIXED_RISK_PERCENT` - 固定风险百分比 - `USE_DYNAMIC_ATR_MULTIPLIER` - 动态ATR倍数 - `MIN_SIGNAL_STRENGTH` - 最小信号强度 - `SCAN_INTERVAL` - 扫描间隔 - `TOP_N_SYMBOLS` - 每次扫描处理的交易对数量 - ... 等等所有非风险旋钮的配置 ### 账号私有配置(每个账户独立) - `BINANCE_API_KEY` - 币安API密钥 - `BINANCE_API_SECRET` - 币安API密钥 - `USE_TESTNET` - 是否使用测试网 --- ## 🎯 实际运行验证 ### 测试场景1:普通用户查看配置 1. 普通用户登录 2. 进入配置页面 3. **预期**:只能看到风险旋钮 + API密钥配置 4. **验证**:前端只显示允许的配置项 ### 测试场景2:普通用户尝试修改核心策略参数 1. 普通用户登录 2. 尝试通过API修改 `ATR_STOP_LOSS_MULTIPLIER` 3. **预期**:返回 403 错误:"该配置由平台统一管理(仅管理员可修改)" 4. **验证**:后端拒绝修改请求 ### 测试场景3:管理员在非全局策略账号修改核心策略参数 1. 管理员登录 2. 切换到非全局策略账号(如 account_id=2) 3. 尝试修改 `ATR_STOP_LOSS_MULTIPLIER` 4. **预期**:返回 403 错误:"该配置由全局策略账号 #1 统一管理,请切换到该账号修改" 5. **验证**:后端拒绝修改请求 ### 测试场景4:管理员在全局策略账号修改核心策略参数 1. 管理员登录 2. 切换到全局策略账号(account_id=1) 3. 修改 `ATR_STOP_LOSS_MULTIPLIER = 2.5` 4. **预期**:修改成功 5. **验证**:所有账户的交易系统都会使用新的值(通过 `config_manager.get_trading_config()` 读取) --- ## 🔍 代码检查清单 - [x] `backend/config_manager.py` - 配置读取逻辑使用全局账号 - [x] `backend/api/routes/config.py` - API权限控制 - [x] `frontend/src/components/ConfigPanel.jsx` - 前端配置页面(依赖后端过滤) - [x] `frontend/src/components/GlobalConfig.jsx` - 管理员全局配置页面 --- ## ✅ 最终结论 1. ✅ **所有用户下的账户都使用全局策略配置** - 通过 `config_manager.get_trading_config()` 的 `eff_get()` 函数实现 - 核心策略参数从全局账号(account_id=1)读取 - 风险旋钮从当前账号读取 2. ✅ **普通用户无法通过自己的配置直接影响核心策略参数** - 前端:只能看到风险旋钮 - 后端:尝试修改核心参数会返回 403 错误 - 即使数据库中有值,读取时也会从全局账号读取 3. ✅ **管理员权限控制** - 管理员在非全局策略账号时,也只能修改风险旋钮 - 只有管理员在全局策略账号时,才能修改核心策略参数 --- ## 📝 注意事项 1. **全局策略账号ID**:默认是 `account_id=1`,可通过环境变量 `ATS_GLOBAL_STRATEGY_ACCOUNT_ID` 修改 2. **配置缓存**:配置存储在 Redis 中,修改后需要确保 Redis 缓存已更新 3. **配置生效**:修改全局策略配置后,所有账户的交易系统会在下次 `reload_from_redis()` 时读取新值 4. **风险旋钮的作用**:虽然核心策略参数是全局的,但每个账户可以通过风险旋钮控制: - 仓位大小(MAX_POSITION_PERCENT) - 交易频率(MAX_DAILY_ENTRIES) - 同时持仓数量(MAX_OPEN_POSITIONS) - 是否启用自动交易(AUTO_TRADE_ENABLED) --- ## 🎯 建议 1. **定期检查**:定期验证全局策略账号的配置是否正确 2. **配置快照**:在修改全局策略配置前,先导出配置快照作为备份 3. **测试环境**:在测试环境验证配置修改的效果,再应用到生产环境 4. **文档更新**:修改配置后,及时更新相关文档