数据层:数据框架 & 使用
简介
数据层 提供了用户友好的 API 来管理和获取数据,并提供了高性能的数据基础设施。
它专为量化投资设计。例如,用户可以轻松地使用 数据层 构建公式化阿尔法因子。更多细节请参考 构建公式化阿尔法因子。
数据层 的介绍包括以下几个部分。
数据准备
数据 API
数据加载器
数据处理器
数据集
缓存
数据与缓存文件结构
以下是 Qlib 数据工作流的一个典型示例
用户下载数据并将其转换为 Qlib 格式(文件名后缀为 .bin)。此步骤通常仅将一些基础数据存储在磁盘上(如 OHLCV)。
基于 Qlib 的表达式引擎创建一些基本特征(例如“Ref($close, 60) / $close”,表示过去 60 个交易日的收盘价比率)。表达式引擎支持的操作符可在此处 查看。此步骤通常由 Qlib 的 数据加载器 实现,它是 数据处理器 的一个组件。
如果用户需要更复杂的数据处理(例如数据归一化),数据处理器 支持用户自定义的处理器来处理数据(一些预定义的处理器可在此处 查看)。这些处理器与表达式引擎中的操作符不同,它们用于实现表达式引擎难以支持的复杂数据处理方法。
最后,数据集 负责从数据处理器处理后的数据中准备模型专用的数据集
数据准备
Qlib 格式数据
我们专门设计了一种数据结构来管理金融数据,详细信息请参阅 Qlib 论文中的文件存储设计部分。此类数据将以 .bin 作为文件名后缀进行存储(我们将称其为 .bin 文件、.bin 格式或 Qlib 格式)。.bin 文件专为金融数据的科学计算而设计。
Qlib 提供了两种现成可用的数据集,可通过此 链接 获取:
数据集 |
美国市场 |
中国市场 |
|---|---|---|
Alpha360 |
√ |
√ |
Alpha158 |
√ |
√ |
此外,Qlib 还提供了一个高频数据集。用户可以通过此 链接 运行高频数据集示例。
Qlib 格式数据集
Qlib 提供了一种现成的 .bin 格式数据集,用户可以使用脚本 scripts/get_data.py 按如下方式下载中国股票数据集。用户也可以使用 numpy 加载 .bin 文件来验证数据。由于价格和成交量数据经过了复权处理(复权价格),因此它们看起来与实际交易价格不同。你可能会发现,不同数据源的复权价格存在差异,这是因为不同数据源的复权方法可能不同。Qlib 在复权时会将每只股票的第一个交易日的价格标准化为 1。用户可以通过 $factor 来还原原始交易价格(例如,使用 $close / $factor 获取原始收盘价)。
以下是一些关于 Qlib 价格复权的讨论。
# download 1d
python scripts/get_data.py qlib_data --target_dir ~/.qlib/qlib_data/cn_data --region cn
# download 1min
python scripts/get_data.py qlib_data --target_dir ~/.qlib/qlib_data/qlib_cn_1min --region cn --interval 1min
除了中国股票数据外,Qlib 还包含一个美国股票数据集,可通过以下命令下载:
python scripts/get_data.py qlib_data --target_dir ~/.qlib/qlib_data/us_data --region us
运行上述命令后,用户可以在 ~/.qlib/qlib_data/cn_data 目录和 ~/.qlib/qlib_data/us_data 目录中分别找到以 Qlib 格式存储的中国股票和美国股票数据。
Qlib 还在 scripts/data_collector 中提供了脚本,帮助用户从互联网爬取最新数据并将其转换为 qlib 格式。
当使用该数据集初始化 Qlib 后,用户即可基于此构建和评估自己的模型。更多细节请参考 初始化。
日频数据的自动更新
建议用户先手动更新一次(如设置 --trading_date 2021-05-25),然后设置为自动更新。
更多信息请参考:yahoo collector
- 每个交易日自动将数据更新到“qlib”目录(Linux 系统)
使用 crontab: crontab -e
设置定时任务:
* * * * 1-5 python <script path> update_data_to_bin --qlib_data_1d_dir <user data dir>
脚本路径:scripts/data_collector/yahoo/collector.py
手动更新数据
python scripts/data_collector/yahoo/collector.py update_data_to_bin --qlib_data_1d_dir <user data dir> --trading_date <start date> --end_date <end date>
trading_date:交易起始日
end_date:交易结束日(不包含)
将 CSV 和 Parquet 格式转换为 Qlib 格式
Qlib 提供了脚本 scripts/dump_bin.py,只要数据格式正确,即可将 CSV 或 Parquet 格式的任意数据转换为 .bin 文件(Qlib 格式)。
除了下载准备好的示例数据外,用户还可以直接从数据采集器下载示例数据,以参考 CSV 格式的具体结构。以下是一些示例:
- 对于日频数据:
python scripts/get_data.py download_data --file_name csv_data_cn.zip --target_dir ~/.qlib/csv_data/cn_data
- 对于 1 分钟数据:
python scripts/data_collector/yahoo/collector.py download_data --source_dir ~/.qlib/stock_data/source/cn_1min --region CN --start 2021-05-20 --end 2021-05-23 --delay 0.1 --interval 1min --limit_nums 10
用户也可以提供自己准备的 CSV 或 Parquet 格式数据。但数据必须满足以下条件:
CSV 或 Parquet 文件需以特定股票命名,或CSV 或 Parquet 文件中包含一列表示股票名称。
以股票命名 CSV 或 Parquet 文件:SH600000.csv、AAPL.csv 或 SH600000.parquet、AAPL.parquet(不区分大小写)。
CSV 或 Parquet 文件包含股票名称列。用户在导出数据时必须指定该列的列名。示例如下:
python scripts/dump_bin.py dump_all ... --symbol_field_name symbol --file_suffix <.csv or .parquet>
数据应为以下格式:
symbol
close
SH600000
120
CSV 或 Parquet 文件必须包含一列表示日期,且在导出数据时用户必须指定日期列的列名。示例如下:
python scripts/dump_bin.py dump_all ... --date_field_name date --file_suffix <.csv or .parquet>
数据应为以下格式:
symbol
date
close
open
volume
SH600000
2020-11-01
120
121
12300000
SH600000
2020-11-02
123
120
12300000
假设用户已将 CSV 或 Parquet 格式的数据准备在目录 ~/.qlib/my_data 中,则可运行以下命令开始转换。
python scripts/dump_bin.py dump_all --data_path ~/.qlib/my_data --qlib_dir ~/.qlib/qlib_data/ --include_fields open,close,high,low,volume,factor --file_suffix <.csv or .parquet>
关于将数据转储到 .bin 文件时支持的其他参数,用户可通过运行以下命令查看详细信息:
python scripts/dump_bin.py dump_all --help
转换完成后,用户可在目录 ~/.qlib/qlib_data/ 中找到其 Qlib 格式的数据。
注意
–include_fields 参数应与 CSV 或 Parquet 文件中的列名相对应。Qlib 提供的数据集列名至少应包括 open、close、high、low、volume 和 factor。
- open
复权后的开盘价
- close
复权后的收盘价
- high
复权后的最高价
- low
复权后的最低价
- volume
复权后的成交量
- factor
复权因子。通常,
factor = 复权价格 / 原始价格,复权价格 参考:前复权
按照 Qlib 数据处理的惯例,若股票停牌,则 open、close、high、low、volume、money 和 factor 将被设为 NaN。如果用户想使用无法通过 OCHLV 计算的自定义 alpha 因子(如 PE、EPS 等),可将其与 OHCLV 数据一同添加到 CSV 或 Parquet 文件中,然后导出为 Qlib 格式数据。
检查数据健康状况
Qlib 提供了一个脚本来检查数据的健康状况。
主要检查点如下
检查 DataFrame 中是否存在缺失数据。
检查 OHLCV 列中是否存在超过阈值的大幅跳变。
检查 DataFrame 中是否缺少必要的列(OLHCV)。
检查 DataFrame 中是否缺少 'factor' 列。
你可以运行以下命令来检查数据是否健康。
- 对于日频数据:
python scripts/check_data_health.py check_data --qlib_dir ~/.qlib/qlib_data/cn_data
- 对于 1 分钟数据:
python scripts/check_data_health.py check_data --qlib_dir ~/.qlib/qlib_data/cn_data_1min --freq 1min
当然,你也可以添加一些参数来调整测试结果。
可用参数如下。
freq:数据频率。
large_step_threshold_price:价格最大允许变化幅度。
large_step_threshold_volume:成交量最大允许变化幅度。
missing_data_num:数据允许为空的最大数量。
你可以运行以下命令来检查数据是否健康。
- 对于日频数据:
python scripts/check_data_health.py check_data --qlib_dir ~/.qlib/qlib_data/cn_data --missing_data_num 30055 --large_step_threshold_volume 94485 --large_step_threshold_price 20
- 对于 1 分钟数据:
python scripts/check_data_health.py check_data --qlib_dir ~/.qlib/qlib_data/cn_data --freq 1min --missing_data_num 35806 --large_step_threshold_volume 3205452000000 --large_step_threshold_price 0.91
股票池(市场)
Qlib 将股票池定义为股票列表及其对应的日期范围。可按如下方式导入预定义的股票池(例如 csi300)。
python collector.py --index_name CSI300 --qlib_dir <user qlib data dir> --method parse_instruments
多种股票模式
Qlib 目前为用户提供两种不同的股票模式:A 股模式和美股模式。以下是这两种模式的一些不同设置:
地区 |
交易单位 |
涨跌停限制 |
|---|---|---|
中国 |
100 |
0.099 |
美国 |
1 |
None |
交易单位 定义了每笔交易中可买卖的股票最小单位数量,涨跌停限制 定义了股票涨跌幅的上下限比例。
- 如果用户在 A 股模式下使用
Qlib,则需要 A 股数据。用户可按照以下步骤在 A 股模式下使用Qlib: 下载以 Qlib 格式提供的中国股票数据,请参考章节 Qlib 格式数据集。
- 以中国股票模式初始化
Qlib 假设用户将 Qlib 格式的数据下载到目录
~/.qlib/qlib_data/cn_data中。用户只需按以下方式初始化Qlib。from qlib.constant import REG_CN qlib.init(provider_uri='~/.qlib/qlib_data/cn_data', region=REG_CN)
- 以中国股票模式初始化
- 如果用户在 A 股模式下使用
- 如果用户以美国股票模式使用
Qlib,则需要美国股票数据。Qlib还提供了一个脚本用于下载美国股票数据。用户可按照以下步骤以美国股票模式使用Qlib: 下载以 Qlib 格式提供的美国股票数据,请参考章节 Qlib 格式数据集。
- 以美国股票模式初始化
Qlib 假设用户已将 Qlib 格式的数据准备在目录
~/.qlib/qlib_data/us_data中。用户只需按以下方式初始化Qlib。from qlib.config import REG_US qlib.init(provider_uri='~/.qlib/qlib_data/us_data', region=REG_US)
- 以美国股票模式初始化
- 如果用户以美国股票模式使用
注意
我们非常欢迎新增数据源的 Pull Request!用户可以像 此处示例 一样提交爬取数据的代码作为 PR。然后我们将使用该代码在服务器上创建数据缓存,其他用户可直接使用。
数据 API
数据获取
用户可以使用 qlib.data 中的 API 来获取数据,请参考 数据获取。
特征
Qlib 提供了 Feature 和 ExpressionOps,可根据用户需求提取特征。
- 特征
从数据提供方加载数据。用户可以获得如 $high、$low、$open、$close 等特征,这些应与 –include_fields 参数相对应,请参考章节 将 CSV 格式转换为 Qlib 格式。
- ExpressionOps
ExpressionOps 将使用算子进行特征构建。欲了解有关
Operator的更多信息,请参考 算子 API。此外,Qlib支持用户自定义Operator,示例已在tests/test_register_ops.py中给出。
欲了解有关 Feature 的更多信息,请参考 特征 API。
过滤器
Qlib 提供了 NameDFilter 和 ExpressionDFilter,可根据用户需求筛选标的。
- NameDFilter
名称动态标的筛选器。基于规定的名称格式筛选标的,需要提供一个名称规则的正则表达式。
- ExpressionDFilter
表达式动态标的筛选器。基于特定表达式筛选标的,需要提供指示某一特征字段的表达式规则。
基础特征筛选:rule_expression = ‘$close/$open>5’
截面特征过滤器:rule_expression = ‘$rank($close)<10’
时序特征过滤器:rule_expression = ‘$Ref($close, 3)>100’
以下是一个简单的示例,展示如何在基本的 Qlib 工作流配置文件中使用过滤器:
filter: &filter
filter_type: ExpressionDFilter
rule_expression: "Ref($close, -2) / Ref($close, -1) > 1"
filter_start_time: 2010-01-01
filter_end_time: 2010-01-07
keep: False
data_handler_config: &data_handler_config
start_time: 2010-01-01
end_time: 2021-01-22
fit_start_time: 2010-01-01
fit_end_time: 2015-12-31
instruments: *market
filter_pipe: [*filter]
要了解更多关于 Filter 的信息,请参考 Filter API。
参考
要了解更多关于 Data API 的信息,请参考 Data API。
数据加载器
Data Loader 在 Qlib 中用于从原始数据源加载原始数据,它将被加载并在 Data Handler 模块中使用。
QlibDataLoader
QlibDataLoader 类是 Qlib 中的一个接口,允许用户从 Qlib 数据源加载原始数据。
StaticDataLoader
StaticDataLoader 类是 Qlib 中的一个接口,允许用户从文件或指定来源加载原始数据。
接口
以下是 QlibDataLoader 类的一些接口:
- 类 qlib.data.dataset.loader.DataLoader
DataLoader 用于从原始数据源加载原始数据。
- abstract load(instruments, start_time=None, end_time=None) DataFrame
将数据加载为 pd.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- 参数:
instruments (str 或 dict) – 可以是市场名称,也可以是由 InstrumentProvider 生成的标的配置文件。如果 instruments 的值为 None,则表示不进行过滤。
start_time (str) – 时间范围的起始时间。
end_time (str) – 时间范围的结束时间。
- 返回:
从底层数据源加载数据
- 返回类型:
pd.DataFrame
- Raises:
KeyError: – 如果不支持 instruments 过滤,则抛出 KeyError
API
要了解更多关于 Data Loader 的信息,请参考 Data Loader API。
数据处理器
Data Handler 模块在 Qlib 中用于处理大多数模型常用的通用数据处理方法。
用户可以通过 qrun 在自动工作流中使用 数据 处理器,更多详细信息请参考 工作流:工作流管理。
DataHandlerLP
除了通过 qrun 在自动工作流中使用 数据 处理器 外,数据 处理器 还可以作为独立模块使用,用户可借此方便地对数据进行预处理(如标准化、去除 NaN 等)并构建数据集。
为了实现这一点,Qlib 提供了一个基类 qlib.data.dataset.DataHandlerLP。该类的核心思想是:我们拥有一些可学习的 处理器,它们能够学习数据处理的参数(例如 z-score 标准化的参数)。当新数据到来时,这些经过训练的 处理器 就可以处理新数据,从而实现高效地处理实时数据。有关 处理器 的更多详细信息将在下一小节中列出。
接口
以下是 DataHandlerLP 提供的一些重要接口:
- 类 qlib.data.dataset.handler.DataHandlerLP(instruments=无, start_time=无, end_time=无, data_loader: 字典 | 字符串 | DataLoader | 无 = 无, infer_processors: 列表 = [], learn_processors: 列表 = [], shared_processors: 列表 = [], process_type='append', drop_raw=False, **kwargs)
动机:- 在我们希望对训练和推理使用不同处理器工作流程的情况下;
带有(可)学习(处)理器的 DataHandler
该处理器将以 pd.DataFrame 格式生成三组数据。
DK_R / self._data:从加载器中加载的原始数据
DK_I / self._infer:为推理处理过的数据
DK_L / self._learn:为模型学习处理过的数据
使用不同的处理器流程分别用于学习和推理的原因如下,以下是一些示例。
用于学习和推理的标的范围可能不同。
某些样本的处理可能依赖于标签(例如,某些触及涨跌停的样本可能需要额外处理或被剔除)。
这些处理器仅应用于学习阶段。
关于数据处理器的提示
为了降低内存开销
drop_raw=True:这将在原始数据上进行就地修改;
请注意,像 self._infer 或 self._learn 这样的已处理数据,与 Qlib 的 Dataset 中的 segments(如“train”和“test”)概念不同
像 self._infer 或 self._learn 这样的已处理数据,是指使用不同处理器处理得到的底层数据
Qlib 的 Dataset 中的 segments(如“train”和“test”)仅仅是在查询数据时的时间分段(“train”通常在时间序列上早于“test”)
例如,你可以在“train”时间段内查询由 infer_processors 处理过的 data._infer
- __init__(instruments=None, start_time=None, end_time=None, data_loader: dict | str | DataLoader | None = None, infer_processors: List = [], learn_processors: List = [], shared_processors: List = [], process_type='append', drop_raw=False, **kwargs)
- 参数:
infer_processors (列表) –
用于生成推理数据的处理器的<描述信息>列表
<描述信息>示例:
1) classname & kwargs: { "class": "MinMaxNorm", "kwargs": { "fit_start_time": "20080101", "fit_end_time": "20121231" } } 2) Only classname: "DropnaFeature" 3) object instance of Processor
learn_processors (列表) – 与 infer_processors 类似,但用于生成模型学习所需的数据
process_type (字符串) –
PTYPE_I = ‘independent’
self._infer 将由 infer_processors 处理
self._learn 将由 learn_processors 处理
PTYPE_A = ‘append’
self._infer 将由 infer_processors 处理
self._learn 将由 infer_processors + learn_processors 共同处理
(例如,self._infer 由 learn_processors 处理)
drop_raw (布尔值) – 是否丢弃原始数据
- fit()
在不处理数据的情况下进行拟合
- fit_process_data()
拟合并处理数据
fit 的输入将是前一个处理器的输出
- process_data(with_fit: 布尔值 = False)
处理数据。如有必要,调用 processor.fit
符号说明:(数据) [处理器]
# self.process_type == DataHandlerLP.PTYPE_I 时的数据处理流程
(self._data)-[shared_processors]-(_shared_df)-[learn_processors]-(_learn_df) \ -[infer_processors]-(_infer_df)# self.process_type == DataHandlerLP.PTYPE_A 时的数据处理流程
(self._data)-[shared_processors]-(_shared_df)-[infer_processors]-(_infer_df)-[learn_processors]-(_learn_df)
- 参数:
with_fit (布尔值) – fit 的输入将是前一个处理器的输出
- config(processor_kwargs: 字典 | 无 = 无, **kwargs)
数据的配置。# 从数据源加载哪些数据
当从数据集中加载已序列化的处理器时,将使用此方法。数据将使用不同的时间范围进行初始化。
- setup_data(init_type: 字符串 = 'fit_seq', **kwargs)
在多次初始化运行时设置数据
- 参数:
init_type (字符串) – 上述列出的 IT_* 类型。
enable_cache (bool) –
默认值为 false:
如果 enable_cache == True:
处理后的数据将被保存到磁盘,当下次调用 init 时,处理器将直接从磁盘加载缓存的数据
- fetch(selector: Timestamp | slice | str = slice(None, None, None), level: str | int = 'datetime', col_set='__all', data_key: Literal['raw', 'infer', 'learn'] = 'infer', squeeze: bool = False, proc_func: Callable | None = None) DataFrame
从底层数据源获取数据
- 参数:
selector (Union[pd.Timestamp, slice, str]) – 描述如何通过索引选择数据。
level (Union[str, int]) – 选择数据的索引层级。
col_set (str) – 选择一组有意义的列。(例如:特征、列)。
data_key (str) – 要获取的数据:DK_*。
proc_func (Callable) – 请参考 DataHandler.fetch 的文档。
- 返回类型:
pd.DataFrame
- get_cols(col_set='__all', data_key: Literal['raw', 'infer', 'learn'] = 'infer') list
获取列名
- 参数:
col_set (str) – 选择一组有意义的列。(例如:特征、列)。
data_key (DATA_KEY_TYPE) – 要获取的数据:DK_*。
- 返回:
列名列表
- 返回类型:
list
- 类方法 转换(处理器: DataHandlerLP) DataHandlerLP
动机
用户在其自定义包中创建了一个 datahandler。然后他希望与其他用户共享已处理的 handler,而无需引入包依赖和复杂的数据处理逻辑。
该类通过将类转换为 DataHandlerLP 并仅保留已处理的数据来实现这一目标。
- 参数:
handler (DataHandlerLP) – DataHandlerLP 的一个子类
- 返回:
转换后的已处理数据
- 返回类型:
- 类方法 从 DataFrame 创建(df: DataFrame) DataHandlerLP
动机:- 当用户想要快速获得一个数据处理器时。
创建的数据处理器将只有一个共享的 DataFrame,且不包含任何处理器。创建处理器后,用户通常希望将其导出以便重复使用。以下是一个典型的使用场景
from qlib.data.dataset import DataHandlerLP dh = DataHandlerLP.from_df(df) dh.to_pickle(fname, dump_all=True)
待办事项:- StaticDataLoader 非常慢。其实没有必要再次复制数据……
如果用户希望通过配置加载特征和标签,可以定义一个新的处理器,并调用 qlib.contrib.data.handler.Alpha158 的静态方法 parse_config_to_fields。
此外,用户还可以将提供了一些基于配置定义特征的预处理方法的 qlib.contrib.data.processor.ConfigSectionProcessor 传入新的处理器中。
处理器
Qlib 中的 Processor 模块被设计为可学习的,负责处理诸如归一化和删除空值/NaN 特征或标签等数据处理任务。
Qlib 提供了以下几种 Processor:
DropnaProcessor:处理器,用于删除包含 N/A 的特征。DropnaLabel:处理器,用于删除包含 N/A 的标签。TanhProcess:处理器,使用 tanh 函数处理噪声数据。ProcessInf:处理器,用于处理无穷大值,会将其替换为该列的均值。Fillna:处理器,用于处理 N/A 值,会用 0 或其他指定数值填充。MinMaxNorm:处理器,执行最小-最大值归一化。ZscoreNorm:处理器,执行 Z-score 标准化。RobustZScoreNorm:processor,用于执行稳健的 z-score 标准化。CSZScoreNorm:processor,用于执行横截面 z-score 标准化。CSRankNorm:processor,用于执行横截面秩次标准化。CSZFillna:processor,通过列的均值以横截面方式填充缺失值(N/A)。
用户也可以通过继承基类 Processor 来创建自己的 processor。更多信息请参考所有处理器的实现(Processor Link)。
如需了解更多关于 Processor 的内容,请参考 Processor API。
示例
Data Handler 可通过修改配置文件后使用 qrun 运行,也可作为独立模块使用。
了解更多如何使用 qrun 运行 Data Handler,请参考 Workflow: Workflow Management。
Qlib 提供了已实现的数据处理器 Alpha158。以下示例展示了如何将 Alpha158 作为独立模块运行。
注意
用户需要先通过 qlib.init 初始化 Qlib,详情请参考 initialization。
import qlib
from qlib.contrib.data.handler import Alpha158
data_handler_config = {
"start_time": "2008-01-01",
"end_time": "2020-08-01",
"fit_start_time": "2008-01-01",
"fit_end_time": "2014-12-31",
"instruments": "csi300",
}
if __name__ == "__main__":
qlib.init()
h = Alpha158(**data_handler_config)
# get all the columns of the data
print(h.get_cols())
# fetch all the labels
print(h.fetch(col_set="label"))
# fetch all the features
print(h.fetch(col_set="feature"))
注意
在 Alpha158 中,Qlib 使用标签 Ref($close, -2)/Ref($close, -1) - 1,表示从 T+1 到 T+2 的变化,而不是 Ref($close, -1)/$close - 1。原因是,在获取中国股票 T 日的收盘价后,该股票可在 T+1 日买入,并在 T+2 日卖出。
API
如需了解更多关于 Data Handler 的内容,请参考 Data Handler API。
数据集
Qlib 中的 Dataset 模块旨在为模型训练和推理准备数据。
该模块的设计动机是:我们希望最大化不同模型处理其适用数据的灵活性。该模块赋予模型以独特方式处理数据的自由度。例如,像 GBDT 这类模型可以在包含 nan 或 None 值的数据上良好运行,而神经网络如 MLP 在此类数据上则会出错。
如果用户的模型需要以不同方式处理数据,可以实现自己的 Dataset 类。如果模型的数据处理方式并无特殊要求,可直接使用 DatasetH。
DatasetH 类是带有数据处理器(Data Handler)的数据集。以下是该类最重要的接口:
- class qlib.data.dataset.__init__.DatasetH(handler: Dict | DataHandler, segments: Dict[str, Tuple], fetch_kwargs: Dict = {}, **kwargs)
带有数据处理(H)andler 的数据集
用户应尽量将数据预处理函数放入 handler 中。只有以下数据处理函数应保留在 Dataset 中:
处理逻辑与特定模型相关。
处理逻辑与数据划分相关。
- __init__(handler: Dict | DataHandler, segments: Dict[str, Tuple], fetch_kwargs: Dict = {}, **kwargs)
初始化底层数据。
- 参数:
handler (Union[dict, DataHandler]) –
handler 可以是:
DataHandler 的实例
DataHandler 的配置。请参考 DataHandler
segments (dict) –
描述数据分段的选项。以下是一些示例:
1) 'segments': { 'train': ("2008-01-01", "2014-12-31"), 'valid': ("2017-01-01", "2020-08-01",), 'test': ("2015-01-01", "2016-12-31",), } 2) 'segments': { 'insample': ("2008-01-01", "2014-12-31"), 'outsample': ("2017-01-01", "2020-08-01",), }
- config(handler_kwargs: dict | None = None, **kwargs)
初始化 DatasetH
- 参数:
handler_kwargs (dict) –
DataHandler 的配置,可能包含以下参数:
DataHandler.conf_data 的参数,例如 'instruments'、'start_time' 和 'end_time'。
kwargs (dict) –
DatasetH 的配置,例如
- segments字典
分段的配置,与 self.__init__ 中的 'segments' 相同
- setup_data(handler_kwargs: dict | None = None, **kwargs)
初始化数据
- 参数:
handler_kwargs (dict) –
DataHandler 的初始化参数,可能包含以下参数:
init_type : Handler 的初始化类型
enable_cache : 是否启用缓存
- prepare(segments: List[str] | Tuple[str] | str | slice | Index, col_set='__all', data_key='infer', **kwargs) List[DataFrame] | DataFrame
为学习和推理准备数据。
- 参数:
segments (Union[List[Text], Tuple[Text], Text, slice]) –
描述要准备的数据范围,以下是一些示例:
“train”
[“train”, “valid”]
col_set (str) –
该 col_set 将在获取数据时传递给 self.handler。TODO:实现自动化:
为测试数据选择 DK_I
为训练数据选择 DK_L。
data_key (str) – 要获取的数据:DK_* 默认值为 DK_I,表示获取用于推理的数据。
kwargs –
- kwargs 可能包含的参数:
- flt_colstr
仅存在于 TSDatasetH 中,可用于添加一列数据(True 或 False)以过滤数据。此参数仅在实例为 TSDatasetH 时支持。
- 返回类型:
Union[List[pd.DataFrame], pd.DataFrame]
- Raises:
NotImplementedError: –
API
要了解更多关于 Dataset 的信息,请参考 Dataset API。
缓存
Cache 是一个可选模块,通过将一些常用数据保存为缓存文件来加速数据提供。Qlib 提供了一个 Memcache 类用于在内存中缓存最常用的数据,以及一个可继承的 ExpressionCache 类和一个可继承的 DatasetCache 类。
全局内存缓存
Memcache 是一种全局内存缓存机制,由三个 MemCacheUnit 实例组成,分别用于缓存 日历、标的 和 特征。MemCache 在 cache.py 中被全局定义为 H。用户可以使用 H[‘c’], H[‘i’], H[‘f’] 来获取或设置 memcache。
- 类 qlib.data.cache.MemCacheUnit(*args, **kwargs)
内存缓存单元。
- __init__(*args, **kwargs)
- 属性 受限
内存缓存是否受限
- 类 qlib.data.cache.MemCache(mem_cache_size_limit=None, limit_type='length')
内存缓存。
- __init__(mem_cache_size_limit=None, limit_type='length')
- 参数:
mem_cache_size_limit – 缓存最大大小。
limit_type – length 或 sizeof;length(调用函数:len),size(调用函数:sys.getsizeof)。
表达式缓存
ExpressionCache 是一种缓存机制,用于保存诸如 Mean($close, 5) 之类的表达式。用户可以继承此类,通过以下步骤定义自己的表达式缓存机制。
重写 self._uri 方法,以定义缓存文件路径的生成方式。
重写 self._expression 方法,以定义将缓存哪些数据以及如何缓存。
以下是相关接口的详细说明:
- 类 qlib.data.cache.表达式缓存(提供者)
表达式缓存机制基类。
该类用于使用自定义的表达式缓存机制包装表达式提供者。
注意
重写 _uri 和 _expression 方法以创建您自己的表达式缓存机制。
- expression(instrument, field, start_time, end_time, freq)
获取表达式数据。
注意
与表达式提供者中的 expression 方法接口相同。
- update(cache_uri: str | Path, freq: str = 'day')
将表达式缓存更新至最新的日历。
重写此方法以定义如何根据用户自定义的缓存机制更新表达式缓存。
- 参数:
cache_uri (str 或 Path) – 表达式缓存文件的完整 URI(包含目录路径)。
freq (str) –
- 返回:
0(成功更新)/ 1(无需更新)/ 2(更新失败)。
- 返回类型:
int
Qlib 目前提供了已实现的磁盘缓存 DiskExpressionCache,它继承自 ExpressionCache。表达式数据将被存储在磁盘中。
DatasetCache
DatasetCache 是一种用于保存数据集的缓存机制。一个特定的数据集由股票池配置(或一系列标的,尽管不推荐)、表达式列表或静态特征字段、特征采集的开始时间与结束时间以及频率来确定。用户可以继承该基类,并按照以下步骤定义自己的数据集缓存机制。
重写 self._uri 方法,以定义其缓存文件路径的生成方式
重写 self._expression 方法,以定义将缓存哪些数据以及如何缓存。
以下是相关接口的详细说明:
- 类 qlib.data.cache.数据集缓存(提供者)
数据集缓存机制基类。
该类用于包装数据集提供者,并支持用户自定义的数据集缓存机制。
注意
重写 _uri 和 _dataset 方法,以创建您自己的数据集缓存机制。
- dataset(instrument, 字段, start_time=无, end_time=无, freq='day', disk_cache=1, inst_processors=[])
获取特征数据集。
注意
与数据集提供者中的 dataset 方法接口相同。
注意
服务器使用 redis_lock 来确保不会触发读写冲突,但不考虑客户端读取者的情况。
- update(cache_uri: str | Path, freq: str = 'day')
将数据集缓存更新到最新的日历。
重写此方法以定义如何根据用户自己的缓存机制更新数据集缓存。
- 参数:
cache_uri (str 或 Path) – 数据集缓存文件的完整 URI(包含目录路径)。
freq (str) –
- 返回:
0(成功更新)/ 1(无需更新)/ 2(更新失败)
- 返回类型:
int
- 静态 cache_to_origin_data(数据, 字段)
将缓存数据转换为原始数据
- 参数:
data – pd.DataFrame,缓存的数据。
fields – 特征字段。
- 返回:
pd.DataFrame。
- 静态 normalize_uri_args(instrument, 字段, freq)
标准化 URI 参数
Qlib 目前已提供实现了磁盘缓存 DiskDatasetCache,它继承自 DatasetCache。数据集的数据将存储在磁盘中。
数据与缓存文件结构
我们专门设计了一种文件结构来管理数据和缓存,详细信息请参考 Qlib 论文中的文件存储设计部分。数据和缓存的文件结构如下所示。
- data/
[raw data] updated by data providers
- calendars/
- day.txt
- instruments/
- all.txt
- csi500.txt
- ...
- features/
- sh600000/
- open.day.bin
- close.day.bin
- ...
- ...
[cached data] updated when raw data is updated
- calculated features/
- sh600000/
- [hash(instrtument, field_expression, freq)]
- all-time expression -cache data file
- .meta : an assorted meta file recording the instrument name, field name, freq, and visit times
- ...
- cache/
- [hash(stockpool_config, field_expression_list, freq)]
- all-time Dataset-cache data file
- .meta : an assorted meta file recording the stockpool config, field names and visit times
- .index : an assorted index file recording the line index of all calendars
- ...