English Русский Español Deutsch 日本語
preview
Ganhe Uma Vantagem Sobre Qualquer Mercado

Ganhe Uma Vantagem Sobre Qualquer Mercado

MetaTrader 5Exemplos | 27 agosto 2024, 10:17
20 0
Gamuchirai Zororo Ndawana
Gamuchirai Zororo Ndawana

Conteúdo

  1. Sinopse
  2. Introdução
  3. Visão geral da estratégia: Fontes de dados alternativas
  4. Técnicas de aprendizado de máquina
  5. Construindo a estratégia
  6. Conclusão
  7. Recomendações


Sinopse

Hoje, vamos desenvolver uma estratégia de trading robusta, projetada para fornecer aos traders uma vantagem competitiva significativa em diversos mercados. Enquanto os participantes convencionais do mercado dependem exclusivamente de uma combinação de dados relacionados a preços, indicadores técnicos e anúncios públicos para tomada de decisão, nossa estratégia adota uma abordagem inovadora, aproveitando fontes de dados alternativas que permanecem em grande parte inexploradas pela maioria.

A premissa por trás de nossa estratégia reside na integração de dados alternativos, uma opção frequentemente negligenciada pelos participantes convencionais do mercado. Ao aproveitar essas fontes de dados inexploradas e aplicar técnicas de machine learning, podemos nos posicionar para obter insights e perspectivas exclusivas para nossa estratégia.

Em nossa exploração, examinaremos os dados fornecidos pelo Federal Reserve Bank de St. Louis, aproveitando especificamente seu banco de dados econométrico de séries temporais conhecido como FRED. O FRED está acessível ao público a qualquer momento e, sem dúvida, oferece dados cruciais para a tomada de decisões informadas no trading. Além disso, dados provenientes de bancos centrais, como o Fed de St. Louis, muitas vezes servem como indicadores principais, aprimorando nossa capacidade de determinar entradas e saídas de forma eficaz.

Além disso, esses dados são imunes à manipulação externa, tornando-os candidatos ideais para integração em nossa estratégia de trading.

Este artigo pretende servir como um guia prático, demonstrando a fácil utilização de Python e MetaTrader 5 para construir estratégias de trading de ponta. Nosso compromisso com a clareza e simplicidade garante que cada aspecto seja explicado de forma clara, permitindo que os leitores compreendam nossa abordagem sem dificuldades e comecem hoje mesmo!


Introdução: Este artigo tem como objetivo demonstrar como aplicar facilmente dados alternativos em estratégias de trading. 

Ao final deste artigo, os leitores terão insights sobre as seguintes áreas-chave:

  1. Como os dados alternativos podem ajudar na tomada de decisões em meio ao ruído e incerteza.
  2. Técnicas para selecionar e identificar fontes confiáveis de dados alternativos.
  3. Melhores práticas para analisar e pré-processar dados alternativos para análise.
  4. Construção de estratégias de trading robustas que integram fontes de dados alternativos para melhorar o processo de tomada de decisão.

Um exemplo que ilustra o impacto dos dados alternativos é o uso estratégico de imagens de satélite. Traders avançados utilizam imagens de satélite para monitorar padrões de tráfego marítimo ou observar os níveis de estoque de petroleiros. Esses pontos de dados únicos permitem que os traders descubram oportunidades de trading lucrativas que, de outra forma, permaneceriam ocultas.

Embora o uso de imagens de satélite possa ser mais comum entre traders abastados, este artigo mostra como qualquer trader pode empregar dados alternativos disponíveis gratuitamente para se manter à frente do mercado. Além disso, ao utilizar modelos de machine learning, podemos analisar várias fontes de dados simultaneamente, aprimorando ainda mais suas capacidades de tomada de decisão.


Visão geral da estratégia de trading: Fontes de dados alternativos

Nossa estratégia de trading é projetada para ser facilmente compreendida. Integraremos dados de mercado convencionais de nosso terminal MetaTrader 5 com dados alternativos provenientes do Federal Reserve Bank de St. Louis, focando especificamente na previsão dos movimentos futuros de preço do par GBPUSD.

Para alcançar isso, aproveitaremos dois conjuntos de dados econômicos chave como nossas fontes de dados alternativos. O primeiro conjunto de dados fornece informações sobre a Libra Esterlina, oferecendo uma série temporal das taxas de juros cobradas por transações bancárias fora do horário no mercado de libras esterlinas. Essas flutuações nas taxas de juros servem como um proxy para medir o nível de demanda institucional pela Libra Esterlina, fornecendo indicadores valiosos para nossos modelos de previsão.

