diff --git a/DESIGN_DOC_UI_UX.md b/DESIGN_DOC_UI_UX.md new file mode 100644 index 0000000000..099e4e2240 --- /dev/null +++ b/DESIGN_DOC_UI_UX.md @@ -0,0 +1,33 @@ +### 2.1. 模型管理 (Model Management) + +* **目的**: 创建、训练、管理和评估用于预测的机器学习模型。产出可供策略使用的"已训练模型"。 +* **主要页面**: + * **`models.html` (模型列表页)**: + * **功能**: 展示所有已创建的模型及其状态和关键信息。提供新建模型入口。 + * **表格列**: + * 名称 + * 类型 (LightGBM, LSTM, ...) + * **训练周期** (例如: "2018-01-01 - 2022-12-31") + * **训练股票池** (例如: "CSI 300") + * **特征集** (例如: "Alpha158", 使用 `truncate` 显示,`title` 显示完整内容) + * **标签** (例如: "Ref($close,-2)/Ref($close,-1)-1", 使用 `truncate` 显示,`title` 显示完整内容) + * 状态 (草稿, 训练中..., 已训练, 失败) + * 创建时间 + * 操作 (详情/编辑, 训练/重新训练, 删除, 取消训练等,根据状态显示不同按钮) + * **`create_model.html` (新建模型页)**: + * **功能**: 配置并启动一个新的模型训练任务。 + * **卡片/区域**: + * **基本信息**: 模型名称 (必填), 模型描述。 + * **训练配置 (Training Configuration - 新增)**: + * 训练开始日期 (必填, `date`) + * 训练结束日期 (必填, `date`) + * 训练股票池 (必填, `select`, 包含 CSI 300, CSI 500, 全市场A股等) + * 所用特征集 (必填, `text`, placeholder: "例如: Alpha158, VWAP") + * 标签/预测目标 (必填, `text`, placeholder: "例如: Ref($close,-2)/Ref($close,-1)-1") + * **模型配置 (Model Configuration)**: + * 模型类型 (必填, `select`, LightGBM, LSTM, ...) + * 模型参数 (根据类型动态显示常用参数输入,或提供高级 YAML/JSON 配置入口) + * **数据配置 (Data Configuration - 已精简)**: *此部分原始目的是映射 Qlib DataHandler 配置。为避免与"训练配置"重复,已移除标的范围(Universe)、特征、标签、训练期、验证期等字段。当前仅保留"数据源"和"数据频率"字段,用于定义基础数据访问信息。其最终必要性待后续审视。* + * **操作按钮**: 取消, 保存草稿, **保存并开始训练**。 + * **`edit_model.html` (编辑/详情页)**: + * **功能**: 查看模型详细配置、训练状态、训练日志(未来)、评估结果(未来),并可编辑配置(对于草稿状态)或触发重新训练。 \ No newline at end of file diff --git a/examples/benchmarks/LSTM/workflow_config_lstm_Alpha158.yaml b/examples/benchmarks/LSTM/workflow_config_lstm_Alpha158.yaml index 522f6443cb..c967da66b5 100755 --- a/examples/benchmarks/LSTM/workflow_config_lstm_Alpha158.yaml +++ b/examples/benchmarks/LSTM/workflow_config_lstm_Alpha158.yaml @@ -17,18 +17,14 @@ data_handler_config: &data_handler_config "ROC60", "RESI10", "VSTD5", "RSQR60", "CORR60", "WVMA60", "STD5", "RSQR20", "CORD60", "CORD10", "CORR20", "KLOW" ] - - class: RobustZScoreNorm + - class: ZScoreNorm kwargs: fields_group: feature - clip_outlier: true - class: Fillna kwargs: fields_group: feature learn_processors: - class: DropnaLabel - - class: CSRankNorm - kwargs: - fields_group: label label: ["Ref($close, -2) / Ref($close, -1) - 1"] port_analysis_config: &port_analysis_config @@ -59,13 +55,13 @@ task: hidden_size: 64 num_layers: 2 dropout: 0.0 - n_epochs: 200 - lr: 1e-3 + n_epochs: 20 + lr: 1e-5 early_stop: 10 batch_size: 800 metric: loss loss: mse - n_jobs: 20 + n_jobs: 8 GPU: 0 dataset: class: TSDatasetH diff --git a/my_work/cursor_rules.md b/my_work/cursor_rules.md new file mode 100644 index 0000000000..4370d450bc --- /dev/null +++ b/my_work/cursor_rules.md @@ -0,0 +1,23 @@ +# Cursor AI Assistant Rules & Context + +## Project Goal +Learn the Qlib framework for quantitative trading by studying its source code. + +## Qlib Source Location +The main Qlib source code is located at the workspace root: `/Users/chengzheng/workspace/trade/qlib` + +## User Workspace +My personal learning scripts and experiments related to Qlib will be created and stored within the `/Users/chengzheng/workspace/trade/qlib/my_work/` directory. Please place any new scripts or generated files here unless otherwise specified. + +## Learning Objectives +- Master the application of all algorithms within Qlib for quantitative trading, including strategy design and backtesting. +- Select and implement specific AI algorithms (learned through Qlib) to build custom trading strategies. +- Gain knowledge in Deep Learning (DL) and Reinforcement Learning (RL) concepts, particularly their application in quantitative finance, potentially using Qlib examples. +- Understand the overall architecture and design principles of the Qlib framework, referencing official documentation (e.g., [Qlib Quick Start](https://www.wuzao.com/document/qlib/introduction/quick.html)) and source code, to enable effective modular usage and customization. + +## Interaction Style +- Assume I have access to the Qlib source code in the specified location. +- When discussing code, refer to file paths relative to the Qlib root (`/Users/chengzheng/workspace/trade/qlib`). +- When creating new code or examples for me, place them in the `my_work/` directory. +- Follow the RIPER-5 protocol for structured interaction. +- Prioritize Chinese for general conversation, while adhering to the protocol's format requirements for specific elements (e.g., mode declarations, checklists). \ No newline at end of file diff --git "a/my_work/doc/QLib\346\225\260\346\215\256\345\212\240\350\275\275\344\270\216\347\211\271\345\276\201\345\244\204\347\220\206\350\257\246\350\247\243.md" "b/my_work/doc/QLib\346\225\260\346\215\256\345\212\240\350\275\275\344\270\216\347\211\271\345\276\201\345\244\204\347\220\206\350\257\246\350\247\243.md" new file mode 100644 index 0000000000..371c7b4352 --- /dev/null +++ "b/my_work/doc/QLib\346\225\260\346\215\256\345\212\240\350\275\275\344\270\216\347\211\271\345\276\201\345\244\204\347\220\206\350\257\246\350\247\243.md" @@ -0,0 +1,932 @@ +# QLib数据加载与特征处理详解 + +## 目录 + +- [1. 概述](#1-概述) +- [2. 数据加载流程](#2-数据加载流程) + - [2.1 初始化阶段](#21-初始化阶段) + - [2.2 数据加载器配置](#22-数据加载器配置) + - [2.3 实际数据加载过程](#23-实际数据加载过程) + - [2.4 时间范围的使用](#24-时间范围的使用) +- [3. 特征计算流程](#3-特征计算流程) + - [3.1 特征配置生成](#31-特征配置生成) + - [3.2 表达式计算](#32-表达式计算) + - [3.3 特征标准化和归一化](#33-特征标准化和归一化) + - [3.4 Alpha158特征详解](#34-alpha158特征详解) +- [4. 数据处理流程](#4-数据处理流程) + - [4.1 处理器初始化](#41-处理器初始化) + - [4.2 数据处理执行](#42-数据处理执行) + - [4.3 处理器拟合](#43-处理器拟合) + - [4.4 infer_processors和learn_processors详解](#44-infer_processors和learn_processors详解) +- [5. 常用处理器详解](#5-常用处理器详解) + - [5.1 RobustZScoreNorm(稳健Z分数标准化)](#51-robustzscorenorm稳健z分数标准化) + - [5.2 CSZScoreNorm(截面Z分数标准化)](#52-cszscorenorm截面z分数标准化) + - [5.3 Fillna(填充缺失值)](#53-fillna填充缺失值) + - [5.4 DropnaLabel(删除缺失标签)](#54-dropnalabel删除缺失标签) +- [6. 数据处理的特殊化处理](#6-数据处理的特殊化处理) + - [6.1 处理类型(process_type)](#61-处理类型process_type) + - [6.2 拟合时间范围](#62-拟合时间范围) + - [6.3 特征分组处理](#63-特征分组处理) + - [6.4 缓存机制](#64-缓存机制) + - [6.5 并行处理](#65-并行处理) +- [7. 完整流程示例](#7-完整流程示例) +- [8. 常见问题解答](#8-常见问题解答) + - [8.1 特征计算的时间范围](#81-特征计算的时间范围) + - [8.2 处理器的作用和区别](#82-处理器的作用和区别) + - [8.3 如何自定义处理器](#83-如何自定义处理器) +- [9. 总结](#9-总结) + +## 1. 概述 + +QLib是一个用于量化投资的开源Python库,提供了强大的数据加载和特征处理功能。本文档详细介绍QLib的数据加载和特征处理流程,包括各个阶段的具体操作和特殊处理方法。 + +Alpha158是QLib中的一个重要数据处理组件,它是一个特征工程工具,用于从原始金融市场数据中提取158个金融因子(特征)。这些特征可以用于量化投资模型的训练和预测。 + +## 2. 数据加载流程 + +### 2.1 初始化阶段 + +当用户创建一个数据处理器(如Alpha158)时,会经历以下初始化步骤: + +```python +h = Alpha158( + instruments="csi300", # 股票池 + start_time="2008-01-01", # 开始时间 + end_time="2020-08-01", # 结束时间 + fit_start_time="2008-01-01", # 拟合开始时间 + fit_end_time="2014-12-31", # 拟合结束时间 + infer_processors=[...], # 推理处理器 + learn_processors=[...], # 学习处理器 +) +``` + +这些参数会被传递给`DataHandlerLP`的初始化方法,然后: + +1. 创建数据加载器(DataLoader)配置 +2. 设置处理器(Processors) +3. 调用`setup_data`方法加载数据 + +### 2.2 数据加载器配置 + +Alpha158会创建一个数据加载器配置: + +```python +data_loader = { + "class": "QlibDataLoader", + "kwargs": { + "config": { + "feature": self.get_feature_config(), # 特征配置 + "label": self.get_label_config(), # 标签配置 + }, + "filter_pipe": filter_pipe, # 过滤管道 + "freq": freq, # 数据频率 + "inst_processors": inst_processors, # 实例处理器 + }, +} +``` + +### 2.3 实际数据加载过程 + +在`DataHandler`的`setup_data`方法中,会调用数据加载器的`load`方法: + +```python +self._data = lazy_sort_index(self.data_loader.load(self.instruments, self.start_time, self.end_time)) +``` + +这个过程包括: + +1. **QlibDataLoader初始化**:解析特征和标签配置 +2. **数据加载**:调用`load`方法,传入股票池和时间范围 +3. **表达式计算**:对于每个特征表达式,QLib会使用内部的表达式引擎计算结果 +4. **数据过滤**:根据股票池和时间范围过滤数据 +5. **数据组装**:将所有特征和标签组装成一个DataFrame + +### 2.4 时间范围的使用 + +在QLib中,有几个不同的时间范围参数: + +- **数据时间范围**:由`start_time`和`end_time`定义,指定要加载的所有数据的时间范围 +- **训练时间范围**:由`fit_start_time`和`fit_end_time`定义,指定用于训练模型和拟合处理器的数据时间范围 + +特征计算会在**整个数据时间范围**(`start_time`到`end_time`)内进行,而不仅仅是训练时间范围。这是因为: + +1. 模型训练需要训练数据(通常是历史数据) +2. 模型评估需要验证数据(通常是训练数据之后的一段时间) +3. 模型应用需要测试数据(通常是最新的数据) + +而`fit_start_time`和`fit_end_time`主要用于: + +1. **处理器的拟合**:处理器需要学习数据的统计特性,为了避免未来信息泄露,这些统计特性只应该从训练数据中学习 +2. **数据集划分**:将数据划分为训练集、验证集和测试集 + +## 3. 特征计算流程 + +### 3.1 特征配置生成 + +Alpha158通过`get_feature_config`方法生成特征配置: + +```python +def get_feature_config(self): + conf = { + "kbar": {}, # K线特征 + "price": { + "windows": [0], # 时间窗口 + "feature": ["OPEN", "HIGH", "LOW", "VWAP"], # 价格特征 + }, + "rolling": {}, # 滚动特征 + } + return Alpha158DL.get_feature_config(conf) +``` + +然后`Alpha158DL.get_feature_config`方法会根据配置生成具体的特征表达式和名称。 + +### 3.2 表达式计算 + +QLib使用一个表达式引擎来计算特征。表达式引擎支持各种操作符,如: + +- **Ref**:引用过去或未来的数据 +- **Mean**:计算移动平均 +- **Std**:计算标准差 +- **Max/Min**:计算最大/最小值 +- **Rank**:计算排名 +- **Corr**:计算相关性 +- 等等... + +这些操作符在`qlib/data/ops.py`中定义,例如: + +```python +class Mean(Rolling): + """Rolling Mean (MA)""" + def __init__(self, feature, N): + super(Mean, self).__init__(feature, N, "mean") +``` + +### 3.3 特征标准化和归一化 + +Alpha158中的特征通常会进行标准化处理,主要有两种方式: + +1. **内置标准化**:在特征表达式中直接除以收盘价,如`"$open/$close"` +2. **处理器标准化**:通过`infer_processors`中的处理器进行,如`RobustZScoreNorm` + +### 3.4 Alpha158特征详解 + +Alpha158中的特征可以分为以下几类: + +1. **K线特征(9个)**:基于开盘价、收盘价、最高价、最低价计算的特征 +2. **价格特征**:原始价格数据 +3. **成交量特征**:成交量数据 +4. **滚动特征(最多可达140个)**:基于滚动窗口计算的各种技术指标 + +滚动特征是Alpha158的核心,包含了大量基于滚动窗口计算的技术指标。默认的滚动窗口大小为[5, 10, 20, 30, 60]天。主要包括: + +- **ROC(价格变化率)**:过去d天的价格变化率 +- **MA(移动平均线)**:过去d天的简单移动平均线 +- **STD(标准差)**:过去d天收盘价的标准差 +- **BETA(斜率)**:过去d天价格变化的斜率 +- **RSQR(R方值)**:过去d天线性回归的R方值,表示趋势的线性程度 +- **RESI(残差)**:过去d天线性回归的残差,表示过去d天趋势的线性程度 +- **MAX(最高价)**:过去d天的最高价 +- **LOW(最低价)**:过去d天的最低价 +- **QTLU(上分位数)**:过去d天收盘价的80%分位数 +- **QTLD(下分位数)**:过去d天收盘价的20%分位数 +- **RANK(排名)**:当前收盘价在过去d天收盘价中的百分位排名 +- **RSV(相对强弱值)**:当前价格在过去d天价格区间中的位置 +- **IMAX(最高价天数)**:当前日期与过去d天最高价日期之间的天数 +- **IMIN(最低价天数)**:当前日期与过去d天最低价日期之间的天数 +- **IMXD(高低价时间差)**:过去d天最高价日期与最低价日期之间的天数差 +- **CORR(相关性)**:收盘价与成交量的相关性 +- **CORD(变化率相关性)**:价格变化率与成交量变化率的相关性 +- **CNTP(上涨天数比例)**:过去d天中价格上涨的天数比例 +- **CNTN(下跌天数比例)**:过去d天中价格下跌的天数比例 +- **CNTD(上涨下跌天数差)**:过去d天中上涨天数与下跌天数的差值 +- **SUMP(总涨幅/总变化)**:过去d天中总涨幅与总价格变化的比值(类似RSI指标) +- **SUMN(总跌幅/总变化)**:过去d天中总跌幅与总价格变化的比值 +- **SUMD(涨跌幅差值比)**:过去d天中总涨幅与总跌幅的差值比 +- **VMA(成交量移动平均)**:过去d天的成交量移动平均 +- **VSTD(成交量标准差)**:过去d天成交量的标准差 +- **WVMA(加权成交量波动率)**:成交量加权的价格变化波动率 +- **VSUMP(成交量增加比例)**:过去d天中成交量增加的比例 +- **VSUMN(成交量减少比例)**:过去d天中成交量减少的比例 +- **VSUMD(成交量增减差值比)**:过去d天中成交量增加与减少的差值比 + +## 4. 数据处理流程 + +### 4.1 处理器初始化 + +在Alpha158初始化时,会设置`infer_processors`和`learn_processors`: + +```python +infer_processors = [ + {"class": "RobustZScoreNorm", "kwargs": {"fields_group": "feature", "clip_outlier": true}}, + {"class": "Fillna", "kwargs": {"fields_group": "feature"}} +] + +learn_processors = [ + {"class": "DropnaLabel"}, + {"class": "CSZScoreNorm", "kwargs": {"fields_group": "label"}} +] +``` + +这些处理器配置会被转换为实际的处理器对象。 + +### 4.2 数据处理执行 + +在`DataHandlerLP`的`process_data`方法中,会按照以下流程处理数据: + +``` +原始数据(self._data) -> 共享处理器(shared_processors) -> 推理处理器(infer_processors) -> 学习处理器(learn_processors) +``` + +具体代码流程: + +```python +def process_data(self, with_fit: bool = False): + # 处理共享数据 + _shared_df = self._data + _shared_df = self._run_proc_l(_shared_df, self.shared_processors, with_fit=with_fit, check_for_infer=True) + + # 处理推理数据 + _infer_df = _shared_df + _infer_df = self._run_proc_l(_infer_df, self.infer_processors, with_fit=with_fit, check_for_infer=True) + self._infer = _infer_df + + # 处理学习数据 + if self.process_type == DataHandlerLP.PTYPE_I: + _learn_df = _shared_df # 独立模式 + elif self.process_type == DataHandlerLP.PTYPE_A: + _learn_df = _infer_df # 附加模式 + _learn_df = self._run_proc_l(_learn_df, self.learn_processors, with_fit=with_fit, check_for_infer=False) + self._learn = _learn_df +``` + +### 4.3 处理器拟合 + +如果`with_fit=True`,处理器会先调用`fit`方法学习数据的统计特性,然后再调用`__call__`方法处理数据: + +```python +@staticmethod +def _run_proc_l(df, proc_l, with_fit, check_for_infer): + for proc in proc_l: + if check_for_infer and not proc.is_for_infer(): + raise TypeError("Only processors usable for inference can be used in `infer_processors`") + if with_fit: + proc.fit(df) # 拟合处理器 + df = proc(df) # 应用处理器 + return df +``` + +### 4.4 infer_processors和learn_processors详解 + +`infer_processors`和`learn_processors`是应用于已经计算好的特征的处理器,它们在特征计算完成后对数据进行进一步的处理。 + +#### infer_processors(推理处理器) + +`infer_processors`主要用于处理**用于模型推理(预测)的数据**。它们的主要作用包括: + +- **数据标准化**:使特征分布更适合模型处理,如`RobustZScoreNorm` +- **缺失值处理**:填充或处理特征中的缺失值,如`Fillna` +- **异常值处理**:处理或裁剪异常值,如`RobustZScoreNorm`中的`clip_outlier`参数 +- **特征转换**:对特征进行变换,如对数变换、幂变换等 + +#### learn_processors(学习处理器) + +`learn_processors`主要用于处理**用于模型训练的数据**,特别是标签数据。它们的主要作用包括: + +- **标签标准化**:对标签进行标准化,如`CSZScoreNorm`(截面Z分数标准化) +- **样本过滤**:过滤不适合训练的样本,如`DropnaLabel`(删除标签为空的样本) +- **标签变换**:对标签进行变换,使其更适合模型学习 +- **样本权重调整**:调整不同样本的权重 + +#### infer_processors 和 learn_processors 的区别 + +1. **处理对象不同** + - **infer_processors**:主要处理特征(feature)数据 + - **learn_processors**:主要处理标签(label)数据,有时也会处理特征数据 + +2. **应用场景不同** + - **infer_processors**:用于模型推理阶段,也用于训练阶段的特征预处理 + - **learn_processors**:仅用于模型训练阶段 + +3. **处理顺序不同** + 在`process_type=PTYPE_A`(附加模式)下: + - 先应用`infer_processors` + - 再应用`learn_processors` + +4. **信息使用限制不同** + - **infer_processors**:不能使用标签信息或未来信息 + - **learn_processors**:可以使用标签信息,但仍不应使用未来信息 + +## 5. 常用处理器详解 + +### 5.1 RobustZScoreNorm(稳健Z分数标准化) + +这是一个特殊的标准化处理器,用于处理异常值: + +```python +class RobustZScoreNorm(Processor): + """Robust ZScore Normalization""" + + def __init__(self, fields_group=None, clip_outlier=True): + self.fields_group = fields_group + self.clip_outlier = clip_outlier + + def fit(self, df): + # 计算每个特征的中位数和中位绝对偏差 + self.median = df[self.fields].median() + self.mad = (df[self.fields] - self.median).abs().median() + + def __call__(self, df): + # 应用稳健Z分数标准化 + df_copy = df.copy() + df_copy[self.fields] = (df_copy[self.fields] - self.median) / (self.mad * 1.4826) + + # 可选:裁剪异常值 + if self.clip_outlier: + df_copy[self.fields] = df_copy[self.fields].clip(-3, 3) + + return df_copy +``` + +与普通的Z分数标准化不同,稳健Z分数使用中位数和中位绝对偏差(MAD)而不是均值和标准差,这使得它对异常值不敏感。 + +### 5.2 CSZScoreNorm(截面Z分数标准化) + +这个处理器在每个时间点对所有股票进行标准化,常用于标签处理: + +```python +class CSZScoreNorm(Processor): + """Cross Sectional ZScore Normalization""" + + def __init__(self, fields_group=None): + self.fields_group = fields_group + + def __call__(self, df): + # 按时间点分组,对每组应用Z分数标准化 + cols = get_group_columns(df, self.fields_group) + df[cols] = df[cols].groupby("datetime").apply(lambda x: (x - x.mean()) / x.std()) + return df +``` + +### 5.3 Fillna(填充缺失值) + +用于填充特征中的缺失值: + +```python +class Fillna(Processor): + """Fill NA values in the features""" + + def __init__(self, fields_group=None, fill_value=0): + self.fields_group = fields_group + self.fill_value = fill_value + + def __call__(self, df): + cols = get_group_columns(df, self.fields_group) + df[cols] = df[cols].fillna(self.fill_value) + return df +``` + +### 5.4 DropnaLabel(删除缺失标签) + +删除标签为缺失值的样本: + +```python +class DropnaLabel(Processor): + """Drop samples with NA in label""" + + def __call__(self, df): + label_cols = get_group_columns(df, "label") + return df.dropna(subset=label_cols) +``` + +## 6. 数据处理的特殊化处理 + +### 6.1 处理类型(process_type) + +QLib支持两种处理类型: + +1. **PTYPE_I(独立模式)**: + ``` + 原始数据 -> 共享处理器 -> 推理处理器 + \ + -> 学习处理器 + ``` + +2. **PTYPE_A(附加模式)**: + ``` + 原始数据 -> 共享处理器 -> 推理处理器 -> 学习处理器 + ``` + +独立模式适用于推理和学习需要不同处理流程的情况,而附加模式适用于学习处理是在推理处理基础上进行的情况。 + +### 6.2 拟合时间范围 + +处理器的拟合通常只在特定的时间范围内进行,以避免未来信息泄露: + +```python +fit_start_time="2008-01-01" # 拟合开始时间 +fit_end_time="2014-12-31" # 拟合结束时间 +``` + +这确保了模型只使用历史数据来学习数据的统计特性。 + +### 6.3 特征分组处理 + +QLib支持按特征组进行处理,常见的分组有: + +- **feature**:所有特征列 +- **label**:所有标签列 +- 自定义分组:可以指定特定的列名模式 + +这使得可以对不同类型的数据应用不同的处理方法。 + +### 6.4 缓存机制 + +为了提高性能,QLib实现了数据缓存机制: + +```python +def setup_data(self, enable_cache: bool = False): + # 如果启用缓存,会尝试从缓存加载数据 + if enable_cache: + # 缓存处理逻辑... +``` + +### 6.5 并行处理 + +对于大规模数据,QLib支持并行处理: + +```python +def parallel_process(self, n_jobs=-1): + """并行处理数据""" + # 并行处理逻辑... +``` + +## 7. 完整流程示例 + +以下是使用Alpha158的完整流程示例: + +```python +import qlib +from qlib.contrib.data.handler import Alpha158 + +# 1. 初始化QLib +qlib.init(provider_uri="~/.qlib/qlib_data/cn_data", region="cn") + +# 2. 创建数据处理器 +handler = Alpha158( + instruments="csi300", # 股票池:沪深300成分股 + start_time="2008-01-01", # 数据开始时间 + end_time="2020-08-01", # 数据结束时间 + fit_start_time="2008-01-01", # 拟合开始时间 + fit_end_time="2014-12-31", # 拟合结束时间 + infer_processors=[ + {"class": "RobustZScoreNorm", "kwargs": {"fields_group": "feature", "clip_outlier": True}}, + {"class": "Fillna", "kwargs": {"fields_group": "feature"}} + ], + learn_processors=[ + {"class": "DropnaLabel"}, + {"class": "CSZScoreNorm", "kwargs": {"fields_group": "label"}} + ], + process_type="A", # 附加模式 +) + +# 3. 获取处理后的数据 +feature_df = handler.fetch(col_set="feature") # 获取特征数据 +label_df = handler.fetch(col_set="label") # 获取标签数据 +``` + +## 8. 常见问题解答 + +### 8.1 特征计算的时间范围 + +**问题**:特征计算是只会在训练时间范围上进行计算吗? + +**回答**:特征计算会在整个指定的数据时间范围(`start_time`到`end_time`)内进行,而不仅限于训练时间范围(`fit_start_time`到`fit_end_time`)。训练时间范围主要用于处理器的拟合和数据集划分,以避免未来信息泄露。 + +在实际应用中,通常会将数据划分为训练集、验证集和测试集: + +``` +全部数据时间范围(start_time到end_time) +|-------------------------------------------| +| | +|训练集 |验证集 |测试集 | +|-----------------|------------|------------| +fit_start_time fit_end_time end_time +``` + +### 8.2 处理器的作用和区别 + +**问题**:infer_processors和learn_processors是干什么的? + +**回答**:`infer_processors`和`learn_processors`是应用于已经计算好的特征的处理器,它们在特征计算完成后对数据进行进一步的处理: + +- **infer_processors**:处理用于模型推理的特征数据,主要进行特征标准化、缺失值处理等 +- **learn_processors**:处理用于模型训练的数据,特别是标签数据,主要进行标签标准化、样本过滤等 + +### 8.3 如何自定义处理器 + +**问题**:如何创建自定义处理器? + +**回答**:您可以创建自定义处理器来满足特定需求: + +```python +class MyCustomProcessor(Processor): + def __init__(self, param1, param2): + self.param1 = param1 + self.param2 = param2 + + def fit(self, df): + # 学习数据统计特性 + pass + + def __call__(self, df): + # 处理数据 + return processed_df +``` + +然后在`infer_processors`或`learn_processors`中使用它: + +```python +infer_processors = [ + {"class": "MyCustomProcessor", "kwargs": {"param1": value1, "param2": value2}} +] +``` + +## 9. 总结 + +QLib的数据加载和特征处理流程是一个复杂而强大的系统,它包括: + +1. **数据加载**:通过DataLoader加载原始数据,支持多种数据源和过滤条件 +2. **特征计算**:使用表达式引擎计算各种技术指标和特征 +3. **数据处理**:通过处理器链对数据进行标准化、缺失值处理等 +4. **特殊化处理**:支持不同的处理模式、拟合时间范围、特征分组等 + +Alpha158是QLib中的一个重要组件,它提供了158个金融因子,涵盖了价格趋势、波动性、动量、相关性等多个方面,为量化投资模型提供了丰富的输入信息。 + +通过合理配置数据加载和处理流程,可以使数据更适合模型训练和推理,提高模型性能。 + +## 10. QLib数据存储结构与时间范围过滤机制 + +### 10.1 QLib数据存储结构 + +QLib的数据存储结构是经过精心设计的,以支持高效的数据访问和过滤。主要包括以下几个部分: + +#### 10.1.1 股票池文件(instruments目录) + +`~/.qlib/qlib_data/cn_data/instruments`目录下的文件(如`csi300.txt`)定义了各个股票池包含的股票代码。例如,`csi300.txt`包含沪深300指数的成分股列表。 + +这些文件的内容通常是股票代码的列表,例如: +``` +SH600000 +SH600004 +SH600009 +... +``` + +#### 10.1.2 特征数据(features目录) + +`~/.qlib/qlib_data/cn_data/features`目录存储了所有股票的特征数据。这些数据通常以二进制格式(.bin文件)存储,以提高读取效率。 + +虽然这些.bin文件本身没有明显的时间范围标记,但QLib内部维护了一个索引结构,使其能够高效地按时间范围访问数据。 + +#### 10.1.3 特征元数据(calendars目录) + +`~/.qlib/qlib_data/cn_data/calendars`目录存储了交易日历信息,定义了哪些日期是交易日。 + +#### 10.1.4 股票元数据(instruments目录下的其他文件) + +除了股票池文件外,instruments目录还可能包含股票的元数据,如上市日期、退市日期等信息。 + +### 10.2 QLib如何根据时间范围过滤数据 + +当您指定`start_time`和`end_time`参数时,QLib通过以下机制确定要获取哪部分时间的特征数据: + +#### 10.2.1 内部索引结构 + +QLib在加载数据时会构建内部索引结构,这个结构将股票代码、日期和特征值关联起来。这个索引结构使QLib能够高效地按时间范围和股票代码过滤数据。 + +#### 10.2.2 数据加载过程 + +当您调用`handler.fetch`或在初始化DataHandler时,QLib会执行以下步骤: + +1. **解析时间范围**:将`start_time`和`end_time`转换为标准格式 +2. **获取交易日列表**:从calendars目录获取指定时间范围内的交易日 +3. **过滤股票列表**:根据instruments文件获取股票列表 +4. **加载特征数据**:从features目录加载特定股票在特定时间范围内的特征数据 + +#### 10.2.3 二进制数据文件的内部结构 + +虽然.bin文件看起来没有明显的时间标记,但它们内部是有结构的: + +- 数据通常按股票代码和日期组织 +- 每个股票的数据包含时间索引,使QLib能够快速定位特定日期的数据 +- 这种结构使QLib能够只读取需要的数据部分,而不是加载整个文件 + +### 10.3 具体实现细节 + +#### 10.3.1 数据提供器(Provider) + +QLib使用Provider类来管理底层数据访问。主要的Provider是`LocalProvider`,它负责从本地文件系统读取数据。 + +```python +class LocalProvider(Provider): + def __init__(self, data_dir): + self.data_dir = data_dir + # 初始化各种路径 + self.instruments_dir = os.path.join(data_dir, "instruments") + self.features_dir = os.path.join(data_dir, "features") + self.calendars_dir = os.path.join(data_dir, "calendars") +``` + +#### 10.3.2 特征存储(FeatureStorage) + +QLib使用FeatureStorage类来管理特征数据的存储和访问。它提供了按时间范围和股票代码过滤数据的功能。 + +```python +class FeatureStorage: + def __init__(self, data_dir): + self.data_dir = data_dir + # 加载元数据和索引 + self._load_metadata() + + def get_feature(self, instrument, field, start_time=None, end_time=None): + # 根据时间范围过滤数据 + start_idx, end_idx = self._locate_time_range(instrument, start_time, end_time) + # 从文件中读取特定范围的数据 + return self._read_data(instrument, field, start_idx, end_idx) +``` + +#### 10.3.3 时间索引定位 + +QLib使用二分查找等算法快速定位时间范围在索引中的位置: + +```python +def _locate_time_range(self, instrument, start_time, end_time): + # 获取股票的时间索引 + time_index = self._get_instrument_time_index(instrument) + + # 如果未指定时间范围,返回全部数据的索引 + if start_time is None and end_time is None: + return 0, len(time_index) + + # 使用二分查找定位开始时间 + if start_time is not None: + start_idx = bisect.bisect_left(time_index, start_time) + else: + start_idx = 0 + + # 使用二分查找定位结束时间 + if end_time is not None: + end_idx = bisect.bisect_right(time_index, end_time) + else: + end_idx = len(time_index) + + return start_idx, end_idx +``` + +#### 10.3.4 数据读取优化 + +为了提高性能,QLib使用了多种优化技术: + +- **内存映射**:使用mmap技术直接映射文件到内存,避免全部加载 +- **缓存机制**:缓存常用数据,减少重复读取 +- **并行处理**:在可能的情况下并行加载多个股票的数据 + +### 10.4 实际例子 + +假设您有以下代码: + +```python +handler = Alpha158( + instruments="csi300", + start_time="2018-01-01", + end_time="2019-12-31", + # 其他参数... +) +``` + +QLib会执行以下步骤: + +1. 从`~/.qlib/qlib_data/cn_data/instruments/csi300.txt`读取股票列表 +2. 从`~/.qlib/qlib_data/cn_data/calendars`获取2018-01-01到2019-12-31之间的交易日 +3. 对于每个股票,从`~/.qlib/qlib_data/cn_data/features`加载该时间范围内的特征数据 +4. 使用内部索引结构快速定位每个股票在特定时间范围内的数据位置 +5. 只读取需要的数据部分,而不是整个文件 + +### 10.5 总结 + +QLib通过精心设计的数据存储结构和索引机制,能够高效地根据指定的时间范围和股票池过滤数据: + +1. **股票池文件**(如csi300.txt)定义了要处理的股票列表 +2. **特征数据文件**(.bin文件)存储了所有股票的特征数据 +3. **内部索引结构**使QLib能够快速定位特定时间范围的数据 +4. **优化技术**(如内存映射、缓存)提高了数据访问效率 + +虽然.bin文件本身没有明显的时间范围标记,但QLib通过内部索引结构和元数据,能够高效地按时间范围访问数据,只加载需要的部分,而不是整个文件。 + +这种设计使QLib能够处理大规模的金融数据,同时保持高效的数据访问性能。 + +## 11. 数据存储与模型训练/预测的关系 + +### 11.1 数据的存储位置 + +在QLib中,数据加载和处理完成后,数据主要存储在`DataHandlerLP`类的实例属性中。具体来说,有三个关键的数据存储位置: + +#### 11.1.1 原始数据:`self._data` + +这是从数据加载器加载的原始数据,包含所有计算出的特征和标签,没有经过任何处理器的处理。 + +```python +# 在DataHandler的setup_data方法中 +self._data = lazy_sort_index(self.data_loader.load(self.instruments, self.start_time, self.end_time)) +``` + +#### 11.1.2 推理数据:`self._infer` + +这是经过推理处理器处理后的数据,适用于模型预测阶段。 + +```python +# 在DataHandlerLP的process_data方法中 +_infer_df = self._run_proc_l(_shared_df, self.infer_processors, with_fit=with_fit, check_for_infer=True) +self._infer = _infer_df +``` + +#### 11.1.3 学习数据:`self._learn` + +这是经过学习处理器处理后的数据,适用于模型训练阶段。 + +```python +# 在DataHandlerLP的process_data方法中 +_learn_df = self._run_proc_l(_learn_df, self.learn_processors, with_fit=with_fit, check_for_infer=False) +self._learn = _learn_df +``` + +### 11.2 数据的访问方式 + +QLib提供了统一的接口来访问这些数据,主要通过`DataHandlerLP`类的`fetch`方法: + +```python +def fetch(self, selector: Union[pd.Timestamp, slice, str] = None, level: Union[str, int] = None, + col_set=DataHandlerLP.DK_I, data_key=DK_I, **kwargs) -> pd.DataFrame: + """ + Fetch data from underlying data source + + Parameters + ---------- + selector : Union[pd.Timestamp, slice, str] + Data selector. + level : Union[str, int] + The level of the index to be used. + col_set : str + The col_set will be passed to self.get_cols. + data_key : str + The data to fetch: + - DK_I: infer data + - DK_L: learn data + - DK_R: raw data + """ +``` + +其中,`col_set`参数指定要获取的列集合(如特征、标签等),`data_key`参数指定要获取的数据类型(推理数据、学习数据或原始数据)。 + +### 11.3 数据提供给模型的流程 + +#### 11.3.1 模型训练阶段 + +在模型训练阶段,通常使用学习数据(`self._learn`): + +```python +# 获取训练数据 +train_data = handler.fetch( + selector=slice("2008-01-01", "2014-12-31"), # 时间范围 + col_set=["feature", "label"], # 获取特征和标签列 + data_key=DataHandlerLP.DK_L # 使用学习数据 +) + +# 分离特征和标签 +X_train = train_data["feature"] +y_train = train_data["label"] + +# 训练模型 +model.fit(X_train, y_train) +``` + +#### 11.3.2 模型预测阶段 + +在模型预测阶段,通常使用推理数据(`self._infer`): + +```python +# 获取预测数据 +pred_data = handler.fetch( + selector=slice("2015-01-01", "2020-08-01"), # 时间范围 + col_set="feature", # 只获取特征列 + data_key=DataHandlerLP.DK_I # 使用推理数据 +) + +# 使用模型预测 +X_pred = pred_data +y_pred = model.predict(X_pred) +``` + +### 11.4 在QLib工作流中的应用 + +在QLib的工作流(Workflow)中,数据处理器的数据会被自动提供给模型: + +```python +# 创建工作流 +workflow = Workflow( + # 数据集配置 + dataset=DatasetConfig( + handler=Alpha158( + instruments="csi300", + start_time="2008-01-01", + end_time="2020-08-01", + fit_start_time="2008-01-01", + fit_end_time="2014-12-31", + infer_processors=[...], + learn_processors=[...], + ), + segments={ + "train": ("2008-01-01", "2014-12-31"), + "valid": ("2015-01-01", "2016-12-31"), + "test": ("2017-01-01", "2020-08-01"), + }, + ), + # 模型配置 + model=ModelConfig( + model_class=LGBModel, + model_kwargs={...}, + ), +) + +# 运行工作流 +workflow.run() +``` + +在这个例子中,工作流会: + +1. 使用`handler.fetch(data_key=DK_L)`获取训练数据 +2. 使用`handler.fetch(data_key=DK_I)`获取验证和测试数据 +3. 自动将这些数据提供给模型进行训练和预测 + +### 11.5 数据的内部结构 + +在QLib中,数据通常以pandas DataFrame的形式存储,具有多级索引结构: + +``` + feature label + $close $volume Ref($close, 1) Mean($close, 3) $high-$low LABEL0 +datetime instrument +2010-01-04 SH600000 81.807068 17145150.0 83.737389 83.016739 2.741058 0.0032 + SH600004 13.313329 11800983.0 13.313329 13.317701 0.183632 0.0042 + SH600005 37.796539 12231662.0 38.258602 37.919757 0.970325 0.0289 +``` + +- 第一级索引是日期时间(datetime) +- 第二级索引是股票代码(instrument) +- 列分为特征(feature)和标签(label)两组 + +### 11.6 数据缓存和内存管理 + +为了提高性能,QLib实现了数据缓存机制: + +```python +def setup_data(self, enable_cache: bool = False): + # 如果启用缓存,会尝试从缓存加载数据 + if enable_cache: + # 缓存处理逻辑... +``` + +此外,QLib还提供了选项来释放原始数据,以节省内存: + +```python +handler = Alpha158( + # 其他参数... + drop_raw=True # 处理完数据后释放原始数据 +) +``` + +当`drop_raw=True`时,`self._data`会在处理完成后被删除,只保留`self._infer`和`self._learn`。 + +### 11.7 总结 + +在QLib中,数据加载和处理完成后: + +1. **存储位置**: + - 原始数据存储在`DataHandlerLP`实例的`self._data`属性中 + - 推理数据存储在`self._infer`属性中 + - 学习数据存储在`self._learn`属性中 + +2. **数据访问**: + - 通过`handler.fetch`方法访问数据 + - 使用`data_key`参数指定要获取的数据类型 + - 使用`col_set`参数指定要获取的列集合 + +3. **提供给模型**: + - 训练阶段:使用`data_key=DK_L`获取学习数据 + - 预测阶段:使用`data_key=DK_I`获取推理数据 + +4. **工作流集成**: + - QLib的工作流会自动将适当的数据提供给模型 + - 训练段使用学习数据,验证和测试段使用推理数据 + +这种设计使QLib能够灵活地处理不同阶段的数据需求,同时保持数据处理的一致性和正确性。 diff --git "a/my_work/doc/\346\225\260\346\215\256\345\244\204\347\220\206\345\216\237\347\220\206.png" "b/my_work/doc/\346\225\260\346\215\256\345\244\204\347\220\206\345\216\237\347\220\206.png" new file mode 100644 index 0000000000..c2df78797c Binary files /dev/null and "b/my_work/doc/\346\225\260\346\215\256\345\244\204\347\220\206\345\216\237\347\220\206.png" differ diff --git "a/my_work/doc/\350\277\220\350\241\214\345\216\237\347\220\206\345\233\276.png" "b/my_work/doc/\350\277\220\350\241\214\345\216\237\347\220\206\345\233\276.png" new file mode 100644 index 0000000000..3e29cc577b Binary files /dev/null and "b/my_work/doc/\350\277\220\350\241\214\345\216\237\347\220\206\345\233\276.png" differ diff --git a/qlib/contrib/data/handler.py b/qlib/contrib/data/handler.py index 2fe5258daa..facd9eb85e 100644 --- a/qlib/contrib/data/handler.py +++ b/qlib/contrib/data/handler.py @@ -98,17 +98,17 @@ def get_label_config(self): class Alpha158(DataHandlerLP): def __init__( self, - instruments="csi500", - start_time=None, - end_time=None, - freq="day", - infer_processors=[], - learn_processors=_DEFAULT_LEARN_PROCESSORS, - fit_start_time=None, - fit_end_time=None, - process_type=DataHandlerLP.PTYPE_A, - filter_pipe=None, - inst_processors=None, + instruments="csi500",# 默认使用中证500成分股 + start_time=None,# 开始时间 + end_time=None,# 结束时间 + freq="day",# 数据频率,默认为日频 + infer_processors=[],# 推理阶段的数据处理器 + learn_processors=_DEFAULT_LEARN_PROCESSORS,# 学习阶段的数据处理器 + fit_start_time=None,# 拟合开始时间 + fit_end_time=None,# 拟合结束时间 + process_type=DataHandlerLP.PTYPE_A,# 处理类型 + filter_pipe=None,# 过滤管道 + inst_processors=None,# 实例处理器 **kwargs, ): infer_processors = check_transform_proc(infer_processors, fit_start_time, fit_end_time) @@ -139,16 +139,22 @@ def __init__( def get_feature_config(self): conf = { - "kbar": {}, + "kbar": {},# K线特征 "price": { - "windows": [0], - "feature": ["OPEN", "HIGH", "LOW", "VWAP"], + "windows": [0],# 时间窗口 + "feature": ["OPEN", "HIGH", "LOW", "VWAP"],# 价格特征 }, - "rolling": {}, + "rolling": {},# 滚动特征 } + # Alpha158DL中的特征可以分为以下几类: + # K线特征(kbar):基于开盘价、收盘价、最高价、最低价计算的特征 + # 价格特征(price):原始价格数据 + # 成交量特征(volume):成交量数据 + # 滚动特征(rolling):基于滚动窗口计算的各种技术指标 return Alpha158DL.get_feature_config(conf) def get_label_config(self): + # 这个标签表示从T+1到T+2的收盘价变化率,而不是T到T+1的变化率。这是因为在中国股市,T日获取收盘价后,可以在T+1日买入,T+2日卖出。 return ["Ref($close, -2)/Ref($close, -1) - 1"], ["LABEL0"] diff --git a/qlib/contrib/data/loader.py b/qlib/contrib/data/loader.py index 4d11f3a34c..11e3b277d3 100644 --- a/qlib/contrib/data/loader.py +++ b/qlib/contrib/data/loader.py @@ -103,15 +103,15 @@ def get_feature_config( names = [] if "kbar" in config: fields += [ - "($close-$open)/$open", - "($high-$low)/$open", - "($close-$open)/($high-$low+1e-12)", - "($high-Greater($open, $close))/$open", - "($high-Greater($open, $close))/($high-$low+1e-12)", - "(Less($open, $close)-$low)/$open", - "(Less($open, $close)-$low)/($high-$low+1e-12)", - "(2*$close-$high-$low)/$open", - "(2*$close-$high-$low)/($high-$low+1e-12)", + "($close-$open)/$open",# KMID:收盘价与开盘价的差值比率 + "($high-$low)/$open",# KLEN:最高价与最低价的差值比率 + "($close-$open)/($high-$low+1e-12)",# KMID2:收盘价与开盘价的差值在价格区间中的位置 + "($high-Greater($open, $close))/$open",# KUP:上影线长度 + "($high-Greater($open, $close))/($high-$low+1e-12)",# KUP2:上影线占总区间的比例 + "(Less($open, $close)-$low)/$open",# KLOW:下影线长度 + "(Less($open, $close)-$low)/($high-$low+1e-12)",# KLOW2:下影线占总区间的比例 + "(2*$close-$high-$low)/$open",# KSFT:价格偏移程度 + "(2*$close-$high-$low)/($high-$low+1e-12)", # KSFT2:价格偏移在区间中的位置 ] names += [ "KMID", @@ -124,8 +124,10 @@ def get_feature_config( "KSFT", "KSFT2", ] - if "price" in config: - windows = config["price"].get("windows", range(5)) + # 价格特征是基于原始价格数据(开盘价、收盘价、最高价、最低价、成交量加权平均价)计算的特征: + if "price" in config: + # 默认使用0-4天的窗口 + windows = config["price"].get("windows", range(5)) feature = config["price"].get("feature", ["OPEN", "HIGH", "LOW", "CLOSE", "VWAP"]) for field in feature: field = field.lower() diff --git a/qlib_web_platform/DESIGN_DOC_UI_UX.md b/qlib_web_platform/DESIGN_DOC_UI_UX.md new file mode 100644 index 0000000000..558a219809 --- /dev/null +++ b/qlib_web_platform/DESIGN_DOC_UI_UX.md @@ -0,0 +1,131 @@ +# Qlib Web 平台 UI/UX 优化方案设计文档 + +**(基于方案二:模块化与上下文关联)** + +## 1. 目标与哲学 + +* **目标**: 构建一个直观、易用且功能强大的 Web UI,用于管理 Qlib 量化策略的整个生命周期,从模型训练到策略配置、回测和实盘部署。 +* **核心哲学 (方案二)**: + * **模块化**: 明确区分**模型管理** (负责训练和评估预测模型) 和**策略管理** (负责定义如何使用模型信号进行交易决策)。 + * **上下文关联**: 在 UI 的各个环节清晰地展示和利用关键上下文信息(如模型的训练周期、股票池、特征等),帮助用户做出明智决策。 + * **智能引导**: 提供合理的默认值,减少用户输入负担,并引导用户遵循最佳实践。 + * **风险提示**: 在可能导致结果不可靠或策略失效的操作前(如训练/执行宇宙不匹配),提供明确警告。 + +## 2. 模块设计详解 + +### 2.1. 模型管理 (Model Management) + +* **目的**: 创建、训练、管理和评估用于预测的机器学习模型。产出可供策略使用的"已训练模型"。 +* **主要页面**: + * **`models.html` (模型列表页)**: + * **功能**: 展示所有已创建的模型及其状态和关键信息。提供新建模型入口。 + * **表格列**: + * 名称 + * 类型 (LightGBM, LSTM, ...) + * **训练周期** (例如: "2018-01-01 - 2022-12-31") + * **训练股票池** (例如: "CSI 300") + * **特征集** (例如: "Alpha158", 使用 `truncate` 显示,`title` 显示完整内容) + * **标签** (例如: "Ref($close,-2)/Ref($close,-1)-1", 使用 `truncate` 显示,`title` 显示完整内容) + * 状态 (草稿, 训练中..., 已训练, 失败) + * 创建时间 + * 操作 (详情/编辑, 训练/重新训练, 删除, 取消训练等,根据状态显示不同按钮) + * **`create_model.html` (新建模型页)**: + * **功能**: 配置并启动一个新的模型训练任务。 + * **卡片/区域**: + * **基本信息**: 模型名称 (必填), 模型描述。 + * **模型定义与训练上下文 (Model Definition & Training Context - 整合自原"训练配置"、"模型配置"和"数据配置")**: + * **模型类型与参数**: 模型类型 (必填, `select`), 模型参数 (常用输入或高级 YAML/JSON)。 + * **数据与训练设定**: 数据源 (必填, `select`), 数据频率 (必填, `select`), 训练股票池 (必填, `select`/`text`), 所用特征集 (必填, `textarea`), 标签/预测目标 (必填, `text`), 训练/验证/测试时间段 (必填, `date` * 6)。 + * **操作按钮**: 取消, 保存草稿, **保存并开始训练**。 + * **`edit_model.html` (编辑/详情页)**: + * **功能**: 查看模型详细配置、训练状态、训练日志(未来)、评估结果(未来),并可编辑配置(对于草稿状态)或触发重新训练。 + * **内容**: 包含与 `create_model.html` 类似的"**基本信息**"和"**模型定义与训练上下文**"区域(根据状态可能只读),并增加显示训练日志、状态详情、模型评估指标等区域。 +* **关键记录数据 (模型元数据)**: 对于每个模型,后端需记录:名称、描述、模型类型、模型参数、**数据源**、**数据频率**、**训练开始/结束日期**、**训练股票池**、**特征集**、**标签配置**、训练状态、创建/更新时间、指向训练好的模型文件的指针、训练日志路径、评估结果等。 + +### 2.2. 策略管理 (Strategy Management) + +* **目的**: 定义如何利用一个"已训练模型"的信号来构建和执行交易策略。 +* **主要页面**: + * **`strategies.html` (策略列表页)**: + * **功能**: 展示所有已创建的策略配置及其运行状态(如果有)。提供新建策略入口和执行操作。 + * **表格列**: + * 名称 + * 状态 (草稿, 回测中, 实盘运行中, 已停止等) + * 关联模型 (例如: "LSTM Alpha158") + * 关键回测指标 (例如: 年化收益, 最大回撤 - *来自最近一次成功回测*) + * 创建/更新日期 + * 操作 (详情, **运行回测 (按钮)**, **提交实盘 (按钮)**, 编辑 (草稿状态), 停止等) + * **`create_strategy.html` (新建策略页)**: + * **功能**: 创建一个策略配置实例,核心是"选择一个已训练模型"并"定义如何使用其信号"。 + * **卡片/区域**: + * **基本信息**: 策略名称 (必填), 策略描述。 + * **选择模型**: + * 下拉框 (`select`, 必填) **只显示状态为"已训练"的模型** (需后端配合)。 + * 下方区域 (`#selected_model_info`) **显著展示选中模型的关键训练上下文**: 训练周期, 训练股票池, 特征集, 标签。 + * **回测配置 (Backtest Configuration - 新增于此页面)**: + * 回测时段 (必填, `date` * 2, 开始/结束日期)。 + * 回测基准 (可选, `select`)。 + * 回测股票池 (可选, `text`, 默认为模型训练池)。 + * **组合策略配置 (Portfolio Strategy Configuration)**: + * 组合策略类型 (必填, `select`, TopkDropoutStrategy, WeightStrategy, ...) + * 策略参数 (根据类型动态显示常用参数输入,或提供高级 YAML/JSON 配置入口) + * 交易成本 (手续费率, 滑点)。 + * **操作按钮**: 取消, 保存草稿, **开始回测**。 + +### 2.3. 执行与结果 (Execution & Results) + +* **目的**: 基于一个已定义的策略配置,设置具体的执行参数(时间、范围、资金)来运行回测或提交实盘,并查看结果。 +* **主要组件/页面**: + * **运行回测模态框 (在 `strategies.html` 触发)**: + * **(注意:由于回测参数(时段、基准、股票池)已移至 `create_strategy.html` 页面配置,此"运行回测模态框"的设计及其触发逻辑需要重新审视。可能不再需要在此处收集参数,或者 `create_strategy.html` 保存的是一个包含完整回测设置的策略实例。)** + * **触发**: 点击策略列表行的"运行回测"按钮。 + * **参数**: + * 回测开始日期 (必填, `date`) - **默认值**: 根据策略关联模型的训练结束日期自动计算下一天。 + * 回测结束日期 (必填, `date`) - 默认值: 空。 + * 初始资金 (必填, `number`) - 默认值: 例如 1,000,000。 + * 基准 (可选, `text`)。 + * **股票池/Universe** (必填, `select`) - **默认值**: 根据策略关联模型的训练股票池自动选中。 + * **警告**: 如果用户修改了股票池,导致与模型训练股票池不一致,**点击"开始回测"时弹出 `confirm` 警告**。 + * **操作**: 开始回测 (触发后端任务), 取消。 + * **提交实盘模态框 (在 `strategies.html` 触发)**: + * **触发**: 点击策略列表行的"提交实盘"按钮。 + * **参数**: + * 选择账户 (必填, `select`)。\ + * 分配类型 (固定金额/账户百分比, `radio`)。\ + * 金额/百分比 (必填, `number`)。\ + * **股票池/Universe** (必填, `select`) - **默认值**: 根据策略关联模型的训练股票池自动选中。 + * **警告**: 如果用户修改了股票池,导致与模型训练股票池不一致,**点击"提交至实盘"时弹出 `confirm` 警告**。 + * **操作**: 提交至实盘 (触发后端任务), 取消。 + * **`strategy_detail.html` (策略详情页)**: + * **功能**: 集中展示一个策略配置的详细信息以及其下所有相关的执行(回测/实盘)记录和结果。 + * **内容区域**: + * **策略配置回顾**: + * 策略名称、描述。 + * **关联模型**: 显示模型名称,并提供链接到模型详情/编辑页 (`edit_model.html`)。 + * **组合策略**: 显示类型和参数。 + * **交易成本**: 显示费率和滑点。 + * **执行记录列表 (关键部分)**: + * 以表格或卡片列表形式展示**每一次**基于此策略配置运行的回测或实盘实例。 + * 每条记录包含: + * 执行类型 (回测/实盘)。 + * **执行参数**: 开始日期, 结束日期, 初始资金, 基准, **股票池/Universe**。 + * 执行状态 (运行中, 已完成, 失败)。 + * **关键结果指标** (年化收益, 最大回撤, Sharpe 等)。 + * 操作 (查看详细报告/日志, 停止实盘等)。 + * 提供触发"运行新回测"(类似列表页弹窗)或"提交新实盘"的入口。 + +## 3. 关键 UX 原则总结 + +* **上下文感知**: 用户在选择模型、配置策略、执行回测/实盘时,都能看到相关的训练背景信息。 +* **智能默认**: 通过预填股票池和回测开始日期,简化用户操作,并鼓励一致性。 +* **风险缓解**: 对潜在的配置不匹配(尤其是 Universe 不匹配)进行明确警告,让用户确认风险。 +* **职责分离**: UI 结构清晰反映模型训练、策略定义、执行配置这三个不同阶段。 +* **记录与追溯**: 策略详情页汇集所有执行记录,方便比较不同参数下的回测结果或追踪实盘表现。 + +## 4. 后续步骤 (概要) + +1. **后端 API 设计**: 为前端提供数据(模型/策略列表及详情)、接收配置、触发后台任务(训练/回测/实盘)、查询任务状态和结果。 +2. **模型元数据存储**: 设计数据库表或文件结构来存储模型的完整配置和训练上下文。 +3. **动态数据加载**: 将前端的硬编码数据(模型列表、上下文、下拉选项)替换为通过 API 从后端获取。 +4. **后台任务管理**: 实现可靠的后台任务队列来处理耗时的训练和回测。 +5. **回测结果展示**: 设计 `strategy_detail.html` 中展示详细回测报告的组件(例如,使用图表库绘制收益曲线)。 \ No newline at end of file diff --git a/qlib_web_platform/create_model.html b/qlib_web_platform/create_model.html new file mode 100644 index 0000000000..f554b386e6 --- /dev/null +++ b/qlib_web_platform/create_model.html @@ -0,0 +1,266 @@ + + + + + + Qlib Web 平台 - 新建模型 + + + + + + +
+ +
+ +
+ Qlib 平台 +
+ + + + +
+ + +
+ +
+

