Erros típicos e como lidar com eles quando se lida com o ambiente comercial

 
Neste tópico discutiremos os erros comuns cometidos ao trabalhar com o ambiente comercial do terminal em alguns algoritmos, métodos de sua eliminação e evitação no futuro.
 
Certo.
Apenas como uma introdução:
O Expert Advisor analisa a direção (ou lucro, ... ) da última ordem fechada. O último pedido foi fechado há 2 dias.
O comerciante estabeleceu a profundidade da história para 1 dia.
OrdensHistóriaTotal() não vê essa ordem.
A solução?
 
Andrei Fandeev:
Ok.
Apenas como uma introdução:
O Expert Advisor analisa a direção (ou lucro, ... ) da última ordem fechada. O último pedido foi fechado há 2 dias.
E o comerciante fixou a profundidade da história em 1 dia.
OrdensHistóriaTotal() não vê essa ordem.
Solução?

Para o MT4 - em minha opinião, sem ambigüidade, dar ao usuário um aviso ao lançar a EA para usar a profundidade necessária da história.

O MT5 permite carregar o histórico até a profundidade necessária.

 
Artyom Trishkin:

Para o MT4 - em minha opinião, sem ambigüidade, dar ao usuário um aviso ao lançar a EA para usar a profundidade necessária da história.

Confiar no usuário é uma má idéia. É preciso haver um cheque.
Artem, no MT4 eu não encontrei Get por ter o valor da profundidade da história definida.
É realmente impossível obtê-lo de forma programática?

 
Andrei Fandeev:

Confiar no usuário é uma má idéia. Você precisa de um cheque.
Artem, no MT4 eu não consegui encontrar o valor da profundidade da história do conjunto.
É realmente impossível obtê-lo de forma programática?

De fato.

 

Existem dois paradigmas para trabalhar com o ambiente comercial e escrever EAs.

  1. As entradas de eventos (OnTick, OnTimer, etc.) dependem uma da outra. Há informações que DEVEM ter entre eventos (não para velocidade, como cache, mas para usabilidade). Por exemplo, precisamos salvar o resultado do OrderSendAsync e usá-lo na OnTradeTransaction. As caches NÃO são informações obrigatórias e são utilizadas apenas para acelerar. É por isso que não os consideramos de imediato.
  2. As entradas de eventos (OnTick, OnTimer, etc.) NÃO dependem uma da outra. Cada entrada é do zero. Mais ou menos como um Roteiro que você mesmo executa em cada evento.
No MT4 você provavelmente poderia resolver tudo através da segunda opção. O MT5 não é tão claro.


Vantagens da segunda opção sobre a primeira

  • Você pode terminar o algoritmo em qualquer lugar (normal e anormal).
  • Você pode iniciar/continuar o algoritmo em qualquer lugar.
  • Alta confiabilidade.


Desvantagens

  • No Testador será inferior à primeira variante em termos de desempenho.
  • A lógica "do zero" faz você escrever um código um tanto "ilógico", o que leva alguns a se acostumarem no primeiro estágio.

 

Como posso comparar as APIs do ambiente comercial? Introduzir uma grande variedade de TSs diferentes. E vamos imaginar nossa API virtual ideal, que permitiria um esforço mínimo para incorporar o TS em um código confiável.

Se for possível criar esta API virtual ideal como uma embalagem a partir de uma API real, então a API original é excelente. Apesar de todo o esforço e tempo necessários para criar um invólucro.


MT4 e MT5 são excelentes APIs por este critério. Somente as APIs de origem são difíceis, mas permitem (sem restrições arquitetônicas/técnicas) escrever um grande invólucro, e portanto são boas.

Portanto, quando dizem que o MT5 é mais complexo que o MT4 - significam que ainda não encontraram um invólucro MT5 (talvez ainda não tenha sido escrito) que seja tão fácil de usar quanto o MT4 que utilizam.


De modo geral, ambas as plataformas permitem criar um único API (wrapper) de alto nível a partir de APIs de baixo nível. Portanto, a complexidade de seu ambiente comercial APIs é igual!

 

