年化收益 21%:lightGBM的WFA滚动训练,使用qlib的alpha158因子集

news2024/11/24 6:00:41

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

开始之前,先说说感受。

把整个框架与思路都在社群里开源出来,就是希望大家看懂思路,而不是拿一两个策略。说实话,投资哪有这种高确定性的“圣杯”

投资是一个“概率”游戏。我们要做的,尽量提升决策的正概率而已。因此,多一些有效因子,模型判断更准确一些。所以,方法论和思路比一个策略本身要重要得多。这是我们这个社群的目标——以盈利为目的开发策略,而且是批量的有效实战策略。

微信群现在的讨论氛围还不错,还没有加入的成员请扫码进入。一般加入之初,我都有发私信给大家,如果没有,请再星球里私信我。

今天要抽空实现“前向滚动”训练回测

从20日动量来看,我们选择29个行业作为候选集合是对的。

因为市场是按行业分化的,尤其是市场情绪震荡有分歧之时:

29个行业等权回测:

年化收益 0.075,最大回测 -0.318,夏普比 0.441。

等权加周再平衡:

年化收益 0.146,最大回测 -0.283,夏普比 0.748。再平衡适合相关性低的组合,正当的行业比较明显。

使用lightGBM的WFA滚动训练

年化收益 0.219,最大回测 -0.259,夏普比 0.861。

etfs = [
        '159870.SZ',
        '512400.SH',
        '515220.SH',
        '515210.SH',
        '516950.SH',
        '562800.SH',

        '515170.SH',
        '512690.SH',
        '159996.SZ',
        '159865.SZ',
        '159766.SZ',

        '515950.SH',
        '159992.SZ',
        '159839.SZ',
        '512170.SH',
        '159883.SZ',

        '512980.SH',
        '159869.SZ',
        '515050.SH',
        '515000.SH',
        '515880.SH',
        '512480.SH',
        '515230.SH',

        '512670.SH',
        '515790.SH',
        '159757.SZ',
        '516110.SH',

        '512800.SH',
        '512200.SH',
    ]

import numpy as np
import pandas as pd
from tqdm import tqdm
from engine.env import Env


from engine.datafeed.dataset import DataSet, AlphaLit, Alpha
ds = DataSet(etfs, start_date='20190101', handler=Alpha(), cache=True)

# ds = DataSet(['000300.SH', '399006.SZ'], start_date='20120101', handler=Alpha())
env = Env(ds.data)

from engine.context import ExecContext
from engine.algo.algos import *
from engine.algo.algo_model import ModelWFA
from engine.models.gbdt_l2r import LGBModel

model = LGBModel(load_model=False, feature_cols=ds.get_feature_names())

env.set_algos([
    RunWeekly(),
    ModelWFA(model=model),
    SelectTopK(K=2, order_by='pred_score', b_ascending=False),
    WeightEqually()
])

env.backtest_loop()
env.show_results()

下面是因子集的定义代码:

class Alpha(AlphaBase):
    def __init__(self):
        pass

    @staticmethod
    def parse_config_to_fields():
        # ['CORD30', 'STD30', 'CORR5', 'RESI10', 'CORD60', 'STD5', 'LOW0',
        # 'WVMA30', 'RESI5', 'ROC5', 'KSFT', 'STD20', 'RSV5', 'STD60', 'KLEN']
        fields = []
        names = []

        # kbar
        fields += [
            "(close-open)/open",
            "(high-low)/open",
            "(close-open)/(high-low+1e-12)",
            "(high-greater(open, close))/open",
            "(high-greater(open, close))/(high-low+1e-12)",
            "(less(open, close)-low)/open",
            "(less(open, close)-low)/(high-low+1e-12)",
            "(2*close-high-low)/open",
            "(2*close-high-low)/(high-low+1e-12)",
        ]
        names += [
            "KMID",
            "KLEN",
            "KMID2",
            "KUP",
            "KUP2",
            "KLOW",
            "KLOW2",
            "KSFT",
            "KSFT2",
        ]

        # =========== price ==========
        feature = ["OPEN", "HIGH", "LOW", "CLOSE"]
        windows = range(5)
        for field in feature:
            field = field.lower()
            fields += ["shift(%s, %d)/close" % (field, d) if d != 0 else "%s/close" % field for d in windows]
            names += [field.upper() + str(d) for d in windows]

        # ================ volume ===========
        fields += ["shift(volume, %d)/(volume+1e-12)" % d if d != 0 else "volume/(volume+1e-12)" for d in windows]
        names += ["VOLUME" + str(d) for d in windows]

        # ================= rolling ====================
        windows = [5, 10, 20, 30, 60]
        fields += ["shift(close, %d)/close" % d for d in windows]
        names += ["ROC%d" % d for d in windows]

        fields += ["mean(close, %d)/close" % d for d in windows]
        names += ["MA%d" % d for d in windows]

        fields += ["std(close, %d)/close" % d for d in windows]
        names += ["STD%d" % d for d in windows]

        fields += ["slope(close, %d)/close" % d for d in windows]
        names += ["BETA%d" % d for d in windows]

        fields += ["max(high, %d)/close" % d for d in windows]
        names += ["MAX%d" % d for d in windows]

        fields += ["min(low, %d)/close" % d for d in windows]
        names += ["MIN%d" % d for d in windows]

        fields += ["corr(close/shift(close,1), log(volume/shift(volume, 1)+1), %d)" % d for d in windows]
        names += ["CORD%d" % d for d in windows]

        fields += ['close/shift(close,20)-1']
        names += ['roc_20']
        return fields, names

