年化18.1%,大模型如何实现因子挖掘(附python代码和数据下载)

 

今天咱们引入大模型(LLM)来强化遗传算法的因子挖掘。

我们知道,遗传算法的初代因子是随机生成的,而后通过fitness的优化进行化和迭代。

所以,初代因子一定程度上决定了进化的方向和速度。

这时候,我们可以通过大模型生成一些低相关的,可解释的因子,而后引导遗传算法的方向。

当然在进化过程中,也可以加入大模型,这是后续的工作了。

 

01

大模型生成因子表达式

安装依赖——我们使用langchain来简化与大模型的交互过程:

langchain
langgraph

langchain_openai

langchain_community

配置自己的KIMI_KEY到系统变量:

图片

注意,这里加完之后,需要重启系统一次才会生效。

当然,你也可以直接改代码里的KIMI_KEY的值。

KIMI_KEY = None
if not KIMI_KEY:

import os
KIMI_KEY = os.getenv('KIMI_KEY')
print(KIMI_KEY)

 

请kimi生成的10个因子,参考worldquant101的格式,看起来还可以:

{

  “expr”: [

    “(-1 * rank(((ts_delta(close, 1) * ts_std(volume, 10)) / ts_mean(volume, 20))) * ts_rank(ts_delta(close, 2), 5))”,

    “(-1 * rank((ts_max(ts_delta(close, 1), 3) / ts_min(ts_delta(close, 1), 3))) * ts_rank(ts_delta(volume, 3), 5))”,

    “(-1 * rank((ts_skew(ts_delta(close, 1), 5) * ts_kurt(ts_delta(close, 1), 5))) * ts_rank(ts_delta(close, 1), 10))”,

    “(-1 * rank((ts_delta(close, 1) * ts_sum(ts_delta(close, 1), 5))) * ts_rank(ts_delta(close, 1), 5))”,

    “(-1 * rank((ts_delta(close, 1) * ts_max(ts_delta(close, 1), 10))) * ts_rank(ts_delta(close, 1), 10))”,

    “(-1 * rank((ts_delta(close, 1) * ts_min(ts_delta(close, 1), 10))) * ts_rank(ts_delta(close, 1), 10))”,

    “(-1 * rank((ts_delta(close, 1) * ts_mean(ts_delta(close, 1), 5))) * ts_rank(ts_delta(close, 1), 5))”,

    “(-1 * rank((ts_delta(close, 1) * ts_median(ts_delta(close, 1), 5))) * ts_rank(ts_delta(close, 1), 5))”,

    “(-1 * rank((ts_delta(close, 1) * ts_pct_change(close, 5))) * ts_rank(ts_delta(close, 1), 5))”

  ]

}

核心代码如下:

class FactorGPTAgent:
def __init__(self):
# self.sources = [x.strip() for x in read_file_2_list('worldquant_101.txt')]
optional_params = {
"response_format": {"type": "json_object"}
}
self.func_names = []
from datafeed.expr_functions import unary_rolling_funcs

for func in unary_rolling_funcs:
self.func_names.append(func)

from datafeed.expr_functions import unary_funcs

for func in unary_funcs:
self.func_names.append(func)

from datafeed.expr_functions import binary_roilling_funcs

for func in binary_roilling_funcs:
self.func_names.append(func)

# openai_api_key = KIMI_KEY
self.model = ChatOpenAI(temperature=0, openai_api_key=KIMI_KEY, model='moonshot-v1-8k',
base_url="https://api.moonshot.cn/v1", max_retries=1, model_kwargs=optional_params)

def build_prompt(self):

prompt = [{
"role": "system",
"content": "你是一个量化分析师. 你可以通过阅读多个alpha因子表达式,总结其内在规律,并且可以创新性的生成可用的因子表达式。"
"对于生成的表达式,你能够解释其有效性,并且能够用清晰简洁的语言解释其各个变量的含义。\n "
}, {
"role": "user",
"content": f"指令描述: 生成因子表达式"
f"可以使用的变量名:open,high,low,close,volume\n"
f"可以使用的函数名列表: {self.func_names}\n "
f"你的任务学习以上资源之后,总结其规律,输出一个同类型表达式。\n "
f"书写表达式时,请仅使用样例数据里的函数,每次生成1个,,生成的表达式,不要带Alpha#xxx,期望因子的相关性低\n"
f"Please return nothing but a JSON in the following format:\n"
f"{sample_json}\n "
}]
return prompt


def run(self):
lc_messages = convert_openai_messages(self.build_prompt())
response = self.model.invoke(
lc_messages).content

print(response)
return json.loads(response)


if __name__ == '__main__':

FactorGPTAgent().run()

代码在如下这个位置:

图片

大家可以下载后,运行看看,代码下载:


图片

 

02

吾日三省吾身

如果你没有过高的预期,那大模型现在真的已经很厉害了。

做过nlp的同学都知道,一个简单的问答系统,多轮对话、意图识别,上下文理解有多难。

更不用说,程序直接返回json格式,遵循我们大白话的指令。

这在几年前是根本不可想象的。

但很多人开始不切实际的预期,希望机器把所有事情都干了,

暂时这还不可能。

 

与几个同学聊天,相互更新一下近况。

之前听说一个同学被一个老板相中,去负责一块业务。后得知已经离开,原因是风格不符。另外还有创业中的朋友也回归了职场。

其实,能回归就已经不错了。

冷暖自知。

世界之精彩,是你自己创造和提供了多少价值,然后与之交换。

否则,世界精彩与你何干。

自己能掌控的,就是你自己的成长,产品化,实现你的价值。

 

 

 

 

 

 

 

 

 

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

(0)
股市刺客的头像股市刺客
上一篇 5分钟前
下一篇 2分钟前

相关推荐

发表回复

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