11 KiB
11 KiB
配置架构验证文档
📋 验证目标
确认:
- ✅ 所有用户下的账户都使用全局策略配置
- ✅ 普通用户无法通过自己的配置直接影响核心策略参数
🏗️ 配置架构设计
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() 方法
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_USDTMIN_POSITION_PERCENTMAX_POSITION_PERCENTMAX_TOTAL_POSITION_PERCENTAUTO_TRADE_ENABLEDMAX_OPEN_POSITIONSMAX_DAILY_ENTRIES
核心策略参数(从全局账号读取):
ATR_STOP_LOSS_MULTIPLIERATR_TAKE_PROFIT_MULTIPLIERRISK_REWARD_RATIOUSE_FIXED_RISK_SIZINGFIXED_RISK_PERCENTUSE_DYNAMIC_ATR_MULTIPLIERMIN_SIGNAL_STRENGTHSCAN_INTERVALTOP_N_SYMBOLS- ... 等等所有非风险旋钮的配置
🔒 权限控制
1. 后端API权限控制
位置:backend/api/routes/config.py
GET /api/config - 获取配置列表
# 普通用户:只展示风险旋钮 + 账号密钥
# 管理员:若当前不是"全局策略账号",同样只展示风险旋钮
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} - 更新单个配置
# 管理员:若不是全局策略账号,则禁止修改策略核心
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 - 批量更新配置
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:核心参数被过滤并返回错误
- GET
代码位置:
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:普通用户查看配置
- 普通用户登录
- 进入配置页面
- 预期:只能看到风险旋钮 + API密钥配置
- 验证:前端只显示允许的配置项
测试场景2:普通用户尝试修改核心策略参数
- 普通用户登录
- 尝试通过API修改
ATR_STOP_LOSS_MULTIPLIER - 预期:返回 403 错误:"该配置由平台统一管理(仅管理员可修改)"
- 验证:后端拒绝修改请求
测试场景3:管理员在非全局策略账号修改核心策略参数
- 管理员登录
- 切换到非全局策略账号(如 account_id=2)
- 尝试修改
ATR_STOP_LOSS_MULTIPLIER - 预期:返回 403 错误:"该配置由全局策略账号 #1 统一管理,请切换到该账号修改"
- 验证:后端拒绝修改请求
测试场景4:管理员在全局策略账号修改核心策略参数
- 管理员登录
- 切换到全局策略账号(account_id=1)
- 修改
ATR_STOP_LOSS_MULTIPLIER = 2.5 - 预期:修改成功
- 验证:所有账户的交易系统都会使用新的值(通过
config_manager.get_trading_config()读取)
🔍 代码检查清单
backend/config_manager.py- 配置读取逻辑使用全局账号backend/api/routes/config.py- API权限控制frontend/src/components/ConfigPanel.jsx- 前端配置页面(依赖后端过滤)frontend/src/components/GlobalConfig.jsx- 管理员全局配置页面
✅ 最终结论
-
✅ 所有用户下的账户都使用全局策略配置
- 通过
config_manager.get_trading_config()的eff_get()函数实现 - 核心策略参数从全局账号(account_id=1)读取
- 风险旋钮从当前账号读取
- 通过
-
✅ 普通用户无法通过自己的配置直接影响核心策略参数
- 前端:只能看到风险旋钮
- 后端:尝试修改核心参数会返回 403 错误
- 即使数据库中有值,读取时也会从全局账号读取
-
✅ 管理员权限控制
- 管理员在非全局策略账号时,也只能修改风险旋钮
- 只有管理员在全局策略账号时,才能修改核心策略参数
📝 注意事项
-
全局策略账号ID:默认是
account_id=1,可通过环境变量ATS_GLOBAL_STRATEGY_ACCOUNT_ID修改 -
配置缓存:配置存储在 Redis 中,修改后需要确保 Redis 缓存已更新
-
配置生效:修改全局策略配置后,所有账户的交易系统会在下次
reload_from_redis()时读取新值 -
风险旋钮的作用:虽然核心策略参数是全局的,但每个账户可以通过风险旋钮控制:
- 仓位大小(MAX_POSITION_PERCENT)
- 交易频率(MAX_DAILY_ENTRIES)
- 同时持仓数量(MAX_OPEN_POSITIONS)
- 是否启用自动交易(AUTO_TRADE_ENABLED)
🎯 建议
- 定期检查:定期验证全局策略账号的配置是否正确
- 配置快照:在修改全局策略配置前,先导出配置快照作为备份
- 测试环境:在测试环境验证配置修改的效果,再应用到生产环境
- 文档更新:修改配置后,及时更新相关文档