Skip to content

chore(deps): bump bandit from 1.7.5 to 1.8.6 in /backend#5

Open
dependabot[bot] wants to merge 94 commits into
mainfrom
dependabot/pip/backend/bandit-1.8.6
Open

chore(deps): bump bandit from 1.7.5 to 1.8.6 in /backend#5
dependabot[bot] wants to merge 94 commits into
mainfrom
dependabot/pip/backend/bandit-1.8.6

Conversation

@dependabot

@dependabot dependabot Bot commented on behalf of github Jan 26, 2026

Copy link
Copy Markdown

Bumps bandit from 1.7.5 to 1.8.6.

Release notes

Sourced from bandit's releases.

1.8.6

What's Changed

New Contributors

Full Changelog: PyCQA/bandit@1.8.5...1.8.6

1.8.5

What's Changed

Full Changelog: PyCQA/bandit@1.8.4...1.8.5

1.8.4

What's Changed

New Contributors

... (truncated)

Commits

Dependabot compatibility score

You can trigger a rebase of this PR by commenting @dependabot rebase.


Dependabot commands and options

You can trigger Dependabot actions by commenting on this PR:

  • @dependabot rebase will rebase this PR
  • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
  • @dependabot merge will merge this PR after your CI passes on it
  • @dependabot squash and merge will squash and merge this PR after your CI passes on it
  • @dependabot cancel merge will cancel a previously requested merge and block automerging
  • @dependabot reopen will reopen this PR if it is closed
  • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
  • @dependabot show <dependency name> ignore conditions will show all of the ignore conditions of the specified dependency
  • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)

Note
Automatic rebases have been disabled on this pull request as it has been open for over 30 days.

@dependabot @github

dependabot Bot commented on behalf of github Jan 26, 2026

Copy link
Copy Markdown
Author

Labels

The following labels could not be found: dependencies, python. Please create them before Dependabot can add them to a pull request.

Please fix the above issues or remove invalid values from dependabot.yml.

P0 优化 (预期收益 25-30%):
- 为 PortfolioManagerArray 添加 positions 缓存机制
- 使用 np.nonzero() 向量化查��有持仓的股票
- 在 _execute_buy 和 _execute_sell 中失效缓存

P1 优化 (预期收益 15-20%):
- 在交易执行循环外预先计算 daily_portfolio_value 和 daily_positions
- 避免每个信号验证时重复调用 get_portfolio_value()

预期总提升: 40-50% (execute_trades_batch 从 41s 降至 20-25s)
优化点:
1. 使用 np.argsort(-score_values) 替代 sorted(scores.items(), ...)
2. 向量化 rank_index 查找和排序
3. 减少 Python 循环和 lambda 函数调用

预期效果: 10-15% 性能提升
- 将 use_multiprocessing 默认值改为 True
- 突破 GIL 限制,利用多核 CPU 并行计算
- 预期性能提升: 15-20% (97s → 24s)

优化目标:
- precompute_signals: 97.41s → ~24s (4核并行)
- 预期总耗时: 229.47s → ~156s
- 预期性能提升: 32%
- 在任务详情页添加'重建任务'按钮
- 支持一键复制任务配置到创建页面
- 自动预填充所有参数(股票、策略、日期等)
- 支持回测和预测两种任务类型
- 支持单一策略和组合策略
- 任务名称自动添加'(重建)'后缀

修改文件:
- frontend/src/app/tasks/[id]/page.tsx: 添加重建按钮和逻辑
- frontend/src/app/tasks/create/page.tsx: 添加URL参数解析
- docs/feature-rebuild-task.md: 功能文档
- 问题:重建任务时策略名称、日期等配置未正确填充
- 原因:配置数据在 result.backtest_config 而非 config.backtest_config
- 修复:优先从 result.backtest_config 读取,兼容 config.backtest_config
- 影响:现在可以正确重建包含策略名称、日期、性能监控等完整配置的任务
- 问题:日期字段未填充,因为 ISO 格式(2023-02-04T00:00:00)与 date input 不兼容
- 修复:将日期从 ISO 格式转换为 YYYY-MM-DD 格式
- 影响:现在日期字段可以正确预填充
- 在 handleRebuild 中添加 hyperparameter_optimization 类型处理
  - 传递优化配置(目标指标、试验次数、优化方法等)
  - 传递参数空间配置(param_space)
  - 传递回测基础配置(日期、资金、手续费等)
  - 跳转到 /optimization/create 页面

