English Русский 中文 Español Deutsch 日本語
preview
Teoria das Categorias em MQL5 (Parte 13): Eventos de calendário com esquemas de banco de dados

Teoria das Categorias em MQL5 (Parte 13): Eventos de calendário com esquemas de banco de dados

MetaTrader 5Testador | 17 novembro 2023, 14:10
263 0
Stephen Njuki
Stephen Njuki

Introdução

Na última parte desta série de artigos, exploramos como a teoria da ordem pode se combinar com a teoria das categorias, discutimos como os conceitos resultantes dessa combinação podem ser implementados no MQL5 e também examinamos um exemplo de um sistema de negociação que utiliza alguns desses princípios.

Nosso último artigo abordou duas concepções da teoria da ordem, a saber, ordens parciais e ordens lineares. Lembremos que as ordens parciais são métodos estabelecidos de classificação que representam um tipo especial de pré-ordem com antissimetria. Como resultado, eles também são caracterizados pela reflexividade e transitividade. Por outro lado, as ordens lineares são uma forma distinta de ordens parciais, uma vez que exigem comparabilidade adicional, o que significa que relações indefinidas não são permitidas.

Neste artigo, em vez de introduzir novos conceitos, daremos um passo atrás para revisitar os tópicos já abordados com o objetivo de integrá-los em um classificador de linguagem que utiliza esquemas de banco de dados.


A necessidade de classificação eficiente de eventos do calendário

Eventos do calendário são criados quase diariamente, sendo que a maioria deles é anunciada adiantadamente, geralmente com vários meses de antecedência. Os eventos são listados no calendário econômico do MetaTrader e abrangem indicadores de moedas e indicadores macroeconômicos da China, Estados Unidos, Japão, Alemanha, União Europeia, Reino Unido, Coreia do Sul, Cingapura, Suíça, Canadá, Nova Zelândia, Austrália e Brasil. A lista é dinâmica, motivo pelo qual novos países podem vir a ser adicionados no futuro. Muitos desses indicadores têm valores numéricos, que geralmente incluem o valor previsto, o valor real e o valor anterior. O formato dos indicadores numéricos varia significativamente de um indicador para outro. Além disso, muitos indicadores são, em essência, incomparáveis entre si, o que de certa forma representa nosso desafio.

Para que os traders possam utilizar os dados desses indicadores de moedas e economias, eles precisam ler de forma confiável e consistente os valores numéricos e/ou interpretar com precisão o texto publicado. Vamos examinar alguns eventos típicos do calendário.


cal_1


cal_2


cal_3


cal_4


Acima estão apresentados quatro eventos para China, Estados Unidos, Japão e Alemanha, refletindo um índice, rendimento percentual, montantes em dinheiro e um valor indefinido, respectivamente. Essas informações podem ser obtidas no MQL5 através de métodos simples, como mostrado abaixo.

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void SampleRetrieval(string Currency)
   {
      MqlCalendarValue _value[];
      datetime _stop_date=datetime(__start_date+int(PeriodSeconds(__stop_date_increment)));
//--- get events
      MqlCalendarEvent _event[];
      int _events=CalendarEventByCurrency(Currency,_event);
      printf(__FUNCSIG__+" for Currency: "+Currency+" events are: "+IntegerToString(_events));
      //
      for(int e=0;e<_events;e++)
      {
         int _values=CalendarValueHistoryByEvent(_event[e].id, _value, __start_date, _stop_date);
         //
         for(int v=0;v<_values;v++)
         {
            //
            printf(__FUNCSIG__+" Calendar Event code: "+_event[e].event_code+", for value: "+TimeToString(_value[v].period)+" on: "+TimeToString(_value[v].time)+", has... ");
            //
            if(_value[v].HasPreviousValue())
            {
               printf(__FUNCSIG__+" Previous value: "+DoubleToString(_value[v].GetPreviousValue()));
            }
            
            if(_value[v].HasForecastValue())
            {
               printf(__FUNCSIG__+" Forecast value: "+DoubleToString(_value[v].GetForecastValue()));
            }
            
            if(_value[v].HasActualValue())
            {
               printf(__FUNCSIG__+" Actual value: "+DoubleToString(_value[v].GetActualValue()));
            }
         }
      }
   }

