期货ML策略(三)基于交易信号的回测

接上一篇文章(期货ML策略(二)构建机器学习模型),这篇文章开始对上一篇的结果进行回测分析。

上一篇文章中我简单的介绍了如何构建ML模型。当在实盘的时候,每隔一分钟我们可以获取到不同合约的实时数据(1分钟k线数据),然后构造需要的特征并将其输入模型中。模型会根据输入的特征输出20分钟后上涨概率,当达到预先设定的阈值时对其做多或做空。

在回测的过程中,为了加快回测的速度,我们只需要提前计算好在何时买入,何时卖出即可。考虑到当获得K线数据之后不能马上给出交易信号,并且存在一些时间差,所以回测的时候延后1分钟交易;即在第0分钟给出交易信号,第1分钟开仓,第20分钟平仓。因为目前考虑的是日内交易,所以策略会在尾盘清仓。

github中的Trian.ipynb程序会自动输出交易信号result.csv。回测过程中根据给定的交易信号进行交易。

因为期货交易中不同合约品种的手续费不太一样,所以这里我借助了天勤平台进行回测。

回测算法的算法步骤如下:

Step1 : 按时间顺序寻找交易信号,如果有交易信号则进入Step2,否则进入Step5

Step2 : 判断当前时间点是否开仓,如果当前时间点需要开仓,则进行开仓操作。如果当前时间点大于开仓时间,则回到Step1,否则进入Step3

Step3 : 遍历判断当前持仓是否达到平仓时间,如果是则平仓。然后进入Step4

Step4 : 如果当前时间是14点58分,清空所有仓位。然后回到Step1寻找新的交易信号

Step5 : 遍历判断当前持仓是否达到平仓时间,如果是则平仓。如果当前时间是14点58分,清空所有仓位,并结束回测程序。

Step1核心代码如下:

for trade_date, tmp_df in pred.groupby('datetime_open'):
    # print(now_time_, now_time_ - trade_date)
    # print(trade_date)
    tmp_df = tmp_df[(tmp_df['pred'] > buying_prob)|(tmp_df['pred'] < selling_prob)]
    flag = False  # 判断是否有进行加减仓等一系列操作

    if len(tmp_df) != 0:
        trade_kind = list(tmp_df['ts_code'].values)
        trade_prob = tmp_df['pred'].values
        close_time = list(tmp_df['datetime_close'])

Step2核心代码如下:

# 进行做多或者做空操作
if pd.Timedelta(seconds=-15) < trade_date - now_time_ < pd.Timedelta(seconds=15):
    for kind, prob, tmp_close_time in zip(trade_kind, trade_prob, close_time):
        target_pos = TargetPosTask(api, kind)
        hold_pos = api.get_position(kind).pos
        if prob > buying_prob:
            target_pos.set_target_volume(hold_pos + 1)
            direction.append(1)
        else:
            target_pos.set_target_volume(hold_pos - 1)
            direction.append(-1)
        hold_kind.append(kind)
        close_datetime.append(tmp_close_time)
        # set_kind.add(kind)
        print(kind, direction[-1], now_time_)
        api.wait_update()
    flag = True
    trade_kind = []
    trade_prob = []
    # break
elif now_time_ - trade_date > pd.Timedelta(seconds=15):
    break

Step3核心代码如下:


# 查看是否已满20分钟
while True:
    if len(hold_kind) == 0:
        break
    # print(now_time-hold_time[0])
    for i in range(len(hold_kind)-1, -1, -1):
        if now_time_ - close_datetime[i] >= pd.Timedelta(seconds=-15):
            target_pos = TargetPosTask(api, hold_kind[i])
            hold_pos = api.get_position(hold_kind[i]).pos
            if direction[i] == 1 and hold_pos != 0:
                target_pos.set_target_volume(hold_pos - 1)
            elif hold_pos != 0:
                target_pos.set_target_volume(hold_pos + 1)
            print('time end, 平1手  ' + hold_kind[i])
            hold_kind.pop(i)
            direction.pop(i)
            close_datetime.pop(i)
            api.wait_update()
    flag = True
    break

Step4核心代码如下:


# 当日清仓
if now_time_.hour == 14 and now_time_.minute >= 58:
    # tmp_kind = []
    # print(api._serials.items())
    print(now_time_)
    for tmp in set(hold_kind):
        target_pos = TargetPosTask(api, tmp)
        if target_pos != 0:
            target_pos.set_target_volume(0)
            print('清空 '+str(tmp))
            api.wait_update()
    flag = True
    hold_kind = []
    close_datetime = []
    direction = []

回测结果

回测时间:2019年9月1日->2020年4月20日
所有结果如下:
期货ML策略(三)基于交易信号的回测_第1张图片
期货ML策略(三)基于交易信号的回测_第2张图片

从结果上来看,策略能够勉强做到盈利,这也很正常,毕竟我才刚开始做,要是这么简单就做出来岂不是随随便便赚钱,相信再深究一些因子设计肯定会有更好的效果。从交易频率上看,可以发现很多时候都是没有进行交易的,这个可以根据涨跌概率排名来进行做多或做空。总之,这个简单的机器学习策略还是很有潜力的,毕竟目前的策略只是一个玩具策略,改进之后肯定有更难以想象的效果。

下一篇文章将会利用构建的模型进行模拟盘交易。

所有代码github:

https://github.com/wbbhcb/futures_strategy/tree/master/ML_Strategy

对量化、数据挖掘、深度学习感兴趣的可以关注公众号,本人不定期分享有关这些方面的研究。
在这里插入图片描述
个人知乎:
https://www.zhihu.com/people/e-zhe-shi-wo/activities

你可能感兴趣的:(量化杂文)