数据层:数据框架与使用方法
简介
``数据层``提供了用户友好的API来管理和检索数据。它提供了高性能的数据基础设施。
数据层专为量化投资设计。例如,用户可以使用``数据层``轻松构建公式化alpha因子。更多详情请参考`构建公式化Alpha因子 <../advanced/alpha.html>`_。
``数据层``的介绍包括以下部分:
数据准备
数据API
数据加载器
数据处理器
数据集
缓存
数据和缓存文件结构
以下是Qlib数据工作流的典型示例:
用户下载数据并将其转换为Qlib格式(文件后缀为`.bin`)。在此步骤中,通常仅将一些基本数据(如OHLCV)存储在磁盘上。
基于Qlib的表达式引擎创建一些基本特征(例如"Ref($close, 60) / $close",表示过去60个交易日的收益率)。表达式引擎支持的运算符可在`此处 <https://github.com/ssvip9527/qlib/blob/main-cn/qlib/data/ops.py>`__找到。此步骤通常在Qlib的`数据加载器 <https://qlib.moujue.com/component/data.html#data-loader>`_中实现,它是`数据处理器 <https://qlib.moujue.com/component/data.html#data-handler>`_的一个组件。
如果用户需要更复杂的数据处理(例如数据归一化),`数据处理器 <https://qlib.moujue.com/component/data.html#data-handler>`_支持用户自定义处理器来处理数据(一些预定义的处理器可在`此处 <https://github.com/ssvip9527/qlib/blob/main-cn/qlib/data/dataset/processor.py>`__找到)。这些处理器与表达式引擎中的运算符不同,它们专为一些难以用表达式引擎运算符支持的复杂数据处理方法而设计。
最后,`数据集 <https://qlib.moujue.com/component/data.html#dataset>`_负责从数据处理器处理后的数据中准备模型特定的数据集
数据准备
Qlib格式数据
我们专门设计了一种数据结构来管理金融数据,详细信息请参考Qlib论文中的`文件存储设计部分 <https://arxiv.org/abs/2009.11189>`_。 此类数据将以`.bin`为文件后缀存储(我们称之为`.bin`文件、.bin`格式或Qlib格式)。.bin`文件专为金融数据的科学计算而设计。
``Qlib``提供了两种现成的数据集,可通过此`链接 <https://github.com/ssvip9527/qlib/blob/main-cn/qlib/contrib/data/handler.py>`__访问:
数据集 |
美国市场 |
中国市场 |
---|---|---|
Alpha360 |
√ |
√ |
Alpha158 |
√ |
√ |
此外,``Qlib``还提供了高频数据集。用户可以通过此`链接 <https://github.com/ssvip9527/qlib/tree/main/examples/highfreq>`__运行高频数据集示例。
Qlib格式数据集
``Qlib``提供了`.bin`格式的现成数据集,用户可以使用脚本``scripts/get_data.py``下载中国股票数据集,如下所示。用户也可以使用numpy加载`.bin`文件来验证数据。 价量数据与实际交易价格不同,因为它们经过了**复权处理**(复权价格)。您可能会发现不同数据源的复权价格有所不同,这是因为不同数据源的复权方式可能不同。Qlib在复权时将每只股票第一个交易日的价格归一化为1。 用户可以使用`$factor`获取原始交易价格(例如,`$close / $factor`可获取原始收盘价)。
以下是关于Qlib价格复权的一些讨论:
# 下载日线数据
python scripts/get_data.py qlib_data --target_dir ~/.qlib/qlib_data/cn_data --region cn
# 下载1分钟数据
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``后,用户可以使用它构建和评估自己的模型。更多详情请参考`初始化 <../start/initialization.html>`_。
日线数据自动更新
建议用户先手动更新一次数据(--trading_date 2021-05-25),然后再设置为自动更新。
更多信息请参考:yahoo数据收集器
- 每个交易日自动更新数据到"qlib"目录(Linux)
使用*crontab*:crontab -e
设置定时任务:
* * * * 1-5 python <脚本路径> update_data_to_bin --qlib_data_1d_dir <用户数据目录>
脚本路径:scripts/data_collector/yahoo/collector.py
手动更新数据
python scripts/data_collector/yahoo/collector.py update_data_to_bin --qlib_data_1d_dir <用户数据目录> --trading_date <开始日期> --end_date <结束日期>
trading_date:交易日开始日期
end_date:交易日结束日期(不包含)
将CSV格式转换为Qlib格式
Qlib``提供了脚本``scripts/dump_bin.py
,可以将**任何**CSV格式的数据转换为`.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格式数据。但是,CSV数据**必须满足**以下条件:
CSV文件以特定股票命名,或者CSV文件包含股票名称列
以股票名称命名CSV文件:SH600000.csv、`AAPL.csv`(不区分大小写)。
CSV文件包含股票名称列。用户在转换数据时**必须**指定列名。例如:
python scripts/dump_bin.py dump_all ... --symbol_field_name symbol
其中数据格式如下:
symbol
close
SH600000
120
CSV文件**必须**包含日期列,并且在转换数据时,用户必须指定日期列名。例如:
python scripts/dump_bin.py dump_all ... --date_field_name date
其中数据格式如下:
symbol
date
close
open
volume
SH600000
2020-11-01
120
121
12300000
SH600000
2020-11-02
123
120
12300000
假设用户在目录``~/.qlib/csv_data/my_data``中准备了CSV格式的数据,可以运行以下命令开始转换:
python scripts/dump_bin.py dump_all --csv_path ~/.qlib/csv_data/my_data --qlib_dir ~/.qlib/qlib_data/my_data --include_fields open,close,high,low,volume,factor
有关将数据转换为`.bin`文件时支持的其他参数,用户可以通过运行以下命令查看:
python dump_bin.py dump_all --help
转换后,用户可以在目录`~/.qlib/qlib_data/my_data`中找到Qlib格式的数据。
备注
`--include_fields`参数应与CSV文件的列名相对应。``Qlib``提供的数据集列名至少应包括open、close、high、low、volume和factor。
- open
复权开盘价
- close
复权收盘价
- high
复权最高价
- low
复权最低价
- volume
复权成交量
- factor
复权因子。通常,
factor = 复权价格 / 原始价格
,复权价格参考:拆股调整
在``Qlib``数据处理的约定中,如果股票停牌,`open、close、high、low、volume、money和factor`将被设置为NaN。 如果您想使用无法通过OHLCV计算的自定义alpha因子(如PE、EPS等),可以将其与OHLCV一起添加到CSV文件中,然后转换为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``将`股票池 <https://github.com/ssvip9527/qlib/blob/main-cn/examples/benchmarks/LightGBM/workflow_config_lightgbm_Alpha158.yaml#L4>`_定义为股票列表及其日期范围。可以按以下方式导入预定义的股票池(如沪深300)。
python collector.py --index_name CSI300 --qlib_dir <用户qlib数据目录> --method parse_instruments
多股票模式
``Qlib``目前为用户提供两种不同的股票模式:中国股票模式和美国股票模式。以下是这两种模式的一些不同设置:
地区 |
交易单位 |
涨跌幅限制 |
---|---|---|
中国 |
100 |
0.099 |
美国 |
1 |
无 |
`交易单位`定义了一次交易中可以使用的股票数量单位,`涨跌幅限制`定义了股票涨跌百分比的界限。
- 如果用户在A股模式下使用``Qlib``,需要A股数据。用户可以按照以下步骤在A股模式下使用``Qlib``:
下载Qlib格式的A股数据,请参考章节`Qlib格式数据集 <#qlib-format-dataset>`_。
- 初始化A股模式的``Qlib``
假设用户在目录``~/.qlib/qlib_data/cn_data``中下载了Qlib格式数据。用户只需按以下方式初始化``Qlib``即可。
from qlib.constant import REG_CN qlib.init(provider_uri='~/.qlib/qlib_data/cn_data', region=REG_CN)
- 如果用户在美股模式下使用``Qlib``,需要美股数据。
Qlib``也提供了下载美股数据的脚本。用户可以按照以下步骤在美股模式下使用``Qlib
: 下载Qlib格式的美股数据,请参考章节`Qlib格式数据集 <#qlib-format-dataset>`_。
- 初始化美股模式的``Qlib``
假设用户在目录``~/.qlib/qlib_data/us_data``中准备了Qlib格式数据。用户只需按以下方式初始化``Qlib``即可。
from qlib.config import REG_US qlib.init(provider_uri='~/.qlib/qlib_data/us_data', region=REG_US)
- 如果用户在美股模式下使用``Qlib``,需要美股数据。
备注
非常欢迎提交新数据源的PR!用户可以像`此处示例 <https://github.com/ssvip9527/qlib/tree/main/scripts>`_一样提交爬取数据的代码作为PR。然后我们将使用该代码在服务器上创建数据缓存,供其他用户直接使用。
数据API
数据检索
用户可以使用``qlib.data``中的API检索数据,请参考`数据检索 <../start/getdata.html>`_。
特征
``Qlib``提供`Feature`(特征)和`ExpressionOps`(表达式操作)来根据用户需求获取特征。
- `Feature`(特征)
从数据提供程序加载数据。用户可以获取诸如`$high`、$low、$open、$close`等特征,这些特征应与--include_fields`参数对应,请参考章节`将CSV格式转换为Qlib格式 <#converting-csv-format-into-qlib-format>`_。
- `ExpressionOps`(表达式操作)
ExpressionOps`将使用运算符进行特征构建。 要了解更多关于``Operator``(运算符)的信息,请参考`运算符API。 此外,
Qlib``支持用户定义自己的自定义``Operator
,示例已在``tests/test_register_ops.py``中给出。
要了解更多关于``Feature``的信息,请参考`特征API <../reference/api.html#module-qlib.data.base>`_。
过滤器
``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``的信息,请参考`过滤器API <../reference/api.html#module-qlib.data.filter>`_。
参考
要了解更多关于``数据API``的信息,请参考`数据API <../reference/api.html#data>`_。
数据加载器
``Qlib``中的``Data Loader``(数据加载器)旨在从原始数据源加载原始数据。它将被加载并在``Data Handler``(数据处理器)模块中使用。
QlibDataLoader
``Qlib``中的``QlibDataLoader``类是一个允许用户从``Qlib``数据源加载原始数据的接口。
StaticDataLoader
``Qlib``中的``StaticDataLoader``类是一个允许用户从文件或提供的数据源加载原始数据的接口。
接口
以下是``QlibDataLoader``类的一些接口:
- class qlib.data.dataset.loader.DataLoader
DataLoader用于从原始数据源加载原始数据。
- abstractmethod 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
参数
- instrumentsstr或dict
可以是市场名称或由InstrumentProvider生成的标的配置文件。 如果instruments的值为None,则表示不进行过滤。
- start_timestr
时间范围的开始。
- end_timestr
时间范围的结束。
返回
- pd.DataFrame:
从底层数据源加载的数据
异常
- KeyError:
如果不支持标的过滤,将引发KeyError
API
要了解更多关于``数据加载器``的信息,请参考`数据加载器API <../reference/api.html#module-qlib.data.dataset.loader>`_。
数据处理器
``Qlib``中的``Data Handler``(数据处理器)模块旨在处理大多数模型将使用的常见数据处理方法。
用户可以通过``qrun``在自动工作流中使用``Data Handler``,更多详情请参考`工作流:工作流管理 <workflow.html>`_。
DataHandlerLP
除了在使用``qrun``的自动工作流中使用``Data Handler``外,``Data Handler``还可以作为独立模块使用,用户可以通过它轻松地预处理数据(标准化、去除NaN等)并构建数据集。
为此,``Qlib``提供了一个基类`qlib.data.dataset.DataHandlerLP <../reference/api.html#qlib.data.dataset.handler.DataHandlerLP>`_。该类的核心思想是:我们将拥有一些可学习的``Processors``(处理器),它们可以学习数据处理的参数(例如zscore归一化的参数)。当新数据到来时,这些“训练好的”``Processors``可以处理新数据,从而能够高效地处理实时数据。关于``Processors``的更多信息将在下一小节中列出。
接口
以下是``DataHandlerLP``提供的一些重要接口:
- class qlib.data.dataset.handler.DataHandlerLP(instruments=None, start_time=None, end_time=None, data_loader: dict | str | DataLoader = None, infer_processors: List = [], learn_processors: List = [], shared_processors: List = [], process_type='append', drop_raw=False, **kwargs)
Motivation: - For the case that we hope using different processor workflows for learning and inference;
DataHandler with (L)earnable (P)rocessor
This handler will produce three pieces of data in pd.DataFrame format.
DK_R / self._data: the raw data loaded from the loader
DK_I / self._infer: the data processed for inference
DK_L / self._learn: the data processed for learning model.
The motivation of using different processor workflows for learning and inference Here are some examples.
The instrument universe for learning and inference may be different.
The processing of some samples may rely on label (for example, some samples hit the limit may need extra processing or be dropped).
These processors only apply to the learning phase.
Tips for data handler
To reduce the memory cost
drop_raw=True: this will modify the data inplace on raw data;
Please note processed data like self._infer or self._learn are concepts different from segments in Qlib's Dataset like "train" and "test"
Processed data like self._infer or self._learn are underlying data processed with different processors
segments in Qlib's Dataset like "train" and "test" are simply the time segmentations when querying data("train" are often before "test" in time-series).
For example, you can query data._infer processed by infer_processors in the "train" time segmentation.
- __init__(instruments=None, start_time=None, end_time=None, data_loader: dict | str | DataLoader = None, infer_processors: List = [], learn_processors: List = [], shared_processors: List = [], process_type='append', drop_raw=False, **kwargs)
- 参数:
infer_processors (list) --
list of <description info> of processors to generate data for inference
example of <description info>:
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 (list) -- similar to infer_processors, but for generating data for learning models
process_type (str) --
PTYPE_I = 'independent'
self._infer will be processed by infer_processors
self._learn will be processed by learn_processors
PTYPE_A = 'append'
self._infer will be processed by infer_processors
self._learn will be processed by infer_processors + learn_processors
(e.g. self._infer processed by learn_processors )
drop_raw (bool) -- Whether to drop the raw data
- fit()
fit data without processing the data
- fit_process_data()
fit and process data
The input of the fit will be the output of the previous processor
- process_data(with_fit: bool = False)
process_data data. Fun processor.fit if necessary
Notation: (data) [processor]
# data processing flow of self.process_type == DataHandlerLP.PTYPE_I
(self._data)-[shared_processors]-(_shared_df)-[learn_processors]-(_learn_df) \ -[infer_processors]-(_infer_df)
# data processing flow of self.process_type == DataHandlerLP.PTYPE_A
(self._data)-[shared_processors]-(_shared_df)-[infer_processors]-(_infer_df)-[learn_processors]-(_learn_df)
- 参数:
with_fit (bool) -- The input of the fit will be the output of the previous processor
- config(processor_kwargs: dict = None, **kwargs)
configuration of data. # what data to be loaded from data source
This method will be used when loading pickled handler from dataset. The data will be initialized with different time range.
- setup_data(init_type: str = 'fit_seq', **kwargs)
Set up the data in case of running initialization for multiple time
- 参数:
init_type (str) -- The type IT_* listed above.
enable_cache (bool) --
default value is false:
if enable_cache == True:
the processed data will be saved on disk, and handler will load the cached data from the disk directly when we call init next time
- 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) DataFrame
fetch data from underlying data source
- 参数:
selector (Union[pd.Timestamp, slice, str]) -- describe how to select data by index.
level (Union[str, int]) -- which index level to select the data.
col_set (str) -- select a set of meaningful columns.(e.g. features, columns).
data_key (str) -- the data to fetch: DK_*.
proc_func (Callable) -- please refer to the doc of DataHandler.fetch
- 返回类型:
pd.DataFrame
- get_cols(col_set='__all', data_key: Literal['raw', 'infer', 'learn'] = 'infer') list
get the column names
- 参数:
col_set (str) -- select a set of meaningful columns.(e.g. features, columns).
data_key (DATA_KEY_TYPE) -- the data to fetch: DK_*.
- 返回:
list of column names
- 返回类型:
list
- classmethod cast(handler: DataHandlerLP) DataHandlerLP
Motivation
A user creates a datahandler in his customized package. Then he wants to share the processed handler to other users without introduce the package dependency and complicated data processing logic.
This class make it possible by casting the class to DataHandlerLP and only keep the processed data
- 参数:
handler (DataHandlerLP) -- A subclass of DataHandlerLP
- 返回:
the converted processed data
- 返回类型:
- classmethod from_df(df: DataFrame) DataHandlerLP
Motivation: - When user want to get a quick data handler.
The created data handler will have only one shared Dataframe without processors. After creating the handler, user may often want to dump the handler for reuse Here is a typical use case
from qlib.data.dataset import DataHandlerLP dh = DataHandlerLP.from_df(df) dh.to_pickle(fname, dump_all=True)
TODO: - The StaticDataLoader is quite slow. It don't have to copy the data again...
如果用户希望通过配置加载特征和标签,可以定义一个新的处理器并调用``qlib.contrib.data.handler.Alpha158``的静态方法`parse_config_to_fields`。
此外,用户可以将``qlib.contrib.data.processor.ConfigSectionProcessor``传递给新处理器,该处理器为配置定义的特征提供一些预处理方法。
处理器
``Qlib``中的``Processor``(处理器)模块设计为可学习的,负责处理数据处理任务,如`归一化`和`删除无/NaN特征/标签`。
Qlib``提供以下``Processors
:
DropnaProcessor
:删除N/A特征的`处理器`。DropnaLabel
:删除N/A标签的`处理器`。TanhProcess
:使用`tanh`处理噪声数据的`处理器`。ProcessInf
:处理无穷大值的`处理器`,将用列的平均值替换无穷大值。Fillna
:处理N/A值的`处理器`,将N/A值填充为0或其他给定数字。MinMaxNorm
:应用最小-最大归一化的`处理器`。ZscoreNorm
:应用z-score归一化的`处理器`。RobustZScoreNorm
:应用稳健z-score归一化的`处理器`。CSZScoreNorm
:应用横截面z-score归一化的`处理器`。CSRankNorm
:应用横截面排名归一化的`处理器`。CSZFillna
:以横截面方式通过列平均值填充N/A值的`处理器`。
用户也可以通过继承``Processor``的基类创建自己的`处理器`。有关所有处理器的实现详情,请参考(处理器链接)。
要了解更多关于``Processor``的信息,请参考`处理器API <../reference/api.html#module-qlib.data.dataset.processor>`_。
示例
``Data Handler``可以通过修改配置文件与``qrun``一起运行,也可以作为独立模块使用。
要了解更多关于如何使用``qrun``运行``Data Handler``的信息,请参考`工作流:工作流管理 <workflow.html>`_
Qlib提供了已实现的数据处理器`Alpha158`。以下示例展示如何将`Alpha158`作为独立模块运行。
备注
用户需要先使用`qlib.init`初始化``Qlib``,请参考`初始化 <../start/initialization.html>`_。
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)
# 获取数据的所有列
print(h.get_cols())
# 获取所有标签
print(h.fetch(col_set="label"))
# 获取所有特征
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
要了解更多关于``数据处理器``的信息,请参考`数据处理器API <../reference/api.html#module-qlib.data.dataset.handler>`_。
数据集
``Qlib``中的``Dataset``(数据集)模块旨在为模型训练和推理准备数据。
该模块的设计动机是最大限度地提高不同模型处理适合自身数据的灵活性。此模块使模型能够以独特的方式处理其数据。例如,``GBDT``等模型可以很好地处理包含`nan`或`None`值的数据,而``MLP``等神经网络则会因此崩溃。
如果用户的模型需要以不同方式处理数据,可以实现自己的``Dataset``类。如果模型的数据处理没有特殊要求,可以直接使用``DatasetH``。
``DatasetH``类是带有`数据处理器`的`数据集`。以下是该类最重要的接口:
- class qlib.data.dataset.__init__.DatasetH(handler: Dict | DataHandler, segments: Dict[str, Tuple], fetch_kwargs: Dict = {}, **kwargs)
带有数据处理器(DataHandler)的数据集。
用户应尝试将数据预处理函数放入处理器中。 只有以下数据处理函数应放在数据集中: - 与特定模型相关的处理 - 与数据拆分相关的处理
- __init__(handler: Dict | DataHandler, segments: Dict[str, Tuple], fetch_kwargs: Dict = {}, **kwargs)
Setup the underlying data.
- 参数:
handler (Union[dict, DataHandler]) --
处理器可以是:
`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, **kwargs)
Initialize the DatasetH
- 参数:
handler_kwargs (dict) --
Config of DataHandler, which could include the following arguments:
arguments of DataHandler.conf_data, such as 'instruments', 'start_time' and 'end_time'.
kwargs (dict) --
Config of DatasetH, such as
- segmentsdict
Config of segments which is same as 'segments' in self.__init__
- setup_data(handler_kwargs: dict = None, **kwargs)
Setup the Data
- 参数:
handler_kwargs (dict) --
init arguments of DataHandler, which could include the following arguments:
init_type : Init Type of Handler
enable_cache : whether to enable cache
- prepare(segments: List[str] | Tuple[str] | str | slice | Index, col_set='__all', data_key='infer', **kwargs) List[DataFrame] | DataFrame
Prepare the data for learning and inference.
- 参数:
segments (Union[List[Text], Tuple[Text], Text, slice]) --
Describe the scope of the data to be prepared Here are some examples:
'train'
['train', 'valid']
col_set (str) --
The col_set will be passed to self.handler when fetching data. TODO: make it automatic:
select DK_I for test data
select DK_L for training data.
data_key (str) -- The data to fetch: DK_* Default is DK_I, which indicate fetching data for inference.
kwargs --
- The parameters that kwargs may contain:
- flt_colstr
It only exists in TSDatasetH, can be used to add a column of data(True or False) to filter data. This parameter is only supported when it is an instance of TSDatasetH.
- 返回类型:
Union[List[pd.DataFrame], pd.DataFrame]
- 抛出:
NotImplementedError: --
API
要了解更多关于``数据集``的信息,请参考`数据集API <../reference/api.html#dataset>`_。
缓存
``Cache``(缓存)是一个可选模块,通过将一些常用数据保存为缓存文件来帮助加速数据提供。``Qlib``提供了一个`Memcache`类用于在内存中缓存最常用的数据,一个可继承的`ExpressionCache`类,以及一个可继承的`DatasetCache`类。
全局内存缓存
Memcache`是一种全局内存缓存机制,由三个`MemCacheUnit`实例组成,用于缓存**日历**、**证券**和**特征**。`MemCache`在`cache.py`中全局定义为`H。用户可以使用`H['c'], H['i'], H['f']`来获取/设置`memcache`。
- class qlib.data.cache.MemCacheUnit(*args, **kwargs)
内存缓存单元。
- __init__(*args, **kwargs)
- property limited
内存缓存是否有限制
- class 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`方法以定义要缓存的数据以及如何缓存它。
以下是接口的详细信息:
- class qlib.data.cache.ExpressionCache(provider)
Expression cache mechanism base class.
This class is used to wrap expression provider with self-defined expression cache mechanism.
备注
Override the _uri and _expression method to create your own expression cache mechanism.
- expression(instrument, field, start_time, end_time, freq)
Get expression data.
备注
Same interface as expression method in expression provider
- update(cache_uri: str | Path, freq: str = 'day')
Update expression cache to latest calendar.
Override this method to define how to update expression cache corresponding to users' own cache mechanism.
- 参数:
cache_uri (str or Path) -- the complete uri of expression cache file (include dir path).
freq (str)
- 返回:
0(successful update)/ 1(no need to update)/ 2(update failure).
- 返回类型:
int
``Qlib``目前提供了已实现的磁盘缓存`DiskExpressionCache`,它继承自`ExpressionCache`。表达式数据将存储在磁盘中。
数据集缓存
`DatasetCache`是一种用于保存数据集的缓存机制。特定数据集由股票池配置(或一系列证券,尽管不推荐)、表达式列表或静态特征字段、收集特征的开始时间和结束时间以及频率来规定。用户可以通过以下步骤继承此基类来定义自己的数据集缓存机制:
重写`self._uri`方法以定义缓存文件路径的生成方式
重写`self._expression`方法以定义要缓存的数据以及如何缓存它。
以下是接口的详细信息:
- class qlib.data.cache.DatasetCache(provider)
Dataset cache mechanism base class.
This class is used to wrap dataset provider with self-defined dataset cache mechanism.
备注
Override the _uri and _dataset method to create your own dataset cache mechanism.
- dataset(instruments, fields, start_time=None, end_time=None, freq='day', disk_cache=1, inst_processors=[])
Get feature dataset.
备注
Same interface as dataset method in dataset provider
备注
The server use redis_lock to make sure read-write conflicts will not be triggered but client readers are not considered.
- update(cache_uri: str | Path, freq: str = 'day')
Update dataset cache to latest calendar.
Override this method to define how to update dataset cache corresponding to users' own cache mechanism.
- 参数:
cache_uri (str or Path) -- the complete uri of dataset cache file (include dir path).
freq (str)
- 返回:
0(successful update)/ 1(no need to update)/ 2(update failure)
- 返回类型:
int
- static cache_to_origin_data(data, fields)
cache data to origin data
- 参数:
data -- pd.DataFrame, cache data.
fields -- feature fields.
- 返回:
pd.DataFrame.
- static normalize_uri_args(instruments, fields, freq)
normalize uri args
``Qlib``目前提供了已实现的磁盘缓存`DiskDatasetCache`,它继承自`DatasetCache`。数据集数据将存储在磁盘中。
数据和缓存文件结构
我们专门设计了一种文件结构来管理数据和缓存,详细信息请参考Qlib论文中的`文件存储设计部分 <https://arxiv.org/abs/2009.11189>`_。数据和缓存的文件结构如下所示。
- data/
[原始数据] 由数据提供程序更新
- calendars/
- day.txt
- instruments/
- all.txt
- csi500.txt
- ...
- features/
- sh600000/
- open.day.bin
- close.day.bin
- ...
- ...
[缓存数据] 当原始数据更新时更新
- calculated features/
- sh600000/
- [hash(instrtument, field_expression, freq)]
- all-time expression -cache data file
- .meta : 记录证券名称、字段名称、频率和访问次数的元文件
- ...
- cache/
- [hash(stockpool_config, field_expression_list, freq)]
- all-time Dataset-cache data file
- .meta : 记录股票池配置、字段名称和访问次数的元文件
- .index : 记录所有日历行索引的索引文件
- ...