Depois de extraído, há o problema de como preparar e classificar o valor obtido para uso na análise. Se nossos valores numéricos fossem padrão, ou seja, estivessem na faixa de 0 a 100, como um índice, então a comparação relativa entre os eventos do calendário seria simples, considerando a capacidade de determinar facilmente a importância relativa de cada evento. No entanto, na realidade, a análise deve ser realizada com a ajuda de uma "terceira parte", utilizando a correlação entre cada evento individual e o movimento de preços de ações ou moedas específicas.

Alguns eventos não têm valor numérico comparável algum, como, por exemplo, o discurso de um membro do conselho do Banco Central Alemão, conforme mostrado na captura de tela acima.

É importante mencionar especialmente a descrição textual do próprio evento, que é supostamente a maneira pela qual o trader identifica o evento. Por exemplo, ao analisar o par EURUSD, idealmente, você precisa considerar eventos relacionados ao EUR e eventos comparáveis ao USD. Mas como lidar, por exemplo, com eventos como estes:


cal_5


Com seus supostos equivalentes no lado do USD:

cal_6


E também:

cal_7


Ao trabalhar com o EUR, estamos levando em conta o sentimento do euro ou o sentimento da Alemanha? Ou devemos usar ambos com ponderação? E, se sim, que pesos devemos usar? Quanto ao USD, quais valores de Michigan ou Filadélfia devemos utilizar?

Portanto, precisamos de uma maneira adicional de classificar nossos eventos além das já fornecidas pelo MQL5, que nos ajude não apenas a comparar os valores numéricos em diferentes economias e moedas, mas também a realizar negociações.

Os métodos de classificação existentes são muito simples. Eles incluem: seleção de eventos por identificador, seleção de eventos por país e seleção de eventos por moeda. Existem algumas outras categorias que levam em consideração o valor desses eventos, mas elas não diferem muito dessas classificações. Além disso, a seleção por país e moeda cria ambiguidade, em grande parte devido ao EUR. Faltam aspectos fundamentais que permitam determinar se um evento é retrospectivo, como um índice, ou prospectivo, como o sentimento de mercado. Além disso, a necessidade de comparar diferentes moedas para o mesmo evento em alguns casos não está tão claramente definida, como mostrado anteriormente para o par EURUSD.


Conceitos da teoria das categorias e esquemas de banco de dados

Nas partes anteriores desta série, exploramos as unidades fundamentais da teoria das categorias - conjuntos (anteriormente chamados de domínios), em seguida, os morfismos com seus tipos e, finalmente, composições com muitas propriedades e formas.

As imagens, que são uma aproximação aos grafos e demonstram o conceito, ao qual os dados correspondem, mesmo sem levar em conta os dados nas tabelas, são o que podemos chamar de esquemas de banco de dados. Os bancos de dados são considerados ferramentas de armazenamento indexadas que garantem a integridade das referências e evitam a duplicação de dados.

A potencial sinergia entre a teoria das categorias e os esquemas de banco de dados reside no fato de que as composições da teoria das categorias podem transmitir algumas de suas propriedades para os esquemas de banco de dados. Assim, se começarmos a classificar eventos em nosso calendário com a ajuda de um banco de dados simples, poderemos facilmente examinar o esquema por diferentes "lentes", seja contagens, gráficos, pedidos e muito mais. Abaixo, é apresentada uma representação esquemática de tabelas que podem definir eventos em nosso calendário.


Com esse layout básico, a tabela de eventos terá uma coluna de data e código como chave primária. A coluna de código contém os dados do código do evento, lidos a partir dos eventos do calendário. As tabelas de Moedas, Países e Eventos podem ter suas chaves primárias como colunas currency_id, countries_id e event_id, respectivamente. No entanto, a tabela de valores do par de moedas precisará combinar as colunas de data e event_id para sua chave primária.

