English Русский Español Deutsch 日本語 Português
preview
在市场中获得优势

在市场中获得优势

MetaTrader 5示例 | 16 十月 2024, 09:57
485 0
Gamuchirai Zororo Ndawana
Gamuchirai Zororo Ndawana

内容

  1. 简介
  2. 概述
  3. 策略概述:另类数据源
  4. 机器学习技术
  5. 创建策略
  6. 结论
  7. 推荐配置


简介

今天,我们将制定一个稳健的交易策略,旨在为交易者在各类市场中提供显著的竞争优势。虽然传统的市场投资者仅依赖价格相关数据、技术指标和公共新闻公告来进行决策,但我们的策略则采取了一种开创性的方法,即利用大多数市场投资者尚未充分接触的另类数据源。

我们策略的前提在于整合另类数据,这是主流市场投资者往往忽视的一个选项。通过利用这些尚未开发的数据源,并应用机器学习技术,我们可以为自己定位,从而获得我们策略独有的独特见解和视角。

在我们的探索过程中,我们将研究美国联邦储备银行提供的数据,特别是利用其全面的经济计量时间序列数据库——FRED。FRED始终对公众开放,它无疑提供了对交易决策至关重要的数据。此外,来自美联储等中央银行的数据通常作为领先指标,提高了我们有效把握入场和出场时机的能力。

此外,这些数据免受外部操纵,使其成为整合到我们交易策略中的理想选择。

本文旨在作为一份实用性指南,展示如何使用Python和MetaTrader 5轻松构建前沿的交易策略。我们致力于清晰和简洁的说明,确保每个方面都解释得清楚明了,使读者能够轻松理解我们的方法,并立即开始实践!


介绍:本文旨在呈现如何轻松地在交易策略中应用另类数据。 

阅读完本文后,读者将对于以下关键领域有更深入地了解:

  1. 在遇到噪音和不确定性时,另类数据如何辅助决策。
  2. 筛选和识别可靠的另类数据源的技术。
  3. 分析和预处理另类数据以供分析的最佳案例。
  4. 构建稳健的交易策略,整合另类数据源以增强决策过程。

其中一个说明另类数据影响力的例子是卫星图像的战略使用。高级交易者利用卫星图像来监测航运交通模式或观察油轮的库存水平。这些独特的数据点使交易者能够发现原本可能隐藏的盈利交易机会。

尽管卫星图像的使用可能在富裕的交易者中更为普遍,但本文呈现了交易者如何利用可免费获得的另类数据来保持市场领先地位。此外,通过使用机器学习模型,我们可以同时分析多个数据源,从而进一步提高它们的决策能力。


交易策略概述:另类数据来源

我们交易策略的设计易于理解。我们将把来自MetaTrader 5终端的传统市场数据与来自美联储的另类数据相结合,特别关注预测GBPUSD货币在未来的价格走势。

为了实现这一目标,我们将利用两个关键的经济数据集作为我们的另类数据源。第一个数据集提供了关于英镑的信息,展示了英镑市场非营业时间银行交易所收取的利率的时间序列。这些利率波动可以作为衡量机构对英镑需求水平的指标,为我们的预测模型提供有价值的参考。

同样地,第二个数据集包含了有关美元的信息,并包含由美联储监管的美国银行隔夜贷款利率的时间序列。美联储通过货币政策调整对这些利率的控制,为可能影响美元的经济趋势提供了另一种见解。

通过分析和解释这些经济时间序列数据,并运用机器学习技术,我们有望发现领先指标,从而在市场上获得竞争优势。