新建模型

+
+ + +
+
+
+ + +
+

基本信息

+
+ + +
+
+ + +
+
+ + +
+

模型定义与训练上下文

+ + +
+

模型类型与参数

+
+
+ + +
+
+ +
+ +

根据所选模型类型,将在此处显示常用参数输入框。

+ + + + +
+ +
+ +
+
+
+
+ + +
+

数据与训练设定

+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ +
+
+ +
+ + + +
+
+
+ +
+ + + +
+
+
+ +
+ + + +
+
+
+
+
+
+ + +
+ + 取消 + + + +
+ +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/qlib_web_platform/create_strategy.html b/qlib_web_platform/create_strategy.html new file mode 100644 index 0000000000..c1e170e91e --- /dev/null +++ b/qlib_web_platform/create_strategy.html @@ -0,0 +1,325 @@ + + + + + + Qlib Web 平台 - 新建策略 + + + + + + +
+ +
+ +
+ Qlib 平台 +
+ + + + +
+ + +
+ +
+

新建策略

+
+ + +
+
+
+ + +
+

基本信息

+
+ + +
+
+ + +
+
+ + +
+

选择模型

+
+ + +
+ +
+ +

请先选择一个模型

+ +

选择模型后,将在此处显示其关键的训练上下文信息。

+
+
+ + +
+