Da mesma forma, o segundo conjunto de dados contém informações sobre o Dólar Americano e compreende uma série temporal das taxas de juros cobradas por empréstimos overnight a bancos americanos, reguladas pelo Federal Reserve. O controle do Federal Reserve sobre essas taxas de juros por meio de ajustes na política monetária oferece insights alternativos sobre as tendências econômicas que podem impactar o USD.

Ao analisar e interpretar esses dados econômicos de séries temporais e empregar técnicas de machine learning, podemos, com sorte, alcançar nosso objetivo de descobrir indicadores principais que nos concedam uma vantagem competitiva no mercado.

O alicerce da eficácia de nossa estratégia depende de garantir uma fonte confiável de dados alternativos. A disponibilidade de fontes confiáveis de dados alternativos varia dependendo dos mercados nos quais você opera. Mercados sintéticos, gerados por geradores de números aleatórios, praticamente não têm fontes de dados alternativos. Isso porque os mercados sintéticos são independentes do mundo exterior.

  1. Credibilidade: Como sua fonte de dados alternativos obtém os dados em primeiro lugar? Examine a confiabilidade dos canais de informação dos quais eles dependem. Questões como "Como eles acessam suas informações?" e "Os canais de informação deles são confiáveis?" são cruciais na avaliação da credibilidade. Qualquer dúvida em relação a esses aspectos sinaliza a necessidade de uma avaliação mais aprofundada.
  2. Frequência de Atualizações: Nosso foco está em fontes de dados alternativos atualizadas diariamente, alinhadas com nosso período de trading. No entanto, é vital notar que nem todas as fontes oferecem atualizações diárias; algumas podem ser atualizadas mensalmente ou anualmente. Portanto, certifique-se de escolher uma fonte que esteja alinhada com a frequência de trading desejada.
  3. Reputação: Além da credibilidade, priorize fontes com um histórico reputado e um interesse comprovado em manter a precisão. Um fornecedor respeitável não só adiciona credibilidade aos nossos dados, mas também demonstra responsabilidade.
  4. Apresentação Transparente: Opte por fornecedores que apresentem dados de forma transparente e em um formato de fácil compreensão. Clareza e simplicidade na apresentação dos dados são fundamentais para uma tomada de decisão eficaz, especialmente considerando a carga cognitiva associada a dados complexos.
  5. Estrutura de Preços: Avalie os modelos de preços das fontes de dados alternativos, equilibrando nossas necessidades e restrições orçamentárias. Embora algumas fontes possam ser gratuitas, outras podem exigir pagamento. Nossa escolha deve estar alinhada com a proposta de valor oferecida por cada fonte.
  6. Termos e Condições: Revise cuidadosamente e compreenda os termos e condições associados às fontes de dados alternativos, especialmente aquelas que exigem pagamento. Compreender claramente as restrições de uso e limitações garante uma tomada de decisão informada e previne qualquer problema de conformidade involuntário.

Em resumo, uma avaliação rigorosa das fontes de dados alternativos baseada em credibilidade, frequência de atualização, reputação, transparência, preços e termos e condições é essencial para aproveitar os dados de forma eficaz dentro de nossa estratégia de trading.

Agora começaremos a examinar alguns dados alternativos obtidos do Federal Reserve Bank de St. Louis. Existem 2 maneiras de buscar dados do Fed de St. Louis:

  1. Programaticamente usando a Biblioteca Python FRED
  2. Manual no site do FRED 

Se esta for sua primeira vez usando esses conjuntos de dados, aconselho que você colete os dados manualmente primeiro. Isso é aconselhável porque o site do FRED possui notas e informações úteis sobre cada conjunto de dados, como foi registrado, o que os dados representam, se estão ou não ajustados sazonalmente, as unidades e escalas de medição e outros detalhes desse tipo. Uma vez que você estiver familiarizado com a natureza dos dados, pode então passar a coletá-los programaticamente. Então, para nossa primeira demonstração, os conjuntos de dados foram baixados manualmente do Site do Federal Reserve de St. Louis. Passaremos para a abordagem programática quando estivermos construindo a estratégia. 