我们战略有效性的基础在于确保有可靠的另类数据源。可靠的另类数据源的可用性取决于您交易的市场。由随机数生成器产生的虚拟市场几乎没有可用的另类数据源。这是因为虚拟市场独立于外部世界。

  1. 可信度:您的另类数据源最初是如何获取数据的?审核它们所依赖的信息渠道的可靠性。在评估可信度时,“它们如何获取信息?”和“它们的信息渠道是否可信?”等问题至关重要。对这些方面有任何疑问都表明需要进行更彻底的评估。
  2. 更新频率:我们的重点在于那些每日更新的另类数据源,这与我们的交易时间框架相吻合。然而,需要注意的是,并非所有数据源都提供每日更新;有些可能每月或每年更新一次。因此,务必选择一个与您的期望交易频率相符的数据源。
  3. 声誉:除了可信度之外,还要优先考虑那些有着良好记录和证明有维持准确性意愿的数据源。一个声誉良好的提供者不仅为我们的数据增加了可信度,还体现了责任感。
  4. 透明展示:选择那些以透明和用户友好的方式展示数据的提供者。数据展示的清晰度和简洁性对于有效决策至关重要,尤其是考虑到复杂数据带来的认知难度。
  5. 定价结构:评估另类数据源的定价模型,平衡我们的需求和预算限制。虽然一些数据源可能是免费的,但另一些可能需要付费。我们的选择应该与每个数据源提供的价值导向相一致。
  6. 条款和条件:仔细审查和了解与另类数据源相关的条款和条件,特别是那些需要付费的数据源。清晰理解使用限制和约束条件以确保做出明智的决策,并避免出现意外的合规问题。

综上所述,基于可信度、更新频率、声誉、透明度、定价以及条款和条件对另类数据源进行严格评估,对于在我们的交易策略中有效利用数据至关重要。

我们现在将开始研究一些来自美联储的另类数据。从美联储获取数据有两种方式:

  1. 使用FRED Python库编程获取数据
  2. 手动登录FRED网站 

如果您是首次使用这些数据集,建议您先手动收集数据。这样做很明智,因为FRED网站为每个数据集提供了实用的说明和信息,包括数据的记录方式、数据代表的含义、是否经过季节性调整、测量单位和比例尺以及其他相关细节一旦熟悉了数据的性质,就可以开始通过编程方式收集数据了。因此,在我们的首次演示中,数据集St Louis Federal Reserve Website是从美联储网站上手动下载的。当我们构建策略时,将采用编程方法来收集数据。 

首先,我们将使用MQL5脚本从MetaTrader 5中收集市场数据。我之所以喜欢用这种方式收集数据,是因为可以在MQL5端对数据进行所需的预处理,并且可以无限制地访问数据。我们的脚本相当简单。

  • 首先,我们为技术指标声明处理程序,这里我们将使用4个移动平均线。
  • 然后,我们声明缓冲区来存储移动平均线的读数,在我们的案例中,缓冲区是动态数组。
  • 接下来,我们需要为文件命名,我们的文件名是交易货币对的名称,后面跟上字符串“Market Data As Series”,并且文件是CSV格式。
  • 接下来,我们将声明要收集多少数据。 
  • 请注意,该脚本将与它应用的图表的当前时间框架一起工作。
  • 现在,我们已经讲到了OnStart()事件处理程序,这是脚本的核心所在。
  • 首先,我们初始化所有四个技术指标。
  • 然后,我们将指标值复制到之前创建的数组中。
  • 完成以上这些流程后,我们将新建一个文件处理程序来新建、写入和关闭文件。
  • 使用简单的for循环遍历数组并将数据写入CSV文件是一种常见的做法。请注意,在循环的第一次迭代中,我们写入列标题,之后再写入我们想要的实际值。
  • 一旦循环完成,我们使用文件处理程序关闭文件,再准备好来自MetaTrader 5终端的数据与我们的替代数据进行合并。

#property copyright "Gamuchirai Zororo Ndawana"
#property link      "https://www.mql5.com"
#property version   "1.00"

//---Our handlers for our indicators
int ma_handle_5;
int ma_handle_15;
int ma_handle_30;
int ma_handle_150;

//---Data structures to store the readings from our indicators
double ma_reading_5[];
double ma_reading_15[];
double ma_reading_30[];
double ma_reading_150[];

//---File name
string file_name = _Symbol + " " + " Market Data As Series.csv";

//---Amount of data requested
int size = 1000000;
int size_fetch = size + 100;