O MT4 tem um API de alto nível, por isso poucas pessoas tentam escrever um invólucro universalmente mais fácil de usar. Mas esse não é o caso do MT5 - a API original de baixo nível apenas EXIGE que se escreva algum tipo de invólucro. Portanto, não há muito sentido em discutir as características de cada embalagem nesta linha. Ao invés disso, é importante mostrar que ainda será necessário um invólucro. Que características de um API de baixo nível precisam ser consideradas ao escrever um API de alto nível.

В общем, обе платформы позволяют из низкоуровневых API создать единый высокоуровневый API (обертка). Так что сложности API торговых окружений у них равны!

Com base nesta afirmação, precisamos aprender a escrever o código MT5 que não é inferior ao código MT4 em termos de usabilidade. Os invólucros API podem ser diferentes (geralmente é a sintaxe), mas arquitetonicamente o MT5 não deve ser inferior ao MT4, caso contrário a afirmação destacada é perdida. Portanto, o código MT5 mais incômodo não deve ser visto como motivo de crítica, mas como uma ajuda para costurá-lo em um invólucro não menos amigável do que o MT4.

 
Vamos tomar um simples MT4-template TS

Fórum sobre comércio, sistemas comerciais automatizados e estratégias comerciais de teste

Organização de um ciclo de pedidos

fxsaber, 2018.02.15 23:19

// Шаблон большинства ТС

#property strict // обязательно

// Сигнал на покупку
bool BuySignal( const string Symb ) { return(true); }

// Сигнал на продажу
bool SellSignal( const string Symb ) { return(false); }

// Находит ордер соответствующего типа
bool OrdersScan( const string Symb, const int Type )
{
  for (int i = OrdersTotal() - 1; i >= 0; i--)
    if (OrderSelect(i, SELECT_BY_POS) && (OrderType() == Type) && (OrderSymbol() == Symb))
      return(true);    
    
  return(false);  
}

// Торговое действие на сигнал
bool Action( const string Symb, const int Type, const double Lots = 1 )
{
  bool Res = true;    
  
  // Закрыли противоположные сигналу позиции
  while ((OrdersScan(Symb, 1 - Type)) && (Res = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 100)));

  // Открыли позицию по сигналу
  return(Res && !OrdersScan(Symb, Type) && OrderSend(Symb, Type, Lots, SymbolInfoDouble(Symb, Type ? SYMBOL_BID : SYMBOL_ASK), 100, 0, 0));
}

// Шаблон торговой стратегии
void Strategy( const string Symb )
{
  if (BuySignal(Symb))
    Action(Symb, OP_BUY);
  else if (SellSignal(Symb))
    Action(Symb, OP_SELL);
}

void OnTick()
{
  Strategy(_Symbol);
}

Ele não mostra nem um pouco a conveniência do MT4, ele apenas serve como ponto de comparação. É essa barra inferior de usabilidade que uma embalagem MT5 deve ser capaz de segurar. O modelo é escrito com base no segundo paradigma.


Parece que escrevemos a mesma coisa no MT5

Fórum sobre comércio, sistemas comerciais automatizados e estratégias comerciais de teste

Organização de um ciclo de transbordo de pedidos

fxsaber, 2018.02.15 22:30

// Шаблон большинства ТС

#include <Trade/Trade.mqh>

// Сигнал на покупку
bool BuySignal( const string Symb ) { return(true); }

// Сигнал на продажу
bool SellSignal( const string Symb ) { return(false); }

// Находит позицию соответствующего типа
bool PositionsScan( const string Symb, const ENUM_POSITION_TYPE Type )
{
  for (int i = PositionsTotal() - 1; i >= 0; i--)
    if ((PositionGetSymbol(i) == Symb) && (PositionGetInteger(POSITION_TYPE) == Type))
      return(true);    
    
  return(false);  
}