A primeira coisa que faremos é coletar dados de mercado do nosso MetaTrader 5 usando um script MQL5, prefiro coletar os dados dessa forma porque você pode realizar qualquer pré-processamento necessário no lado do MQL5, onde você tem acesso ilimitado aos dados. Nosso script é modestamente simples.

  • Começamos declarando manipuladores para nossos indicadores técnicos, usaremos 4 médias móveis.
  • Em seguida, declaramos buffers para armazenar as leituras de nossas médias móveis, os buffers, no nosso caso, são arrays dinâmicos.
  • Avançando, precisamos então de um nome para nosso arquivo, o nosso será o nome do par que estamos negociando seguido da string "Market Data As Series", e será em formato CSV.
  • Subsequentemente, declaramos quantos dados gostaríamos de coletar. 
  • Observe que o script funciona com o período de tempo atual do gráfico ao qual está aplicado.
  • Agora chegamos ao nosso manipulador de eventos OnStart(), onde está o coração do nosso script.
  • Começamos inicializando todos os 4 de nossos indicadores técnicos.
  • Depois, copiamos os valores dos indicadores para os arrays que criamos anteriormente.
  • Uma vez feito isso, criamos um manipulador de arquivos para criar, escrever e fechar nosso arquivo.
  • Usamos então um simples loop for para iterar pelos arrays e escrever no nosso arquivo CSV. Observe que, na primeira iteração do nosso loop, escrevemos os cabeçalhos das colunas; posteriormente, escrevemos os valores reais que queremos.
  • Uma vez que o loop é concluído, fechamos nosso arquivo, usando o manipulador de arquivos, e estamos prontos para mesclar os dados do nosso terminal MetaTrader 5 com nossos dados alternativos.

#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]
                                 );
      } 
    }
  }
//+------------------------------------------------------------------+

Agora estamos prontos para começar a explorar nossos dados alternativos junto com nossos dados de mercado.

Como sempre, começaremos importando os pacotes necessários.

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

Agora, vamos ler os dados que exportamos do nosso script MQL5.

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

Ao preparar dados de mercado para machine learning, certifique-se de que o preço de hoje seja o último e o preço mais antigo seja o primeiro. 

GBPUSD = GBPUSD[::-1]

Em seguida, precisamos redefinir o índice.

GBPUSD.reset_index(inplace=True)

Vamos definir com que antecedência gostaríamos de fazer a previsão.

look_ahead = 30
splits = 30

Agora precisamos preparar o target. 

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

Agora precisamos definir a data como o índice, isso nos ajudará a alinhar facilmente nossos dados de mercado com nossos dados alternativos mais tarde.

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

O primeiro conjunto de dados alternativos que consideraremos é o Daily Sterling Overnight Index Average (SOIA). É a média das taxas de juros cobradas dos bancos para empréstimos em libras esterlinas fora do horário bancário normal.

Se a média das taxas de juros em libras esterlinas estiver subindo enquanto a média das taxas de juros no dólar estiver caindo, isso pode sinalizar que a GBP está se fortalecendo em relação ao USD em um nível institucional. 

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

Vamos limpar os dados alternativos. Primeiro, transforme a coluna de datas em um objeto de data.

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

Nosso conjunto de dados contém pontos, que presumivelmente representam observações ausentes. Vamos substituir todos os pontos por zeros e, em seguida, substituir os zeros pelo valor médio da coluna. 

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)

Em seguida, definimos a data como o índice.

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

A próxima fonte de dados alternativos que consideraremos será o Secured Overnight Financing Rate (SOFR). É o custo dos empréstimos garantidos overnight, e é publicado diariamente pelo Federal Reserve Bank de Nova York. 

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

Observe que os passos de pré-processamento aplicados ao conjunto de dados SOFR são idênticos aos passos aplicados ao conjunto de dados SOIA, portanto, para manter o artigo fácil de ler do início ao fim, omitiremos esses passos. 

Agora, vamos mesclar os 3 data frames que temos. Definindo left_index e right_index como verdadeiros, estamos garantindo que ambos os conjuntos de dados estejam sendo alinhados apenas nos dias em que temos observações completas para cada um deles. Por exemplo, o conjunto de dados GBPUSD não possui registros durante o fim de semana, portanto, todos os pontos de dados alternativos observados durante o fim de semana não são incluídos em nosso data frame final mesclado. 

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

Em seguida, precisamos redefinir nosso índice.

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

Vamos definir nossos preditores.

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

Então, criaremos um data frame para armazenar os níveis de erro de cada combinação de preditores.

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

Este é o aspecto do nosso data frame agora.

merged_df

Nosso Data Frame Mesclado

Fig 3: Nosso conjunto de dados que contém tanto nossos dados normais quanto nossos dados alternativos.