O mencionado acima não é um esquema, já que as relações entre as tabelas não estão especificadas. Isso são apenas tabelas em nosso banco de dados. A parte do esquema é mostrada abaixo.

Essa estrutura esquemática pode ser facilmente vista como um produto categorial. Isso significa que temos uma propriedade universal entre nossa tabela de eventos e a representação de valores de pares de moedas.

Lembrando que geralmente a propriedade universal do coproduto é útil ao lidar com curvas fragmentadas. Peguemos, por exemplo, um experimento em que a temperatura registrada em duas áreas A e B varia linearmente e quadraticamente, respectivamente. Para estudar o perfil de temperatura da área combinada, a propriedade universal do coproduto A e B permitiria unir os perfis de temperatura separados de cada área em uma única função, que, com base nos dados da curva, seria uma estimativa razoável do que esperar se alguém decidisse viajar para essa região sem uma rota definida.

Para nossos propósitos como traders, a composição apresentada acima é bastante útil, pois os valores dos eventos de cada moeda individual nunca são publicados simultaneamente. Dito isto, se os dados sobre o sentimento em relação ao EUR forem publicados, por exemplo, hoje, os indicadores do USD podem aparecer duas semanas depois. Poderíamos usar os valores antigos (os mais recentes) do USD para obter o valor do par de moedas, mas com a teoria das categorias, podemos efetivamente usar a propriedade universal para prever ou estimar o valor da moeda que não foi atualizada desde o movimento do gráfico.


Implementação no MQL5

Dado que nossa teoria das categorias e esquemas podem ser representados no MQL5 como um quadrado comutativo, podemos fazer algumas modificações na classe CSquareCommute das partes anteriores da seguinte forma:

//+------------------------------------------------------------------+
//| Square Commute Class to illustrate Universal Property            |
//+------------------------------------------------------------------+
template <typename TA,typename TB,typename TC,typename TD>
class CCommuteSquare
   {
      public:
      
      CHomomorphism<TA,TB>          ab;
      CHomomorphism<TA,TC>          ac;
      CHomomorphism<TD,TB>          db;
      CHomomorphism<TD,TC>          dc;
      
      CHomomorphism<TD,TA>          da;   //universal property
      
      virtual void                  SquareAssert()
                                    {
                                       ab.domain=ac.domain;
                                       ab.codomain=db.codomain;
                                       dc.domain=db.domain;
                                       dc.codomain=ac.codomain;
                                       
                                       da.domain=db.domain;
                                       da.codomain=ac.domain;
                                    }
      
                                    CCommuteSquare(){};
                                    ~CCommuteSquare(){};
   };

O que adicionamos ao original é simplesmente um homomorfismo adicional da propriedade universal. Desse modo, após isso, o próximo passo crucial será definir elementos para cada conjunto que coleta os dados necessários. Isso pode ser feito para o conjunto de eventos (mostrado como uma tabela de eventos), conforme indicado abaixo:

//sample constructor for event set
CElement<string> _e_event;_e_event.Cardinality(7);
//

Assim que esse elemento for definido, o trader pode facilmente preenchê-lo com dados usando o código listado acima (Listagem 1) ou qualquer outra abordagem adequada. Você pode encontrar um método mais adequado para a sua estratégia. Uma vez que o elemento esteja preenchido com dados, ele pode ser facilmente adicionado ao domínio correspondente da classe de movimento, conforme mostrado nas partes anteriores. Os valores dos eventos e até mesmo os elementos do conjunto de moedas também podem ser criados, como mostrado abaixo:

//sample constructor for type set
CDomain<string> _d_type;_d_type.Cardinality(_types);
//data population
CElement<string> _e_type;_e_type.Cardinality(1);
      //sample constructor for currency set
CDomain<string> _d_currency;_d_currency.Cardinality(_currencies);
//data population
CElement<string> _e_currency;_e_currency.Cardinality(1);

