English Русский 中文 Español Deutsch 日本語
Expert Advisor multiplataforma: Ordens

Expert Advisor multiplataforma: Ordens

MetaTrader 5Integração | 3 outubro 2016, 10:19
1 788 0
Enrico Lambino
Enrico Lambino


Tabela de conteúdos


Introdução

MetaTrader 4 e MetaTrader 5 usam regras diferentes para o processamento de pedidos de negociação. Este artigo discute a possibilidade de utilizar um objeto de classe que representa as transações processadas pelo servidor, graças a isso o Expert Advisor poderá trabalhar com elas independentemente da versão da plataforma de negociação e o modo usado.

Condições

Existem muitas diferenças em como a MetaTrader 4 e a MetaTrader 5 processam os pedidos a partir do terminal. Ao discutir os detalhes do processamento -feito pelos servidores- dos pedidos de negociação, devemos considerar três modos diferentes em ambas as plataformas de negociação: (1) MetaTrader 4, (2) modo "compensação# na MetaTrader 5 e (3) modo "cobertura" na MetaTrader 5.

MetaTrader 4

Na MetaTrader 4, quando o EA envia com sucesso uma ordem, ele obtém um número de bilhete que se torna seu identificador numérico. Quando a ordem se fecha ou altera, esse mesmo bilhete se usa até você sair do mercado.

Uma situação mais complexa surge quando a ordem é fechada parcialmente. Esta operação é executada usando a função OrderClose e indicando os lotes inferiores ao tamanho do lote total no pedido. Quando um pedido desse tipo é enviado, a ordem é fechada por uma certa dimensão do tamanho de lote especificado na chamada de função. Após isso, o volume do lote restante permanecerá no mercado como uma nova ordem do mesmo tipo da parcialmente fechada. Como a função OrderClose apenas retorna a variável lógica, não há outras maneiras rápidas para obter um novo bilhete, exceto revisar a lista de pedidos que estão atualmente ativos na conta. Observe que você não pode obter um novo bilhete usando apenas a função OrderClose. A função retorna uma variável booleana, enquanto as funções semelhantes à função OrderSend, na MQL4, retornam um bilhete válido após uma operação bem-sucedida.

MetaTrader 5 (compensação)

O processamento de transações de negociação na MetaTrader 5, à primeira vista, parece muito complicada, mas é muito mais fácil de usar do que na MetaTrader 4. Na verdade, esta afirmação é verdadeira para o trader, mas não para o programador.

O modo padrão na MetaTrader 5 usa compensação. Neste modo, os resultados do processamento das ordens no servidor são consolidados numa posição única. O volume deste tipo particular de posição pode mudar, ao longo do tempo, com base no volume e tipos de ordens abertas. Do ponto de vista do programador, é um pouco difícil. Em contraste com a MQL4 onde há apenas um conceito de ordens, o programador terá que lidar com três entidades diferentes usadas na negociação. A tabela a seguir mostra uma comparação entre o modo de compensação em MQL5 e seu equivalente aproximado em MQL4:

 Artifact
 MQL5 (Compensação)
MQL4 (Equivalente aproximado)
OrdemPedido de negociação (pendente ou de mercado)Pedido de negociação (pendente ou de mercado)
 Operação As transações são feitas com base numa ordem quer de mercado quer pendente  Única ordem de mercado reflectida no terminal de negociação
 Posição Transações (combinadas) Soma de todas as ordens de mercado no terminal de negociação (tipos de ordem)

Em MQL5, após a execução, as ordens ficam inalteradas no lado do cliente, enquanto, em MQL4, algumas propriedades das ordens poderão ser alteradas, mesmo quando elas já estão no mercado. Ou seja, no primeiro caso, a ordem é simplesmente um pedido de negociação enviado para o servidor. No segundo caso, ela pode ser usada para representar o pedido do negociação, bem como o resultado de um pedido semelhante. Neste aspecto, em MQL5 é complicado tornar todo o processo menos ambíguo, porque há uma diferença óbvia entre o pedido de negociação e o resultado de negociação. Em MQL4, ao entrar e sair do mercado, a ordem pode ter diferentes parâmetros, enquanto em MQL5 pode ser monitorada dependendo do tipo de execução de ordem o pedido de negociação foi concluída a operação.

