因子表达式完美重构 | Qlib Alpha158因子库复现 (代码+数据)

原创文章第447篇,专注“AI量化投资、个人成长与财富自由"。

本周星球代码计划——因子分析,因子挖掘

1、(因子表达式优化)Alpha158以及world quant101部分因子实现。

2、基于lightgbm的因子筛选。 

3、优秀因子的单因子分析。 

4、deepalphagen和gplearn部分代码优化。

或者可以这么说,当前主流私募基金的做法就是因子挖掘。——手工挖,遗传算法,机器学习等。然后合成因子。

因为因子到策略,还有很多人工可以干预的环节。

完全所谓端到端,哪怕就是现在最强的GPT-5也做不到。当下大模型可以真正落地的场景,还是Agent生态,通过多环节的串联+工具来实现预期的目标。

投资也如此。

最多到端对端挖掘因子,然后把因子拿出来做策略。

因子表达式重构

两个包装器,一个按symbol来groupby,另一个按date来groupby

def calc_by_date(func):@wraps(func)def wrapper(*args, **kwargs):other_args = []se_args = []se_names = []for arg in args:if type(arg) is not pd.Series:other_args.append(arg)else:se_args.append(arg)se_names.append(arg.name)if len(se_args) == 1:ret = se_args[0].groupby(level=0, group_keys=False).apply(lambda x: func(x, *other_args, **kwargs))elif len(se_args) > 1:count = len(se_args)df = pd.concat(se_args, axis=1)df.index = se_args[0].indexret = df.groupby(level=0, group_keys=False).apply(lambda sub_df: func(*[sub_df[name] for name in se_names], *other_args))ret.index = df.indexreturn retreturn wrapperdef calc_by_symbol(func):@wraps(func)def wrapper(*args, **kwargs):other_args = []se_args = []se_names = []for arg in args:if type(arg) is not pd.Series:other_args.append(arg)else:se_args.append(arg)se_names.append(arg.name)if len(se_args) == 1:ret = se_args[0].groupby(level=1, group_keys=False).apply(lambda x: func(x, *other_args, **kwargs))elif len(se_args) > 1:count = len(se_args)df = pd.concat(se_args, axis=1)df.index = se_args[0].indexret = df.groupby(level=1, group_keys=False).apply(lambda sub_df: func(*[sub_df[name] for name in se_names], *other_args))ret.index = df.indexreturn retreturn wrapper

目前,需要使用截面排序rank,需要截面排序。

这样做的好处,就是所有的计算子函数都不需要变更了,加上这个包装器即可:

@calc_by_symbol
def ta_atr(high, low, close, period=14):se = talib.ATR(high, low, close, period)se = pd.Series(se)se.index = high.indexreturn se
@calc_by_date
def rank(se: pd.Series):ret = se.rank(pct=True)return ret

这样csv_dataloader加载数据,因子计算速度也快了很多,最重要的是,我们解决了rank,ts_rank嵌套的问题。

图片

Alpha158因子库

代码完全移植过来了,qlib的158因子,大家感兴趣可以把alpha360也迁移过来。

图片

代码在如下位置:

图片