void OnStart()
  {
      //---Setup our technical indicators
      ma_handle_5 = iMA(_Symbol,PERIOD_CURRENT,5,0,MODE_EMA,PRICE_CLOSE);
      ma_handle_15 = iMA(_Symbol,PERIOD_CURRENT,15,0,MODE_EMA,PRICE_CLOSE);
      ma_handle_30 = iMA(_Symbol,PERIOD_CURRENT,30,0,MODE_EMA,PRICE_CLOSE);
      ma_handle_150 = iMA(_Symbol,PERIOD_CURRENT,150,0,MODE_EMA,PRICE_CLOSE);
      
      //---Copy indicator values
      CopyBuffer(ma_handle_5,0,0,size_fetch,ma_reading_5);
      ArraySetAsSeries(ma_reading_5,true);
      CopyBuffer(ma_handle_15,0,0,size_fetch,ma_reading_15);
      ArraySetAsSeries(ma_reading_15,true);
      CopyBuffer(ma_handle_30,0,0,size_fetch,ma_reading_30);
      ArraySetAsSeries(ma_reading_30,true);
      CopyBuffer(ma_handle_150,0,0,size_fetch,ma_reading_150);
      ArraySetAsSeries(ma_reading_150,true);

      //---Write to file
       int file_handle=FileOpen(file_name,FILE_WRITE|FILE_ANSI|FILE_CSV,",");
       
    for(int i=-1;i<=size;i++){
      if(i == -1){
            FileWrite(file_handle,"Time","Open","High","Low","Close","MA 5","MA 15","MA 30","MA 150");
      }
      
      else{
            FileWrite(file_handle,iTime(_Symbol,PERIOD_CURRENT,i),
                                 iOpen(_Symbol,PERIOD_CURRENT,i),
                                 iHigh(_Symbol,PERIOD_CURRENT,i),
                                 iLow(_Symbol,PERIOD_CURRENT,i),
                                 iClose(_Symbol,PERIOD_CURRENT,i),
                                 ma_reading_5[i],
                                 ma_reading_15[i],
                                 ma_reading_30[i],
                                 ma_reading_150[i]
                                 );
      } 
    }
  }
//+------------------------------------------------------------------+

我们现在已经准备好开始探索我们的另类数据以及市场数据。

跟之前一样,我们将首先导入必要的数据包。

import pandas as pd
import numpy as np 
import matplotlib.pyplot as plt
import seaborn as sns

现在我们开始读取从MQL5脚本中导出的数据。

GBPUSD = pd.read_csv("C:\\Enter\\Your\\Path\\Here\\MetaQuotes\\Terminal\\NVUSDVJSNDU3483408FVKDL\\MQL5\\Files\\GBPUSD Market Data As Series.csv")

在准备用于机器学习的市场数据时,请确保今天的价格在最后面,而最先前的价格在最前面。 

GBPUSD = GBPUSD[::-1]

然后我们需要重置索引。

GBPUSD.reset_index(inplace=True)

让我们定义一下我们想要预测多远的将来。

look_ahead = 30
splits = 30

我们现在要准备向目标冲刺。 

GBPUSD["Target"] = GBPUSD["Close"].shift(-look_ahead)
GBPUSD.dropna(inplace=True)

现在我们要将日期设置为索引,这将有助于我们以后轻松地将市场数据与另类数据对齐。

GBPUSD["Time"] = pd.to_datetime(GBPUSD["Time"])
GBPUSD.set_index("Time",inplace=True)

我们要考虑的第一个另类数据集是每日英镑隔夜指数平均利率(SOIA)。它是银行在正常营业时间之外借入英镑所收取的平均利率。

如果英镑的平均利率上升,而美元的平均利率下降,这可能潜在地表明在机构层面上,英镑相对于美元正在走强。 

SOIA = pd.read_csv("C:\\Enter\\Your\\Path\\Here\\Downloads\\FED Data\\Daily Sterling Overnight Index Average\\IUDSOIA.csv")

让我们清理另类数据。首先,将日期列设置为日期对象。