- 完善 prediction 类型的重建处理
  - 传递模型 ID、预测周期、置信水平
  - 注意置信水平的格式转换(小数 → 百分比)
  - 跳转到 /tasks/create 页面

- 在 optimization/page.tsx 中添加 URL 参数检测
  - 检测 rebuild=true 标志自动切换到创建标签页

- 在 CreateOptimizationTaskForm 中添加 URL 参数解析
  - 解析任务名称、股票代码、策略名称
  - 解析日期范围(YYYY-MM-DD 格式)
  - 解析优化配置(目标指标、方向、试验次数等)
  - 解析参数空间配置(JSON 格式)

技术要点:
- 参考回测任务的实现模式(URL 参数 + useEffect 解析)
- 日期格式转换:ISO → YYYY-MM-DD(使用 split('T')[0])
- 数值类型转换:字符串 → 数字(parseInt/parseFloat)
- 复杂对象使用 JSON.stringify/JSON.parse 传递
- 从 config 顶层读取 start_date 和 end_date(而非 backtest_config)
- 从 optimization_config.objective_config 读取 objective_metric 和 direction
- 从 optimization_config 读取 strategy_name
- 修复 timeout 为 null 时的处理
- 问题:跳转到 /optimization/create 导致 404
- 修复:改为跳转到 /optimization(正确的优化页面路径)
- 减少数据库查询开销
- 预期提升: 8-12秒
- 减少数据库写入次数
- 预期提升: 10-15秒
- 价格数据对齐使用 searchsorted 进行索引映射
- 信号数据对齐同样使用 searchsorted
- 避免 pandas reindex 的开销
- 预期提升: 15-20秒
- 添加任务重建功能(从已完成任务复制配置)
- 修复 TaskStatusCache 导入问题(添加 app/utils/__init__.py)
- 前端支持 URL 参数自动填充任务配置

性能基线:
- 任务 ID: f0ccc89b-e64b-458b-b7cf-5bf5a40fc5d7
- 总收益率: 40.50%
- 夏普比率: 0.4736
- 总耗时: 370秒 (6分10秒)
- 配置: 500只股票, 3年数据, RSI策略
- 添加任务重建功能
- 修复 TaskStatusCache 导入问题
- 前端支持 URL 参数自动填充任务配置
**重构目标**:
- 将 1,656 行的单体文件拆分为模块化结构
- 提高代码可维护性和可读性
- 保持所有 API 接口向后兼容

**拆分方案**:
1. __init__.py (63行) - 主入口,聚合所有子路由
2. models_query.py (307行) - 模型查询功能
   - GET /models - 获取模型列表
   - GET /models/{model_id} - 获取模型详情
   - GET /models/{model_id}/versions - 获取模型版本
   - GET /models/search - 搜索模型

3. models_training.py (888行) - 模型训练功能
   - POST /models/train - 创建训练任务
   - GET /models/available-features - 获取可用特征

4. models_evaluation.py (132行) - 模型评估功能
   - GET /models/{model_id}/evaluation-report - 评估报告
   - GET /models/{model_id}/performance-history - 性能历史

5. models_lifecycle.py (132行) - 生命周期管理
   - GET /models/{model_id}/lifecycle - 生命周期状态
   - GET /models/{model_id}/lineage - 模型血缘
   - GET /models/{model_id}/dependencies - 依赖关系
   - POST /models/{model_id}/lifecycle/transition - 状态转换

6. models_management.py (139行) - 模型管理功能
   - DELETE /models/{model_id} - 删除模型
   - POST /models/{model_id}/tags - 添加标签
   - DELETE /models/{model_id}/tags - 删除标签

7. models_utils.py (183��) - 共享工具函数和全局变量