A primeira coluna é a taxa de juros média da Libra Esterlina, a segunda coluna contém a taxa de juros média do Dólar Americano. A partir daí, as colunas seguintes já devem ser familiares para você. Lembre-se de que o target é o preço de fechamento 30 dias no futuro.

Por fim, exportaremos nosso data frame mesclado para um arquivo CSV para uso posterior.

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

Vamos escalonar nossos dados.

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)

Agora vamos nos preparar para treinar nosso modelo e ver se nossos dados alternativos estão nos ajudando ou nos atrapalhando.

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

Vamos preparar nossa divisão de treino/teste.

para i,(treinamento,teste) em enumerate(tscv.split(merged_df)):
    modelo = 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]))


Agora, estamos plotando os resultados como box-plots.

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])

Combinações de Preditores

Fig 4: Analisando os valores de erro obtidos ao usar Dados Normais (esquerda), Dados Alternativos (meio), Todos os Dados Disponíveis (direita).

Vamos interpretar os resultados: podemos ver claramente que o conjunto normal de preditores e o conjunto alternativo de preditores ambos têm caudas longas que se estendem para o topo do gráfico. No entanto, o último gráfico, que contém tanto os preditores normais quanto os alternativos, tem uma forma achatada. Essa forma achatada é desejável porque mostra que, quando usamos ambos os conjuntos de preditores juntos, temos menos variação em nossos erros. Nossa precisão é estável no último gráfico; no entanto, nos dois primeiros gráficos, onde dependemos totalmente dos dados normais ou dos dados alternativos, nossa precisão não é tão estável. 

Também podemos verificar se há algum efeito de interação em nossos dados. Vamos criar um gráfico de dispersão com o target no eixo y e a taxa de juros da Libra Esterlina no eixo x.

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

Efeitos de Interação da Libra Esterlina

Fig 5: Analisando a relação entre a taxa de juros cobrada em Libras Esterlinas e o valor futuro do par GBPUSD.

Aqui está uma maneira de interpretar este gráfico: cada linha que vai do topo ao fundo do gráfico representa como o target muda quando a taxa de juros da Libra Esterlina é fixa. O fato de podermos observar valores de target variáveis, mesmo que nossa taxa de juros da Libra Esterlina esteja fixa, é um sinal definitivo de efeitos de interação em nossos dados. Isso pode ser um indicador de que há outras forças poderosas em ação que estão influenciando o target além dos dados alternativos que coletamos.


Técnicas de Machine Learning 

A seleção de uma técnica de machine learning adequada é influenciada pela natureza dos dados que você possui. Considere o seguinte:

  • Tamanho do Conjunto de Dados: Para conjuntos de dados pequenos, com menos de dez mil linhas ou menos de 30 colunas, é aconselhável empregar modelos mais simples para mitigar o risco de overfitting. Modelos complexos, como redes neurais profundas, podem ter dificuldades em aprender de forma eficaz com dados tão limitados.
  • Ruído nos Dados: Conjuntos de dados ruidosos, geralmente com pontos de dados ausentes ou flutuações aleatórias e inexplicáveis, são mais adequados para modelos simples. Modelos complexos tendem a exibir alta variância, tornando-os mais propensos a overfitting em dados ruidosos e, além disso, em dias de mercado especialmente ruidosos, podemos até nos sair melhor sem eles.
  • Dimensionalidade dos Dados: Em casos em que o conjunto de dados tem um alto número de colunas, técnicas de pré-processamento podem ser benéficas. Empregue modelos que sejam eficazes no tratamento de dados de alta dimensionalidade e aplique seleção de características e redução de dimensionalidade.
  • Tamanho do Conjunto de Dados e Poder Computacional: Se você tiver grandes conjuntos de dados com níveis de ruído aceitáveis e, além disso, também tiver acesso a recursos computacionais suficientes, isso pode justificar o uso de modelos sofisticados, como redes neurais profundas. Esses modelos podem capturar efetivamente padrões e relacionamentos complexos dentro dos dados, desde que haja capacidade computacional adequada e dados limpos.

Em conclusão, não existe uma solução perfeita para a seleção de modelos de machine learning. A natureza dos dados, incluindo tamanho, ruído, dimensionalidade e poder computacional disponível, desempenha um papel crucial na determinação da abordagem mais adequada. Adaptar a escolha do modelo para alinhar-se às características dos dados é crucial para alcançar resultados preditivos robustos e precisos.
Agora, demonstraremos como você pode selecionar um bom modelo para seus dados.


Vamos começar importando as bibliotecas necessárias.

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