SOIA["DATE"] = pd.to_datetime(SOIA["DATE"])

我们的数据集中包含点(.),这很可能是用来表示缺失的观测值。我们将把所有的点替换为零,然后用该列的平均值替换这些零。 

SOIA["IUDSOIA"] = SOIA["IUDSOIA"].replace(".","0")
SOIA["IUDSOIA"] = pd.to_numeric(SOIA["IUDSOIA"])
non_zero_mean = SOIA.loc[SOIA['IUDSOIA'] != 0, 'IUDSOIA'].mean()
SOIA['IUDSOIA'] = SOIA['IUDSOIA'].replace(0, non_zero_mean)

然后,我们将日期设置为索引。

SOIA.set_index("DATE",inplace=True)

接下来我们要考虑的另类数据来源将是有担保的隔夜融资利率(SOFR)。它是有担保隔夜贷款的成本,由纽约联邦储备银行每日公布。 

SOFR = pd.read_csv("C:\\Enter\\Your\\Path\\Here\\Downloads\\FED Data\\Secured Overnight Financing Rate\\SOFR.csv")

请注意,应用于SOFR数据集的预处理步骤与应用于SOIA数据集的步骤是相同的,因此,为了保持文章从头到尾易于阅读,我们将省略这些步骤。 

现在让我们合并现有的三个数据框。通过将left_index和right_index设置为true,我们确保两个数据集仅在有完整观测值的天数上对齐。例如,GBPUSD数据集在周末没有记录,因此我们在最终合并的数据框中不包括周末观测到的所有另类数据点。 

merged_df = SOIA.merge(SOFR,left_index=True,right_index=True)
merged_df = merged_df.merge(GBPUSD,left_index=True,right_index=True)

然后,我们需要重置索引。

merged_df.reset_index(inplace=True)
merged_df.drop(columns=["index"],inplace=True)

让我们定义一下我们的预测变量。

normal_predictors = ['Open', 'High', 'Low', 'Close', 'MA 5', 'MA 15','MA 30', 'MA 150']
alternative_predictors = ['IUDSOIA', 'SOFR']
all_predictors = normal_predictors + alternative_predictors

然后,我们将创建一个数据框来存储每种预测变量组合的误差水平。

accuracy = pd.DataFrame(columns=["Normal","Alternative","All"],index=np.arange(0,splits))

这就是现在我们数据框的样子。

merged_df

我们合并的数据框

Fig 1: 这是我们的数据集,它包含正常数据和替代数据。


第一列是英镑的平均利率,第二列是美元的平均利率。从那里开始,后面的列应该已经熟悉。记住,我们的目标是预测30天后的收盘价。

最后,我们将导出合并后的数据框到一个csv文件中,以便后续使用。

merged_df.to_csv('Alternative Data Target Look Ahead 30.csv')

让我们对数据进行缩放处理。

from sklearn.preprocessing import StandardScaler
scaled_data = merged_df.loc[:,all_predictors]
scaler = StandardScaler()
scaler.fit(scaled_data)
scaled_data = pd.DataFrame(scaler.transform(scaled_data),index=merged_df.index,columns=all_predictors)

现在,让我们准备训练我们的模型,看看另类数据究竟是在帮助我们,还是在阻碍我们。

from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error 
from sklearn.model_selection import TimeSeriesSplit

让我们准备划分训练集和测试集。

tscv = TimeSeriesSplit(gap=look_ahead+10,n_splits=splits)

for i,(train,test) in enumerate(tscv.split(merged_df)):
    model = LinearRegression()
    model.fit(scaled_data.loc[train[0]:train[-1],all_predictors],merged_df.loc[train[0]:train[-1],"Target"])
    accuracy["All"][i] = mean_squared_error(merged_df.loc[test[0]:test[-1],"Target"],model.predict(scaled_data.loc[test[0]:test[-1],all_predictors]))


现在我们正在以箱线图的形式绘制结果。

fig,axs = plt.subplots(1,3,sharex=True,sharey=True,figsize=(16,4))

