章节大纲

  • 数据层:数据框架与使用


    简介

    数据层提供了用户友好的 API 来管理和检索数据。它提供了高性能的数据基础设施。

    它专为量化投资而设计。例如,用户可以轻松地使用数据层构建公式化因子 (alphas)。有关更多详细信息,请参阅构建公式化因子

    数据层的介绍包括以下几个部分:

    • 数据准备

    • 数据 API

    • 数据加载器

    • 数据处理器

    • 数据集

    • 缓存

    • 数据和缓存文件结构

    下面是 Qlib 数据工作流的一个典型示例:

    1. 用户下载数据并将其转换为 Qlib 格式(文件名后缀为 .bin)。在此步骤中,通常只有一些基本数据(例如 OHLCV)存储在磁盘上。

    2. 基于 Qlib 的表达式引擎创建一些基本特征(例如 “Ref($close, 60) / $close”,即过去 60 个交易日的收益)。表达式引擎中支持的运算符可以在这里找到。此步骤通常在 Qlib数据加载器中实现,它是数据处理器的一个组件。

    3. 如果用户需要更复杂的数据处理(例如数据归一化),数据处理器支持用户自定义的处理器来处理数据(一些预定义的处理器可以在这里找到)。这些处理器与表达式引擎中的运算符不同。它专为一些难以在表达式引擎中用运算符支持的复杂数据处理方法而设计。

    4. 最后,数据集负责从数据处理器处理过的数据中为特定模型准备数据集。


    数据准备

    Qlib 格式数据

    我们专门设计了一种数据结构来管理金融数据,有关详细信息,请参阅 Qlib 论文中的文件存储设计部分。此类数据将以 .bin 为文件名后缀存储(我们将称之为 .bin 文件.bin 格式Qlib 格式)。.bin 文件专为金融数据的科学计算而设计。

    Qlib 提供了两个现成的数据集,可通过此链接访问:

    数据集 美股市场 A股市场
    Alpha360
    Alpha158

    此外,Qlib 还提供了一个高频数据集。用户可以通过此链接运行高频数据集示例。

    Qlib 格式数据集

    Qlib 提供了一个 .bin 格式的现成数据集,用户可以使用 scripts/get_data.py 脚本下载 A股数据集,如下所示。用户还可以使用 numpy 加载 .bin 文件来验证数据。价格和成交量数据看起来与实际成交价不同,因为它们是复权的(复权价格)。然后您可能会发现不同数据源的复权价格可能不同。这是因为不同的数据源在复权方式上可能有所不同。Qlib 在复权时将每只股票第一个交易日的价格归一化为 1。用户可以利用 $factor 获取原始交易价格(例如,$close / $factor 获取原始收盘价)。

    以下是关于 Qlib 价格复权的一些讨论。

    https://github.com/microsoft/qlib/issues/991#issuecomment-1075252402

    # 下载日数据
    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
    

    除了 A股数据,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 格式的 A股和美股数据。

    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 格式转换为 Qlib 格式

    Qlib 提供了 scripts/dump_bin.py 脚本,可以将任何符合正确格式的 CSV 格式数据转换为 .bin 文件(Qlib 格式)。

    除了下载准备好的演示数据,用户还可以直接从 Collector 下载演示数据作为 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.csvAAPL.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 提供的数据集的列名至少应包含 openclosehighlowvolumefactor

    • open:复权开盘价

    • close:复权收盘价

    • high:复权最高价

    • low:复权最低价

    • volume:复权交易量

    • factor:复权因子。通常,factor = 复权价格 / 原始价格,复权价格参考:split adjusted

    Qlib 数据处理的约定中,如果股票停牌,openclosehighlowvolumemoneyfactor 将被设置为 NaN。如果您想使用无法通过 OCHLV 计算的自定义因子,如 PE、EPS 等,您可以将其与 OHCLV 一起添加到 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股票池定义为股票列表及其日期范围。可以按如下方式导入预定义的股票池(例如 csi300)。

    python collector.py --index_name CSI300 --qlib_dir <user qlib data dir> --method parse_instruments

    多种股票模式

    Qlib 现在为用户提供了两种不同的股票模式:A股模式和美股模式。这两种模式的一些不同设置如下:

    区域 交易单位 涨跌幅限制阈值
    A股 100 0.099
    美股 1 None

    交易单位定义了可用于交易的股票数量单位,涨跌幅限制阈值定义了股票涨跌百分比的界限。

    如果用户在 A股模式下使用 Qlib,则需要 A股数据。用户可以按照以下步骤在 A股模式下使用 Qlib

    1. 下载 Qlib 格式的 A股数据,请参阅 Qlib 格式数据集一节。

    2. 在 A股模式下初始化 Qlib。

      假设用户将 Qlib 格式数据下载到 ~/.qlib/qlib_data/cn_data 目录中。用户只需按如下方式初始化 Qlib 即可。

      Python
      from qlib.constant import REG_CN
      qlib.init(provider_uri='~/.qlib/qlib_data/cn_data', region=REG_CN)
      

    如果用户在美股模式下使用 Qlib,则需要美股数据。Qlib 也提供了下载美股数据的脚本。用户可以按照以下步骤在美股模式下使用 Qlib

    1. 下载 Qlib 格式的美股数据,请参阅 Qlib 格式数据集一节。

    2. 在美股模式下初始化 Qlib。

      假设用户将 Qlib 格式数据准备在 ~/.qlib/qlib_data/us_data 目录中。用户只需按如下方式初始化 Qlib 即可。

      Python
      from qlib.config import REG_US
      qlib.init(provider_uri='~/.qlib/qlib_data/us_data', region=REG_US)
      

    注意

    我们非常欢迎新的数据源的 PR!用户可以将抓取数据的代码作为 PR 提交,就像这里的示例一样。然后,我们将在我们的服务器上使用该代码创建数据缓存,其他用户可以直接使用。


    数据 API

    数据检索

    用户可以使用 qlib.data 中的 API 检索数据,请参阅数据检索

    特征

    Qlib 提供了 FeatureExpressionOps 以根据用户的需求获取特征。

    • Feature:从数据提供者加载数据。用户可以获取 $high$low$open$close 等特征,这些特征应与 --include_fields 的参数相对应,请参阅将 CSV 格式转换为 Qlib 格式一节。

    • ExpressionOpsExpressionOps 将使用运算符进行特征构建。要了解更多关于运算符的信息,请参阅运算符 API。此外,Qlib 支持用户定义自己的自定义运算符tests/test_register_ops.py 中给出了一个示例。

    要了解更多关于特征的信息,请参阅特征 API

    过滤器

    Qlib 提供了 NameDFilterExpressionDFilter 来根据用户的需求过滤成分股。

    • NameDFilter:动态名称过滤器。根据规范的名称格式过滤成分股。需要一个名称规则正则表达式。

    • ExpressionDFilter:动态表达式过滤器。根据某个表达式过滤成分股。需要一个表示某个特征字段的表达式规则。

      • 基本特征过滤器:rule_expression = '$close/$open>5'

      • 横截面特征过滤器:rule_expression = '$rank($close)<10'

      • 时间序列特征过滤器:rule_expression = '$Ref($close, 3)>100'

    下面是一个简单的示例,展示了如何在基本的 Qlib 工作流配置文件中使用过滤器:

    YAML
    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]
    

    要了解更多关于过滤器的信息,请参阅过滤器 API

    参考

    要了解更多关于数据 API 的信息,请参阅数据 API


    数据加载器

    Qlib 中的数据加载器旨在从原始数据源加载原始数据。它将在数据处理器模块中加载和使用。

    QlibDataLoader

    Qlib 中的 QlibDataLoader 类是一个这样的接口,它允许用户从 Qlib 数据源加载原始数据。

    StaticDataLoader

    Qlib 中的 StaticDataLoader 类是一个这样的接口,它允许用户从文件或作为提供的数据加载原始数据。

    接口

    以下是 QlibDataLoader 类的一些接口:

    class 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 (strdict) – 可以是市场名称,也可以是 InstrumentProvider 生成的成分股配置文件。如果 instruments 的值为 None,则表示不进行过滤。

    • start_time (str) – 时间范围的开始。

    • end_time (str) – 时间范围的结束。

    返回:

    从底层源加载的数据。

    返回类型:

    pd.DataFrame

    引发:

    KeyError – 如果不支持成分股过滤器,则引发 KeyError。

    API

    要了解更多关于数据加载器的信息,请参阅数据加载器 API


    数据处理器

    Qlib 中的数据处理器模块旨在处理大多数模型将使用的常见数据处理方法。

    用户可以通过 qrun 在自动化工作流中使用数据处理器,有关更多详细信息,请参阅工作流:工作流管理

    DataHandlerLP

    除了在 qrun 的自动化工作流中使用数据处理器外,数据处理器还可以作为一个独立的模块使用,用户可以通过它轻松地预处理数据(标准化、删除 NaN 等)和构建数据集。

    为了实现这一点,Qlib 提供了一个基类 qlib.data.dataset.DataHandlerLP。这个类的核心思想是:我们将拥有一些可学习的处理器Processors),它们可以学习数据处理的参数(例如,zscore 归一化的参数)。当新数据到来时,这些训练过的处理器可以处理新数据,从而可以高效地处理实时数据。有关处理器的更多信息,将在下一小节中列出。

    接口

    以下是 DataHandlerLP 提供的一些重要接口:

    class qlib.data.dataset.handler.DataHandlerLP(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)

    带**(L)可学习 (P)处理器**的数据处理器。

    此处理器将生成三部分 pd.DataFrame 格式的数据。

    • DK_R / self._data: 从加载器加载的原始数据

    • DK_I / self._infer: 为推断处理的数据

    • DK_L / self._learn: 为学习模型处理的数据

    使用不同的处理器工作流进行学习和推断的动机是多方面的。以下是一些例子:

    • 学习和推断的成分股范围可能不同。

    • 某些样本的处理可能依赖于标签(例如,一些达到涨跌停的样本可能需要额外处理或被删除)。

    • 这些处理器仅适用于学习阶段。

    数据处理器提示:

    为了减少内存开销:

    drop_raw=True: 这将就地修改原始数据;

    请注意,self._infer 或 self._learn 等处理过的数据与 Qlib 数据集中的 segments(如“train”和“test”)是不同的概念。

    • self._inferself._learn 等处理过的数据是使用不同处理器处理的底层数据。

    • Qlib 数据集中的 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 (list) –

      用于生成推断数据的一系列处理器描述信息。

      描述信息的示例:

      1. 类名和 kwargs:

      JSON
      {
          "class": "MinMaxNorm",
          "kwargs": {
              "fit_start_time": "20080101",
              "fit_end_time": "20121231"
          }
      }
      
      1. 仅类名:"DropnaFeature"

      2. 处理器对象实例

    • learn_processors (list) – 类似于 infer_processors,但用于生成模型学习数据。

    • process_type (str) –

      • 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._inferlearn_processors 处理)

    • drop_raw (bool) – 是否删除原始数据。

    fit():不处理数据,仅拟合数据。

    fit_process_data():拟合并处理数据。前一个处理器的输出将作为 fit 的输入。

    process_data(with_fit: bool = False):处理数据。如有必要,运行 processor.fit。

    符号(data) [processor]

    # 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 (bool) – 前一个处理器的输出将作为 fit 的输入。

    config(processor_kwargs: dict | None = None, **kwargs)

    数据配置。# 从数据源加载哪些数据。

    此方法将在从数据集加载腌制(pickled)处理器时使用。数据将使用不同的时间范围进行初始化。

    setup_data(init_type: str = 'fit_seq', **kwargs)

    在多次运行初始化时设置数据。

    参数:

    • init_type (str) – 上面列出的 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) – 选择一组有意义的列(例如 features, columns)。

    • data_key (str) – 获取的数据:DK_*

    • proc_func (Callable) – 请参阅 DataHandler.fetch 的文档。

    返回类型:pd.DataFrame

    引发:NotImplementedError –

    get_cols(col_set='__all', data_key: Literal['raw', 'infer', 'learn'] = 'infer') -> list

    获取列名。

    参数:

    • col_set (str) – 选择一组有意义的列(例如 features, columns)。

    • data_key (DATA_KEY_TYPE) – 获取的数据:DK_*

    返回:

    列名列表。

    返回类型:

    list

    classmethod cast(handler: DataHandlerLP) -> DataHandlerLP

    动机:

    用户在他的自定义包中创建了一个数据处理器。然后,他想将处理过的处理器分享给其他用户,而无需引入包依赖和复杂的数据处理逻辑。这个类通过将类转换为 DataHandlerLP 并仅保留处理过的数据来实现这一点。

    参数:

    • handler (DataHandlerLP) – DataHandlerLP 的子类。

      返回:

      转换后的处理过的数据。

      返回类型:

      DataHandlerLP

    classmethod from_df(df: DataFrame) -> DataHandlerLP

    动机:当用户想要快速获取一个数据处理器时。

    创建的数据处理器将只有一个共享 DataFrame,不带处理器。创建处理器后,用户通常会想将其转储以供重用。这是一个典型的用例:

    Python
    from qlib.data.dataset import DataHandlerLP
    dh = DataHandlerLP.from_df(df)
    dh.to_pickle(fname, dump_all=True)
    

    TODO: - StaticDataLoader 相当慢。它不必再次复制数据…

    如果用户想通过配置加载特征和标签,可以定义一个新的处理器并调用 qlib.contrib.data.handler.Alpha158 的静态方法 parse_config_to_fields。

    此外,用户还可以将 qlib.contrib.data.processor.ConfigSectionProcessor 传递给新的处理器,它提供了一些用于通过配置定义的特征的预处理方法。

    处理器

    Qlib 中的处理器模块被设计为可学习的,它负责处理数据处理,例如归一化删除空/NaN 特征/标签

    Qlib 提供了以下处理器

    • DropnaProcessor:删除 N/A 特征的处理器。

    • DropnaLabel:删除 N/A 标签的处理器。

    • TanhProcess:使用 tanh 处理噪声数据的处理器。

    • ProcessInf:处理无穷大值的处理器,它将被替换为该列的平均值。

    • Fillna:处理 N/A 值的处理器,它将用 0 或其他给定数字填充 N/A 值。

    • MinMaxNorm:应用 Min-Max 归一化的处理器。

    • ZscoreNorm:应用 Z-score 归一化的处理器。

    • RobustZScoreNorm:应用鲁棒 Z-score 归一化的处理器。

    • CSZScoreNorm:应用横截面 Z-score 归一化的处理器。

    • CSRankNorm:应用横截面排名归一化的处理器。

    • CSZFillna:以横截面方式用该列的平均值填充 N/A 值的处理器。

    用户还可以通过继承 Processor 的基类来创建自己的处理器。有关更多信息,请参阅所有处理器的实现(处理器链接)。

    要了解更多关于处理器的信息,请参阅处理器 API

    示例

    数据处理器可以通过修改配置文件与 qrun 一起运行,也可以作为一个独立的模块使用。

    要了解更多关于如何与 qrun 一起运行数据处理器的信息,请参阅工作流:工作流管理。

    Qlib 提供了已实现的数据处理器 Alpha158。以下示例展示了如何将 Alpha158 作为一个独立的模块运行。

    注意

    用户需要先用 qlib.init 初始化 Qlib,请参阅初始化

    Python
    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。原因是在获取 A股的 T 日收盘价时,股票可以在 T+1 日买入,在 T+2 日卖出。

    API

    要了解更多关于数据处理器的信息,请参阅数据处理器 API


    数据集

    Qlib 中的数据集模块旨在为模型训练和推断准备数据。

    该模块的动机是我们希望最大化不同模型处理适合其自身的数据的灵活性。该模块赋予模型以独特方式处理其数据的灵活性。例如,像 GBDT 这样的模型可能在包含 nanNone 值的数据上运行良好,而像 MLP 这样的神经网络模型则会因此崩溃。

    如果用户的模型需要以不同的方式处理数据,用户可以实现自己的 Dataset 类。如果模型的数据处理不特殊,则可以直接使用 DatasetH

    DatasetH 类是带有数据处理器数据集。这是该类最重要的接口:

    class qlib.data.dataset.__init__.DatasetH(handler: Dict | DataHandler, segments: Dict[str, Tuple], fetch_kwargs: Dict = {}, **kwargs)

    带数据处理器的数据集。

    用户应尽量将数据预处理功能放入处理器中。只有以下数据处理功能应放在数据集中:

    • 与特定模型相关的处理。

    • 与数据拆分相关的处理。

    __init__(handler: Dict | DataHandler, segments: Dict[str, Tuple], fetch_kwargs: Dict = {}, **kwargs)

    设置底层数据。

    参数

    • handler (Union[dict, 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 的参数,例如 instrumentsstart_timeend_time

      • kwargs (dict) –

        DatasetH 的配置,例如:

        • segments dict

          • segments 的配置与 self.__init__ 中的相同。

    • 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) –

        获取数据时将传递给 self.handler。TODO:使其自动化:

        • 为测试数据选择 DK_I

        • 为训练数据选择 DK_L

      • data_key (str) – 要获取的数据:DK_*。默认是 DK_I,表示获取用于推断的数据。

      • kwargs –

        kwargs 可能包含的参数:

        • flt_col str

          • 它只存在于 TSDatasetH 中,可用于添加一个数据列(True 或 False)来过滤数据。此参数仅在它是 TSDatasetH 的实例时受支持。

            返回类型:Union[List[pd.DataFrame], pd.DataFrame]

            引发:NotImplementedError –

    API

    要了解更多关于数据集的信息,请参阅数据集 API。


    缓存

    缓存是一个可选模块,通过将一些常用数据保存为缓存文件来帮助加速数据提供。Qlib 提供了一个 Memcache 类来缓存内存中最常用的数据,一个可继承的 ExpressionCache 类,以及一个可继承的 DatasetCache 类。

    全局内存缓存

    Memcache 是一个全局内存缓存机制,由三个 MemCacheUnit 实例组成,用于缓存日历成分股特征MemCachecache.py 中全局定义为 H。用户可以使用 H['c'], H['i'], H['f'] 来获取/设置内存缓存。

    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_typelengthsizeoflength(调用函数:len),size(调用函数:sys.getsizeof)。

    表达式缓存

    ExpressionCache 是一个缓存机制,用于保存 Mean($close, 5) 等表达式。用户可以继承这个基类来定义自己的缓存机制,以保存表达式,步骤如下。

    1. 重写 self._uri 方法以定义如何生成缓存文件路径。

    2. 重写 self._expression 方法以定义将缓存哪些数据以及如何缓存。

    以下是接口的详细信息:

    class qlib.data.cache.ExpressionCache(provider)

    表达式缓存机制基类。

    此类用于使用自定义的表达式缓存机制封装表达式提供者。

    注意

    重写 _uri 和 _expression 方法来创建您自己的表达式缓存机制。

    expression(instrument, field, start_time, end_time, freq)

    获取表达式数据。

    注意

    与表达式提供者中的 expression 方法接口相同。

    update(cache_uri: str | Path, freq: str = 'day')

    将表达式缓存更新到最新的日历。

    重写此方法以定义如何根据用户自己的缓存机制更新表达式缓存。

    参数:

    • cache_uri (strPath) – 表达式缓存文件的完整 URI(包括目录路径)。

    • freq (str) –

    返回:

    0(更新成功)/ 1(无需更新)/ 2(更新失败)。

    返回类型:int

    Qlib 目前提供了已实现的磁盘缓存 DiskExpressionCache,它继承自 ExpressionCache。表达式数据将存储在磁盘上。

    数据集缓存

    DatasetCache 是一个缓存机制,用于保存数据集。一个特定的数据集由股票池配置(或一系列成分股,尽管不推荐)、表达式列表或静态特征字段、所收集特征的开始时间和结束时间以及频率来规范。用户可以继承这个基类来定义自己的缓存机制,以保存数据集,步骤如下。

    1. 重写 self._uri 方法以定义如何生成缓存文件路径。

    2. 重写 self._expression 方法以定义将缓存哪些数据以及如何缓存。

    以下是接口的详细信息:

    class qlib.data.cache.DatasetCache(provider)

    数据集缓存机制基类。

    此类用于使用自定义的数据集缓存机制封装数据集提供者。

    注意

    重写 _uri 和 _dataset 方法来创建您自己的数据集缓存机制。

    dataset(instruments, fields, start_time=None, end_time=None, freq='day', disk_cache=1, inst_processors=[])

    获取特征数据集。

    注意

    与数据集提供者中的 dataset 方法接口相同。

    注意

    服务器使用 redis_lock 来确保不会触发读写冲突,但客户端读取器不在考虑范围内。

    update(cache_uri: str | Path, freq: str = 'day')

    将数据集缓存更新到最新的日历。

    重写此方法以定义如何根据用户自己的缓存机制更新数据集缓存。

    参数

    • cache_uri (strPath) – 数据集缓存文件的完整 URI(包括目录路径)。

    • freq (str) –

    返回:

    0(更新成功)/ 1(无需更新)/ 2(更新失败)。

    返回类型:int

    static cache_to_origin_data(data, fields)

    将缓存数据转换为原始数据。

    参数:

    • datapd.DataFrame,缓存数据。

    • fields – 特征字段。

      返回:

      pd.DataFrame。

    static normalize_uri_args(instruments, fields, freq)

    规范化 URI 参数。

    Qlib 目前提供了已实现的磁盘缓存 DiskDatasetCache,它继承自 DatasetCache。数据集数据将存储在磁盘上。


    数据和缓存文件结构

    我们专门设计了一种文件结构来管理数据和缓存,有关详细信息,请参阅 Qlib 论文中的文件存储设计部分。数据和缓存的文件结构如下。

    • data/

      • [raw data] 由数据提供者更新

        • calendars/

          • day.txt

        • instruments/

          • all.txt

          • csi500.txt

          • ...

        • features/

          • sh600000/

            • open.day.bin

            • close.day.bin

            • ...

          • ...

      • [cached data] 原始数据更新时更新

        • 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:一个辅助索引文件,记录所有日历的行索引。

          • ...