from datafeed import AlphaBaseclass Alpha158(AlphaBase):def get_fields_names(self):# ['CORD30', 'STD30', 'CORR5', 'RESI10', 'CORD60', 'STD5', 'LOW0',# 'WVMA30', 'RESI5', 'ROC5', 'KSFT', 'STD20', 'RSV5', 'STD60', 'KLEN']fields = []names = []# kbarfields += ["(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 += ["quantile(close, %d, 0.8)/close" % d for d in windows]names += ["QTLU%d" % d for d in windows]fields += ["quantile(close, %d, 0.2)/close" % d for d in windows]names += ["QTLD%d" % d for d in windows]#fields += ["ts_rank(close, %d)" % d for d in windows]#names += ["RANK%d" % d for d in windows]fields += ["(close-min(low, %d))/(max(high, %d)-min(low, %d)+1e-12)" % (d, d, d) for d in windows]names += ["RSV%d" % d for d in windows]fields += ["idxmax(high, %d)/%d" % (d, d) for d in windows]names += ["IMAX%d" % d for d in windows]fields += ["idxmin(low, %d)/%d" % (d, d) for d in windows]names += ["IMIN%d" % d for d in windows]fields += ["(idxmax(high, %d)-idxmin(low, %d))/%d" % (d, d, d) for d in windows]names += ["IMXD%d" % d for d in windows]fields += ["corr(close, log(volume+1), %d)" % d for d in windows]names += ["CORR%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 += ["mean(close>shift(close, 1), %d)" % d for d in windows]names += ["CNTP%d" % d for d in windows]fields += ["mean(close<shift(close, 1), %d)" % d for d in windows]names += ["CNTN%d" % d for d in windows]fields += ["mean(close>shift(close, 1), %d)-mean(close<shift(close, 1), %d)" % (d, d) for d in windows]names += ["CNTD%d" % d for d in windows]fields += ["sum(greater(close-shift(close, 1), 0), %d)/(sum(Abs(close-shift(close, 1)), %d)+1e-12)" % (d, d)for d in windows]names += ["SUMP%d" % d for d in windows]fields += ["sum(greater(shift(close, 1)-close, 0), %d)/(sum(Abs(close-shift(close, 1)), %d)+1e-12)" % (d, d)for d in windows]names += ["SUMN%d" % d for d in windows]fields += ["(sum(greater(close-shift(close, 1), 0), %d)-sum(greater(shift(close, 1)-close, 0), %d))""/(sum(Abs(close-shift(close, 1)), %d)+1e-12)" % (d, d, d)for d in windows]names += ["SUMD%d" % d for d in windows]fields += ["mean(volume, %d)/(volume+1e-12)" % d for d in windows]names += ["VMA%d" % d for d in windows]fields += ["std(volume, %d)/(volume+1e-12)" % d for d in windows]names += ["VSTD%d" % d for d in windows]fields += ["std(Abs(close/shift(close, 1)-1)*volume, %d)/(mean(Abs(close/shift(close, 1)-1)*volume, %d)+1e-12)"% (d, d)for d in windows]names += ["WVMA%d" % d for d in windows]fields += ["sum(greater(volume-shift(volume, 1), 0), %d)/(sum(Abs(volume-shift(volume, 1)), %d)+1e-12)"% (d, d)for d in windows]names += ["VSUMP%d" % d for d in windows]fields += ["sum(greater(shift(volume, 1)-volume, 0), %d)/(sum(Abs(volume-shift(volume, 1)), %d)+1e-12)"% (d, d)for d in windows]names += ["VSUMN%d" % d for d in windows]fields += ["(sum(greater(volume-shift(volume, 1), 0), %d)-sum(greater(shift(volume, 1)-volume, 0), %d))""/(sum(Abs(volume-shift(volume, 1)), %d)+1e-12)" % (d, d, d)for d in windows]names += ["VSUMD%d" % d for d in windows]return fields, names

吾日三省吾身

“若无闲事在心头,便是人间好时节”。

这里的闲事,就是短期内,没有确定deadline要做的事情。

当然,本身很多事情,随着时间的推移,变得可有可无,或者就是随手的事情。

但在强迫症的眼里,既然要做,那就尽快做完,然后痛快地玩。

强迫症很难与杂事共处,尤其是带着不确定的事情。

要做就尽快做,不做就不做。

确实很多时候可以带来自律,给人专业,靠谱的感觉。

但过犹不及,对于家人,身边的朋友有时候也会造成困扰。

历史文章:

Quantlab3.3代码发布:全新引擎 | 静待花开:年化13.9%,回撤小于15% | lightGBM实现排序学习

创业板指布林带突破策略:年化12.8%,回撤20%+| Alphalens+streamlit单因子分析框架(代码+数据)

轮动策略模板重写,先来一个年化21%的策略(代码+数据)

去掉底层回测引擎,完全自研,增加超参数优化,因子自动挖掘,机器模型交易。

飞狐量化——AI驱动的量化。(持续给大家写代码的,交付最前沿AI量化技术和策略的星球)AI量化实验室——2024量化投资的星辰大海

关于我:CFA,北大光华金融硕士,十年量化投资实战。 / CTO,全栈技术,AI大模型 。——应该是金融圈最懂技术的男人

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

x-cmd pkg | dasel - JSON、YAML、TOML、XML、CSV 数据的查询和修改工具

目录 简介首次用户快速实验指南基本功能性能特点竞品进一步探索 简介 dasel&#xff0c;是数据&#xff08;data&#xff09;和 选择器&#xff08;selector&#xff09;的简写&#xff0c;该工具使用选择器查询和修改数据结构。 支持 JSON&#xff0c;YAML&#xff0c;TOML&…

项目流程管理效率提升的3个核心点

