diff --git a/backend/api/routes/config.py b/backend/api/routes/config.py index a019dd1..39d25ba 100644 --- a/backend/api/routes/config.py +++ b/backend/api/routes/config.py @@ -800,6 +800,10 @@ async def check_config_feasibility( except Exception: suggestions = [] + max_open_positions = int(_tc("MAX_OPEN_POSITIONS", 3)) + max_daily_entries = int(_tc("MAX_DAILY_ENTRIES", 8)) + max_single_position_margin_usdt = round(available_balance * max_position_percent, 2) + return { "feasible": is_feasible, "account_balance": available_balance, @@ -809,7 +813,10 @@ async def check_config_feasibility( "current_config": { "min_margin_usdt": min_margin_usdt, "min_position_percent": min_position_percent, - "max_position_percent": max_position_percent + "max_position_percent": max_position_percent, + "max_open_positions": max_open_positions, + "max_daily_entries": max_daily_entries, + "max_single_position_margin_usdt": max_single_position_margin_usdt, }, "calculated_values": { "required_position_value": base_result['required_position_value'], diff --git a/frontend/src/components/ConfigPanel.jsx b/frontend/src/components/ConfigPanel.jsx index dc4d966..fff0316 100644 --- a/frontend/src/components/ConfigPanel.jsx +++ b/frontend/src/components/ConfigPanel.jsx @@ -42,6 +42,19 @@ const ConfigPanel = () => { } } + // 普通用户仅可编辑的配置项(与后端 USER_RISK_KNOBS 一致;用于隐藏不可编辑分组与项) + const USER_RISK_KNOBS_SET = new Set([ + 'MIN_MARGIN_USDT', 'MIN_POSITION_PERCENT', 'MAX_POSITION_PERCENT', 'MAX_TOTAL_POSITION_PERCENT', + 'AUTO_TRADE_ENABLED', 'MAX_OPEN_POSITIONS', 'MAX_DAILY_ENTRIES', + 'TOP_N_SYMBOLS', 'MIN_SIGNAL_STRENGTH', 'MIN_VOLUME_24H', 'MIN_VOLATILITY', + 'SCAN_EXTRA_SYMBOLS_FOR_SUPPLEMENT', 'EXCLUDE_MAJOR_COINS', 'MAX_SCAN_SYMBOLS', 'SCAN_INTERVAL', + ]) + const USER_EDITABLE_KEYS = new Set([ + ...USER_RISK_KNOBS_SET, + 'BINANCE_API_KEY', 'BINANCE_API_SECRET', 'USE_TESTNET', + ]) + const isKeyEditableForUser = (key) => USER_EDITABLE_KEYS.has(key) + const [credForm, setCredForm] = useState({ api_key: '', api_secret: '', use_testnet: false }) // 预设方案配置 @@ -521,8 +534,8 @@ const ConfigPanel = () => { } // 重新加载配置 await loadConfigs() - // 如果更新的是与可行性相关的配置,重新检查可行性 - if (['MIN_MARGIN_USDT', 'MIN_POSITION_PERCENT', 'MAX_POSITION_PERCENT', 'LEVERAGE'].includes(key)) { + // 如果更新的是与可行性/展示相关的配置,重新检查可行性(含最大单笔、持仓数、每日开仓等) + if (['MIN_MARGIN_USDT', 'MIN_POSITION_PERCENT', 'MAX_POSITION_PERCENT', 'MAX_OPEN_POSITIONS', 'MAX_DAILY_ENTRIES', 'LEVERAGE'].includes(key)) { await checkFeasibility() } } catch (error) { @@ -811,6 +824,17 @@ const ConfigPanel = () => { 'api': 'API配置' } + // 普通用户只展示含“可编辑项”的分组,避免出现不可修改的策略组 + const visibleCategories = isAdmin + ? configCategories + : Object.fromEntries( + Object.entries(configCategories).filter(([cat]) => + Object.keys(configs).some( + (key) => configs[key]?.category === cat && isKeyEditableForUser(key) + ) + ) + ) + return (
+ 最大单笔保证金: {feasibilityCheck.current_config?.max_single_position_margin_usdt != null ? feasibilityCheck.current_config.max_single_position_margin_usdt.toFixed(2) : 'N/A'} USDT + {feasibilityCheck.current_config?.max_open_positions != null && ( + <> | 最多持仓: {feasibilityCheck.current_config.max_open_positions} 个> + )} + {feasibilityCheck.current_config?.max_daily_entries != null && ( + <> | 每日最多开仓: {feasibilityCheck.current_config.max_daily_entries} 次> + )} +
{!feasibilityCheck.feasible && (@@ -1148,17 +1181,18 @@ const ConfigPanel = () => {