**代码行数对比**:
- 原文件:1,656 行
- 拆分后:1,844 行(+188 行,主要是模块导入和文档)
- 平均每个模块:264 行

**验证结果**:
✅ 所有文件通过 Python 语法检查
✅ 模块导入成功,无循环依赖
✅ 15 个路由路径完全一致
✅ 路由前缀正确:/models
✅ 保持向后兼容,API 接口不变

**技术细节**:
- 使用 add_api_route 直接注册路由函数,避免空路径冲突
- 保留所有异步函数签名和依赖注入
- 共享全局变量通过 models_utils 统一管理
- 保持原有的错误处理和日志记录逻辑
- 主文件从 2,265 行减少到 261 行 (-88.5%)
- 创建 9 个子组件 (position-analysis/)
- 创建 3 个自定义 hooks (hooks/backtest/)
- 创建 3 个工具函数模块 (utils/backtest/)
- 提高代码可维护性和可测试性
- 主文件从 2,189 行减少到 305 行(减少 86.1%)
- 提取 4 个自定义 Hooks(402 行)
  - useTaskDetail: 任务详情加载和管理
  - useTaskWebSocket: WebSocket 实时更新
  - useBacktestData: 回测详细数据加载
  - useTaskActions: 任务操作处理
- 拆分 9 个 UI 组件(1,658 行)
  - TaskHeader: 页面标题和操作按钮
  - TaskProgress: 任务进度显示
  - TaskInfo: 任务基本信息
  - StrategyConfig: 策略配置展示
  - BacktestTabs: 回测结果标签页
  - PredictionTabs: 预测结果标签页
  - TaskSidebar: 侧边栏
  - DeleteTaskDialog: 删除确认对话框
  - PerformanceMonitor: 性能监控展示
- 提高代码可维护性和可测试性
- 保持所有原有功能不变
- 所有导入路径使用 @/ 别名
- 保持原有的动态导入(dynamic import)
- 主文件从 2,189 行减少到 305 行 (-86.1%)
- 创建 9 �� UI 组件 (components/)
- 创建 4 个自定义 hooks (hooks/)
- 提高代码可维护性和可测试性
- 原文件:1507 行
- 新结构:18 个文件,4 个模块目录
- base/: 基础策略类(StatisticalArbitrageStrategy, FactorStrategy)
- technical/: 技术指标策略(BollingerBand, Stochastic, CCI)
- statistical_arbitrage/: 统计套利策略(PairsTrading, MeanReversion, Cointegration)
- factor/: 因子策略(Value, Momentum, LowVolatility, MultiFactor)
- 创建 factory.py 统一策略工厂
- 保留 strategies.py.backup 备份文件
原文件 2704 行拆分为:
- backtest_executor.py (465行) - 主执行器
- data_preprocessor.py (23KB) - 数据预处理
- backtest_loop_executor.py (57KB) - 回测循环
- report_generator.py (22KB) - 报告生成
- validators.py (6KB) - 参数验证
- performance_tracker.py (2.6KB) - 性能追踪

已修复所有导入错误:
- 添加缺失的类型注解 (Any, Tuple, List, Dict, Optional)
- 修复 BaseStrategy, PortfolioManager 导入路径
- 修复 BacktestConfig 导入 (models.data_models)
- 修复 AdvancedStrategyFactory 引用
- 修复 TaskError 导入 (core.error_handler)
- 添加 TradingSignal 导入
从相对导入改为从子模块导入:
- from .technical.bollinger_band import ...
  → from .technical import ...
- from .statistical_arbitrage.pairs_trading import ...
  → from .statistical_arbitrage import ...
- from .factor.value_factor import ...
  → from .factor import ...