for i,ax in enumerate(axs.flat):
    ax.boxplot(merged_df.iloc[:,i])
    ax.set_title(accuracy.columns[i])

预测变量组合

Fig 2: 分析使用正常数据(左)、另类数据(中)和所有可用数据(右)时得到的误差值

让我们来解释一下结果:我们可以清楚地看到,正常预测变量集和另类预测变量集都有向图表顶部延伸的长尾。然而,最后一个图表(即同时包含正常和另类预测变量的图表)的形状被压扁了。这种被压扁的形状是我们希望看到的,因为它表明当我们同时使用这两组预测变量时,我们的误差变化会更小。在最后一个图表中,我们的准确性是稳定的,但在前两个图表中(即我们完全依赖正常数据或另类数据时),我们的准确性并不稳定。 

我们还可以检查数据中是否存在任何交互作用。我们将创建一个散点图,将目标值放在y轴上,将英镑利率放在x轴上。

sns.scatterplot(x=merged_df["IUDSOIA"],y=merged_df["Target"])

英镑交互作用影响

Fig 3: 分析英镑利率与GBPUSD货币对之间的未来价值关系。

这是对该图表的解释:从图表顶部到底部的每条线都表示在英镑利率固定时目标值如何变化。尽管我们的英镑利率是固定的,但我们仍然可以观察到不同的目标值,这无疑是数据中存在交互作用影响的明确迹象。尽管我们的英镑利率是固定的,但我们仍然可以观察到不同的目标值,这无疑是数据中存在交互作用影响的明确迹象。


机器学习技术 

选择合适的机器学习技术取决于您所拥有数据的性质。考虑以下事项:

  • 数据集大小:对于少于一万行或少于30列的小型数据集,建议使用更简单的模型来降低过度拟合的风险。像深度神经网络这样的复杂模型可能很难在如此有限的数据上有效运作。
  • 数据噪声:噪声数据集(通常指包含缺失数据点或随机无法解释波动的数据集)更适合使用简单的模型。复杂模型往往具有较高的方差,这使得它们更容易在噪声数据上过度拟合,而且在特别嘈杂的市场交易日,我们甚至不使用这些模型可能会更好。
  • 数据维度:如果数据集有很多列,那么预处理技术可能会很有用。使用能有效处理高维数据的模型,并应用特征选择和降维技术。
  • 数据大小和计算能力:如果您拥有噪声水平可接受的大型数据集,并且还有足够的计算资源,那么这可能需要使用像深度神经网络这样的复杂模型。在具有足够的计算能力和清除数据的情况下,这些模型可以有效地捕捉数据中的复杂模式和关系。

总之,机器学习模型选择没有完美的解决方案。数据的性质,包括大小、噪声、维度和可用的计算能力,在确定最适合的方法这方面起到了关键作用。 使模型的选择与数据的特征相匹配,对于实现稳健和准确的预测结果至关重要。
现在,我们将演示如何为您的数据选择一个好的模型。


我们将从导入所需的库开始。

import statistics as st

import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt

from sklearn.linear_model import Lasso,Ridge,LinearRegression
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import TimeSeriesSplit
from sklearn.metrics import mean_squared_error
from sklearn.svm import SVR
from sklearn.preprocessing import StandardScaler

from xgboost import XGBRegressor

现在,我们将从导出的CSV文件中读取数据。该CSV文件包含了我们所有的合并数据。

csv = pd.read_csv("C:\\Enter\\Your\\Path\\Here\\Alternative Data.csv")

我们准备对数据进行缩放。

predictors = ['IUDSOIA', 'SOFR', 'Open', 'High', 'Low', 'Close']
target = 'Target'
scaled_data = csv.loc[:,predictors]
scaler = StandardScaler()
scaler.fit(scaled_data)
scaled_data = scaler.transform(scaled_data)

让我们来训练我们的模型。

splits = 10
gap = 30
models = ['Linear','Lasso','Ridge','Random Forest','Linear SVR','Sigmoid SVR','RBF SVR','2 Poly SVR','3 Poly SVR','XGB']

我们准备训练/测试集的划分,然后创建一个数据框来存储误差指标。

tscv = TimeSeriesSplit(n_splits=splits,gap=gap)
error_df = pd.DataFrame(index=np.arange(0,splits),columns=models)

现在我们可以观察我们模型的误差指标了。

for i,(train,test) in enumerate(tscv.split(csv)):
    model=XGBRegressor()
    model.fit(scaled_data.loc[train[0]:train[-1],predictors],csv.loc[train[0]:train[-1],target])
    error_df.iloc[i,9] =mean_squared_error(csv.loc[test[0]:test[-1],target],model.predict(scaled_data.loc[test[0]:test[-1],predictors]))

error_df

每种模型的误差

Fig 4: 我们从每个拟合的模型中得到的误差值。


我们将一些数据可视化为箱线图。

fig , axs = plt.subplots(2,5,figsize=(20,20),sharex=True)

for i,ax in enumerate(axs.flat):
    ax.boxplot(error_df.iloc[:,i])
    ax.set_title(error_df.columns[i])


线性模型

Fig 5: 我们使用的部分线性模型的误差。


非线性模型

Fig 6: 我们使用的部分非线性模型的误差。


我们将展示一些获得的摘要统计信息。

方差      误差 
线性方差: 1.3365981802501968e-06 线性均方误差: 0.0022242681292296462
拉索方差: 3.0466413126186177e-05 拉索均方误差: 0.004995731270431843
山脊方差: 2.5678314939547713e-06 山脊均方误差: 0.002467126140156681
随机森林方差: 2.607918492340197e-06 随机森林均方误差: 0.002632579355696408
线性SVR方差: 3.825627012092798e-05 线性SVR均方误差: 0.004484702122899226
Sigmoid SVR方差: 27.654341711864102 Sigmoid SVR均方误差: 1.6693947903605928
RBF SVR方差: 4.1654658535332505e-05 RBF SVR均方误差: 0.004992333849448852
2 Poly SVR方差: 6.739873404310582e-05 2 Poly SVR均方误差: 0.008163708245600027
3 Poly SVR方差: 6.739873404310582e-05 3 Poly SVR均方误差: 0.008163708245600027
XGB方差: 7.053078880392137e-06 XGB均方误差: 0.003163819414983548


我们注意到所有模型的性能都没有特别出色,它们的性能几乎都处于同一水平。在这种情况下,简单的模型可能是最佳选择,因为它过度拟合的可能性较小。因此,在这个例子中,我们将选择线性回归作为我们交易策略的首选模型。我们选择它是因为它的误差水平与其他我们可以选择的模型一样好,而且它的方差很低。所以,线性模型过度拟合的可能性较小,并且随着时间的推移更可能保持稳定。 


创建策略 

我们现在准备将之前各节中讨论的所有内容应用到一个使用MetaTrader 5 Python库的稳健交易策略中。 

在每一步中,我们都会给出解释,以确保所有代码都易于理解。

首先,我们导入所需的包。

from fredapi import Fred
import MetaTrader5 as mt5
import pandas as pd
import numpy as np
import time
from datetime import datetime
import matplotlib.pyplot as plt

fredapi包允许我们通过编程方式地从FRED(联邦储备经济数据库)中拉取数据。但是,在使用该库之前,必须创建一个API密钥。API密钥的创建是免费的,但是您只能在美联储创建一个免费帐户。

现在,我们将定义全局变量。

LOGIN = ENTER_YOUR_LOGIN
PASSWORD = 'ENTER_YOUR_PASSWORD'
SERVER = 'ENTER_YOUR_SERVER'
SYMBOL = 'GBPUSD'
TIMEFRAME = mt5.TIMEFRAME_D1
DEVIATION = 1000
VOLUME = 0
LOT_MULTIPLE = 1
FRED = Fred(api_key='ENTER_YOUR_API_KEY')

现在我们将登录到我们的交易账户。