所有代码,数据均打包发布至星球,请大家前往下载:

我的开源项目及知识星球

欢迎大家提建议,bug,可以在专属微信群里发起讨论。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/649136.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

通义听悟上线,强大的视频会议和学习直播分析能力,人工智能如何改变我们的生活和工作方式?

什么是通义听悟 通义听悟已开启公测,公测期(2023年6月1日至30日)用户可体验所有AI功能,含全文概要、章节速览、发言总结等高阶AI功能,通过阿里云主账号登录。 官方给的应用场景: 1、实时会议记录&#x…

4.MySQL表的增删改查(进阶)

文章目录 🍯1. 数据库约束🍯🍎1.1 约束类型🍎🍏1.2 NULL约束🍏🍊1.3 UNIQUE:唯一约束🍊🍋1.4 DEFAULT:默认值约束🍋🍒1.5 …

MySQL数据库语言三、DCL语句

😘作者简介:正在努力的99年公司职员。 👊宣言:人生就是B(birth)和D(death)之间的C(choise),做好每一个选择。 🙏创作不易,…

绩效管理的本质是激发员工,而不是扣工资!

绩效管理是企业管理中非常重要的一个环节,通过对员工表现进行评估和奖励,可以提高整个团队的士气和生产力。 然而,在实际操作中,有些企业却将绩效管理变成了惩罚员工的手段,甚至使用绩效扣除员工的薪水。这种做法不仅…

VALSE 2023:版面分析技术如何赋能生产生活?

目录 0 写在前面1 文档版面分析2 版面元素检测3 文档排版引擎总结 0 写在前面 VALSE年度研讨会旨在为中国青年学者在计算机视觉、图像处理、模式识别与机器学习研究领域提供一个具有深度的学术交流平台。VALSE秉持理性批判、勇于探索、实证和创新等科学精神,倡导自…

光伏电池建模及温度光照的影响曲线

光伏电池建模及温度光照的影响MATLAB程序及仿真资源-CSDN文库https://download.csdn.net/download/weixin_56691527/87910193模型介绍: 需要MATLAB2018B及以上的版本!! 首先根据根据环境修正公式搭建光伏电池仿真模型: 温度变化…

传统机器学习算法解析(opencv实现)

前言 文本主要解析在传统机器学习当中一些小的算法与思想,只是传统机器学习算法当中的一小部分,更多传统机器学习算法可参考我的另外几篇博客 链接1: PCA主成分分析 链接2: Canny边缘检测算法 链接3: K-Means聚类算法 链接4: SIFT算法分析 1. opencv …

MMDeploy安装和pth转ONNX

参考: https://github.com/open-mmlab/mmdeploy/blob/main/README_zh-CN.md MMDeploy安装指导 MMDeploy 是 OpenMMLab 模型部署工具箱,为各算法库提供统一的部署体验。基于 MMDeploy,开发者可以轻松从训练 repo 生成指定硬件所需 SDK&#…

