机器学习在量化中的应用

| 随便聊聊

想了很多,写了删,删了写,还是随性一些。

如果有人问人工智能(Artificial Intelligence,AI)带来了什么变化,那么就是让机器具备了学习和总结的能力。计算机视觉(Computer Vision,CV)让机器学会了识别人脸,识别车牌,识别一切。自然语言处理(Nature Language Processing,NLP)则赋予机器理解和处理语言的能力,从而实现文章分类、内容理解和多语言翻译。机器学习(Machine Learning,ML)(通过总结数据间的规律,使机器能够进行复杂的预测和决策。

在股市中,我们能用到的就是机器学习和自然语言处理。机器学习能够分析和总结不同因子与目标值之间的关系。而NLP模型则通过处理时序类数据,如股票的历史价格,进行预测。NLP不仅可以利用因子预测股票目标值,还能处理新闻舆论,将其作为基本面因子来预测股票的走势。然而,这里存在一个挑战:当新闻舆论发布时,你可能尚未及时获取到相关信息,导致模型无法及时提供建议。当你做出反应时,股票市场可能已经发生了变化。

| 机器学习

在机器学习和量化的结合中,小木屋采用的更多是树模型。什么是树模型呢?就是随机森林(RF)、XGBoost、CatBoost、lightGBM模型这一系列。那么这几个模型有什么太大的区别吗?有的,RF、XGBoost、CatBoost、lightGBM这四个模型在训练速度、内存使用,对缺失值的处理、对类别特征的处理上有很大的不同。但是这些区别对预测结果的准确性影响并不大,除非训练数据量很大,则需要考虑训练速度和内存使用的问题。

树模型的结构是怎样的呢?树模型的结构如下图所示,以预测股票涨跌为例。这是一个二分类任务,模型通过学习各种因子之间的关系,将股票划分为可能涨的一类和可能跌的一类。树模型的层次结构直观地展示了模型对数据进行分割的过程,使得它成为处理复杂关系和非线性问题的强大工具。

机器学习在量化中的应用_第1张图片

在这个结构中,每个节点表示一个特征,分支代表特征值的分割,叶子节点表示最终的分类结果。通过多棵树的集成,树模型能够更准确地捕捉数据中的模式和规律,为量化分析提供强大的预测能力。另外,图中显示,树模型通过一系列因子的大小判断。这些因子的大小是通过向树模型提供大量历史数据进行学习得到的,树模型通过总结这些历史因子和目标值之间的关系进行预测。

随机森林模型由许多这样的决策树组成。我们之所以选择使用多棵树,是因为我们认为单棵树学习到的规律可能不够准确。这类似于我们在做决策时依赖于过去学习和经历的事物,而每个人的经历和学习都是不同的,因此做出的决策也会有所不同。模型也是如此,因此我们训练多颗树,并通过对它们的决策进行投票(对于分类任务)或平均(对于回归任务),从而获得更加准确的结果。

机器学习在量化中的应用_第2张图片

XGBoost、CatBoost、lightGBM模型大同小异,也是由多棵树组合而成。下面就不一一赘述了。如果对这三个模型有兴趣,可以找对应的论文或者找一些讲解文章看看。

小木屋现在实盘的策略是采用了随机森林的,因此我把我实盘代码简化版的核心代码展示出来。

下图是小木屋经过改动并只采用了小市值因子的策略效果(没有采用随机森林)

机器学习在量化中的应用_第3张图片

下图是小木屋采用随机森林和多因子进行训练得到的策略效果。

机器学习在量化中的应用_第4张图片

两个策略的运行时间都是2020年1月1日到2023年11月22日。第一个策略只采用了小市值因子,从策略效果图可以看出2020年该策略的效果是很差的,几乎没有正收益。而随机森林+多因子策略也有采用小市值因子,但经过随机森林和其他因子的结合,使得其在2020年的效果变好了。

再经过微调,效果变成下图所示。

机器学习在量化中的应用_第5张图片

修改后的随机森林+多因子策略
上面几个图的变化,小木屋觉得随机森林模型最大的作用就是降低回撤频次和幅度,不用自己构造多个因子的组合关系,由模型总结多因子组合关系。

代码核心思想

训练和预测过程:

使用上周五的因子数据进行模型训练。

使用这周五的因子数据进行未来市值的预测。

调仓策略:

在这周五,计算预测出的未来市值与当前市值之差,选择差值最大的N只股票。 对选取的股票进行调仓,以期望获得更好的投资回报。
每周一对选取的股票进行调仓,以期望获得更好的投资回报。

基于聚宽平台的核心代码,完整可跑通代码可关注后私信我领取。


def get_stock_list(context):
    final_list = set()
    initial_list = list(g.pools)
    today = context.current_dt
    # 通过timedelta算出前一天的日期
    delta = datetime.timedelta(days=1)
    yesterday = today - delta
    yesterday = yesterday.strftime('%Y-%m-%d')

    q = query(valuation.code, 
        valuation.market_cap, 
        valuation.turnover_ratio,
        valuation.pe_ratio, 
        valuation.pb_ratio, 
        valuation.ps_ratio,
        indicator.roa,
         income.total_operating_revenue).filter(valuation.code.in_(initial_list))
    # 将获得的因子值存入一个数据表
    dataset = get_fundamentals(q, date = yesterday)
    dataset.columns = ['code', 'market_cap',
            '换手率','PE','PB','PS','总资产收益率','营业总收入']
    dataset['平均差']=list(DMA(dataset.code,  yesterday)[0].values())
    dataset['移动平均']=list(MA(dataset.code,  yesterday).values())
    dataset['乖离率']=list(BIAS(dataset.code,  yesterday)[0].values())
    dataset['相对强弱指标']=list(RSI(dataset.code,yesterday,N1=6).values())
    dataset.fillna(0, inplace=True)

    if len(g.pre_df) == 0:
        dataset_pre = dataset.copy()
    else:
        dataset_pre = g.pre_df

    dataset_pre.index = dataset_pre.code
    dataset_pre = dataset_pre.drop('code', axis=1)
    X_train = dataset_pre.drop('market_cap', axis=1)
    y_train = dataset_pre['market_cap']

    dataset_train = dataset.copy()
    dataset_train.index = dataset_train.code
    dataset_train = dataset_train.drop('code', axis=1)
    X_test = dataset_train.drop('market_cap', axis=1)
    y_test = dataset_train['market_cap']
    #这里我们使用随机森林来训练模型
    reg = RandomForestRegressor(random_state=200)
    reg.fit(X_train, y_train)
    # 找到模型市值比预测值低最多的股票
    y_pred = pd.DataFrame(reg.predict(X_test), index=y_test.index, columns=['market_cap'])['market_cap']
    factor = y_test - y_pred
    final_list = list(factor.sort_values(ascending=True).index)
    # 过滤停牌、ST、退市标签和退市公告股票
    final_list = filter_paused_stock(final_list)
    final_list = filter_st_stock(final_list)
    target_stocks = final_list[:min(len(final_list),g.stock_num)]
    message = '需要购买的股票为:\n {}'.format('\n'.join(target_stocks))
    send_message(message, channel='weixin')
    g.target_buy_stocks = target_stocks
    g.pre_df = dataset

你可能感兴趣的:(机器学习,人工智能)