if mt5.initialize(login=LOGIN,password=PASSWORD,server=SERVER):
    print('Logged in successfully')
else:
    print('Failed To Log in')

登录成功

定义我们的交易量。

for index,symbol in enumerate(mt5.symbols_get()):
    if symbol.name == SYMBOL:
        print(f"{symbol.name} has minimum volume: {symbol.volume_min}")
        VOLUME = symbol.volume_min * LOT_MULTIPLE

GBPUSD有最小交易量限制: 0.01


让我们定义在整个程序中会使用到的函数。

首先,我们需要一个函数来从MetaTrader 5终端获取当前的市场价格。

def get_prices():
    start = datetime(2024,3,20)
    end   = datetime.now()
    data  = pd.DataFrame(mt5.copy_rates_range(SYMBOL,TIMEFRAME,start,end))
    data['time'] = pd.to_datetime(data['time'],unit='s')
    data.set_index('time',inplace=True)
    return(data.iloc[-1,:])

接下来,我们需要一个函数来从美联储请求另类数据。

def get_alternative_data():
    SOFR = FRED.get_series_as_of_date('SOFR',datetime.now())
    SOFR = SOFR.iloc[-1,-1]
    SOIA = FRED.get_series_as_of_date('IUDSOIA',datetime.now())
    SOIA = SOIA.iloc[-1,-1]
    return(SOFR,SOIA)

然后,我们需要一个函数来为模型输入做准备。

def get_model_inputs():
    LAST_OHLC = get_prices()
    SOFR , SOIA = get_alternative_data()
    MODEL_INPUT_DF = pd.DataFrame(index=np.arange(0,1),columns=predictors)
    MODEL_INPUT_DF['Open'] = LAST_OHLC['open']
    MODEL_INPUT_DF['High'] = LAST_OHLC['high']
    MODEL_INPUT_DF['Low'] =  LAST_OHLC['low']
    MODEL_INPUT_DF['Close'] = LAST_OHLC['close']
    MODEL_INPUT_DF['IUDSOIA'] = SOIA
    MODEL_INPUT_DF['SOFR'] = SOFR
    model_input_array = np.array([[MODEL_INPUT_DF.iloc[0,0],MODEL_INPUT_DF.iloc[0,1],MODEL_INPUT_DF.iloc[0,2],MODEL_INPUT_DF.iloc[0,3],MODEL_INPUT_DF.iloc[0,4],MODEL_INPUT_DF.iloc[0,5]]])
    return(model_input_array,MODEL_INPUT_DF.loc[0,'Close'])


然后,我们需要一个函数来帮助我们使用模型进行预测。

def ai_forecast():
    model_inputs,current_price = get_model_inputs()
    prediction = model.predict(model_inputs)
    return(prediction[0],current_price)

让我们来训练我们的模型。

training_data = pd.read_csv('C:\\Enter\\Your\\Path\\Here\\Alternative Data.csv')

设置我们的模型。

from sklearn.linear_model import LinearRegression
model = LinearRegression()

定义我们的预测变量和目标变量。

predictors = ['Open','High','Low','Close','IUDSOIA','SOFR']
target     = 'Target'

拟合我们的模型。

model.fit(training_data.loc[:,predictors],training_data.loc[:,target])

现在进入了交易算法的核心,

  • 首先,我们定义了一个无限循环来保持我们的策略持续运行。
  • 接下来,我们获取当前市场数据,并使用这些数据来进行预测。
  • 之后,我们将使用布尔标识来表示模型的预期。如果模型预期价格上涨,那么BUY_STATE为True;如果模型预期价格下跌,那么SELL_STATE为False。
  • 如果我们没有持仓,我们将遵循模型的预测。
  • 如果我们已有持仓,那么我们将检查模型的预测是否与我们的持仓方向相反。如果相反,我们将平仓。否则,我们可以保持持仓不变。
  • 最后,在完成上述所有步骤后,我们将让算法暂停一天,并在第二天获取更新后的数据。

