This commit is contained in:
薇薇安 2026-01-23 17:36:31 +08:00
parent efbd149f1f
commit fe420ad1a4

View File

@ -282,6 +282,137 @@ async def get_all_configs(
raise HTTPException(status_code=500, detail=str(e)) raise HTTPException(status_code=500, detail=str(e))
# ⚠️ 重要:全局配置路由必须在 /{key} 之前,否则会被动态路由匹配
@router.get("/global")
async def get_global_configs(
user: Dict[str, Any] = Depends(get_current_user),
):
"""获取全局策略配置(仅管理员)"""
if (user.get("role") or "user") != "admin":
raise HTTPException(status_code=403, detail="仅管理员可访问全局策略配置")
try:
from database.models import GlobalStrategyConfig
configs = GlobalStrategyConfig.get_all()
logger.info(f"从数据库加载了 {len(configs)} 个全局配置项")
result = {}
for config in configs:
key = config['config_key']
value = GlobalStrategyConfig._convert_value(
config['config_value'],
config['config_type']
)
result[key] = {
"value": value,
"type": config['config_type'],
"category": config['category'],
"description": config.get('description'),
}
logger.debug(f"加载配置项: {key} = {value} (type: {config['config_type']}, category: {config['category']})")
# 添加默认配置(如果数据库中没有)
for k, meta in CORE_STRATEGY_CONFIG_DEFAULTS.items():
if k not in result:
result[k] = meta
# 固定风险百分比配置
FIXED_RISK_CONFIG_DEFAULTS = {
"USE_FIXED_RISK_SIZING": {
"value": True,
"type": "boolean",
"category": "risk",
"description": "使用固定风险百分比计算仓位(凯利公式)。启用后,每笔单子承受的风险固定为 FIXED_RISK_PERCENT避免大额亏损。",
},
"FIXED_RISK_PERCENT": {
"value": 0.02,
"type": "number",
"category": "risk",
"description": "每笔单子承受的风险百分比(相对于总资金)。例如 0.02 表示 2%。启用固定风险后,每笔亏损限制在该百分比内。",
},
}
for k, meta in FIXED_RISK_CONFIG_DEFAULTS.items():
if k not in result:
result[k] = meta
# 添加更多核心策略配置的默认值(确保前端能显示所有重要配置)
ADDITIONAL_STRATEGY_DEFAULTS = {
"USE_ATR_STOP_LOSS": {
"value": True,
"type": "boolean",
"category": "strategy",
"description": "是否使用ATR动态止损优先于固定百分比",
},
"ATR_PERIOD": {
"value": 14,
"type": "number",
"category": "strategy",
"description": "ATR计算周期默认14",
},
"USE_DYNAMIC_ATR_MULTIPLIER": {
"value": False,
"type": "boolean",
"category": "strategy",
"description": "是否根据波动率动态调整ATR倍数",
},
"ATR_MULTIPLIER_MIN": {
"value": 1.5,
"type": "number",
"category": "strategy",
"description": "动态ATR倍数最小值",
},
"ATR_MULTIPLIER_MAX": {
"value": 2.5,
"type": "number",
"category": "strategy",
"description": "动态ATR倍数最大值",
},
"MIN_SIGNAL_STRENGTH": {
"value": 8,
"type": "number",
"category": "strategy",
"description": "最小信号强度0-10只交易高质量信号",
},
"SCAN_INTERVAL": {
"value": 1800,
"type": "number",
"category": "scan",
"description": "市场扫描间隔默认30分钟",
},
"TOP_N_SYMBOLS": {
"value": 8,
"type": "number",
"category": "scan",
"description": "每次扫描后处理的交易对数量",
},
"MIN_VOLUME_24H_STRICT": {
"value": 10000000,
"type": "number",
"category": "scan",
"description": "严格成交量过滤24H Volume低于此值USD直接剔除",
},
"USE_TRAILING_STOP": {
"value": False,
"type": "boolean",
"category": "strategy",
"description": "是否启用移动止损(默认关闭,让利润奔跑)",
},
"SMART_ENTRY_ENABLED": {
"value": False,
"type": "boolean",
"category": "strategy",
"description": "智能入场开关。关闭后回归纯限价单模式",
},
}
for k, meta in ADDITIONAL_STRATEGY_DEFAULTS.items():
if k not in result:
result[k] = meta
logger.info(f"返回全局配置项数量: {len(result)}")
return result
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@router.get("/feasibility-check") @router.get("/feasibility-check")
async def check_config_feasibility( async def check_config_feasibility(
user: Dict[str, Any] = Depends(get_current_user), user: Dict[str, Any] = Depends(get_current_user),
@ -840,136 +971,6 @@ async def get_config_meta(user: Dict[str, Any] = Depends(get_current_user)) -> D
} }
@router.get("/global")
async def get_global_configs(
user: Dict[str, Any] = Depends(get_current_user),
):
"""获取全局策略配置(仅管理员)"""
if (user.get("role") or "user") != "admin":
raise HTTPException(status_code=403, detail="仅管理员可访问全局策略配置")
try:
from database.models import GlobalStrategyConfig
configs = GlobalStrategyConfig.get_all()
logger.info(f"从数据库加载了 {len(configs)} 个全局配置项")
result = {}
for config in configs:
key = config['config_key']
value = GlobalStrategyConfig._convert_value(
config['config_value'],
config['config_type']
)
result[key] = {
"value": value,
"type": config['config_type'],
"category": config['category'],
"description": config.get('description'),
}
logger.debug(f"加载配置项: {key} = {value} (type: {config['config_type']}, category: {config['category']})")
# 添加默认配置(如果数据库中没有)
for k, meta in CORE_STRATEGY_CONFIG_DEFAULTS.items():
if k not in result:
result[k] = meta
# 固定风险百分比配置
FIXED_RISK_CONFIG_DEFAULTS = {
"USE_FIXED_RISK_SIZING": {
"value": True,
"type": "boolean",
"category": "risk",
"description": "使用固定风险百分比计算仓位(凯利公式)。启用后,每笔单子承受的风险固定为 FIXED_RISK_PERCENT避免大额亏损。",
},
"FIXED_RISK_PERCENT": {
"value": 0.02,
"type": "number",
"category": "risk",
"description": "每笔单子承受的风险百分比(相对于总资金)。例如 0.02 表示 2%。启用固定风险后,每笔亏损限制在该百分比内。",
},
}
for k, meta in FIXED_RISK_CONFIG_DEFAULTS.items():
if k not in result:
result[k] = meta
# 添加更多核心策略配置的默认值(确保前端能显示所有重要配置)
ADDITIONAL_STRATEGY_DEFAULTS = {
"USE_ATR_STOP_LOSS": {
"value": True,
"type": "boolean",
"category": "strategy",
"description": "是否使用ATR动态止损优先于固定百分比",
},
"ATR_PERIOD": {
"value": 14,
"type": "number",
"category": "strategy",
"description": "ATR计算周期默认14",
},
"USE_DYNAMIC_ATR_MULTIPLIER": {
"value": False,
"type": "boolean",
"category": "strategy",
"description": "是否根据波动率动态调整ATR倍数",
},
"ATR_MULTIPLIER_MIN": {
"value": 1.5,
"type": "number",
"category": "strategy",
"description": "动态ATR倍数最小值",
},
"ATR_MULTIPLIER_MAX": {
"value": 2.5,
"type": "number",
"category": "strategy",
"description": "动态ATR倍数最大值",
},
"MIN_SIGNAL_STRENGTH": {
"value": 8,
"type": "number",
"category": "strategy",
"description": "最小信号强度0-10只交易高质量信号",
},
"SCAN_INTERVAL": {
"value": 1800,
"type": "number",
"category": "scan",
"description": "市场扫描间隔默认30分钟",
},
"TOP_N_SYMBOLS": {
"value": 8,
"type": "number",
"category": "scan",
"description": "每次扫描后处理的交易对数量",
},
"MIN_VOLUME_24H_STRICT": {
"value": 10000000,
"type": "number",
"category": "scan",
"description": "严格成交量过滤24H Volume低于此值USD直接剔除",
},
"USE_TRAILING_STOP": {
"value": False,
"type": "boolean",
"category": "strategy",
"description": "是否启用移动止损(默认关闭,让利润奔跑)",
},
"SMART_ENTRY_ENABLED": {
"value": False,
"type": "boolean",
"category": "strategy",
"description": "智能入场开关。关闭后回归纯限价单模式",
},
}
for k, meta in ADDITIONAL_STRATEGY_DEFAULTS.items():
if k not in result:
result[k] = meta
logger.info(f"返回全局配置项数量: {len(result)}")
return result
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@router.put("/global/{key}") @router.put("/global/{key}")
async def update_global_config( async def update_global_config(
key: str, key: str,