// Торговое действие на сигнал
bool Action( const string Symb, const ENUM_POSITION_TYPE Type, const double Lots = 1 )
{
  static CTrade Trade;    
  bool Res = true;    
  
  // Закрыли противоположные сигналу позиции
  while ((PositionsScan(Symb, (ENUM_POSITION_TYPE)(1 - Type))) && (Res = Trade.PositionClose(PositionGetInteger(POSITION_TICKET))));

  // Открыли позицию по сигналу
  return(Res && !PositionsScan(Symb, Type) && (Type ? Trade.Sell(Lots, Symb) : Trade.Buy(Lots, Symb)));
}

// Шаблон торговой стратегии
void Strategy( const string Symb )
{
  if (BuySignal(Symb))
    Action(Symb, POSITION_TYPE_BUY);
  else if (SellSignal(Symb))
    Action(Symb, POSITION_TYPE_SELL);
}

void OnTick()
{
  Strategy(_Symbol);
}

Por alguma razão, algumas pessoas escrevem mais código para o mesmo TS. Mas na verdade, este código também faz bem. A maioria dos TCs requer apenas a escrita BuySignal e SellSignal. Nada mais é necessário.

O modelo de exemplo é escrito especificamente com SB. Então, pergunta aos especialistas do MT5, o código está correto?


A função que mostra a necessidade de invólucro é marcada em vermelho. Seu problema é descrito aqui. Alguém se lembrará que este é o antigo problema de reabertura de posição que foi resolvido usando Sleep em tempos antigos, esperando que a posição fosse aberta após OrderSend. Mas, na verdade, este problema não tem nada a ver com a OrderSend. Você precisa saber como ler corretamente o ambiente comercial.

 
fxsaber:

Você precisa ser capaz de ler corretamente o ambiente comercial.

Fazendo certo com um exemplo simples

// Возвращает количество позиций по символу
int GetAmountPositions( const string Symb )
{
  int Res = 0;
  
  for (int i = PositionsTotal() - 1; i >= 0; i--)
    if (PositionGetSymbol(i) == Symb)
      Res++;
      
  for (int i = OrdersTotal() - 1; i >= 0; i--)
    if (OrderGetTicket(i) && (OrderGetInteger(ORDER_TYPE) <= ORDER_TYPE_SELL) &&
        !OrderGetInteger(ORDER_POSITION_ID) && (OrderGetString(ORDER_SYMBOL) == Symb))
      Res++;  

/*
  for (int i = OrdersTotal() - 1; i >= 0; i--)
    if (OrderSelect(i, SELECT_BY_POS) && (OrderType() <= OP_SELL) && (OrderSymbol() == Symb))
      Res++;
*/      
  return(Res);
}

O ponto em poucas palavras é este: se existe uma ordem de mercado, considere-a também uma "posição". Em citações, porque é uma posição embrulhada. O código destacado geralmente não aparece em nenhum lugar. Mas evita a reabertura de posições. A coisa mais interessante aqui é destacada em vermelho. A necessidade deste chip não é imediatamente aparente.

A questão é que existem as chamadas ordens de fechamento de mercado. O mesmo SL/TP. Obviamente, não gostaríamos de ver tais ordens de mercado como "posições". E não gostaríamos de ver também aqueles pedidos que fizemos para fechar. Portanto, a condição destacada é o filtro apropriado.


ZZZ cole este código aqui e verifique o resultado no servidor de demonstração.

 
fxsaber:

A opção certa usando um exemplo simples

O ponto em poucas palavras é o seguinte: se houver uma ordem de mercado, considere-a também uma "posição". Em citações, porque é uma posição embrulhada. O código destacado geralmente não aparece em nenhum lugar. Mas evita a reabertura de posições. A coisa mais interessante aqui é destacada em vermelho. A necessidade deste chip não é imediatamente aparente.

A questão é que existem as chamadas ordens de fechamento de mercado. O mesmo SL/TP. Obviamente, não gostaríamos de ver tais ordens de mercado como "posições". E não gostaríamos de ver também os pedidos que fizemos para fechar. Portanto, a condição destacada é o filtro apropriado.


HZ cole este código aqui e verifique o resultado no servidor de demonstração.

Pergunta: o que acontecerá se depois de enviar uma ordem de comércio até o próximo tick a ordem de mercado não for colocada pelo servidor?

Razão: