年化33.8%,夏普1.22:lightGBM在ETF行业模动上小试牛刀(附代码下载)。

news2024/11/18 7:39:22

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

今天做排序学习算法在ETF行业轮动上的策略,我们选用的DBDT框架是lightGBM,它的优点就是快且效果不错。

我们的候选集是29个行业ETF:

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',
]

我们使用的alpha数据集:

这里的因子列表可以再扩展的,可以替换成qlib的alpha158,或者是补充更多的技术指标。

class Alpha:
    def __init__(self):
        pass

    def get_feature_config(self):
        return self.parse_config_to_fields()

    def get_label_config(self):
        return ["shift(close, -5)/shift(open, -1) - 1", "qcut(shift(close, -5)/shift(open, -1) - 1,20)"
                ], ["label_c", 'label']

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

        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

下面是梯度提升树的代码:

from quant.datafeed.dataset import DataSet
import joblib, os


class LGBModel:
    def __init__(self, load_model=False, feature_cols=None):
        self.feature_cols = feature_cols
        if load_model:
            path = os.path.dirname(__file__)
            self.ranker = joblib.load(path + '/lgb.pkl')

    def _prepare_groups(self, df):
        df['day'] = df.index
        group = df.groupby('day')['day'].count()
        return group

    def predict(self, data):
        data = data.copy(deep=True)
        if self.feature_cols:
            data = data[self.feature_cols]

        pred = self.ranker.predict(data)
        return pred

    def train(self, ds: DataSet):
        X_train, X_test, y_train, y_test = ds.get_split_data()
        X_train_data = X_train.drop('symbol', axis=1)
        X_test_data = X_test.drop('symbol', axis=1)

        # X_train, X_val, y_train, y_val = train_test_split(X_train, y_train, test_size=0.2, random_state=1)

        query_train = self._prepare_groups(X_train.copy(deep=True)).values
        query_val = self._prepare_groups(X_test.copy(deep=True)).values
        query_test = [X_test.shape[0]]

        import lightgbm as lgb
        gbm = lgb.LGBMRanker()

        gbm.fit(X_train_data, y_train, group=query_train,
                eval_set=[(X_test_data, y_test)], eval_group=[query_val],
                eval_at=[5, 10, 20], early_stopping_rounds=50)

        print(gbm.feature_importances_)

        joblib.dump(gbm, 'lgb.pkl')

模型训练好了之后,我们使用algo的机器学习“模块”来加载,预测:

from quant.context import ExecContext


class ModelPredict:
    def __init__(self, model):
        self.model = model

    def __call__(self, context: ExecContext):
        context.bar_df['pred_score'] = self.model.predict(context.bar_df)
        return False  # 需要继续处理

整合的代码依然简洁:

env = Env(ds)

from quant.context import ExecContext
from quant.algo.algos import *
from quant.algo.algo_model import ModelPredict
from quant.models.gbdt_l2r import LGBModel

model = LGBModel(load_model=True, feature_cols=ds.features)

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

env.backtest_loop()
env.show_results()

年化33.8%,夏普1.22。(整合回测框架代码,数据,策略均上传到星球,请大家前往下载我的开源项目及知识星球)

作为对比,如果我们把pred_score按最差的买入。

结果是如下这样,也侧面印证我们排序的正确性。

明天把alpha因子集扩充,然后加入前向滚动回测看效果。

闲庭独坐对闲花, 轻煮时光慢煮茶, 不问人间烟火事, 任凭岁月染霜华。

财富自由的生活,值得期待。

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

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

相关文章

Python编程:标准库logging使用

Python编程:标准库logging使用 一、 基础使用 1.1 logging使用场景 ​ 日志是什么?这个不用多解释。百分之九十的程序都需要提供日志功能。Python内置的logging模块,为我们提供了现成的高效好用的日志解决方案。但是,不是所有的…

python爬虫——怎么抓取职位信息

目录 背景 为什么要抓取职位信息 怎么抓取职位信息 代码示例 被反爬怎么办 使用代理IP进行爬取 总结 背景 高考刚结束,马上又到了大学生毕业的时候了,各大厂也开始了一波招工潮了,想知道大厂或竞争对手都招些什么人,有什么…

来了解一下这几个网络设备日志级别分别都适用在何种场景?

在华为设备中,涉及到日志的,我们经常会在日志级别上迷糊,本文就给大家介绍8种日志级别以及每个级别适用的场景。 1. Emergency(紧急) 紧急级别的日志是指最高级别的日志,表示系统遇到了严重的错误或故障&…

JMeter+Ant+jenkins搭建接口自动化测试环境

目录 前言: 1.ant简介 2. 构建ant环境 3.JMeter与Ant集成 4. 报告优化 5.jenkins持续集成 前言: JMeter是一个开源的性能测试工具,可以用于测试Web应用程序或API接口的性能,支持多种通信协议和数据格式。Ant是一个构建工具&…

ui自动化 SeleniumBase

目录 前言: git克隆 校验邮件的案例: 注意事项: 前言: SeleniumBase是一个基于Selenium WebDriver的Python框架,用于UI自动化测试。它具有简单易用的API接口,可轻松编写测试脚本以及管理测试用例。SeleniumBase不仅提供了Web…

【LeetCode】HOT 100(10)

题单介绍: 精选 100 道力扣(LeetCode)上最热门的题目,适合初识算法与数据结构的新手和想要在短时间内高效提升的人,熟练掌握这 100 道题,你就已经具备了在代码世界通行的基本能力。 目录 题单介绍&#…

5月总共面试31次,我人麻了....

3年测试经验原来什么都不是,只是给你的简历上画了一笔,一直觉得经验多,无论在哪都能找到满意的工作,但是现实却是给我打了一个大巴掌!事后也不会给糖的那种... 先说一下自己的个人情况,普通二本计算机专业…

华为OD机试真题 JavaScript 实现【寻找密码】【2023Q1 100分】,附详细解题思路

一、题目描述 小王在进行游戏大闯关,有一个关卡需要输入一个密码才能通过,密码获得的条件如下: 在一个密码本中,每一页都有一个由 26 个小写字母组成的若干位密码,从它的末尾开始依次去掉一位得到的新密码也在密码本…

母线保护(4)

4、母联死区保护 在各种母差保护中,存在一个共同的问题,就是死区问题。 如图,在母联合位时,当故障发生在母联断路器与母联CT之间时,故障电流由II母流向I母,I母小差有差流,判断为I母故障&#x…

yum安装nginx

Nginx介绍 Nginx是一款轻量级的Web服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个BSD-like 协议下发行。其特点是占有内存少,并发能力强,事实上Nginx的并发能力确实在同类型的网页服务器中表现较好&…

电脑提示由于找不到vcomp140.dll无法继续执行代码怎么修复呢?这个三个方法可以帮到你

在我们打开游戏或者获取软件的时候,点击电脑提示由于找不到vcomp140.dll无法继续执行代码需要怎么办呢?vcomp140.dll是什么呢?相信困扰着不少小伙伴,vcomp140.dll是Microsoft Visual C Redistributable中的一个动态链接库文件&…

牛客网Java面试题及答案整理(2023年秋招最新版,持续更新)

学习如逆水行舟,尤其是 IT 行业有着日新月异的节奏,我们更要抓紧每一次可以学习和进步的机会。所以,没有撤退可言。 即使是面试跳槽,那也是一个学习的过程。只有全面的复习,才能让我们更好的充实自己,武装…

基于Java高校专业信息管理系统设计与实现(源码+lw+部署文档+讲解等)

博主介绍: ✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战 ✌ 🍅 文末获取源码联系 🍅 👇🏻 精…

Spring Security--会话管理

就像登录qq一样,一个手机登录会将另外一个手机挤下线,这个就叫会话管理。 这个东西非常简单,在默认情况下可以登录n多次,一旦开启,就不允许登录多个。 什么是一个会话。 我们简单理解就是一个浏览器的同一个用户算一…

Redux 异步解决方案2. Redux-Saga中间件

利用Generator特性实现异步 因为Generator。结合yield yield操作符会获取右边表达示的值返回 可以用于异步变同步操作 中间件的特性: 以前的 action -> reducers -> store 现在的 action -> middleware -> reducers -> store 注意: reducer的type…

群晖云同步失败?一直卡在连接中怎么办?

群晖云同步是群晖NAS的一款基于网络的数据备份和同步服务,它可以帮助我们在不同设备之间轻松地同步文件、照片、文档等,并且支持自动化执行同步备份任务,让您的数据存储更加安全。 虽然群晖云同步能给我们带来很多便利,但是在…

yolov5 6.1 关于 tensorrt 加速的使用以及问题说明

文章目录 1. 参考连接2. 使用说明2.1 导出加速模型2.1 使用加速模型2.2 加速参数对比 3. 问题说明3.1 在 Tensorrt 8.4.1.5 版本上使用 export.py 导出失败的问题3.2 把模型文件由 best.pt 更换成加速后的 best.engine 后,执行推理时标注的类别名不正确的问题3.3 导…

面向教育机构的IT管理

多年来,高等教育见证了一些惊人的技术创新,包括远程学习、VR 和 AR 实验室、物联网等。随着技术席卷高等教育领域,机构有望高度依赖其技术基础设施,将学生的想法变为现实,以支持学习渠道并促进研究和合作。 另一方面&…

JMeter发送表单数据,响应体报错:参数校验异常

请求方式是post,请求参数就是表单形式。这个时候我们可以把请求参数写到参数里,也可以选择写到消息体数据里。 1、如果是写到参数中,那Content-Type默认就是表单格式,不需要格外添加HTTP信息头管理器。 2、如果是写到消息体数据中…

语音消息实现(聊天向)

语音消息实现记录下: SpringBootVue3客服项目,网页录制发送语音消息 Vue中使用js-audio-recorder插件实现录音功能并实现上传Blob数据到SpringBoot后台接口 2fps/recorder github地址 Recorder的API 语音测试地址 [Web] 4分钟搭建一个简洁好看的 We…