Se o pedido de negociação for enviado, existem apenas dois resultados: ele é processado ou não processado. Se a operação não for processada, o servidor não conseguirá processar o pedido por algum motivo (geralmente devido a erros). E, ao contrário, se a operação for processada, em MQL5, a transação será confirmada entre o cliente e o servidor. Neste caso, a ordem pode ser executada, por completo ou em parte.

Na MetaTrader 4 não existe essa opção, já que a ordem é totalmente executada ou não executada(fill or kill).

Uma das principais desvantagens deste modo na MetaTrader 5 é que não permite que você use a cobertura. O tipo de posição nesse instrumento pode variar. Por exemplo, se você tiver uma posição longa com um volume de 0,1 lotes e for levada a cabo uma operação de venda de 1 lote, no final, será transformada esta última numa posição com volume de 0.9 lotes.

MetaTrader 5 (Cobertura)

Na MetaTrader 5, o modo de cobertura assemelha-se ao modo usado na MetaTrader 4. Em vez de combinar todas as operações processadas em uma posição única, o modo de cobertura permite que você tenha mais de uma posição no símbolo. A posição é gerada sempre que a ordem pendente é acionada ou o pedido de negociação é processado no servidor de negociação.

Artifact
MQL5 (Compensação)
MQL4 (Equivalente aproximado)
OrdemPedido de negociação (pendente ou de mercado)Pedido de negociação (pendente ou de mercado)
OperaçõesAs operações são feitas com base numa ordem únicaAs ordens de mercado são refletidas no terminal de negociação
PosiçãoAs operações (combinadas) são baseadas num pedido único de negociação.A ordem é exibida no terminal de negociação

Para adaptar o Expert Advisor multiplataforma a essas diferenças, uma possível solução seria ter um EA que armazene informações sobre transações individuais colocadas por ele no mercado. Cada vez que uma transação é concluída, é armazenada uma cópia das informações da ordem num objeto de classe COrder. O código a seguir mostra a declaração de sua classe base:

class COrderBase : public CObject
  {
protected:
   bool              m_closed;
   bool              m_suspend;
   long              m_order_flags;
   int               m_magic;
   double            m_price;
   ulong             m_ticket;
   ENUM_ORDER_TYPE   m_type;
   double            m_volume;
   double            m_volume_initial;
   string            m_symbol;
public:
                     COrderBase(void);
                    ~COrderBase(void);
   //--- getters and setters     
   void              IsClosed(const bool);
   bool              IsClosed(void) const;
   void              IsSuspended(const bool);
   bool              IsSuspended(void) const;
   void              Magic(const int);
   int               Magic(void) const;
   void              Price(const double);
   double            Price(void) const;
   void              OrderType(const ENUM_ORDER_TYPE);
   ENUM_ORDER_TYPE   OrderType(void) const;
   void              Symbol(const string);
   string            Symbol(void) const;
   void              Ticket(const ulong);
   ulong             Ticket(void) const;
   void              Volume(const double);
   double            Volume(void) const;
   void              VolumeInitial(const double);
   double            VolumeInitial(void) const;
   //--- output
   virtual string    OrderTypeToString(void) const;
   //--- static methods
   static bool       IsOrderTypeLong(const ENUM_ORDER_TYPE);
   static bool       IsOrderTypeShort(const ENUM_ORDER_TYPE);
  };

Como o EA se lembra de suas negociações, ele pode trabalhar independentemente das políticas de negociação utilizadas pela plataforma em execução. No entanto, sua desvantagem é que as instâncias dessa classe serão mantidas apenas durante a atividade do Expert Advisor. Se o Expert Advisor ou a plataforma em si estiver sujeito a reinicialização, todos os dados salvos serão perdidos a menos que você encontre maneiras de salvar e carregar as informações.

ID de transação (bilhete)

Outro possível obstáculo ao utilizar instâncias COrder na criação do Expert Advisor multiplataforma pode ser a maneira de salvar o bilhete da ordem (ou posição). As diferenças são coletadas na tabela a seguir:

Operação
 MQL4MQL5 (Compensação)
 MQL5 (Cobertura)
Envio de ordensBilhete da nova ordem
Novo bilhete de posição (para recém-aberta) ou bilhete de uma posição existente (uma posição que já existe).
Bilhete da nova posição
Fechamento parcialBilhete da nova ordem
O mesmo bilhete (se houver um restante), caso contrário, N/A
O mesmo bilhete