Agora leremos os dados do csv que exportamos. O CSV continha todos os nossos dados mesclados.

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

Vamos nos preparar para escalonar os dados.

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)

Vamos treinar nossos modelos.

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

Vamos preparar nossa divisão de treino/teste e, em seguida, criar um data frame para armazenar as métricas de erro.

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

Agora podemos observar as métricas de erro de nossos modelos.

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

O Erro de Cada Modelo

Fig 6: Os valores de erro que recebemos de cada um dos modelos que ajustamos.


Vamos visualizar alguns dos dados como boxplots.

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])


Modelos Lineares

Fig 7: Os valores de erro de alguns dos modelos lineares que usamos.


Modelos Não Lineares

Fig 8: Os valores de erro de alguns dos modelos não lineares que usamos.


Vamos exibir algumas das estatísticas resumo obtidas.

Variância      Erro 
Variância Linear: 1.3365981802501968e-06 Erro quadrático médio Linear: 0.0022242681292296462
Variância Lasso: 3.0466413126186177e-05 Erro quadrático médio Lasso: 0.004995731270431843
Variância Ridge: 2.5678314939547713e-06 Erro quadrático médio Ridge: 0.002467126140156681
Variância Random Forest: 2.607918492340197e-06 Erro quadrático médio Random Forest: 0.002632579355696408
Variância Linear SVR: 3.825627012092798e-05 Erro quadrático médio Linear SVR: 0.004484702122899226
Variância Sigmoid SVR: 27.654341711864102 Erro quadrático médio Sigmoid SVR: 1.6693947903605928
Variância RBF SVR: 4.1654658535332505e-05 Erro quadrático médio RBF SVR: 0.004992333849448852
Variância 2 Poly SVR: 6.739873404310582e-05 Erro quadrático médio 2 Poly SVR: 0.008163708245600027
Variância 3 Poly SVR: 0.0005393054392191576 Erro quadrático médio 3 Poly SVR: 0.018431036676781344
Variância XGB: 7.053078880392137e-06 Erro quadrático médio XGB: 0.003163819414983548


Observe que nenhum dos modelos está se destacando de maneira excepcional, todos estão mais ou menos dentro da mesma faixa de desempenho. Em tais circunstâncias, o modelo mais simples pode ser a melhor escolha, pois é menos provável que apresente overfitting. Portanto, neste exemplo, usaremos a regressão linear como nosso modelo de escolha para nossa estratégia de trading. Optamos por ela porque seu nível de erro é tão bom quanto qualquer outro modelo que poderíamos ter escolhido e, além disso, sua variância é baixa. Assim, o modelo linear é menos propenso a overfitting e mais provável de ser estável ao longo do tempo. 


Construindo a estratégia 

Agora estamos prontos para aplicar tudo o que discutimos nas seções anteriores em uma estratégia de trading robusta, usando a Biblioteca MetaTrader 5 para Python. 

Explicações serão dadas em cada etapa para garantir que todo o código seja fácil de seguir.

Primeiro, importamos os pacotes necessários.

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

O pacote fredapi nos permite extrair dados programaticamente do banco de dados FRED. No entanto, antes de poder usar a biblioteca, você deve criar uma chave de API. As chaves de API são gratuitas, mas você só pode obter uma após criar uma conta gratuita no site do St. Louis Fed.

Agora vamos definir variáveis globais.

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')

Agora vamos fazer login na nossa conta de trading.

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

Logged in successfully

Vamos definir nosso volume de trading.

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 tem volume mínimo: 0.01


Vamos definir as funções que vamos usar ao longo do nosso programa.

Primeiro, precisamos de uma função para buscar o preço atual do mercado no nosso Terminal 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,:])

Em seguida, precisamos de uma função para solicitar dados alternativos do Federal Reserve de St. Louis.

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)

Depois, precisamos de uma função para preparar as entradas para o nosso modelo.

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'])


Então, precisamos de uma função para nos ajudar a fazer uma previsão usando o nosso modelo.

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

Vamos treinar nossos modelos.

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

Configurando nosso modelo.

from sklearn.linear_model import LinearRegression
model = LinearRegression()

Definindo nossos preditores e o target.

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

Ajustando nosso modelo.

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