Isso leva aos elementos de valor do par de moedas. Esse conjunto combina moedas em um par negociado comum que tem um gráfico de preços quando selecionado na "Observação do mercado" com a adição de um novo valor numérico, que é o valor efetivo do par resultante da combinação dos dois valores de evento de cada moeda. Assim, por exemplo, se tivermos valores de vendas no varejo para a zona do euro correspondentes ao EUR e valores de vendas no varejo para os EUA correspondentes ao USD, o conjunto de valores do par de moedas incluirá o par EURUSD com seu valor efetivo de vendas no varejo. Abaixo está a listagem para criar seu elemento:

//sample constructor for values set
CDomain<string> _d_values;_d_values.Cardinality(_values);
//data population
CElement<string> _e_values;_e_values.Cardinality(4);

Você pode estar se perguntando por que a representação de um par de moedas é tão importante. Ela combina os valores dos eventos de duas moedas, conforme indicados no calendário de eventos, em um único valor para o par de moedas composto por essas duas moedas. Esse único valor pode, por exemplo, criar uma série temporal que abre oportunidades para análises posteriores, como uma série temporal de preços desse par ou qualquer outra série de indicadores relacionados a esse par.

Resumindo o que discutimos até agora, observe que as etapas de desenvolvimento e implementação dessa classificação envolvem principalmente a organização dos eventos brutos do calendário em um esquema de banco de dados. Isso identifica textos repetitivos e permite o uso de índices. Para este projeto, pode-se usar um esquema simples em que a tabela de eventos está relacionada a todas as outras tabelas.

Com esse design, percorremos os eventos do calendário que podem ser facilmente extraídos, conforme mostrado na listagem 1 acima, e preenchemos os valores em nosso banco de dados. Para não reinventar a roda, a classe para nosso banco de dados com tabelas correlatas, representadas como estruturas, poderia ser assim:

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class CDatabase
  {
      public:
      
      STableEvents               events;
      STableEventTypes           event_types;
      STableCountries            countries;
      STableCurrencies           currncies;
      
      
                                 CDatabase(void);
                                 ~CDatabase(void);
  };

A diferença entre essa abordagem e o SQL está no fato de que os dados são armazenados na memória RAM, que é temporária, enquanto o SQL geralmente armazena dados no disco rígido. No entanto, essa classe nos permite exportá-la para um banco de dados físico existente, e como a IDE MQL5 possui algumas capacidades de manipulação de banco de dados, você eventualmente pode ler esses valores de um banco de dados físico, em vez de da memória RAM, para economizar recursos computacionais.

Assim que tivermos o banco de dados, preparamos nossa comutação quadrada a partir da classe mencionada acima. Esse processo simplesmente envolve a definição de conjuntos de vértices, como mostrado na figura abaixo. Para cada conjunto, definimos sua estrutura de elementos. Seu código já foi publicado acima. Após a definição dos elementos, eles são preenchidos com dados de nosso banco de dados e, em seguida, adicionados a uma instância da classe de comutação quadrada.



Quando temos conjuntos, passamos para a parte mais interessante - a definição de homomorfismos entre esses conjuntos. O homomorfismo do conjunto de eventos para o conjunto de tipos de eventos simplesmente associa eventos aos seus tipos, o que, do ponto de vista do design de banco de dados, significa que podemos ter apenas uma coluna de índice de tipos na tabela de eventos, e os tipos reais com seus índices estarão na tabela de tipos de eventos. A relação de chave estrangeira (foreign key) entre eles seria equivalente ao nosso homomorfismo. Como esta não é uma base de dados, em nosso conjunto de tipos, temos todos os tipos já listados como parte do conjunto de eventos, mas sem repetições, o que significa que nosso conjunto de eventos é o domínio, e os tipos de eventos são o codomínio. Portanto, o homomorfismo pode ser facilmente definido usando o código abaixo:

      //ab homomorphisms
      CHomomorphism<string,string> _ab;
      
      CElement<string> _e;
      for(int s=0;s<_sc.ab.domain.Cardinality();s++)
      {
         _e.Let();
         if(_sc.ab.domain.Get(s,_e))
         {
            string _s="";
            if(_e.Get(0,_s))
            {
               CMorphism<string,string> _m;
               _m.Morph(_sc.ab.domain,_sc.ab.codomain,s,EventType(_s));
               
               _ab.Morphisms(_ab.Morphisms()+1);
               _ab.Set(_ab.Morphisms()-1,_m);
            }
         }
      }