Ao enviar a ordem todas as três versões têm caminhos diferentes de exibir a transação. Em MQL4, quando o pedido de negociação é bem-sucedido, será aberta uma nova ordem. Esta nova ordem será exibida sob a forma de identificador (bilhete da ordem). No modo de compensação, em MQL5, todos os pedidos de negociação para entrada no mercado são apresentados pelo bilhete da ordem. Ele pode ser a melhor maneira de exibir a posição final. A razão é que, ao contrário da MQL4, o bilhete da ordem não pode ser diretamente usado para trabalhos futuros com a negociação final -com a qual o Expert Advisor entrou no mercado-. No entanto, o recibo do número de bilhete pode ser útil em casos quando é necessário obter a posição formada como resultado de uma ordem específica. Além disso, quando há uma posição atual do mesmo tipo, o bilhete da posição permanecerá igual (ao contrário de MQL4). Por outro lado, no modo de cobertura de MQL5, cada nova transação cria uma nova posição (equivalente ordinário do bilhete da ordem em MQL4). A diferença em MQL4 é que o resultado de um pedido de negociação será sempre uma ordem, enquanto em MQL5 (no modo de cobertura) é possível obter mais de uma transação (se as políticas de execução especificadas não são SYMBOL_FILLING_FOK).

Há um outro problema relacionado com o fechamento parcial de uma ordem de mercado (em MQL4) ou posição (em MQL5). Como mencionado anteriormente, em MQL4, quando um bilhete específico é fechado parcialmente (OrderLots), o bilhete, que representa a operação, é fechado, e ao volume remanescente é atribuído um novo tipo de bilhete do mesmo tipo do parcialmente fechado. Em MQL5 é um pouco diferente. No modo de compensação, para fechar a posição (total ou parcialmente), deve ocorrer uma operação no sentido oposto (vender, comprar ou vender para comprar). No modo de compensação, o processo é mais semelhante à MQL4 (OrderClose contra PositionClose em CTrade), mas, ao contrário da MQL4, o fechamento de posição parcial não causa quaisquer alterações do identificador que representa.

Uma solução para este problema consiste em quebrar a implementação da representação dos identificadores de determinadas transações nas duas plataformas. Como o bilhete da ordem é alterado na MetaTrader 5, nós simplesmente podemos atribuir a ele uma variável numérica típica. Para MetaTrader 4 usaremos uma instância da classe CArrayInt para armazenar os números de bilhete. Para COrderBase (e, portanto, para MQL5 COrder), usaremos o seguinte código de método Ticket:

COrderBase::Ticket(const ulong value)
  {
   m_ticket=value;
  }

Em MQL4, esse método é substituído pelo seguinte código:

COrder::Ticket(const ulong ticket)
  {
   m_ticket_current.InsertSort((int)ticket);   
  }

Estado

No EA multiplataforma, para as ordens, são possíveis, pelo menos, duas condições:

  • Fechado

  • Suspenso

São muito semelhantes, mas há uma diferença fundamental entre elas. O estado fechado mostra que a ordem já está fechada, e a EA deve arquivá-la em seus dados internos. O equivalente ordinário deste processo em MQL4 é o envio de ordens para o histórico. O estado suspenso indica apenas que o EA não conseguiu fechar a ordem ou uma das ordens stop associadas a ele. Neste caso, o Expert Advisor pode tentar fechar a ordem (e seu stop) até que esteja completamente fechada.

Volume

Em MQL4, o cálculo de volume acontece de maneira simples. Sempre que o Expert Advisor envia um pedido de negociação, ele também inclui o volume. Nesse sentido, este pedido será rejeitado ou aceite. Isto é equivalente á política de execução, Fill or Kill (FOK) em MQL5, que é a configuração padrão para objetos de negociação (CTrade e CExpertTrade). Receber funções gerais pode nos dar exatamente esta política. Para tornar o processamento de volume compatível entre MQL4 e MQL5, uma forma seria obter o volume da instância do volume COrder com base no volume do pedido de negociação. Isto significa que, na versão MQL5, devemos adotar a política FOK. Você pode usar outras políticas de execução, mas os resultados serão ligeiramente diferentes (ou seja, o número de instâncias COrder, em MQL5, no teste do mesmo EA, pode ser maior).