Agora chegamos ao coração do nosso algoritmo de trading.

  • Primeiro, definimos um loop infinito para manter nossa estratégia em execução.
  • Em seguida, buscamos os dados de mercado atuais e os usamos para realizar uma previsão.
  • Depois, teremos flags booleanas para representar as expectativas do nosso modelo. Se o nosso modelo estiver esperando que o preço suba, BUY_STATE será verdadeiro; caso contrário, se o modelo estiver esperando que o preço caia, SELL_STATE será falso.
  • Se não tivermos posições abertas, seguiremos a previsão do nosso modelo.
  • Se tivermos posições abertas, verificaremos se a previsão do nosso modelo está indo contra a nossa posição aberta. Se estiver, então fecharemos a posição. Caso contrário, podemos deixar a posição aberta.
  • Por fim, após completar todas as etapas acima, colocaremos o algoritmo em espera por um dia e buscaremos dados atualizados no dia seguinte.

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)


Resultado Final

Fig 9: Nossa negociação no primeiro dia em que a abrimos.



Dia 2

Fig 10: Nossa negociação no dia seguinte.


Conclusão 

Os dados alternativos têm um potencial imenso para mudar a forma como olhamos para os mercados financeiros. Ao escolher cuidadosamente as fontes certas de dados, podemos potencialmente nos encontrar do lado certo da maioria das negociações em que entramos. O componente mais importante dessa estratégia é ter uma fonte confiável de dados alternativos; caso contrário, você pode simplesmente usar dados normais. Tire seu tempo, faça sua própria pesquisa, chegue às suas próprias conclusões e siga seus instintos. Lembre-se de que, no final do dia, construir estratégias é tanto uma ciência quanto uma arte. Portanto, aplique suas habilidades de raciocínio de forma criteriosa ao selecionar quais fontes de dados alternativos seriam úteis e, além disso, deixe sua imaginação encontrar aplicações e casos de uso novos que a maioria das pessoas não pensaria, e você estará em uma liga própria. 


Recomendações

Futuros leitores podem achar proveitoso procurar mais fontes de conjuntos de dados alternativos e usar técnicas de machine learning, como a seleção do melhor subconjunto, para escolher fontes úteis de dados alternativos. Além disso, lembre-se de que o modelo linear que usamos em nossa demonstração faz suposições fortes sobre o processo que gerou os dados; se essas suposições forem violadas, a precisão do nosso modelo se deteriorará com o tempo. 

Traduzido do Inglês pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/en/articles/14441

Arquivos anexados |
Alternative_Data.zip (569.06 KB)
O Método de Agrupamento para Manipulação de Dados: Implementando o Algoritmo Iterativo Multicamadas em MQL5 O Método de Agrupamento para Manipulação de Dados: Implementando o Algoritmo Iterativo Multicamadas em MQL5
Neste artigo, descrevemos a implementação do Algoritmo Iterativo Multicamadas do Método de Agrupamento para Manipulação de Dados em MQL5.
Do básico ao intermediário: Comando WHILE e DO WHILE Do básico ao intermediário: Comando WHILE e DO WHILE
Neste artigo, vermos de maneira prática e bastante didática o primeiro comando de laço. Apesar de muitos iniciantes temerem nas bases quando precisa criar laços. Saber como fazer isto de maneira adequada e segura. É algo que somente a experiência e prática irá lhe fornecer. Mas quem sabe, eu possa lhe ajudar a reduzir as dores e sofrimento. Isto lhe mostrando os principais problemas e cuidados a serem tomados quando for utilizar laços em seus códigos. O conteúdo exposto aqui, visa e tem como objetivo, pura e simplesmente a didática. De modo algum deve ser encarado como sendo, uma aplicação cuja finalidade não venha a ser o aprendizado e estudo dos conceitos mostrados.
Introdução ao MQL5 (Parte 6): Um Guia para Iniciantes sobre Funções de Array em MQL5 Introdução ao MQL5 (Parte 6): Um Guia para Iniciantes sobre Funções de Array em MQL5
Embarque na próxima fase da nossa jornada com MQL5. Neste artigo esclarecedor e amigável para iniciantes, exploraremos as funções restantes de arrays, desmistificando conceitos complexos para capacitá-lo a criar estratégias de negociação eficientes. Discutiremos as funções ArrayPrint, ArrayInsert, ArraySize, ArrayRange, ArrayRemove, ArraySwap, ArrayReverse e ArraySort. Eleve sua expertise em negociação algorítmica com essas funções essenciais de arrays. Junte-se a nós no caminho para a maestria em MQL5!
Processos não estacionários e regressão espúria Processos não estacionários e regressão espúria
O objetivo do artigo é demonstrar a ocorrência de falsa regressão quando se aplica a análise de regressão a processos não estacionários, utilizando simulação pelo método de Monte Carlo.