回测配置

+
+ +
+ +
+ + + +
+

请指定回测的开始和结束日期。

+
+ +
+ + +

选择一个用于比较策略表现的基准指数。

+
+ +
+ + +

留空则使用所选模型训练时的股票池。

+
+
+
+ + +
+

组合策略配置

+

定义如何根据模型预测信号来构建投资组合、管理仓位和执行交易。

+
+
+ + +
+
+ +
+ +

根据所选策略类型,将在此处显示常用参数输入框。

+ + +
+ +
+ +
+
+
+ +
+
+ + +
+
+ + +
+
+
+
+
+ + +
+ + 取消 + + + +
+ +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/qlib_web_platform/dashboard.html b/qlib_web_platform/dashboard.html new file mode 100644 index 0000000000..de8bd35043 --- /dev/null +++ b/qlib_web_platform/dashboard.html @@ -0,0 +1,115 @@ + + + + + + Qlib Web 平台 - 仪表盘 + + + + + + + + +
+ +
+ +
+ Qlib 平台 +
+ + + + +
+ + +
+ +
+

仪表盘

+
+ 欢迎, 用户! + +
+
+ + +
+
+ +
+
+

我的策略

+

您有 5 个运行中策略。

+ 查看策略 +
+
+

近期回测

+

今日完成 2 次回测。