0x80080005 windows更新失败导致的net framework3.5安装失败

缘起 客户安装应用软件提示需要安装net framework3.5 sp1,但是下载了net framework的安装包后一直提示正在下载中,后来发现系统的windows更新功能都用不了,真的是坑啊。 解决方案 按Windows按键(田字按键)X,选择Powe…

2023-6-15-第六式适配器模式

🍿*★,*:.☆( ̄▽ ̄)/$:*.★* 🍿 💥💥💥欢迎来到🤞汤姆🤞的csdn博文💥💥💥 💟💟喜欢的朋友可以关注一下&#xf…

如何通过java程序获取表的自增主键值?

获取自增主键: 在 Java 程序中,使用 JDBC 插入记录到 MySQL 数据库时,可以通过以下步骤获取自增主键的值: 第一步:在 PreparedStatement 对象中添加 Statement.RETURN_GENERATED_KEYS 常量作为参数,表示希…

Zabbix与信创、云原生、高可用等热点解析|Zabbix大会·上海站

根据信通院调研显示,超过90%的中国金融机构已经引入开源软件。工信部突出强调开源在驱动软件产业发展的重要作用。作为一个完全开源免费的企业级监控解决方案,Zabbix在IT基础监控、网络监控、Server监控和云监控等领域都获得了同行和用户极高的评价。 Za…

html好看的登录页面1(十三种风格登录页面源码)

文章目录 1.登录风格效果说明1.1 背景凹起风登录界面1.2 弹出风登录界面1.3 科技时尚风登录界面1.4 蓝色一夏风登录界面1.5 模糊背景左右风登录界面1.6 上中下介绍风登录界面1.7 深沉科技风登陆界面1.8 舒适简洁风登录界面1.9 网站风登录界面1.10 小框清爽风登录界面1.11 夜色风…

【IoU全总结】GIoU, DIoU, CIoU, EIoUFocal, αIoU, SIoU,WIoU【基础收藏】

🥑 Welcome to Aedream同学 s blog! 🥑 并不存在效果一定优秀的IoU,需要结合自己的网络、数据集试验。 不想深究原理可直接跳转总结。文内公式均为手打,非图片,方便查看 文章目录 L1 Loss,L2Loss&#xff0…

深入浅出剖析EL表达式和JSTL

el表达式 产生背景 从JSP2.0开始,就不推荐使用java脚本,而是使用el表达式或者动态标签代替 java脚本; 页面标签; 概念和原理 概念:Expression Language :jsp内置的一种表达式语言;原理:el表达式的出现目的是替换js…

这些excel英语翻译方法你会吗?

大家平常的时候应该都会去做Excel表格吧?无论是在读书、上班或者日常,必然都会使用到吧?但是在处理国际业务时,我们要来处理表格就会比较费时一点,因为语言的不同会有一点影响,所以我们可能需要将Excel表格…

第九章节 用Python实现常微分方程初值问题的数值解法

参考书籍:数值分析 第五版 李庆杨 王能超 易大义编 第9章 常微分方程初值问题的数值解法 文章声明:如有发现错误,欢迎批评指正 文章目录 欧拉法后退的欧拉方法梯形方法改进欧拉公式补充龙格—库塔方法线性多步法阿当姆斯显示与隐式公式 9.1引…

cesium学习(entities实体)

什么是entities CesiumJS具有丰富的空间数据API,可分为两类:面向图形开发人员的低级Primitive API,以及用于数据驱动可视化的高级Entity API。 entitiesAPI公开了一组一致设计的高级对象,这些对象将相关的可视化和信息聚合到一个…

(转载)有导师学习神经网络的分类(matlab实现)

有导师学习神经网络以其良好的学习能力广泛应用于各个领域中,其不仅可以解决拟合回归问题,亦可以用于模式识别、分类识别。将继续介绍两种典型的有导师学习神经网络(GRNN和PNN),并以实例说明其在分类识别中的应用。 1 理论基础 1.1 广义回归神经网络(…

小雉系统U盘安装包制作

​ 本文原地址: http://www.feitianzhi.com/boke/index.php/archives/57/ 概述 小雉系统可从线上系统制作安装包到U盘,制作的安装包可用于新系统的安装; 小雉系统只提供升级包,对应的安装包均是客户在应用升级包后按本文或http://www.f…