Repositório de ordens

Se o Expert Advisor lida com mais de uma instância COrder, pode ser necessário algum método de organização. Uma das classes, que podem ajudar nisto, é o repositório de ordens ou COrders. A classe é herdada da CArrayObj e mantém as instâncias COrder. Ela faz com que seja fácil o armazenamento e busca das operações realizadas pelos Expert Advisors. O principal modelo para a classe anterior é mostrado abaixo:

#include <Arrays\ArrayObj.mqh>
#include "OrderBase.mqh"
class CExpertAdvisor;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class COrdersBase : public CArrayObj
  {
public:
                     COrdersBase(void);
                    ~COrdersBase(void);
   virtual bool      NewOrder(const ulong,const string,const int,const ENUM_ORDER_TYPE,const double,const double);
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
COrdersBase::COrdersBase(void)
  {
   if(!IsSorted())
      Sort();
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
COrdersBase::~COrdersBase(void)
  {
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool COrdersBase::NewOrder(const ulong ticket,const string symbol,const int magic,const ENUM_ORDER_TYPE type,const double volume,const double price)
  {
   COrder *order=new COrder(ticket,symbol,type,volume,price);
   if(CheckPointer(order)==POINTER_DYNAMIC)
      if(InsertSort(GetPointer(order)))
         order.Magic(magic);
   return false;
  }
//+------------------------------------------------------------------+
#ifdef __MQL5__
#include "..\..\MQL5\Order\Orders.mqh"
#else
#include "..\..\MQL4\Order\Orders.mqh"
#endif
//+------------------------------------------------------------------+

Como sua função principal é armazenar instâncias da classe COrder, ele deve ter maneiras de adicionar essas instâncias da classe especificada. Por padrão, para isso, usa-se o método Add da classe CArrayObj. No entanto, não é sempre ideal, porque a instância COrder requer criar uma instância. Para fazer isso, nós podemos ter o método NewOrder para criar nova instância da classe COrder e automaticamente adiciona-la como um elemento de uma matriz:

bool COrdersBase::NewOrder(const ulong ticket,const string symbol,const int magic,const ENUM_ORDER_TYPE type,const double volume,const double price)
  {
   COrder *order=new COrder(ticket,symbol,type,volume,price);
   if(CheckPointer(order)==POINTER_DYNAMIC)
      if(InsertSort(GetPointer(order)))
         order.Magic(magic);
   return false;
  }

Agora, após criado o modelo principal, a esta classe podem ser adicionados outros métodos. Um exemplo é o método OnTick. Neste método, a classe de armazenamento (contêiner) passará apenas pelos itens que estão armazenados nela. Outra possibilidade é fazer com que a classe COrder também contenha o método OnTick. Depois disso, ele pode ser codificado de tal forma que este método na COrders seja chamado em cada tick.

Exemplo

Nosso código de exemplo irá tentar abrir uma posição longa. Depois da posição entrar no mercado, as informações de transação serão então armazenadas na instância COrder. Isso é feito chamando o método NewOrder da classe COrders (sua missão é criar uma instância COrder).

Ambas as versões usarão as instâncias de objeto de negociação (CExpertTradeX), objeto de ordem (COrders) e caractere de objeto. (CSymbolInfo). No manipulador OnTick do Expert Advisor, o objeto de negociação tenta entrar numa posição longa usando o método Buy. A única diferença entre as duas versões (MQL4 e MQL5) é como são extraídas as informações sobre as transações. Em MQL5, os detalhes das transações são obtidas usando HistoryOrderSelect e outras funções relacionadas. O bilhete de ordem é obtido usando o método ResultOrder do objeto de negociação. A implementação desta versão é mostrada abaixo:

ulong retcode=trade.ResultRetcode();
ulong order = trade.ResultOrder();
 if(retcode==TRADE_RETCODE_DONE)
 {
  if(HistoryOrderSelect(order))
  {
   ulong ticket=HistoryOrderGetInteger(order,ORDER_TICKET);
   ulong magic=HistoryOrderGetInteger(order,ORDER_MAGIC);
   string symbol = HistoryOrderGetString(order,ORDER_SYMBOL);
   double volume = HistoryOrderGetDouble(order,ORDER_VOLUME_INITIAL);
   double price=HistoryOrderGetDouble(order,ORDER_PRICE_OPEN);
   ENUM_ORDER_TYPE order_type=(ENUM_ORDER_TYPE)HistoryOrderGetInteger(order,ORDER_TYPE);
   orders.NewOrder((int)ticket,symbol,(int)magic,order_type,volume,price);
  }
 }

O objeto de negociação em MQL4 tem menos funções do que em MQL5. Você pode expandir um objeto de negociação para esta versão ou simplesmente iterar todas as ordens ativas na conta para obter a ordem recém-aberta:

for(int i=0;i<OrdersTotal();i++)
{
 if(!OrderSelect(i,SELECT_BY_POS))
  continue;
 if(OrderMagicNumber()==12345)
  orders.NewOrder(OrderTicket(),OrderSymbol(),OrderMagicNumber(),(ENUM_ORDER_TYPE)OrderType(),OrderLots(),OrderOpenPrice());
}

O código completo para o arquivo de cabeçalho principal é mostrado abaixo:

(test_orders.mqh)

#include <MQLx-Orders\Base\Trade\ExpertTradeXBase.mqh>
#include <MQLx-Orders\Base\Order\OrdersBase.mqh>
CExpertTradeX trade;
COrders orders;
CSymbolInfo symbolinfo;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   if(!symbolinfo.Name(Symbol()))
     {
      Print("failed to initialize symbol");
      return INIT_FAILED;
     }
   trade.SetSymbol(GetPointer(symbolinfo));
   trade.SetExpertMagicNumber(12345);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   if(!symbolinfo.RefreshRates())
   {
      Print("cannot refresh symbol");
      return;
   }   
   if(trade.Buy(1.0,symbolinfo.Ask(),0,0))
     {
#ifdef __MQL5__
      int retcode=trade.ResultRetCode();
      ulong order = trade.ResultOrder();
      if(retcode==TRADE_RETCODE_DONE)
        {
         if(HistoryOrderSelect(order))
           {
            ulong ticket=HistoryOrderGetInteger(order,ORDER_TICKET);;
            ulong magic=HistoryOrderGetInteger(order,ORDER_MAGIC);
            string symbol = HistoryOrderGetString(order,ORDER_SYMBOL);
            double volume = HistoryOrderGetDouble(order,ORDER_VOLUME_INITIAL);
            double price=HistoryOrderGetDouble(order,ORDER_PRICE_OPEN);
            ENUM_ORDER_TYPE order_type=order_type;
            m_orders.NewOrder((int)ticket,symbol,(int)magic,order_type,volume,price);
           }
        }
#else
      for(int i=0;i<OrdersTotal();i++)
        {
         if(!OrderSelect(i,SELECT_BY_POS))
            continue;
         if(OrderMagicNumber()==12345)
            orders.NewOrder(OrderTicket(),OrderSymbol(),OrderMagicNumber(),(ENUM_ORDER_TYPE)OrderType(),OrderLots(),OrderOpenPrice());
        }
#endif
     }
   Sleep(5000);
   ExpertRemove();
  }
//+------------------------------------------------------------------+


O arquivo de cabeçalho contém todo o código necessário. Assim, os arquivos fonte básicos precisam ter pelo menos a diretiva de pré-processador para habilitar test_orders.mqh:

(test_orders.mq4 e test_orders.mq5)

#include "test_orders.mqh"

A execução do Expert Advisor nas plataformas dá as seguintes entradas no log.

MetaTrader 4:

Expert test_orders EURUSD,H1: loaded successfully
test_orders EURUSD,H1: initialized
test_orders EURUSD,H1: open #125001338 buy 1.00 EURUSD at 1.10684 ok
test_orders EURUSD,H1: ExpertRemove function called
test_orders EURUSD,H1: uninit reason 0
Expert test_orders EURUSD,H1: removed

As imagens a seguir mostram, como funciona o Expert Advisor na plataforma. Observe que como o Expert Advisor chama a função ExpertRemove, ele é excluído automaticamente do gráfico no final da execução do código (apenas uma única execução do manipulador OnTick). 

Na MetaTrader 5, é gerado quase o mesmo arquivo de log:

Experts    expert test_orders (EURUSD,M1) loaded successfully
Trades    '3681006': instant buy 1.00 EURUSD at 1.10669 (deviation: 10)
Trades    '3681006': accepted instant buy 1.00 EURUSD at 1.10669 (deviation: 10)
Trades    '3681006': deal #75334196 buy 1.00 EURUSD at 1.10669 done (based on order #90114599)
Trades    '3681006': order #90114599 buy 1.00 / 1.00 EURUSD at 1.10669 done in 275 ms
Experts    expert test_orders (EURUSD,M1) removed

Ao contrário da MetaTrader 4, as mensagens de log são encontradas na guia "diário" da janela "Terminal" e não na guia "Experts".

O Expert Advisor também imprime uma mensagem ma guia "Experts". No entanto, isto não é uma mensagem sobre a execução de uma transação: ela apenas informa que a chamada da função ExpertRemove foi realizada.

Expansão

Nossa implementação atual não possui algumas funções que são frequentemente usadas em Expert Advisors reais, tais como, por exemplo:

1. Stop loss e take profit fonte para transações.

2. Modificação dos níveis stop (por exemplo, break-even, trailing stop loss ou qualquer método definido pelo usuário).

3. Armazenamento de dados: existem diferenças em como as plataformas armazenam informações sobre as transações e seus níveis de stop loss. Nosso objeto de classe combina métodos de ambas as plataformas, mas armazena apenas na memória. Assim, precisamos de um método para fazer o armazenamento de dados mais permanente. Ou seja, para nossos Expert Advisors, é necessário um método para armazenar e baixar informações sobre ordens depois de reiniciar o terminal ou ao alternar os gráficos em que ainda está em execução o expert advisor multiplataforma. Esses métodos serão cobertos em futuros artigos.

Conclusão

Neste artigo, discutimos um método pelo qual o Expert Advisor multiplataforma obtém a chance de armazenar os detalhes das transações processadas com êxito pelo servidor de negociação. Este método é armazenado como uma instância do objeto de classe. Esta instância de objeto também pode ser usada por um Expert Advisor para continuar o trabalho sobre a estratégia escolhida. Para essa classe de objeto foi desenvolvido o modelo principal, que, por sua vez, é possível refinar para uso em estratégias de negociação mais complexas.

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

Arquivos anexados |
Orders.zip (208.87 KB)
Estudando a Classe CCanvas. Anti-aliasing e Sombras Estudando a Classe CCanvas. Anti-aliasing e Sombras
Um algoritmo anti-aliasing da classe CCanvas é a base para todas as construções onde o antisserrilhamento está sendo usado. O artigo contém informações sobre como este algoritmo opera e fornece exemplos relevantes de visualização. Ele também abrange as sombras desenhadas dos objetos gráficos e tem um algoritmo detalhadamente desenvolvido para desenhar sombras nas canvas. A análise numérica da biblioteca ALGLIB é usada para os cálculos.
Interfaces Gráficas VI: Os Controles Deslizante e Deslizante Duplo (Capítulo 2) Interfaces Gráficas VI: Os Controles Deslizante e Deslizante Duplo (Capítulo 2)
No artigo anterior, nós enriquecemos a nossa biblioteca com quatro controles que são frequentemente usados ​​nas interfaces gráficas: caixa de seleção, campo de edição, campo de edição com caixa de seleção e a lista combinada com a caixa de seleção. O segundo capítulo da sexta parte será dedicado aos controles deslizante e deslizante duplo.
Trabalhando Com Soquetes em MQL, ou como se tornar um provedor de sinal Trabalhando Com Soquetes em MQL, ou como se tornar um provedor de sinal
Soquetes… O que seria do nosso mundo de TI sem eles? Datado por volta de 1982 e até o presente momento, pouco mudou, eles continuam trabalhando para nós a cada momento. Esta é a base da rede, as terminações nervosas da Matriz que todos nós vivemos.
Expert Advisor multiplataforma: reutilização de componentes a partir da Biblioteca padrão MQL5 Expert Advisor multiplataforma: reutilização de componentes a partir da Biblioteca padrão MQL5
Na biblioteca padrão MQL5, existem alguns componentes que podem ser úteis em versões de EAs MQL4 multiplataforma. Este artigo descreve um método para a criação de alguns componentes da biblioteca padrão MQL5 compatíveis com o compilador MQL4.