+ 查看回测记录 +
+
+

实盘交易状态

+

IB 连接: 已连接

+ 查看实盘状态 +
+
+ + +
+

整体表现 (占位符)

+
+ 图表区域 +
+
+
+
+
+
+ + \ No newline at end of file diff --git a/qlib_web_platform/data_management.html b/qlib_web_platform/data_management.html new file mode 100644 index 0000000000..5360d76b06 --- /dev/null +++ b/qlib_web_platform/data_management.html @@ -0,0 +1,203 @@ + + + + + + Qlib Web 平台 - 数据管理 + + + + + + +
+ +
+ +
+ Qlib 平台 +
+ + + + +
+ + +
+ +
+

数据管理

+
+ + +
+
+ + +
+

内置数据包

+
+
+

中国 A 股日线数据 (qlib_data)

+

来源: 爬虫/公开数据

+

覆盖范围: 2007-至今

+

状态: 可用

+ +
+
+

Alpha158 因子

+

来源: 基于日线数据计算

+

依赖: 中国 A 股日线数据

+

状态: 可用

+ +
+ +
+
+ + +
+

自定义数据包

+ + +
+ +
+ +

点击此处选择文件或拖放文件到此区域

+

仅支持 CSV 文件

+ +
+ +
+ + +

已导入的数据包

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
包名称源文件名导入日期大小操作
港股通日线hk_daily_data_2024.csv2024-07-20150 MB + 查看 + 删除 +
美股科技股us_tech_stocks.csv2024-07-1585 MB + 查看 + 删除 +
+
+
+ +
+
+
+
+ + + \ No newline at end of file diff --git a/qlib_web_platform/edit_model.html b/qlib_web_platform/edit_model.html new file mode 100644 index 0000000000..87b4fa0410 --- /dev/null +++ b/qlib_web_platform/edit_model.html @@ -0,0 +1,272 @@ + + + + + + Qlib Web 平台 - 编辑模型 + + + + + + +
+ +
+ +
+ Qlib 平台 +
+ + + + +
+ + +
+ +
+

