DeepAlphaGen:强化学习的因子组合挖掘:框架代码+数据下载

Quantlab近期的计划:

1、重构dagster:含etf数据更新定时任务(symbol列表来自django),回测任务来自mongo(需要设计mongo存储json,比当前的toml还要简单,再抽象一层,当前的Toml还是通用结构,精细化为四大模板:大类资产配置+定期再平衡;轮动策略,择时策略,多策略组合)。

2、整合回测系统到dagster,支持定时跑任务,更新结果(结果指标,订单明细,交易明细, equity曲线等,可以一个任务存一个hdf5到mongo)

3、策略集回测结果写回mongo

4、通过GraphQL向dagster集群远程发布命令,执行回测。

我们要解决同学们环境配置复杂,使用策略不易的问题,最好就是尽量SAAS化,能不安装就不安装,能提供在线服务就提供在线服务。比如数据更新,比如策略自动运行。否则后续的tensorflow,pytorch,强化学习,对于新手都太难了。给代码也用不起来。

以Dagster为主,还是Django为主,我还是思考了一下,决定还是Dagster为主。

Django擅长做管理系统,当然它也可以做异步任务与定时任务(通过Celery,但没那么直观和方便),Django最强项是它的管理后台以及ORM。但金融上,更多依赖mongo等NoSQL数据库。

01 Dagster搭建AI量化系统底座

Dagster的文档如下:https://docs.dagster.io/getting-started/install

直接在venv使用pip进行安装:

pip install dagster dagster-webserver

新版本Dagster是1.5.5,多了一个dagster-webserver。

我们使用官方案例——一个ETL的pipline来初始化我们的QuantTask子系统。

dagster project from-example –name quanttask –example quickstart_etl

然后cd进入quanttask目录,使用命令:dagster dev即可以打开webui。

图片

import pandas as pd
from dagster import get_dagster_logger, asset

from quanttask.utils import loader_ak, mongo_utils
from quanttask.utils.tools import _get_start_date


@asset(description='更新场内基金日线数据', group_name='etf')
def update_etf_quotes():
    symbol = '518880.SH'
    table_name = 'etf_quotes'
    df = loader_ak.load_etf_hist_quotes(symbol, _get_start_date(table_name, symbol))
    mongo_utils.write_df(table_name, df)

吾日三省吾身

每篇文章,前面这句话,用于蛮长一段时间,个人成长与财富自由,能让你的自由意志更好的发挥。投资是手段,世界运作的逻辑关乎好奇心。

人与动物之区别,在于人是有自由意志的,就是你得意识到,任何时候,你都有的选。

首先需要意识到,生而为人,永远有的选。其次,这个选择来自内在的价值判断,而非外在的困难。

没有完美的东西,都是平稳和取舍。成年人的世界,那有那么多即要又要还要。其实他只要守好一个底限,就能让自己的生活走上正循环。

今天来一个比昨天还简单的策略,创业板ETF动量择时:年化21%,最大回撤18%。

图片

图片

创业板择时策略代码如下:

def gen_cy_picktime():
    proj = ProjConfig()
    proj.name = '创业板动量择时'
    proj.commission = 0.0001
    proj.slippage = 0.0001
    proj.symbols = ['159915.SZ']  # 证券池列表
    proj.benchmark = '159915.SZ'
    proj.start_date = '20100101'
    proj.data_folder = 'etfs'  # 这里指定data/数据目录

    fields = ['roc(close,20)']
    names = ['roc_20']
    proj.fields = fields
    proj.names = names

    # 这里是策略算子列表
    proj.algos.append(
        AlgoConfig(name=SelectBySignal().name, kwargs={'rules_buy': ['roc_20>0.08'], 'rules_sell': ['roc_20<-0.0']})

    )
    #proj.algos.append(
    #    AlgoConfig(name=SelectTopK().name, kwargs={'factor_name': 'roc_20'})
    #)
    proj.algos.append(AlgoConfig(name=WeightEqually().name))
    proj.algos.append(AlgoConfig(name=Rebalance().name))

    return proj

昨天的策略,再优化一下,年化20.3%,就两个标的:沪深300ETF和创业板ETF两个宽基ETF。

图片

大家选择“大小盘轮动”策略即可:

图片

代码在个位置:

图片

之前的文章提及的DeepAlphaGen:

代码在如下目录:

图片

代码已经同步至星球:

图片

吾日三省吾身

“凡事发生必有利于我”。

上周开始,眼晴不舒服,初步判断是干眼症。

想来,沉浸式写代码,做研究,用眼过度。

停下来,思考方向,人的精力真的很有限,专注做好能力圈的一点事情就好。

做有积累的事情,尽量自动化。一次时间投入,多次复用的事情。

如无必要,勿增实体。

投资应该是轻松,愉悦,甚至是略显无聊的事情,它不需要你特别努力,也不是你努力就有用的。关键是你要做对的事情,方向对就好。

后续的重心:

Dagster盘后更新数据,在线的, SAAS化的回测系统,不排除可转接对实盘。数据上会专注把ETF先搞扎实,当然技术栈,框架,因子挖掘,我相信都是通用的,大家愿意用在股票上,期货上,甚至加密货币上,都是可以的。

后端的框架应该还是Django,如果需要前后端分离,会使用django-ninja 一个类似fastapi的框架。前端暂时不想引入nodejs,太麻烦,还是喜欢bootstrap(jquery)的老方式。

