章节大纲

  • 以下是 Qlib-Server 文档的中文翻译:


    Qlib-Server 文档

    Qlib-ServerQlib 的配套服务器系统,它利用 Qlib 进行基础计算,并提供扩展的服务器系统和缓存机制。有了 Qlib-Server,可以对为 Qlib 提供的数据进行集中管理。


    文档结构

    引言 (INTRODUCTION):

    Qlib-Server

    • 简介 (Introduction)

    • 框架 (Framework)

      • 监听来自客户端的传入请求 (Listening to incoming request from client)

      • 向客户端响应数据 (Responding clients with data)

      • 接受来自 RabbitMQ 的任务并处理数据 (Accepting tasks from RabbitMQ and processing data)

    构建 (BUILDING):

    Qlib-Server 部署

    • 简介 (Introduction)

    • 一键部署 (One-click Deployment)

      • 使用 docker-compose 一键部署 (One-click Deployment with docker-compose)

      • Azure 中一键部署 (One-click Deployment in Azure)

    • 分步部署 (Step-by-step Deployment)

      • 构建 RabbitMQ (Build RabbitMQ)

      • 构建 Redis (Build Redis)

      • 构建 NFS (Build NFS)

      • 构建 Qlib-Server (Build Qlib-Server)

    使用 (USAGE):

    Qlib 在线模式

    • 简介 (Introduction)

    • 在线 (Online) 模式 下使用 Qlib (Using Qlib in Online Mode)

    • Qlib 客户端 中启用 NFS 功能 (Opening NFS Features in Qlib Client)

    • 在线 (online) 模式 下初始化 Qlib (Initializing Qlib in online Mode)

    • 配置文件 (Configuration File)

    • 参数 (Arguments)

    变更日志 (CHANGELOG):

    变更日志 (Changelog)

    • 版本 0.1.0 (Version 0.1.0)

    • 版本 0.1.1 (Version 0.1.1)

    • 版本 0.1.2 (Version 0.1.2)

  • Qlib-Server:量化库数据服务器

    简介

    Qlib-ServerQlib 的配套服务器系统,它利用 Qlib 进行基础计算,并提供了丰富的服务器系统和缓存机制。有了 Qlib-Server,可以对为 Qlib 提供的数据进行集中管理。


    框架

    Qlib 的客户端/服务器框架基于 WebSocket,因为它支持客户端和服务器之间在异步模式下的双向通信。

    Qlib-Server 基于 Flask,这是一个用于 Python 的微框架。这里使用 Flask-SocketIO 来建立 WebSocket 连接。

    Qlib-Server 提供以下功能流程:

    监听来自客户端的传入请求

    客户端会向服务器发送几种类型的请求。服务器将解析这些请求,从不同的客户端收集相同的请求,记录它们的会话 ID(session-ids),并将这些解析后的任务提交到一个管道中。Qlib 使用 RabbitMQ 作为这个管道。这些任务将被发布到名为 task_queue 的通道中。

    RequestListener 用于实现此功能:

    在接收到这些请求后,服务器会检查不同的客户端是否请求了相同的数据。如果是,为了防止重复生成数据或重复生成缓存文件,服务器将使用 Redis 来维护这些客户端的会话 ID。一旦任务完成,这些会话 ID 将被删除。为了避免 I/O 冲突,我们引入了 Redis_Lock,以确保 Redis 中的任务不会被同时读写。

    向客户端响应数据

    服务器从 message_queue 消费结果,并获取请求此结果的客户端的会话 ID。然后,它将结果响应给这些客户端。

    RequestResponder 用于实现此方法。

    上述两个类被组合成 RequestHandler,它负责与客户端进行通信。

    接受来自 RabbitMQ 的任务并处理数据

    服务器会自动从 RabbitMQ 收集任务并处理相关数据。RabbitMQ 提供了一种机制:当服务器消费一个任务时,会触发一个回调函数。数据处理过程就是在这些回调中实现的,目前它支持以下三种类型的任务:

    • Calendar (日历)

    • Instruments (标的)

    • Features (特征)

    DataProcessor 用于实现此功能。

    服务器将使用 qlib.data.Provider 来处理数据。RabbitMQ 还提供了一种机制,可以确保所有任务都被消费者成功消费和完成。这要求消费者在成功处理数据后调用 ch.basic_ack(delivery_tag=method.delivery_tag)。如果任务没有被 acked(确认),它将返回到管道中并等待另一次消费。

    一旦任务完成,一个结果(可以是数据或 URI)将被发布到另一个名为 message_queue 的通道中。

  • 以下是 Qlib-Server 部署文档的中文翻译:


    Qlib-Server 部署

    简介

    要构建一个 Qlib-Server,用户可以选择:

    • Qlib-Server 的一键部署

    • Qlib-Server 的分步部署


    一键部署

    Qlib-Server 支持一键部署,用户可以选择以下两种方法中的任何一种进行一键部署:

    • 使用 docker-compose 部署

    • Azure 中部署

    使用 docker-compose 一键部署

    按照以下步骤使用 docker-compose 部署 Qlib-Server

    1. 安装 docker,请参考 Docker 安装。

    2. 安装 docker-compose,请参考 Docker-compose 安装。

    3. 运行以下命令来部署 Qlib-Server

    Bash
    git clone https://github.com/microsoft/qlib-server
    cd qlib-server
    sudo docker-compose -f docker_support/docker-compose.yaml --env-file docker_support/docker-compose.env build
    sudo docker-compose -f docker_support/docker-compose.yaml --env-file docker_support/docker-compose.env up -d
    # 使用以下命令查看日志
    sudo docker-compose -f docker_support/docker-compose.yaml --env-file docker_support/docker-compose.env logs -f
    

    在 Azure 中一键部署

    注意

    • 用户需要拥有一个 Azure 账户才能在 Azure 中部署 Qlib-Server

    按照以下步骤在 Azure 中部署 Qlib-Server

    1. 安装 azure-cli,请参考 install-azure-cli。

    2. 将 Azure 账户信息添加到配置文件 azure_conf.yaml

    YAML
    sub_id: 你的订阅ID (Your Subscription ID)
    username: Azure 用户名 (azure user name)
    password: Azure 密码 (azure password)
    # 虚拟机所在的资源组
    resource_group: 资源组名称 (Resource group name)
    
    1. 执行部署脚本:

      运行以下命令:

    Bash
    git clone https://github.com/microsoft/qlib-server
    cd qlib-server/scripts
    python azure_manager.py create_qlib_cs_vm \
        --qlib_server_name test_server01 \
        --qlib_client_names test_client01 \
        --admin_username test_user \
        --ssh_key_value ~/.ssh/id_rsa.pub \
        --size standard_NV6_Promo\
        --conf_path azure_conf.yaml
    

    要了解更多参数,请运行以下命令:

    Bash
    python azure_manager.py create_qlib_cs_vm -- --help
    

    分步部署

    用户可以分步部署 Qlib-Server,其过程如下:

    • 构建 RabbitMQ

    • 构建 Redis

    • 构建 NFS

    • 构建 Qlib-Server

    构建 RabbitMQ

    RabbitMQ 是一个通用任务队列,它使 qlib-server 能够将请求处理过程和数据生成过程分开。

    注意

    • 用户不必在与 Qlib-Server 相同的服务器上构建 RabbitMQ 实例。

    按照以下步骤构建 RabbitMQ

    1. 在您的系统上导入 RabbitMQ 签名密钥

    Bash
    echo 'deb http://www.rabbitmq.com/debian/ testing main' | sudo tee /etc/apt/sources.list.d/rabbitmq.list
    wget -O- https://www.rabbitmq.com/rabbitmq-release-signing-key.asc | sudo apt-key add -
    
    1. 更新 apt 缓存并在您的系统上安装 RabbitMQ 服务器

    Bash
    sudo apt-get update
    sudo apt-get install rabbitmq-server
    
    1. 启用 RabbitMQ 服务并启动它

    • 使用 Init

    Bash
    sudo update-rc.d rabbitmq-server defaults
    sudo service rabbitmq-server start
    sudo service rabbitmq-server stop
    
    • 使用 Systemctl -

    Bash
    sudo systemctl enable rabbitmq-server
    sudo systemctl start rabbitmq-server
    sudo systemctl stop rabbitmq-server
    
    1. 在 RabbitMQ 中创建管理员用户:

      默认情况下,RabbitMQ 会创建一个用户名为 guest,密码为 guest 的用户。用户也可以在 RabbitMQ 中创建管理员用户:

    Bash
    sudo rabbitmqctl add_user admin <你的密码>
    sudo rabbitmqctl set_user_tags admin administrator
    sudo rabbitmqctl set_permissions -p / admin ".*" ".*" ".*"
    
    1. 启用 Web 管理控制台:

      RabbitMQ 还提供了一个 Web 管理控制台,用于管理整个 RabbitMQ。要启用 Web 管理控制台,请运行以下命令。Web 管理控制台有助于用户管理 RabbitMQ 服务器。

    Bash
    sudo rabbitmq-plugins enable rabbitmq_management
    

    访问 <你的 rabbitmq 主机>:15672 来管理您的队列。请记住您的 rabbitmq 主机和凭据,它们将用于 qlib-server 配置中。

    构建 Redis

    Qlib-Server 需要 Redis 来存储和读取一些元信息以及线程锁。

    注意

    • 用户不必在与 Qlib-Server 相同的服务器上构建 Redis 实例。

    按照以下步骤构建 Redis

    1. 下载并安装最新版本的 Redis

    Bash
    mkdir ~/redis
    cd ~/redis
    wget http://download.redis.io/releases/redis-5.0.4.tar.gz
    tar -zxvf redis-5.0.4.tar.gz
    cd redis-5.0.4
    sudo make && make install
    
    1. 启动 Redis 服务

    Bash
    /usr/local/bin/redis-server
    

    Redis 的默认端口是 6379。请记住您的 Redis 主机和端口,它们将用于 qlib-server 配置中。

    构建 NFS

    在启动 Qlib-Server 之前,需要确保缓存文件目录已挂载(或至少准备好挂载)到客户端,这可以通过配置 nfs 服务来完成。

    按照以下步骤构建 NFS

    1. 安装 NFS 服务

    Bash
    sudo apt-get install nfs-kernel-server
    
    1. 检查 nfs 端口是否打开

    Bash
    netstat -tl
    

    注意

    • 如果看到 tcp 0 0 *:nfs *:* LISTEN,则表示 nfs 端口已准备好监听。重启服务以确保它可以使用:

    Bash
    sudo /etc/init.d/nfs-kernel-server restart
    
    1. 修改 /etc/exports 以允许目录被挂载。要了解 rw 等关键字的作用并进行更改,请参考 nfs 文档。

    Bash
    sudo echo '<你的数据目录> *(rw,sync,no_subtree_check,no_root_squash)'>>/etc/exports
    
    1. 使用 showmount 查看已导出的目录

    构建 Qlib-Server

    用户可以选择以下两种方法中的任何一种来构建 Qlib-Server

    • 使用源代码构建

    • 使用 Dockerfile 构建

    使用源代码构建

    按照以下步骤使用源代码构建 Qlib-Server

    1. 进入 Qlib-Server 目录并运行 python setup.py install

    2. 根据用户的需求和配置修改 config.yaml

    3. 通过运行以下命令开始使用 Qlib-server

    Bash
    cp config_template.yaml config.yaml
    edit config.yaml # 请编辑服务器配置。
    python main.py -c config.yaml
    

    警告

    • RabbitMQ 和 Redis 的配置不能在多个 qlib-server 实例之间共享。

      例如:

      在 config_1.yaml 中,redis_db:1 task_queue: 'task_queue_1' ✔️

      在 config_2.yaml 中,redis_db:2 task_queue: 'task_queue_2' ✔️


    在 config_1.yaml 中,redis_db:1 task_queue: 'task_queue_1' ❌

    在 config_2.yaml 中,redis_db:1 task_queue: 'task_queue_1' ❌

    注意

    • config.yaml 的内容如下:

      • provider_uri:Qlib 数据目录

      • flask_server:Flask 服务器的主机/IP,可以是 0.0.0.0 或私有 IP

      • flask_port:数据服务端口,客户端端口必须与之保持一致才能访问服务器

      • queue_host:RabbitMQ 服务器 IP/主机

      • queue_user:RabbitMQ 用户名

      • queue_pwd:RabbitMQ 密码

      • task_queue:Qlib-Server 的任务队列,如果 RabbitMQ 服务于多个 Qlib-Server,此值不能重复

      • message_queue:Qlib-Server 的消息队列,如果 RabbitMQ 服务于多个 Qlib-Server,此值不能重复

      • redis_host:Redis 服务器主机/IP

      • redis_port:Redis 服务器端口

      • redis_task_db:Redis 数据库名称

      • auto_update:目前此参数未使用

      • update_time:目前此参数未使用

      • client_versionQlib 的版本必须比 client_version 新才能访问 Qlib-Server

      • server_versionQlib 的版本必须比 server_version 新才能安装或运行 Qlib-Server

      • dataset_cache_dir_name:数据集缓存目录的名称,不建议修改

      • features_cache_dir_name:特征缓存目录的名称,不建议修改

      • logging_level:Qlib-Server 日志的级别控制

      • logging_config:日志配置,不建议修改

    使用 Dockerfile 构建

    按照以下步骤使用 Dockerfile 构建 Qlib-Server

    1. 安装 docker,请参考 Docker Installation。

    2. 通过运行以下命令开始使用 Qlib-Server

    Bash
    git clone https://github.com/microsoft/qlib-server
    cd qlib-server
    sudo docker build -f docker_support/Dockerfile -t qlib-server \
        --build-arg QLIB_DATA=/data/stock_data/qlib_data \
            QUEUE_HOST=rabbitmq_server \
            QUEUE_USER=rabbitmq_user \
            QUEUE_PASS=rebbitmq_password \
            MESSAGE_QUEUE=message_queue \
            TASK_QUEUE=task_queue \
            REDIS_HOST=redis_server \
            REDIS_PORT=6379\
            REDIS_DB=1
            FLASK_SERVER_HOST=127.0.0.1 \
            QLIB_CODE=/code\
    sudo docker run -p 9710:9710 qlib-server
    
  • 使用 Qlib 在线模式


    引言

    Qlib 文档 中,我们介绍了 离线(Offline)模式。除了离线模式,用户还可以使用 在线(Online)模式

    在线模式旨在解决以下问题:

    • 以集中化的方式管理数据,用户无需管理不同版本的数据。

    • 减少需要生成的缓存量。

    • 使数据能够远程访问。

    在在线模式下,为 Qlib 提供的数据将由 Qlib-Server 以集中化的方式进行管理。


    在在线模式下使用 Qlib

    请按照以下步骤在在线模式下使用 Qlib

    1. Qlib 客户端中开启 NFS 功能

    2. 在线模式 下初始化 Qlib

    在 Qlib 客户端中开启 NFS 功能

    • 如果运行在 Linux 系统上,用户需要在客户端安装 nfs-common,执行以下命令:

      Bash
      sudo apt-get install nfs-common
      
    • 如果运行在 Windows 系统上,请按以下步骤操作:

      1. 打开 “程序和功能”

      2. 点击 “启用或关闭 Windows 功能”

      3. 向下滚动并勾选 “NFS 服务” 选项,然后点击“确定”。

      4. 参考地址:https://graspingtech.com/mount-nfs-share-windows-10/


    在在线模式下初始化 Qlib

    如果用户想在在线模式下使用 Qlib,可以选择以下两种方法中的任何一种来初始化 Qlib

    • 使用配置文件初始化 Qlib

    • 使用参数初始化 Qlib

    配置文件

    配置文件的内容如下:

    YAML
    calendar_provider:    class: LocalCalendarProvider    kwargs:        remote: True
    feature_provider:    class: LocalFeatureProvider    kwargs:        remote: True
    expression_provider: LocalExpressionProvider
    instrument_provider: ClientInstrumentProvider
    dataset_provider: ClientDatasetProvider
    provider: ClientProvider
    expression_cache: null
    dataset_cache: null
    calendar_cache: null
    provider_uri: 127.0.0.1:/
    mount_path: /data/stock_data/qlib_data
    auto_mount: True
    flask_server: 127.0.0.1
    flask_port: 9710
    
    • provider_uri:NFS 服务器路径;格式为 host:data_dir,例如:127.0.0.1:/。如果在本地模式下使用 Qlib,它可以是本地数据目录。

    • mount_path:本地数据目录,provider_uri 将被挂载到此目录。

    • auto_mount:是否在 qlib init 期间自动将 provider_uri 挂载到 mount_path;用户也可以手动挂载。

      • 注意:自动挂载需要 sudo 权限。

    • flask_server:数据服务主机/IP。

    • flask_port:数据服务端口。

    使用参数配置文件初始化 Qlib 如下:

    Python
    import qlib
    
    qlib.init_from_yaml_conf("qlib_clinet_config.yaml")
    
    from qlib.data import D
    ins = D.list_instruments(D.instrumetns("all"), as_list=True)
    

    注意

    • 如果在 Windows 上运行 Qlib,用户应正确填写 mount_path

    • 在 Windows 中,挂载路径必须是不存在的路径和根路径。

      • 正确格式,例如:Hi...

      • 错误格式,例如:CC:/user/nameqlib_data...

    • 配置文件可以写成:

      YAML
      ...
      provider_uri: 127.0.0.1:/
      mount_path: H
      auto_mount: True
      flask_server: 127.0.0.1
      flask_port: 9710
      

    参数

    使用参数初始化 Qlib 如下:

    Python
    import qlib
    
    # qlib 客户端配置
    ONLINE_CONFIG = {
        # 数据提供者配置
        "calendar_provider": {"class": "LocalCalendarProvider", "kwargs": {"remote": True}},
        "instrument_provider": "ClientInstrumentProvider",
        "feature_provider": {"class": "LocalFeatureProvider", "kwargs": {"remote": True}},
        "expression_provider": "LocalExpressionProvider",
        "dataset_provider": "ClientDatasetProvider",
        "provider": "ClientProvider",
        # 在用户自己的代码中配置
        "provider_uri": "127.0.0.1:/",
        # 缓存
        # 使用参数 'remote' 来声明客户端正在使用服务器缓存,并且将禁用写入权限。
        "expression_cache": None,
        "dataset_cache": None,
        "calendar_cache": None,
        "mount_path": "/data/stock_data/qlib_data",
        "auto_mount": True,  # NFS 已在我们的服务器上挂载 [auto_mount: False]。
        "flask_server": "127.0.0.1",
        "flask_port": 9710,
        "region": "cn",
    }
    qlib.init(**ONLINE_CONFIG)
    
    from qlib.data import D
    ins = D.list_instruments(D.instrumetns("all"), as_list=True)
    

    注意

    • 如果在 Windows 上运行 Qlib,用户应正确填写 mount_path

    • 参数可以写成:

      Python
      ONLINE_CONFIG = {
          ...
          ...
          "mount_path": "H",
          "auto_mount": True,
          "flask_server": "127.0.0.1",
          "flask_port": 9710,
          "region": "cn",
      }