编辑模型

+
+ + +
+
+
+ + + + +
+

+ 基本信息 + 当前状态: 已训练 +

+
+ + + +
+
+ + + +
+
+ + +
+

模型定义与训练上下文

+ + +
+

模型类型与参数

+
+
+ + + +
+
+ + +
+

根据所选模型类型,将在此处显示常用参数输入框。

+ +
+ + + + +
+ + +
+ +
+ +
+
+
+
+ + +
+

数据与训练设定

+
+
+ + + +
+
+ + + +
+
+ + + +

使用 Qlib 识别的名称或 Python 列表格式。

+
+
+ + + +

每行输入一个特征表达式。

+
+
+ + + +

输入标签表达式。

+
+ +
+
+ +
+ + + + +
+
+
+ +
+ + + + +
+
+
+ +
+ + + + +
+
+
+
+
+
+ + +
+ + 取消 + + + +
+ +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/qlib_web_platform/live_trading.html b/qlib_web_platform/live_trading.html new file mode 100644 index 0000000000..7760a4e981 --- /dev/null +++ b/qlib_web_platform/live_trading.html @@ -0,0 +1,213 @@ + + + + + + Qlib Web 平台 - 实盘交易 (IB) + + + + + + +
+ +
+ +
+ Qlib 平台 +
+ + + + +
+ + +
+ +
+

