欢迎光临散文网 会员登陆 & 注册

量化交易软件:梯度提升CatBoost在交易系统开发中的应用

2023-08-04 15:18 作者:bili_45793681098  | 我要投稿

介绍

赫兹量化梯度提升是一种强大的机器学习算法。该方法产生了一个弱模型的集合(例如,决策树),其中(与bagging相反)模型是按顺序构建的,而不是独立地(并行地)构建的。这意味着下一棵树从上一棵树的错误中学习,然后重复这个过程,增加了弱模型的数量。这就建立了一个强大的模型,可以使用异构数据进行泛化。在这个实验中,我使用了Yandex开发的CatBoost库,它与 XGBoost和 LightGBM 一起是最流行的库之一。

本文的目的是演示如何创建一个基于机器学习的模型。创建过程包括以下步骤:

编辑切换为居中

  • 接收和预处理数据

  • 使用准备好的数据训练模型

  • 在自定义策略测试器中测试模型

  • 将模型移植到赫兹量化

Python 语言和 赫兹量化 库用于准备数据和训练模型。


准备数据

导入所需的 Python 模块:

import MetaTrader5 as mt5 import pandas as pd import numpy as np from datetime import datetime import random import matplotlib.pyplot as plt from catboost import CatBoostClassifier from sklearn.model_selection import train_test_split mt5.initialize() # check for gpu devices is availible from catboost.utils import get_gpu_device_count print('%i GPU devices' % get_gpu_device_count())


然后初始化所有全局变量:

LOOK_BACK = 250 MA_PERIOD = 15 SYMBOL = 'EURUSD' MARKUP = 0.0001 TIMEFRAME = mt5.TIMEFRAME_H1 START = datetime(2020, 5, 1) STOP = datetime(2021, 1, 1)



这些参数的作用如下:


  • look_back — 分析历史的深度

  • ma_period  — 用于计算价格增量的移动平均周期数

  • symbol — 应当在 赫兹量化终端中载入的交易品种报价

  • markup  — 用于自定义测试器的点差大小

  • timeframe  — 应当载入数据的时间框架

  • start, stop  — 数据范围

赫兹量化编写一个函数,直接接收原始数据并创建一个包含训练所需列的数据帧:

def get_prices(look_back = 15):    prices = pd.DataFrame(mt5.copy_rates_range(SYMBOL, TIMEFRAME, START, STOP),                            columns=['time', 'close']).set_index('time')    # set df index as datetime    prices.index = pd.to_datetime(prices.index, unit='s')    prices = prices.dropna()    ratesM = prices.rolling(MA_PERIOD).mean()    ratesD = prices - ratesM    for i in range(look_back):        prices[str(i)] = ratesD.shift(i)    return prices.dropna()


函数接收指定时间段的收盘价并计算移动平均值,然后计算增量(价格和移动平均值之间的差)。在最后一步中,它通过 look_back 来计算额外的列,其中的行向后移动到历史中,这意味着向模型中添加额外的(滞后的)特性。

例如,对于 look_back=10,数据帧中将包含10个额外的列,其价格增量为:

>>> pr = get_prices(look_back=LOOK_BACK) >>> pr                       close         0         1         2         3         4         5         6         7         8         9 time 2020-05-01 16:00:00  1.09750  0.001405  0.002169  0.001600  0.002595  0.002794  0.002442  0.001477  0.001190  0.000566  0.000285 2020-05-01 17:00:00  1.10074  0.004227  0.001405  0.002169  0.001600  0.002595  0.002794  0.002442  0.001477  0.001190  0.000566 2020-05-01 18:00:00  1.09976  0.002900  0.004227  0.001405  0.002169  0.001600  0.002595  0.002794  0.002442  0.001477  0.001190 2020-05-01 19:00:00  1.09874  0.001577  0.002900  0.004227  0.001405  0.002169  0.001600  0.002595  0.002794  0.002442  0.001477 2020-05-01 20:00:00  1.09817  0.000759  0.001577  0.002900  0.004227  0.001405  0.002169  0.001600  0.002595  0.002794  0.002442 ...                      ...       ...       ...       ...       ...       ...       ...       ...       ...       ...       ... 2020-11-02 23:00:00  1.16404  0.000400  0.000105 -0.000581 -0.001212 -0.000999 -0.000547 -0.000344 -0.000773 -0.000326  0.000501 2020-11-03 00:00:00  1.16392  0.000217  0.000400  0.000105 -0.000581 -0.001212 -0.000999 -0.000547 -0.000344 -0.000773 -0.000326 2020-11-03 01:00:00  1.16402  0.000270  0.000217  0.000400  0.000105 -0.000581 -0.001212 -0.000999 -0.000547 -0.000344 -0.000773 2020-11-03 02:00:00  1.16423  0.000465  0.000270  0.000217  0.000400  0.000105 -0.000581 -0.001212 -0.000999 -0.000547 -0.000344 2020-11-03 03:00:00  1.16464  0.000885  0.000465  0.000270  0.000217  0.000400  0.000105 -0.000581 -0.001212 -0.000999 -0.000547 [3155 rows x 11 columns]

黄色高亮显示表示每列都有相同的数据集,但有一个偏移量。因此,每一行都是一个单独的训练实例。

创建训练标签(随机抽样)