确保与重构后的模块结构一致
- 创建 training/ 目录,按职责拆分为14个模块:
  * config.py: 配置类和枚举 (109行)
  * qlib_check.py: Qlib可用性检查 (51行)
  * data_preprocessing.py: 数据预处理 (197行)
  * dataset_adapter.py: DataFrame到DatasetH适配器 (540行)
  * dataset_preparation.py: 数据集准备 (336行)
  * model_config.py: 模型配置工厂 (267行)
  * training.py: 训练逻辑 (285行)
  * evaluation.py: 模型评估 (178行)
  * feature_analysis.py: 特征分析 (134行)
  * model_io.py: 模型保存/加载 (91行)
  * prediction.py: 预测逻辑 (152行)
  * utility.py: 工具函数 (78行)
  * engine.py: 主引擎类 (465行)
  * __init__.py: 包导出 (18行)

- 主文件改为兼容包装器 (18行)
- 保留原文件为 unified_qlib_training_engine_old.py
- 所有功能完整保留,无 NotImplementedError
- 语法检查通过

参考: backtest_executor.py (2704行 → 465行 + 5模块)
- 补全 model_io.py 的 save_qlib_model 和 load_qlib_model 函数
- 移除 prediction.py 的错误导入,直接在 engine.py 中实现预测逻辑
- 修复 training.py 缺少 pandas 和 EarlyStoppingManager 导入
- 修复 engine.py 中函数名不匹配 (_train_qlib_model)
- 验证通过:所有模块可以正常导入
willrone and others added 28 commits February 12, 2026 08:06
…data, signals, DeleteTaskDialog

- backtest/page: 标题/按钮响应式布局
- predictions/page: 响应式padding/fontSize, 移动端卡片列表
- settings/page: 响应式padding/fontSize, Grid改Box grid, tabs scrollable
- monitoring/page: 响应式fontSize, 统计卡片padding
- data/page: 响应式fontSize, 按钮size适配
- signals/page: 响应式fontSize, dialog margin
- DeleteTaskDialog: 移动端fullScreen
- AppLayout: Drawer variant=temporary, 宽度响应式(80vw/280px), keepMounted
- TradingViewChart: 头部flex-wrap, 图表overflowX+minWidth
- PredictionChart: 摘要卡片2列xs, 响应式fontSize, 图表容器
- BacktestChart: 指标卡片响应式, 图表overflowX+minWidth, 表格minWidth
- EquityCurveChart: 图表容器overflowX+minWidth, 响应式padding
- DrawdownChart: 图表容器overflowX+minWidth, 响应式padding
- MonthlyHeatmapChart: 图表容器overflowX+minWidth, 响应式padding
- InteractiveChartsContainer: allowScrollButtonsMobile, 响应式padding
- SaveStrategyConfigDialog: 移动端fullScreen(useMediaQuery)
- StockSelector: CardHeader flex-wrap, 随机按钮文字缩短, 股票列表2列xs
- BacktestTaskStatus: 任务ID word-break, CardHeader响应式fontSize
- PortfolioStrategyConfig: 策略卡片标题wrap, 权重显示响应式
- CreateOptimizationTaskForm: 标题响应式fontSize, 参数项移动端堆叠, 提交按钮全宽
- BacktestProgressIndicator: 进度条flex-wrap
- PositionAnalysis: Tabs allowScrollButtonsMobile
- ModelListTable: 已有移动端卡片视图,无需额外适配
P0-1: 止损止盈
- 新增 risk_manager.py 模块,独立管理风险逻辑
- 每日持仓检查:浮亏达 stop_loss_pct 触发卖出
- 每日持仓检查:浮盈达 take_profit_pct 触发卖出
- 止损止盈在策略信号之前执行(优先级更高)
- stop_loss_pct/take_profit_pct 为 None 或 0 时不启用

P0-2: 最大回撤熔断
- BacktestConfig 新增 max_drawdown_pct 参数(默认 None)
- 跟踪组合净值历史最高点
- 回撤超过阈值时暂停所有新开仓(保留卖出)
- 回撤缩小到阈值 50% 时恢复开仓
- 回测报告中记录熔断触发次数和���件详情
- 进度更新节流:每50 trials或30秒写一次DB,减少SQLite写入压力
- 最后一个trial必须更新,保证最终状态正确
- Optuna n_jobs=1 改为 n_jobs=4,启用并行trials
- RDBStorage + SQLite timeout=30s 已支持并发访问