实盘交易 (IB)

+
+ + +
+
+ + +
+
+

IB 连接状态

+
+

状态: 已连接

+

账户ID: U1234567

+

服务器时间: 2024-07-21 10:35:00 CST

+ + + +
+
+
+

账户概要

+
+
+

净清算价值

+

$105,234.50

+
+
+

总权益含贷款

+

$105,234.50

+
+
+

可用资金

+

$80,112.00

+
+
+

当日盈亏

+

+$350.75

+
+
+
+
+ + + +
+

运行中的策略

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
策略名称状态开始时间分配资金/比例当日盈亏累计盈亏操作
LightGBM Alpha158 TopK运行中2024-07-18 09:30:00$10,000+$85.50+$210.20 + 停止 + 日志 +
LSTM Momentum已停止2024-07-15 10:00:005%$0.00-$55.00 + 重启 + 日志 +
+
+
+ + +
+

近期订单

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
时间戳标的方向数量类型价格状态
2024-07-21 10:30:05SH600036买入100市价35.50已成交
2024-07-21 09:45:10SZ000001卖出200限价15.20已提交
+
+
+ +
+
+
+
+ + + \ No newline at end of file diff --git a/qlib_web_platform/models.html b/qlib_web_platform/models.html new file mode 100644 index 0000000000..e8a809f02a --- /dev/null +++ b/qlib_web_platform/models.html @@ -0,0 +1,150 @@ + + + + + + Qlib Web 平台 - 模型管理 + + + + + + +
+ +
+ +
+ Qlib 平台 +
+ + + + +
+ + +
+ +
+

模型管理

+ + + 新建模型 + +
+ + +
+
+
+

模型列表

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
名称类型训练周期训练股票池特征集标签状态创建时间操作
A股日线预测模型v1LightGBM2018-01-01 - 2022-12-31CSI 300Alpha158Ref($close, -2) / Ref($close, -1) - 1已训练2024-07-20 10:30:00 + 详情/编辑 + 重新训练 + 删除 +
分钟择时模型-LSTMLSTM2020-01-01 - 2023-06-30CSI 500Vwap, Amount, High-LowRef($close, -60)/Ref($close, -1)-1训练中...2024-07-19 15:00:00 + 查看配置 + 训练 + 取消训练 +
新因子测试模型XGBoost---A-ShareMyNewFactor, VolumeReturn(lag=5)草稿2024-07-18 09:00:00 + 编辑 + 训练 + 删除 +
+
+
+
+
+
+
+ + \ No newline at end of file diff --git a/qlib_web_platform/strategies.html b/qlib_web_platform/strategies.html new file mode 100644 index 0000000000..65bbdf53ea --- /dev/null +++ b/qlib_web_platform/strategies.html @@ -0,0 +1,477 @@ + + + + + + Qlib Web 平台 - 我的策略 + + + + + + + + +
+ +
+ +
+ Qlib 平台 +
+ + + + +
+ + +
+ +
+

我的策略

+ + + 新建策略 + +
+ + +
+
+
+

策略列表

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
名称状态模型年化收益最大回撤开始日期操作
LSTM Alpha158 TopK回测中LSTM-1.83%-15.76%2024-07-19 + 详情 + + +
LightGBM Alpha158 TopK实盘运行中LightGBM8.07%-8.61%2024-07-18 + 详情 + + +
+
+
+
+
+
+
+ + + + + + + + + + + \ No newline at end of file diff --git a/qlib_web_platform/strategy_detail.html b/qlib_web_platform/strategy_detail.html new file mode 100644 index 0000000000..9b8e7a4baa --- /dev/null +++ b/qlib_web_platform/strategy_detail.html @@ -0,0 +1,377 @@ + + + + + + Qlib Web 平台 - 策略详情 + + + + + + +
+ +
+ +
+ Qlib 平台 +
+ + + + +
+ + +
+ +
+
+ ← 返回策略列表 +

策略: LSTM Alpha158 TopK

+
+
+ + +
+
+ + +
+
+ + +
+

策略配置详情

+
+
+

策略名称:

+

LSTM Alpha158 TopK

+
+
+

策略描述:

+

此策略基于 LSTM 模型预测的 Alpha158 因子信号,采用 TopK 排序选股。

+
+
+

关联模型:

+

A股日线预测模型v1 (LightGBM)

+

训练于: CSI 300 (2018-01-01 - 2022-12-31)

+
+
+

组合策略类型:

+

TopkDropoutStrategy

+
+
+

组合策略参数:

+

topk: 50, n_drop: 5

+ +
+
+

交易成本:

+

手续费: 0.03%, 滑点: 0.001

+
+ +
+
+ + +
+
+

回测历史记录

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
运行时间回测周期股票池初始资金基准状态年化最大回撤Sharpe操作
2024-07-22 10:15:302023-01-01 - 2023-12-31CSI 3001,000,000SH000300已完成15.2%-12.5%1.20报告
2024-07-21 16:05:002021-01-01 - 2022-12-31CSI 3001,000,000SH000300已完成9.8%-9.1%0.95报告
2024-07-23 09:30:102023-01-01 - 2024-06-30CSI 500 500,000SH000905运行中...---------报告
+
+
+ + + + +
+
+
+
+ + + + \ No newline at end of file