Da mesma forma, o homomorfismo de eventos e moedas é uma correspondência direta, que pode ser implementada com o código a seguir:

      //ac homomorphisms
      CHomomorphism<string,string> _ac;
      
      for(int s=0;s<_sc.ac.domain.Cardinality();s++)
      {
         _e.Let();
         if(_sc.ac.domain.Get(s,_e))
         {
            string _s="";
            if(_e.Get(1,_s))
            {
               CMorphism<string,string> _m;
               int _c=EventCurrency(_s);
               if(_c!=-1)
               {
                  _m.Morph(_sc.ac.domain,_sc.ac.codomain,s,_c);
                  
                  _ac.Morphisms(_ac.Morphisms()+1);
                  _ac.Set(_ac.Morphisms()-1,_m);
               }
            }
         }
      }

No entanto, a essência está nos três homomorfismos restantes, ou seja, a correspondência com tipos de eventos estabelecidos a partir do conjunto de valores de pares de moedas, a correspondência com moedas estabelecidas a partir do conjunto de valores de pares de moedas e, finalmente, a correspondência da propriedade universal com os valores do par de moedas a partir do conjunto de eventos. Se descompactarmos essa estrutura, começando pelos dois primeiros, que são relativamente simples, teremos a correspondência dos valores dos pares de moedas com os tipos de eventos, bem como a correspondência dos valores dos pares de moedas com as moedas, tornando nossa composição um produto. Vale ressaltar que, de acordo com as regras fundamentais dos homomorfismos, um elemento no domínio só pode ser associado a um elemento no codomínio. Logo, isso significa que, ao lidar com várias moedas, não podemos ter uma correspondência inversa, pois isso resultaria em associar valores de eventos a vários pares sempre que o par se referisse ao seu valor. Para moedas, a correspondência a partir daí com conjuntos de valores de pares de moedas também estaria sujeita ao mesmo problema de repetição. Portanto, a implementação da correspondência com valores de eventos pode se parecer com o seguinte:

      //db homomorphisms
      CHomomorphism<string,string> _db;
      
      for(int s=0;s<_values;s++)
      {
         _e.Let();
         if(_sc.db.domain.Get(s,_e))
         {
            string _s="";
            if(_e.Get(3,_s))
            {
               int _t=TypeToInt(_s);
               CMorphism<string,string> _m;
               //
               _m.Morph(_sc.db.domain,_sc.db.codomain,s,_t);
               
               _db.Morphisms(_db.Morphisms()+1);
               _db.Set(_db.Morphisms()-1,_m);
            }
         }
      }

Da mesma forma, a correspondência de moedas pode ser semelhante a esta:

      //dc homomorphisms
      CHomomorphism<string,string> _dc;
      
      for(int s=0;s<_values;s++)
      {
         _e.Let();
         if(_sc.dc.domain.Get(s,_e))
         {
            string _s="";
            if(_e.Get(0,_s))//morphisms for margin currency only
            {
               int _c=EventCurrency(_s);
               
               CMorphism<string,string> _m;
               //
               _m.Morph(_sc.dc.domain,_sc.dc.codomain,s,_c);
               
               _dc.Morphisms(_dc.Morphisms()+1);
               _dc.Set(_dc.Morphisms()-1,_m);
            }
         }
      }

