论文是使用一个非常老的qlib版本实现了,这个版本现在都不好找了,而且qlib有个麻烦的事情,就是数据做增量更新比较麻烦。
所以,我们还是使用Quantlab自己的数据管理吧。
Quantlab2.4源代码现在就可以下载,大家可以先熟悉数据加载:系统源代码发布v2.4供下载,带年化32.1%策略,简化GUI逻辑
这是一个“通用框架”。
输入是一堆基础数据,一堆算子。那通过强化学习去合成高ic的因子。
无论是股票,etf,可转债都可以通用。
强化学习环境,用于因子表达式的生成:
大家重点看强化学习环境里的step的代码:
每次生成一个token作为action,若遇到SEP结束符,则生成结果,使用ic作为它的reward,非正常结束的reward都设为零。
本身这个环境的逻辑比较简单。
话说——强化学习的env一般都不复杂。我们直接实现一个金融量化的Env也比较简单。
class AlphaEnvCore(gym.Env): pool: AlphaPoolBase _tokens: List[Token] _builder: ExpressionBuilder _print_expr: bool def __init__(self, pool: AlphaPoolBase, device: torch.device = torch.device('cuda:0'), print_expr: bool = False ): super().__init__() self.pool = pool self._print_expr = print_expr self._device = device self.eval_cnt = 0 self.render_mode = None def step(self, action: Token) -> Tuple[List[Token], float, bool, bool, dict]: if (isinstance(action, SequenceIndicatorToken) and action.indicator == SequenceIndicatorType.SEP): reward = self._evaluate() done = True elif len(self._tokens) < MAX_EXPR_LENGTH: self._tokens.append(action) self._builder.add_token(action) done = False reward = 0.0 else: done = True reward = self._evaluate() if self._builder.is_valid() else -1. if math.isnan(reward): reward = 0. truncated = False # Fk gymnasium return self._tokens, reward, done, truncated, self._valid_action_types() def _evaluate(self): expr: Expression = self._builder.get_tree() if self._print_expr: print(expr) try: ret = self.pool.try_new_expr(expr) self.eval_cnt += 1 return ret except OutOfDataRangeError: return 0. def _valid_action_types(self) -> dict: valid_op_unary = self._builder.validate_op(UnaryOperator) valid_op_binary = self._builder.validate_op(BinaryOperator) valid_op_rolling = self._builder.validate_op(RollingOperator) valid_op_pair_rolling = self._builder.validate_op(PairRollingOperator) valid_op = valid_op_unary or valid_op_binary or valid_op_rolling or valid_op_pair_rolling valid_dt = self._builder.validate_dt() valid_const = self._builder.validate_const() valid_feature = self._builder.validate_feature() valid_stop = self._builder.is_valid() ret = { 'select': [valid_op, valid_feature, valid_const, valid_dt, valid_stop], 'op': { UnaryOperator: valid_op_unary, BinaryOperator: valid_op_binary, RollingOperator: valid_op_rolling, PairRollingOperator: valid_op_pair_rolling } } return ret def valid_action_types(self) -> dict: return self._valid_action_types() def render(self, mode='human'): pass
吾日三省吾身
今天听《爱迪生传》,挺有收获。
之前基于对特斯拉这个悲情传奇人物的同情,给爱迪生一些刻板的商人,资本家,都是团队的研究成果之类的印象。
真实的人性,远比一些标签来得复杂。
纳瓦尔说的:构建和销售能力。
我觉得 构建 和 商业能力更合适一些。
像牛顿,特斯拉都是构建能力特别强,但商业能力一般。
而马斯克,爱迪生,本身构建能力,学习能力极强,又有同样强的商业能力,可以借助商业的杠杆,实现自己的梦想。
国内的传奇,更多是“文科生”居多,李白,苏东坡。
理想主义者“老罗”,做手机,也只能做做体验优化。体验优化是打败不了苹果的。
发明和创造首先是理工科的事情,能结合科技和人文就更完美了,比如乔布斯。
爱迪生的热情是在没有上帝的世界,研究自然哲学。
快速学习,结果导向。
2024年的规划,广度的读书,满足的是好奇心。在可以上手解决的领域,躬身入局,比如AI量化,金融领域的LLM到AGI。
世界格局,宏观经济,我们都身在其中,我们能做的不多,最多“顺势而为”,别在方向上“南辕北辙”。
量化模型里,因子模型是主流。
DeepAlphaGen:强化学习的因子组合挖掘:框架代码+数据下载
这篇论文创新之处在于,传统多因子,我们是一个一个因子挖掘/构造,去计算IC/IR(线性),然后把多个因子通过等权加权,或者IC值加权等方式,组合起来。
一是低效,二是不科学。
实践中早就发现,有时候添加一个低IC的因子到组合里,可以明显提升绩效。这种因子就类似催化剂的效果吧。
如上图所示,整个算法分为两部分:因子生成和因子评估,两部分交替运行。
左边是生成表达式:
先定义框架使用的token,有操作符,其实就是自定义函数,特征:OHLCV,常数,时间窗口,然后是一些序列起始的标志符。
有点像文本生成,只不过我们不是要生成一句话,而是生成一个“表达式因子”(带约束的序列生成)。
深度学习模型的代码一向是比较简洁的,就算当下流行的LLM,比如开源的Llama2,也就几百行的代码,主要就是堆叠Tranformer单元。
但周边数据整理,数据准备还是需要花一些工夫的
原论文使用的是qlib,我们也使用qlib来复现吧。后续可以再与咱们Quantlab来打通。
原文件的qlib是0.0.2-dev,我换成了最新的,也不需要自己准备数据,使用qlib的get_data直接下载。
# Copyright (c) Microsoft Corporation. # Licensed under the MIT License. import fire from qlib.tests.data import GetData if __name__ == "__main__": fire.Fire(GetData)
沪深300指数数据,日频20几M,很快就能准备好。
明天咱们继续调强化学习的模型来生成“因子表达式”。
系统源代码发布v2.4供下载,带年化32.1%策略,简化GUI逻辑
吾日三省吾身
今天在飞机上,再一次听《反脆弱》。
追求稳定其实本身是让系统更脆弱。书里讲的公务员和出租车司机。不过这是国外的例子,国内会有所不同。
但道理是相通的。
就像投资领域,你怎么看波动,风险还是机会?
不确定性可能会带来机会,当然会带来风险。
反脆弱=从不确定性中获益。
生物体本身都会从挫折,打击中获益。
我们自己的人生规划也应该如此。
守住自己的底线,健康,家庭,财务安全,让账户自动运转的小财务自由等,这是自己可以控制的。
然后可以“大胆”的拥抱变化。
有时候,危机意味着转机。
温水煮青蛙,未必是好事。
有些人,有些事情的出现就是来“推”你一把,帮你做一个决定。
所以,不必焦虑。
发布者:股市刺客,转载请注明出处:https://www.95sca.cn/archives/103644
站内所有文章皆来自网络转载或读者投稿,请勿用于商业用途。如有侵权、不妥之处,请联系站长并出示版权证明以便删除。敬请谅解!