.env 配置变更(gitignored,未入库):
- WORKERS=4(从1改为4)
- DEBUG=false(从true改为false)
- PROCESS_POOL_SIZE=6(从3改为6)
P0-1: 修复 preload_async 未传 data_loader 导致缓存完全失效的问题
  - optimizer 创建 DataLoader 并传给 preload_async
  - 一次性加载所有股票数据到内存,所有 trial 共享
  - run_backtest 新增 preloaded_stock_data 参数跳过重复磁盘 I/O

P0-2: 预计算 trading_dates 供所有 trial 复用
  - optimizer 预计算一次 trading_dates
  - run_backtest 新增 precomputed_context 参数跳过重复计算

P0-3: 进度更新节流从 50 trials/30s 提升到 100 trials/60s
  - 减少 SQLite 写入频率,降低锁竞争
- schemas: ParamSpaceConfig 添加 step 字段,n_trials 上限 1000→10000
- optimization API: 传递 step 参数到优化配置
- optimizer: 导入 GridSampler
- 前端表单: 新增网格搜索选项、步长输入框、动态提示
- 新增 task_recovery_service.py: 恢复 running/queued 状态的中断任务
- main.py: 应用启动时调用恢复服务
- 将通用 cache/ 规则改为 /cache/(仅匹配根目录)
- 添加 !backend/app/services/qlib/cache/ 排除规则
- 强制添加 factor_cache.py 和 __init__.py

修复另一台电脑拉取后 ModuleNotFoundError: No module named 'app.services.qlib.cache'
- 指标卡片改为移动端 2 列布局(BacktestOverview, CostAnalysis)
- 风险评估总结改为 3 列紧凑布局
- 成本明细卡片改为 3 列布局,缩小移动端字号
- 操作按钮增加 44px 最小触摸目标(TaskHeader, TaskSidebar, BacktestTaskStatus)
- 按钮文案精简(重建任务→重建,导出结果→导出)
- BacktestTabs 标签栏支持移动端滚动,缩小图标和字号
- StrategyConfig 标题区移动端改为纵向排列
- 页面整体间距响应式调整
- 删除中间 _flush_batch_to_db 调用(每1000条同步写入→0次中间写入)
- 在信号收集时直接设置 executed/execution_reason,避免后续 UPDATE
- 最终写入改用 Raw SQL executemany 替代 ORM add_all
- 删除 batch_update_signal_execution_reasons 和 batch_mark_signals_as_executed 调用
- 预期:回测速度从 19 天/分钟提升到 200-300 天/分钟
P1 参数修复:
- LGBConfig: objective mse, reg_alpha/lambda 0.6→200, num_leaves 45→128,
  max_depth 6→8, lr 0.015→0.05, feature/bagging_fraction 0.65→0.8,
  min_child_samples 100→200
- XGBConfig: eval_metric mae→rmse, reg_alpha/lambda 0.6→200, max_depth 5→8,
  lr 0.015→0.05, subsample/colsample 0.65→0.8, min_child_weight 100→200
- MAX_BOOST_ROUNDS=2000 和 EARLY_STOPPING_ROUNDS=100 已合理,保持不变
- 新增 label_transform.py: 截面排名标准化
  - 每日截面 rank → percentile → inverse normal N(0,1)
  - 处理停牌/缺失(NaN 自动跳过)
  - 截面 < 10 只股票时跳过该日
  - rank percentile 裁剪到 [0.001, 0.999] 避免 ±inf