Aqui, vale a pena mencionar os parâmetros de peso para demanda e margem. Isso pode ser alcançado por meio de otimização ou ponderação relativa das taxas de juros básicas de cada economia ou nível de inflação (esta lista não é exaustiva). O trader terá que fazer uma escolha com base em sua estratégia e perspectivas de mercado. O último homomorfismo dos valores dos pares de moedas obtidos dos eventos corresponderá a um único elemento dos valores dos pares de moedas e duas entradas no conjunto de eventos. Com base no peso usado para os dois homomorfismos mencionados acima, a correspondência da propriedade universal parecerá assim:

      //da homomorphisms
      CHomomorphism<string,string> _da;
      
      for(int s=0;s<_values;s++)
      {
         _e.Let();
         if(_sc.da.domain.Get(s,_e))
         {
            string _s_c="",_s_t="";
            if(_e.Get(0,_s_c) && _e.Get(3,_s_t))// for margin currency
            {
               for(int ss=0;ss<_sc.ac.domain.Cardinality();ss++)
               {
                  CElement<string> _ee;
                  if(_sc.da.codomain.Get(ss,_ee))
                  {
                     string _ss_c="",_ss_t="";
                     if(_ee.Get(1,_ss_c) && _ee.Get(6,_ss_t))// for margin currency
                     {
                        if(_ss_c==_s_c && _ss_t==_s_t)
                        {
                           CMorphism<string,string> _m;
                           //
                           _m.Morph(_sc.da.domain,_sc.da.codomain,s,ss);
                           
                           _da.Morphisms(_da.Morphisms()+1);
                           _da.Set(_da.Morphisms()-1,_m);
                           
                           _sc.da=_da; _sc.SquareAssert();
                           
                           break;
                        }
                     }
                  }
               }
            }
         }
      }
      
      _da.domain=_sc.da.domain;
      _da.codomain=_sc.da.codomain;
      _sc.da=_da; _sc.SquareAssert();

Deste modo, este será o último passo na definição dos pesos eficazes do par de moedas com base nos eventos do calendário de moedas individuais.


Classificação de eventos do calendário

Ao criar uma tabela de tipos de eventos, pode ser sensato seguir uma metodologia rigorosa que leve em consideração uma massa crítica de dados antes de prosseguir para os tipos de eventos. A classificação de eventos é importante, como mencionado no problema inicial, então uma possível metodologia para classificar esses eventos em tipos comparáveis pode incluir: coleta de dados - a extração básica de dados usando as classes embutidas do MQL5 foi descrita anteriormente. Em seguida, vem a categorização de eventos, onde podemos usar grupos padrão, como índices, indicadores de sentimentos, rendimento de títulos do governo, indicadores de inflação, etc. Isso será seguido pela extração de recursos, já que cada evento será analisado em busca de palavras-chave para determinar a qual grupo ele pertence. Em seguida, vem o treinamento do modelo e a avaliação de nossa classificação de objetos, onde criaremos conjuntos de dados de treinamento e teste e começaremos o treinamento do modelo. A seguir, vem o teste do modelo no conjunto de dados de teste para ver o quão bem ele classifica nossos eventos. E, finalmente, a pós-análise e a melhoria iterativa completarão o processo, examinando maneiras de afinar com precisão nosso modelo sem ajustes excessivos.

Assim que nossos tipos de eventos forem criados, então os preencheremos em nossa tabela de tipos de eventos, conforme mostrado no diagrama acima. Isso significará que a coluna de identificação de tipo de evento na tabela de eventos será atualizada para todos os eventos para atribuí-los a um grupo. Um procedimento armazenado que insira novas linhas ou atualize linhas pode ajudar na implementação do nosso modelo, conforme descrito anteriormente.

Esse acréscimo ao conjunto de eventos significaria que a única alteração significativa em nossa estrutura acima é o homomorfismo de eventos para valores de eventos, já que o tipo de dados do elemento é um array de strings, em que cada índice do array atende a uma coluna de dados. Em vez de incluir apenas valores em que o texto da descrição seja idêntico em diferentes moedas, como "vendas a varejo", agora consideraremos um espectro mais amplo de eventos.


Informação sobre decisões de negociação

Assim, a criação de um domínio de valores a partir de nossa(s) estrutura(s) acima implica que temos valores de pares de moedas com marcação de tempo. Essa marcação de data e hora nos permite comparar o tamanho (e, em alguns casos, a direção) desses valores com possíveis mudanças nos preços. Um processo de análise cuidadoso, envolvendo conjuntos de dados de treinamento e teste, nos permite ver como cada tipo de evento se correlaciona com a possível ação de preço e o quão bem.

Com esses dados de correlação entre valores de eventos e ação de preço subsequente, podemos não apenas estabelecer regras para colocar negociações, abrindo posições longas ou curtas com base nos resultados da análise, mas também determinar o tamanho da posição com base na magnitude da correlação.

A precisão de um sistema que usa valores ponderados de pares de moedas para prever possíveis ações de preço pode ser aprimorada se vários eventos forem agregados em uma média ponderada e, em seguida, esse "indicador" for correlacionado com possíveis ações de preço. Isso levanta a questão de quais pesos são aplicados a qual evento. Essa pergunta pode ser respondida por meio de otimização. O entendimento da macroeconomia por parte do trader também pode orientar esse processo. Independentemente do método escolhido, uma abordagem mais abrangente certamente resultará em previsões mais precisas.


Exemplo: implementação e avaliação no MQL5

Por questões de brevidade, este não será um sistema de negociação completo, mas apenas o início dele, levando em consideração nossa estrutura composta por quatro conjuntos: eventos, tipo, moedas e valores. Obtemos dados do calendário de eventos diretamente, em vez de usar nossa classe de banco de dados, preenchemos uma instância da classe de deslocamento quadrado e calculamos quais homomorfismos podemos gerar. Novamente, isso é apenas um primeiro passo, destinado exclusivamente a demonstrar o potencial. Para este fim, nossos dados de entrada incluem: o tipo de evento no qual nos concentraremos, o peso para a moeda de compra (bid)/margem e o peso para a moeda de venda (ask)/lucro. Como mencionado anteriormente, esses pesos se destinam a combinar os valores do calendário de duas moedas em uma. Para esta pesquisa, consideramos apenas eventos relacionados ao PMI (Índice de Gerentes de Compras) e examinamos apenas as moedas EUR, GBP, USD, CHF e JPY, bem como valores apenas para os pares EURUSD, GBPUSD, USDCHF e USDJPY. Todo o código está incluído no final do artigo. Ao imprimir o homomorfismo das propriedades universais, devemos obter os seguintes registros:

2023.07.11 13:51:52.966 ct_13 (GBPUSD.i,H1) void OnStart() d to a homomorphisms are... 
2023.07.11 13:51:52.966 ct_13 (GBPUSD.i,H1) 
2023.07.11 13:51:52.966 ct_13 (GBPUSD.i,H1) {(EUR,USD,45.85000000,TYPE_PMI),(GBP,USD,47.00000000,TYPE_PMI),(USD,CHF,45.05000000,TYPE_PMI),(USD,JPY,48.75000000,TYPE_PMI)}
2023.07.11 13:51:52.966 ct_13 (GBPUSD.i,H1) |
2023.07.11 13:51:52.966 ct_13 (GBPUSD.i,H1) (EUR,USD,45.85000000,TYPE_PMI)|----->(markit-manufacturing-pmi,EUR,44.60000000,44.60000000,44.80000000,2023.06.01 11:00,TYPE_PMI)
2023.07.11 13:51:52.966 ct_13 (GBPUSD.i,H1) |
2023.07.11 13:51:52.966 ct_13 (GBPUSD.i,H1) {(markit-manufacturing-pmi,EUR,44.60000000,44.60000000,44.80000000,2023.06.01 11:00,TYPE_PMI),(markit-manufacturing-pmi,EUR,44.80000000,44.20000000,43.60000000,2023.06.23 11:00,TYPE_PMI),(markit-services-pmi,EUR,55.90000000,55.90000000,55.10000000,2023.06.05 11:00,TYPE_PMI),(markit-services-pmi,EUR,55.10000000,55.50000000,52.40000000,2023.06.23 11:00,TYPE_PMI),(markit-composite-pmi,EUR,53.30000000,53.30000000,52.80000000,2023.06.05 11:00,TYPE_PMI),(markit-composite-pmi,EUR,52.80000000,53.00000000,50.300000


Com apenas os dados do PMI e as moedas e pares selecionados anteriormente, obtemos apenas um homomorfismo para a moeda de margem, que, neste caso, é o EUR. Nosso valor agregado foi superior ao valor de entrada do EUR simplesmente porque o valor equivalente do PMI para o dólar dos EUA era maior, e o valor impresso para o par EURUSD era apenas uma média ponderada. Neste teste específico, pesos iguais foram usados tanto para o EUR quanto para o USD.


Conclusão

Eu não apresentei um exemplo de como essa classificação pode ser aplicada a um sistema de negociação, pois o artigo ficaria muito longo, mas acredito que este artigo apresente código e material suficientes para que os leitores possam implementar tal aplicação por conta própria. Em resumo, exploramos como a teoria das categorias e os esquemas de bancos de dados podem se combinar e ajudar não apenas na classificação de eventos do calendário, mas também na determinação de composições, como produtos com propriedades universais, que desempenham um papel importante na avaliação quantitativa do impacto de eventos do calendário sobre a ação dos preços.

Uma vantagem disso, além da classificação padrão de eventos que facilita a combinação de valores de pares de moedas, é a utilização do axioma de propriedades universais da teoria das categorias, que auxilia na determinação de homomorfismos que podem ser associados diretamente a partir dos eventos estabelecidos no conjunto de valores de pares de moedas (sem a necessidade de conjuntos angulares de valores de eventos ou moedas). Como mencionado anteriormente, isso permite prever o preço de um par de moedas no caso em que apenas um valor de evento de moeda é novo, enquanto o outro ainda está pendente por vários dias ou semanas.


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

Arquivos anexados |
ct_13.mqh (25 KB)
ct_13.mq5 (22.43 KB)
Aprendendo PrintFormat() e obtendo exemplos prontos para uso Aprendendo PrintFormat() e obtendo exemplos prontos para uso
Este artigo será útil tanto para iniciantes quanto para desenvolvedores experientes. Nele, analisaremos a função PrintFormat(), veremos exemplos de formatação de strings e escreveremos modelos para a exibição de diferentes informações no log do terminal.
Relembrando a antiga estratégia de tendência: dois osciladores estocásticos, MA e Fibonacci Relembrando a antiga estratégia de tendência: dois osciladores estocásticos, MA e Fibonacci
Estratégias de negociação tradicionais. Neste artigo, vamos explorar uma estratégia de acompanhamento de tendências. Essa abordagem é totalmente baseada em análise técnica e faz uso de vários indicadores e ferramentas para gerar sinais e identificar metas de negociação. Os elementos-chave dessa estratégia incluem um oscilador estocástico de 14 períodos, um oscilador estocástico de cinco períodos, uma média móvel de 200 períodos e uma projeção de Fibonacci (para determinar as metas de negociação).
Desenvolvendo um sistema de Replay (Parte 36): Ajeitando as coisas (II) Desenvolvendo um sistema de Replay (Parte 36): Ajeitando as coisas (II)
Uma das coisas que mais pode complicar a nossa vida como programadores é o fato de supor as coisas. Neste artigo mostrarei o perigo de fazer suposições. Tanto na parte da programação em MQL5, onde você supõem que um tipo terá um dado tamanho. Assim como no uso do MetaTrader 5, onde você supõem que servidores diferentes funcionam da mesma forma.
Desenvolvendo um sistema de Replay (Parte 35): Ajeitando as coisas (I) Desenvolvendo um sistema de Replay (Parte 35): Ajeitando as coisas (I)
Temos que corrigir algumas coisas antes de realmente poder continuar. Mas não se trata necessariamente de uma correção e sim de um aperfeiçoamento na forma de gerir e utilizar classe. O motivo é que existem falhas ocorrendo por conta de algum tipo de interação dentro do sistema. Apesar das tentativas de tentar compreender o motivo de algumas das falhas, para assim sana-las. Todas foram frustradas, já que não fazia o mínimo sentido de algumas delas estarem ocorrendo. Quando fazemos uso de ponteiros ou recursão em C / C++, e o programa começa a apresentar falhas.