训练实例是特征及其相应标签的集合。模型必须输出一定的信息,模型必须学会预测这些信息。赫兹量化考虑二元分类,其中模型将预测将训练示例确定为类0或1的概率。0和1可用于交易方向:买入或卖出。换句话说,模型必须学会预测给定环境参数(一组特征)的交易方向。

def add_labels(dataset, min, max):    labels = []    for i in range(dataset.shape[0]-max):        rand = random.randint(min, max)        if dataset['close'][i] >= (dataset['close'][i + rand]):            labels.append(1.0)        elif dataset['close'][i] <= (dataset['close'][i + rand]):            labels.append(0.0)                      else:            labels.append(0.0)    dataset = dataset.iloc[:len(labels)].copy()    dataset['labels'] = labels    dataset = dataset.dropna()    return dataset

add_labels 函数随机(在最小、最大范围内)设置每笔交易的持续时间(以柱形为单位)。通过更改最大和最小持续时间,您可以更改交易采样频率。因此,如果当前价格大于下一个“rand”柱向前的价格,这就是卖出标签(1)。在相反的情况下,标签是0。让我们看看应用上述函数后数据集的外观:

>>> pr = add_labels(pr, 10, 25) >>> pr                       close         0         1         2         3         4         5         6         7         8         9  labels time 2020-05-01 16:00:00  1.09750  0.001405  0.002169  0.001600  0.002595  0.002794  0.002442  0.001477  0.001190  0.000566  0.000285     1.0 2020-05-01 17:00:00  1.10074  0.004227  0.001405  0.002169  0.001600  0.002595  0.002794  0.002442  0.001477  0.001190  0.000566     1.0 2020-05-01 18:00:00  1.09976  0.002900  0.004227  0.001405  0.002169  0.001600  0.002595  0.002794  0.002442  0.001477  0.001190     1.0 2020-05-01 19:00:00  1.09874  0.001577  0.002900  0.004227  0.001405  0.002169  0.001600  0.002595  0.002794  0.002442  0.001477     1.0 2020-05-01 20:00:00  1.09817  0.000759  0.001577  0.002900  0.004227  0.001405  0.002169  0.001600  0.002595  0.002794  0.002442     1.0 ...                      ...       ...       ...       ...       ...       ...       ...       ...       ...       ...       ...     ... 2020-10-29 20:00:00  1.16700 -0.003651 -0.005429 -0.005767 -0.006750 -0.004699 -0.004328 -0.003475 -0.003769 -0.002719 -0.002075     1.0 2020-10-29 21:00:00  1.16743 -0.002699 -0.003651 -0.005429 -0.005767 -0.006750 -0.004699 -0.004328 -0.003475 -0.003769 -0.002719     0.0 2020-10-29 22:00:00  1.16731 -0.002276 -0.002699 -0.003651 -0.005429 -0.005767 -0.006750 -0.004699 -0.004328 -0.003475 -0.003769     0.0 2020-10-29 23:00:00  1.16740 -0.001648 -0.002276 -0.002699 -0.003651 -0.005429 -0.005767 -0.006750 -0.004699 -0.004328 -0.003475     0.0 2020-10-30 00:00:00  1.16695 -0.001655 -0.001648 -0.002276 -0.002699 -0.003651 -0.005429 -0.005767 -0.006750 -0.004699 -0.004328     1.0

添加了“labels”列,其中分别包含买入和卖出的类别号(0或1)。现在,每个训练示例或功能集(这里是10个)都有自己的标签,它指示在什么条件下应该买入,在什么条件下应该卖出(即它属于哪个类)。模型必须能够记住和泛化这些例子-这个能力将在后面讨论。

开发自定义测试器

因为赫兹量化正在创建一个交易系统,所以最好有一个策略测试器来进行及时的模型测试。下面是此类测试器的示例:

def tester(dataset, markup = 0.0):    last_deal = int(2)    last_price = 0.0    report = [0.0]    for i in range(dataset.shape[0]):        pred = dataset['labels'][i]        if last_deal == 2:            last_price = dataset['close'][i]            last_deal = 0 if pred <=0.5 else 1            continue        if last_deal == 0 and pred > 0.5:            last_deal = 1            report.append(report[-1] - markup + (dataset['close'][i] - last_price))            last_price = dataset['close'][i]            continue        if last_deal == 1 and pred <=0.5:            last_deal = 0            report.append(report[-1] - markup + (last_price - dataset['close'][i]))            last_price = dataset['close'][i]          return report



tester 函数接受一个数据集和一个“标记”(可选)并检查整个数据集,类似于在 赫兹量化测试器中的操作。在每一个新柱都会检查一个信号(标签),当标签改变时,交易就会反转。因此,卖出信号作为结束买入头寸和打开卖出头寸的信号。现在,让我们测试上述数据集:

pr = get_prices(look_back=LOOK_BACK) pr = add_labels(pr, 10, 25) rep = tester(pr, MARKUP) plt.plot(rep) plt.show()


编辑切换为居中


不计入点差测试原始数据集


编辑切换为居中


以70个五位小数点差测试原始数据集

这是一种理想化的图像(这就是我们希望模型工作的方式)。由于标签是随机抽样的,这取决于一系列参数,这些参数决定了交易的最短和最长寿命,因此曲线总是不同的。尽管如此,它们都会表现出一个很好的点增长(沿Y轴)和不同的交易数量(沿X轴)。


量化交易软件:梯度提升CatBoost在交易系统开发中的应用的评论 (共 条)

分享到微博请遵守国家法律