while True:
    #Get data on the current state of our terminal and our portfolio
    positions = mt5.positions_total()
    forecast , current_price = ai_forecast()
    BUY_STATE , SELL_STATE = False , False

    #Interpret the model's forecast
    if(current_price > forecast):
        SELL_STATE = True
        BUY_STATE  = False 

    elif(current_price > forecast):
        SELL_STATE = False
        BUY_STATE  = True

    print(f"Current price is {current_price} , our forecast is {forecast}")

    #If we have no open positions let's open them
    if(positions == 0):
        print(f"We have {positions} open trade(s)")
        if(SELL_STATE):
            print("Opening a sell position")
            mt5.Sell(SYMBOL,VOLUME)
        elif(BUY_STATE):
            print("Opening a buy position")
            mt5.Buy(SYMBOL,VOLUME)

    #If we have open positions let's manage them
    if(positions > 0):
        print(f"We have {positions} open trade(s)")
        for pos in mt5.positions_get():
            if(pos.type == 1):
                if(BUY_STATE):
                    print("Closing all sell positions")
                    mt5.Close(SYMBOL)
            if(pos.type == 0):
                if(SELL_STATE):
                    print("Closing all buy positions")
                    mt5.Close(SYMBOL)
    #If we have finished all checks then we can wait for one day before checking our positions again
    time.sleep(24 * 60 * 60)


最终结果

Fig 7: 我们在第一天开仓交易。



Day 2

Fig 8: 第二天的交易情况如下。


结论 

另类数据蕴含着巨大的潜力,能够改变我们看待金融市场的方式。通过精心挑选合适的数据来源,我们可能会发现自己在大多数交易中都能做出正确的选择。这一策略最重要的部分是拥有一个可靠的另类数据来源,否则你可能只是在使用普通数据。花时间做自己的研究,得出自己的结论,并跟随自己的判断。记住,归根结底,构建策略既是一门科学,也是一门艺术。因此,在判断哪些另类数据来源会有用时,要明智地运用你的推理能力,此外,发挥你的想象力去发现大多数人不会想到的新应用和使用场景,这样你就能遥遥领先。 


推荐配置

未来,对读者来说,探索更多另类数据集的来源,并运用机器学习技术(如最佳子集选择)来挑选有用的另类数据源,可能会带来显著的收益。此外,请记住,我们在演示中使用的线性模型对数据生成过程做出了大胆的假设,但是如果这些假设被推翻,那么模型的准确性将随着时间的推移而变差。 

本文由MetaQuotes Ltd译自英文
原文地址: https://www.mql5.com/en/articles/14441

附加的文件 |
Alternative_Data.zip (569.06 KB)
因果推理中的倾向性评分 因果推理中的倾向性评分
本文探讨因果推理中的匹配问题。匹配用于比较数据集中的类似观察结果,这对于正确确定因果关系和消除偏见是必要的。作者解释了这如何有助于构建基于机器学习的交易系统,这些系统在没有经过训练的新数据上变得更加稳定。倾向性评分在因果推理中起着核心作用并被广泛应用。
神经网络变得简单(第 73 部分):价格走势预测 AutoBot 神经网络变得简单(第 73 部分):价格走势预测 AutoBot
我们将继续讨论训练轨迹预测模型的算法。在本文中,我们将领略一种称为 “AutoBots” 的方法。
DoEasy.服务功能(第 1 部分):价格形态 DoEasy.服务功能(第 1 部分):价格形态
在本文中,我们将开始开发使用时间序列数据搜索价格形态的方法。一种形态有一组参数,对任何类型的形态都是通用的。所有此类数据都将集中在基础抽象形态的对象类中。在本文中,我们将创建一个抽象形态类和一个 Pin Bar 形态类。
因果推断中的时间序列聚类 因果推断中的时间序列聚类
在机器学习中,聚类算法是重要的无监督学习算法,它们可以将原始数据划分为具有相似观测值的组。利用这些组,可以分析特定聚类的市场情况,使用新数据寻找最稳定的聚类,并进行因果推断。本文提出了一种在Python中进行时间序列聚类的原创方法。