前言 项目流程管理效率提升的3个核心点 一、 业务层面 分支业务 ——> 整体业务 剖析: 总体来说就是个人业务能力从百分之十到百分之百的覆盖, 达到后期在团队中随时可替补其他人的业务测试, 直至最终你可以一个人独立负责整个系统的业务测试, 那么在测试团队里你的价值…

解决vue 2.6通过花生壳ddsn(内网穿透)实时开发报错Invalid Host header和websocket

请先核对自己的vue版本,我的是2.6.14,其他版本未测试 起因 这两天在维护一个基于高德显示多个目标(门店)位置的项目,由于高德要求定位必须使用https服务,遂在本地无法获取到定位坐标信息,于是就想着通过内网穿透的方式临时搭一个测试站进行实时更新开发,于是就有了今…

【Linux驱动】休眠与唤醒 | POLL机制 | 异步通知 | 阻塞与非阻塞 | 软件定时器

&#x1f431;作者&#xff1a;一只大喵咪1201 &#x1f431;专栏&#xff1a;《Linux驱动》 &#x1f525;格言&#xff1a;你只管努力&#xff0c;剩下的交给时间&#xff01; 目录 &#x1f3d3;休眠与唤醒&#x1f3f8;内核函数&#x1f3f8;驱动框架及编程 &#x1f3d3;…

Opencv中cv2.calcHist的mask的使用方法

引入 我们用来画直方图函数: cv2.calcHist([img], [0], mask, [256], [0, 256]) 有一个mask属性.我们应该如何去使用它呢,以及他的作用是什么 mask顾名思义就是一个遮罩层,我们可以选择图片上我们想要的位置进行画直方图 实际用法介绍 首先我们用一张图片来进行讲解 陶大郎的…

消息队列之王——Kafka

Zookeeper 在学习kafka之前&#xff0c;我们需要先学习Zookeeper&#xff0c;那Zookeeper是什么呢&#xff1f;Zookeeper是一个开源的分布式的&#xff0c;为分布式框架提供协调服务的Apache项目。 Zookeeper 工作机制 Zookeeper从设计模式角度来理解&#xff1a;是一个基于观…

40尺货柜可以装载多少张建筑模板?

在建筑行业&#xff0c;40尺货柜一直以其标准化、便捷的特点成为建材运输的首选。然而&#xff0c;对于建筑模板这样的大型且薄型货物&#xff0c;如何在40尺货柜中实现最高效的装载一直是一项具有挑战性的任务。让我们一起揭秘&#xff0c;40尺货柜究竟能够装载多少张建筑模板…

helm---自动化一键部署

什么是helm?? 在没有这个helm之前&#xff0c;deployment service ingress helm的作用就是通过打包的方式&#xff0c;把deployment service ingress 这些打包在一块&#xff0c;一键式部署服务&#xff0c;类似于yum 官方提供的一个类似于安装仓库的功能&#xff0c;可以实…

飞书+ChatGPT+cpolar搭建企业智能AI助手并实现无公网ip远程访问

文章目录 推荐 前言环境列表1.飞书设置2.克隆feishu-chatgpt项目3.配置config.yaml文件4.运行feishu-chatgpt项目5.安装cpolar内网穿透6.固定公网地址7.机器人权限配置8.创建版本9.创建测试企业10. 机器人测试 推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂…

HCIA——21C/S、P2P、peer的选择

学习目标&#xff1a; 计算机网络 1.掌握计算机网络的基本概念、基本原理和基本方法。 2.掌握计算机网络的体系结构和典型网络协议&#xff0c;了解典型网络设备的组成和特点&#xff0c;理解典型网络设备的工作原理。 3.能够运用计算机网络的基本概念、基本原理和基本方法进行…

【JS逆向学习】国家加密系列-SM算法实例

SM系列 1、国家加密算法介绍 事实上从 2010 年开始&#xff0c;我国国家密码管理局就已经开始陆续发布了一系列国产加密算法&#xff0c;其中SM1、SM4、SM7、祖冲之密码&#xff08;ZUC&#xff09;是对称算法&#xff1b;SM2、SM9是非对称算法&#xff1b;SM3是哈希算法。目…

旧路由重置新路由设置新路由设置教程|适用于自动获取IP模式

前言 如果你的光猫是直接拨号&#xff08;路由模式&#xff09;的&#xff0c;就可以按照本教程进行路由重置或者更换新路由器。 本文章适合电脑小白&#xff0c;请注意每一步哦&#xff01; 注意事项 开始之前需要确认光猫是桥接模式还是路由模式。如果光猫是路由模式&…