我们那个年代的程序员,对于SEO是有执念的,也不知道有没有用。

SAAS版本AI量化回测系统,最大的挑战在于,任务可能需要异步运行,当然django也有celery这样的框架。

原创文章第364篇,专注“个人成长与财富自由、世界运作的逻辑与投资”。

2018年,看到机会,但没有知行合一,2020左右完成建仓。

2023年,我看到的是机会,这次争取知行合一。

今天开始深度学习挖因子。

前面的文章开了个头:DeepAlphaGen:强化学习的因子组合挖掘

主流的公、私募量化,多因子模型是重中之重和热点方向。容量大,可以与前沿技术相结合。

东方证券的一张图:多因子选股体系

图片

多因子选股体系主要包括 Alpha 模型、风险模型、交易成本模型和组合优化四个模块。Alpha 模型负责对股票收益或 Alpha 的预测,对组合收益的影响相对更大,是量化研究的重中之
重。传统的 Alpha 模型一般分为 Alpha 因子库构建和 Alpha 因子加权两个核心步骤。

其中:在 Alpha 因子构建中,可以引入的常见机器学习模型主要有两大类:遗传规划和神经网络

先挖掘因子,再合成,忽略了因子之间的相互作用。

今天开始要代码实现的:一种新的因子组合挖掘框架,直接使用因子组合的表现来优化一个强化
学习因子生成器,最终生成的是一组公式因子集合,这些因子协同使用具有较高的选股效力。这
样做既能保留遗传规划算法公式化的优势,也能提升模型泛化能力,适应多种股票池,还能大幅
提升运算效率。

论文上周已经在星球里分享,代码后续会跟上。

图片

我对这篇论文感兴趣的核心在于,它具备一定程度上的通用性,集传统遗传规划的优点,可以显示生成表达式,结果了深度学习的泛化能力和端到端的能力。另外,原作者是提供代码的,不过它使用qlib的数据库,我进行了拆分,与咱们的开源项目,数据模块整合起来,让这个模块更加通用。

核心代码在Quantlab工程的如下位置:alphagen。

图片

代码环境,需要:pytorch框架上的强化学习包:

stable_baselines3==2.0.0
sb3_contrib==2.0.0

核心的调用代码如下:

import json
import os
from datetime import datetime
from typing import Optional

import numpy as np
from sb3_contrib import MaskablePPO
from stable_baselines3.common.callbacks import BaseCallback

from alphagen.data.calculator import AlphaCalculator
from alphagen.models.alpha_pool import AlphaPool, AlphaPoolBase
from alphagen.rl.env.core import AlphaEnvCore
from alphagen.rl.env.wrapper import AlphaEnv
import torch

from alphagen.rl.policy import LSTMSharedNet
from alphagen.utils import reseed_everything
from alphagen.caculator.duckdb_caculator import DuckdbCalculator


def train(seed: int = 0, pool_capacity: int = 10, steps: int = 200_000, instruments: str = "csi300"):
    calculator_train = DuckdbCalculator(instrument=instruments,
                           start_time='2010-01-01',
                           end_time='2019-12-31')
    calculator_valid = DuckdbCalculator(instrument=instruments,
                           start_time='2020-01-01',
                           end_time='2020-12-31')
    calculator_test = DuckdbCalculator(instrument=instruments,
                          start_time='2021-01-01',
                          end_time='2022-12-31')

    pool = AlphaPool(
        capacity=pool_capacity,
        calculator=calculator_train,
        ic_lower_bound=None,
        l1_alpha=5e-3
    )

    reseed_everything(seed)

    device = torch.device('cuda:0')
    env = AlphaEnv(pool=pool, device=device, print_expr=True)

    name_prefix = f"new_{instruments}_{pool_capacity}_{seed}"
    timestamp = datetime.now().strftime('%Y%m%d%H%M%S')

    checkpoint_callback = CustomCallback(
        save_freq=10000,
        show_freq=10000,
        save_path='/path/for/checkpoints',
        valid_calculator=calculator_valid,
        test_calculator=calculator_test,
        name_prefix=name_prefix,
        timestamp=timestamp,
        verbose=1,
    )

    model = MaskablePPO(
        'MlpPolicy',
        env,
        policy_kwargs=dict(
            features_extractor_class=LSTMSharedNet,
            features_extractor_kwargs=dict(
                n_layers=2,
                d_model=128,
                dropout=0.1,
                device=device,
            ),
        ),
        gamma=1.,
        ent_coef=0.01,
        batch_size=128,
        tensorboard_log='/path/for/tb/log',
        device=device,
        verbose=1,
    )
    model.learn(
        total_timesteps=steps,
        callback=checkpoint_callback,
        tb_log_name=f'{name_prefix}_{timestamp}',
    )

其中DuckdbCaculator是我们实现的。

就是根据表达式计算因子,IC值等等。

使用了sb3的强化学习扩展包里的MaskablePPO算法

发布者:股市刺客,转载请注明出处:https://www.95sca.cn/archives/103745
站内所有文章皆来自网络转载或读者投稿,请勿用于商业用途。如有侵权、不妥之处,请联系站长并出示版权证明以便删除。敬请谅解!

(0)
股市刺客的头像股市刺客
上一篇 2024 年 7 月 29 日
下一篇 2024 年 7 月 29 日

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注