如何设计一个机器学习驱动的策略?

原创文章第105篇,专注“个人成长与财富自由、世界运作的逻辑, AI量化投资”。

"AI量化平台"当前目标,可以快速开发策略,相当于是搭建一个快速实验平台——工欲善其事,必先利其器。

昨天完成了轮动策略模板,并快速完成了“动量策略轮动”。“积木式”策略通用模板,整合backtrader的回测引擎:动量轮动策略代码案例,年化15.25%

文章里的交易信号是由规则给定的,若是交易信号由机器模型生成,则就是一个AI驱动的模型。今天我们主要还做这个。

01 数据集

机器学习驱动的量化策略,与传统量化不同在于,它的交易信号是由模型给出,所以它需要遵守机器学习流程。机器学习需要对数据集进行划分:训练集、测试集。在训练集上“学习”模型,在测试集上评估训练的结果。

与传统机器学习随机抽样不同在于,由于我们需要在测试集在做“连续”的回测,所以不能把总体随机打乱取其中一部分,而是将期按比列分成两段。一段当训练集,一段当测试集。因此,我们不使用sklearn的train_test_split函数,而是自己实现一个金融时间序列的数据集切分函数。

import numpy as np
import datetime as dt
from engine.datafeed.dataloader import Dataloader


def get_date_by_percent(start_date, end_date, percent):
    days = (end_date - start_date).days
    target_days = np.trunc(days * percent)
    target_date = start_date + dt.timedelta(days=target_days)
    # print days, target_days,target_date
    return target_date


def split_df(df, x_cols, y_col, split_ratio=0.8):
    split_date = get_date_by_percent(df.index[0], df.index[df.shape[0] - 1], split_ratio)

    input_data = df[x_cols]
    output_data = df[y_col]

    # Create training and test sets
    X_train = input_data[input_data.index < split_date]
    X_test = input_data[input_data.index >= split_date]
    Y_train = output_data[output_data.index < split_date]
    Y_test = output_data[output_data.index >= split_date]

    return X_train, X_test, Y_train, Y_test


class Dataset:
    def __init__(self, feature_names, feature_fields, label_name='label', label_field=None):
        self.feature_names = feature_names
        self.feature_fields = feature_fields
        self.label_name = label_name
        self.label_field = 'Ref($close,-1)/$close -1' if label_field is None else label_field

    def get_split_dataset(self, symbols, valid_date=None):
        names = self.feature_names + [self.label_name]
        fields = self.feature_fields + [self.label_field]
        loader = Dataloader()
        df = loader.load_one_df(symbols, names, fields)
        X_train, X_test, Y_train, Y_test = split_df(df, x_cols=self.feature_names, y_col=self.label_name)
        return X_train, X_test, Y_train, Y_test


if __name__ == '__main__':
    codes = ['000300.SH', 'SPX']
    names = []
    fields = []
    fields += ["Corr($close/Ref($close,1), Log($volume/Ref($volume, 1)+1), 30)"]
    names += ["CORR30"]

    dataset = Dataset(names, fields)
    X_train, X_test, Y_train, Y_test = dataset.get_split_dataset(codes)
    print(X_train, Y_train)

02 模型训练与预测

对划分好的数据集,进行模型训练和预测,模型提供了两个函数,fit和predict,代码比较简法,就是从dataset中分别读取训练集和测试集,使用model进行训练和预测。

 
 
class ModelRunner:
    def __init__(self, model, ds: Dataset):
        self.model = model
        self.dataset = ds

    def fit(self):
        X_train, y_train = self.dataset.get_train_data()
        self.model.fit(X_train, y_train)

    def predict(self):
        X_test, y_test = self.dataset.get_test_data()
        pred = self.model.predict(X_test, y_test)


        hit_count = 0
        total_count = len(y_test)
        for index in range(total_count):
            if (pred[index]) == (y_test[index]):
                hit_count = hit_count + 1

        hit_ratio = hit_count / total_count
        score = self.model.score(X_test, y_test)
        logger.debug("准确率:", hit_ratio, '得分:', score)
        return hit_ratio, score

传统机器学习得分在52%左右,比瞎猜好一点,当然这里还没有优化。

随机森林比SVM和逻辑回归效果要差,这是一个意外。另外就是SVM=LR,这个也很奇怪,可以相近,但不应该严格等于。

明天继续把深度学习模型(keras版本整合进来做一个对比),并整合向量化回测。

代码和数据,请前往星球下载。

“积木式”策略通用模板,整合backtrader的回测引擎:动量轮动策略代码案例,年化15.25%

知识星球

猜你喜欢

转载自blog.csdn.net/weixin_38175458/article/details/127867100