碧沼

V1

2022/10/22阅读:35主题:默认主题

研报复现——逻辑回归市场择时策略

研报复现系列(1) 华西证券——逻辑回归市场择时策略

前言

 本文参考华西证券2021年12月1日的研报《机器学习择时系列——逻辑回归模型市场择时策略》对其研究过程和结论进行复现学习。复现金工研报是学习量化策略,训练编程能力的很好途径。

 如果您对我的内容感兴趣,欢迎后台私信进行交流。

图1:本文复现的研报
图1:本文复现的研报

1.研报概述

逻辑回归是经典的广义线性模型之一,虽然称作回归,但实际往往用作分类。模型形式为:

量化择时是指采用数据化的方式,判断进场或者离场时机。通过计算机技术分析相关数据,得出对证券市场未来一段时间内发展趋势的分析预判,如果判定上涨则给出买入持有的操盘建议,如果判定下跌则提示投资者卖出清仓规避风险,如果判定震荡则进行高抛低吸或低吸高抛以此来降低持仓成本。可以看出,预测股票的涨跌趋势本质上是一个二类分类问题。 逻辑回归一般用于预测二分类变量,它不仅可以提供除类别标签信息外的明确分类概率,而且可以分析所有类型数据的预测值。 我们这里来研究基于逻辑回归模型的择时建模。

逻辑回归的优缺点主要有以下几条。

  • 模型的解释性强,根据权重向量在每个特征上的大小,可以很直观的判断出了不同变量之间的重要性。
  • 模型的训练速度快,计算效率比其他大部分分类方法高。
  • 对噪声处理的代价小,对二分类问题,结果介于0到1之间,具有概率意义,可以拓展到概率意义上进行推荐。
  • 逻辑回归对多重共线性较为敏感,此外由于预测结果的概率曲线呈现出S型,两边概率变化小,中间概率变化大,因此输入可能存在阈值效应。

该研报的主要思路是,选取一些特征变量作为预测的输入变量,下一交易日的涨跌情况与否为输出变量。如果上涨为1,下跌为0。来训练逻辑回归模型。标的为沪深300(000300)的日线数据来进行测试。研报中选择的几个指标如下表所示:

表1:4个特征变量及其含义 来源:华西证券研究所
表1:4个特征变量及其含义 来源:华西证券研究所

2.本文的研究环境与数据来源

本文的数据来源是通过同花顺的量化接口下载保存得到的,从2015年1月到2022年10月沪深300(000300)的日线走势。数据样例如下:

图2:000300数据
图2:000300数据

3.指标生成与数据描述

根据研报,我们需要生成持仓收益率、平均收益率、夏普比、5日成交量平均与持仓期间平均成交量之比几个指标。本文以10日作为交易持仓期限。同时计算夏普比率的无风险收益率时,以年化利率1.31%计算。

#5日平均收益率
data['5d_mean_return'] = (data['quote_rate']*0.01).shift(1).rolling(window=5).mean()
#10日持仓收益率
data['10d_return'] = (data['quote_rate']*0.01+1).shift(1).rolling(10).apply(np.prod)-1
#夏普比率
riskfree_rate = (1.0131**(10/252)-1)
annual_std =  data['quote_rate'].shift(1).rolling(10).std() * (10 ** 0.5)
data['sharpe_ratio'] = (data['10d_return'] - riskfree_rate) / annual_std 
#5日成交量与持仓期平均交易量之比
data['v_t_ratio'] = data['volume'].shift(1).rolling(5).mean()/data['volume'].shift(1).rolling(10).mean()
#预测变量
L=list(data.index)
for i in range(1,len(L)-1):
    if data.loc[L[i],'10d_return']>0 :
        data.loc[L[i-1],'y']=1
    else:
        data.loc[L[i-1],'y']=0
data.dropna(inplace=True)
plt.figure(figsize=(15,7))
plt.subplot(2,2,1)
data['10d_return'].hist(bins=30)
plt.legend(['10日收益率'],loc='best')
plt.subplot(2,2,2)
data['5d_mean_return'].hist(bins=30)
plt.legend(['5日平均收益率'])
plt.subplot(2,2,3)
data['sharpe_ratio'].hist(bins=30)
plt.legend(["Sharpe_Ratio"])
plt.subplot(2,2,4)
data['v_t_ratio'].hist(bins=30)
plt.legend(["10日平均交易量/5日平均交易量"])

图3:特征变量表现
图3:特征变量表现

本文生成的变量分布与研报原文中在极端值方面存在一定的差异,但整体分布来看基本一致。

4.回测表现

首先不进行训练集和测试集的划分,直接在全样本上进行训练和预测。设定逻辑回归结果大于0.6的发出买入信号,小于0.6的发出卖出信号,持仓时间10天。交易信号生成:

    L=list(data.index)
    model = LogisticRegression(C=1,max_iter=100,penalty='l2',solver='liblinear',tol=0.0001)
    train_x = data.loc[L,['5d_mean_return','10d_return','sharpe_ratio','v_t_ratio']]
    train_y = data.loc[L,'y']
    test_x = data.loc[L,['5d_mean_return','10d_return','sharpe_ratio','v_t_ratio']]
    test_y = data.loc[L,'y']
    model.fit(train_x,train_y)
    pred = model.predict_proba(test_x)[:,[1]]
    print(metrics.r2_score(test_y, pred))
    print(metrics.mean_absolute_error(test_y, pred))
    print(metrics.mean_squared_error(test_y, pred))
    print(metrics.explained_variance_score(test_y, pred))
    context.output =  test_x
    context.output.loc[:,'信号'] = ['买入' if i >0.6 else '卖出' for i in pred]
    context.output = context.output['信号'][::11]

回测结果并不如人意,没有实现原文类似的曲线,并且信息比率为负。对比原文其在变量设置处语焉不详,本文使用的变量全部通过shift滑动到下一天,若原文在调仓日当天使用了包含调仓日当天的交易量计算平均值,那么使用了未来函数,很可能造成结果偏好。不过值得肯定的是如果将阈值设定为0.8再开仓,表现更好可以极大程度上降低相比于沪深300的波动。

图4:全样本逻辑回归回测结果
图4:全样本逻辑回归回测结果
图5:全样本回测结果(0.8阈值)
图5:全样本回测结果(0.8阈值)

接下来本文模仿原文研报进行3:2样本划分测试,结果如下图所示。是一个较差的结果,择时的效果并没有优于基准。

图6:训练集测试集划分回测结果
图6:训练集测试集划分回测结果

5.GBDT的拓展

相比于逻辑回归这种基础模型,GBDT的精度和准确率要显著强于逻辑回归。本文在原文的基础上尝试使用了GBDT作为模型,发现收益表现在全样本和划分样本上均上强于逻辑回归模型。

图7:全样本GBDT回测结果
图7:全样本GBDT回测结果
图8:划分训练集测试集的GBDT回测结果
图8:划分训练集测试集的GBDT回测结果

6.总结

本文对【华西证券——逻辑回归模型市场择时策略】的研究流程基本进行了复现,虽然结果与原文存在差异,但这种择时策略在15年之前表现出了增强的趋势,并且可以通过设定不同的阈值来提升交易的表现。

  • 受限于算力限制,并没有进行滚动预测。
  • 该研报构建的指标还是相对比较简单,如引入更多指标理论上可以更好的构建择时策略。

公众号后台回复研报复现1获取本文回测代码

分类:

后端

标签:

后端

作者介绍

碧沼
V1