- TrainingConfig 新增 label_transform 选项
- data_loader.prepare_dataset 集成 CSRankNorm 步骤
三组对比:
- Baseline: 旧参数(huber/reg=0.6) + 原始标签
- B1: 新参数(mse/reg=200) + 原始标签
- B2: 新参数 + CSRankNorm 标签
输出 IC / RankIC / MSE 对比表
reg=200 对 raw return (~0.01) 太强导致模型不学习(1轮即停)。
B1 降为 reg=5 后恢复正常训练(47轮)。
B2(CSRankNorm) 的 RankIC=0.0771 最优(+29% vs baseline)。
reg=200 适配 CSRankNorm (N(0,1)),原始收益率需降到 ~5.0
- label_transform: str = None → Optional[str] = None(符合 PEP 484)
- CSRankNorm 模式下先 winsorize 原始标签再做排名变换(语义正确)
- split_with_embargo 中 CSRankNorm 模式跳过二次 winsorize
- DataFrame 切片处添加 .copy() 避免 SettingWithCopyWarning
- P0: CSRankNorm 截面排名标准化标签变换
- P1: LightGBM/XGBoost 参数对齐 Qlib 官方基准
- A/B 实验验证: RankIC 0.0759 vs Baseline 0.0596 (+27%)
- 修复类型注解、winsorize 顺序、SettingWithCopyWarning
- 新增 enable_cs_rank_norm 配置项(默认 false,保持兼容)
- 实现 CSRankNormTransformer: rank→percentile→clip→ppf(inverse normal)
- 处理边界: 样本数<10跳过、全NaN、全重复值
- winsorize 在 CSRankNorm 之前执行,CSRankNorm 后不再 winsorize
- 前端表单添加 CSRankNorm 开关(仅回归标签时显示)
- API schema/路由全链路透传 enable_cs_rank_norm
…t names, add label quality checks

Root cause: RankIC≈0.99 was caused by:
1. fillna(0) creating 50% zero labels - model just learned has-label vs no-label
2. Alpha158 instrument naming mismatch causing row doubling on concat
3. Cross-sectional label std≈0.0003 making ranking trivial

Fixes:
- _generate_regression_label: keep NaN, dropna before training
- process_stock_data: only fillna(0) on features, not labels
- _create_return_label in adapter: same fix
- _add_alpha_factors: normalize instrument names before concat
- _build_instrument_mapping: canonical format mapping (SH600036 ↔ 600036_SH)
- _check_label_quality: warn on zero_ratio>30%, cross-sectional std<0.001
根因分析:
1. 行数膨胀(3x): Alpha158因子index为(instrument,datetime),
   基础数据index为(datetime,instrument),pd.concat axis=1时
   level顺序不一致导致笛卡尔积效应。
   修复: concat前reorder_levels对齐,concat后检测异常增长并去重。

2. Split 50:50假象: embargo_days=0时,train_dates[:-0]返回空数组
   (Python切片边界情况),且val_dataset指向同一adapter对象,
   len()报告相同值造成误导性日志。
   修复: 增加embargo_days>0判断;新增ValidationDatasetView包装器
   正确报告验证集大小。

测试: 12 passed, 1 skipped (已知pandas行为演示)
- 新增 DOCKER_DEPLOY.md 文件,提供 Docker 生产环境的详细部署步骤和配置。
- 更新 docker-compose.yml,修改后端、前端和 Grafana 服务的端口映射,支持通过环境变量自定义生产端口。
- 修复 Prometheus 端口冲突,调整为 9091。
- 更新 README.md,添加生产环境启动说明和访问地址。
- 后端 Dockerfile 和 requirements.txt 进行了优化,确保依赖安装顺利。
- 新增 run_all_strategies.py 脚本,用于串行回测所有策略并保存结果。
- 在 docker-compose.yml 中添加 DATA_ROOT_PATH 和 QLIB_DATA_PATH 环境变量,确保数据路径配置。
- 更新前端 Dockerfile,添加 NEXT_PUBLIC_BACKEND_HOST 参数以支持后端服务地址配置。
- 新增 run_cointegration_opt.py 脚本,用于独立执行协整优化任务,简化任务管理。
- 优化策略超参数优化器,动态构建 BacktestConfig,增强参数采样的防御机制。
Bumps [bandit](https://github.com/PyCQA/bandit) from 1.7.5 to 1.8.6.
- [Release notes](https://github.com/PyCQA/bandit/releases)
- [Commits](PyCQA/bandit@1.7.5...1.8.6)

---
updated-dependencies:
- dependency-name: bandit
  dependency-version: 1.8.6
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot dependabot Bot force-pushed the dependabot/pip/backend/bandit-1.8.6 branch from 61b80b6 to 578fa61 Compare February 17, 2026 12:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant