Discussão do artigo "Ordens, posições e negócios no MetaTrader 5" - página 4

 

Se a função OrderSend retornar true e result.order tiver um tíquete de ordem (result.order!=0), isso garante que a ordem foi aceita pelo corretor e está na guia de negociação ou, nesse estágio, a solicitação é aceita apenas pelo servidor do corretor, mas não pela bolsa?

E a segunda pergunta: pode haver uma situação em que OrderSend retorne true e result.order==0?

 
Aleksey Gunin:

Se a função OrderSend retornar true e result.order tiver um tíquete de ordem (result.order!=0), isso garante que a ordem seja aceita pelo corretor e esteja na guia de negociação ou, nesse estágio, a solicitação é aceita apenas pelo servidor do corretor, mas não pela bolsa?

Garantido.

E a segunda pergunta: pode haver uma situação em que OrderSend retorne true e result.order==0?

Não.

 
fxsaber:

Garantias.

Não.

Outro dia, eles adicionaram um esclarecimento para a função OrderSend, consulte a ajuda on-line.

 
Rashid Umarov:

Há pouco tempo, eles acrescentaram um esclarecimento para a função OrderSend, consulte a ajuda on-line.

Isso se aplica a ordens de mercado?

Cada ordem aceita é armazenada no servidor de negociação, aguardando para ser processada até que ocorra uma das condições para sua execução:

  • expiração,
  • a ocorrência de uma solicitação contrária,
  • acionamento da ordem após o recebimento do preço de execução,
  • recebimento de uma solicitação para cancelar a ordem.
Não há especificação de que o próprio Terminal sempre chame o OrderCheck antes do OrderSendAsync, e o OrderSend é um complemento do OrderSendAsync

Fórum sobre negociação, sistemas de negociação automatizados e teste de estratégias de negociação

Erros típicos e maneiras de eliminá-los ao trabalhar com o ambiente de negociação

fxsaber, 2018.02.20 12:23 pm.

Esquema condicional de implementação do OrderSend padrão (sem tempo limite)
static MqlTradeResult LastResult = {0};

void OnTradeTransaction( const MqlTradeTransaction&, const MqlTradeRequest&, const MqlTradeResult &Result )
{ 
  LastResult = Result;
}

// Algoritmo condicional para implementar o OrderSend padrão
bool OrderSend( const MqlTradeRequest &Request, MqlTradeResult &Result )
{  
  bool Res = OrderSendAsync(Request, Result);
  
  if (Res)
  {
    while (LastResult.request_id != Result.request_id)
      OnTradeTransaction(); // chamada esquemática
          
    Result = LastResult;    
    Res = (Result.retcode == TRADE_RETCODE_PLACED) ||
          (Result.retcode == TRADE_RETCODE_DONE) ||
          (Result.retcode == TRADE_RETCODE_DONE_PARTIAL);

    LastResult.request_id = 0;
  }
    
  return(Res);
}


A partir desse esquema, podemos ver claramente que, ao colocar uma ordem de mercado via OrderSendAsync no mesmo MetaQuotes-Demo, é impossível garantir a captura do evento de colocar a ordem correspondente até que a ordem seja executada ou rejeitada. Ou seja, o MT5 não tem nenhum mecanismo simples para avaliar os resultados intermediários de seu OrderSendAsync.


O OrderSend é executado até que Result.request_id seja igual ao mesmo valor de OrderSendAsync em OnTradeTransaction. Ou ele é encerrado por tempo limite. Portanto, o resultado do OrderSend depende apenas do tipo de mensagem em OnTradeTransaction com o request_id correspondente.

Seria útil saber sobre a formação do próprio request_id. Se entendi corretamente, é um contador de ordens enviadas ao servidor de negociação a partir do momento em que o Terminal/Conta é iniciado/conectado. O próprio Terminal analisa as mensagens recebidas do servidor de negociação e atribui o request_id necessário a apenas uma (o que é duvidoso) ou redefine o request_id para uma determinada mensagem (o mais provável). Esse comportamento tornou possível, há algum tempo, fazer com que o histórico de lances correspondesse à saída do OrderSend. Mas como apenas uma mensagem em OnTradeTransaction é visível com o request_id correto, ocorre a desagradável situação assíncrona da citação acima.

 

Boa tarde, encontrei inconsistências para MqlTradeResult.deal e MqlTradeResult.order

1) Descrição (Manual de Referência MQL5)


2) Negociação em tempo real

Eu coloco ordens a mercado (TRADE_ACTION_DEAL). Emito os valores de MqlTradeResult usando a função Print:


e a transação aparece no registro:

Tentei "adormecer" com a função Sleep por alguns segundos e emitir os dados novamente (quando a transação já estava exatamente feita e a posição estava aberta), mas o número da transação não apareceu.


3) Testador de estratégia

Todos os campos estão preenchidos aqui:



O que causa essas diferenças?

 
Konstantin Kulikov:

Boa tarde, encontrei inconsistências para MqlTradeResult.deal e MqlTradeResult.order




https://www.mql5.com/pt/docs/trading/ordersend

Ao enviar uma ordem a mercado (MqlTradeRequest.action=TRADE_ACTION_DEAL), o resultado bem-sucedido da função OrderSend() não significa que a ordem foi executada (as negociações correspondentes foram executadas): verdadeiro, nesse caso, significa apenas que a ordem foi colocada com sucesso no sistema de negociação para execução posterior. O servidor de negociação pode preencher os valores dos campos de negociação ou de ordem na estrutura de resultados retornada , se esses dados forem de seu conhecimento no momento da formação da resposta à chamada OrderSend(). Em geral, o evento ou eventos de execução de negócios correspondentes à ordem podem ocorrer após o envio da resposta à chamada OrderSend(). Portanto, para qualquer tipo de solicitação de negociação, ao receber o resultado da execução do OrderSend(), é necessário verificar primeiramente o código de retorno do servidor de negociação retcode e o código de resposta do sistema de negociação externo retcode_external (se necessário), que estão disponíveis na estrutura do resultado retornado.


Документация по MQL5: Торговые функции / OrderSend
Документация по MQL5: Торговые функции / OrderSend
  • www.mql5.com
Торговый запрос проходит несколько стадий проверок на торговом сервере. В первую очередь проверяется корректность заполнения всех необходимых полей параметра , и при отсутствии ошибок сервер принимает ордер для дальнейшей обработки. При успешном принятии ордера торговым сервером функция OrderSend() возвращает значение true. Рекомендуется...
 

Obrigado por esse artigo tão informativo. @MetaQuotes

Consulta: Como posso fazer um loop coletivo entre as ordens abertas e as posições abertas em um único loop for() (da mesma forma que fazemos um loop de todas as ordens na MQL4 e depois verificamos se uma ordem já foi executada ou se é uma ordem pendente)?

 
Rahul Dhangar :

Obrigado por esse artigo tão informativo. @MetaQuotes

Consulta: Como posso fazer um loop coletivo entre as ordens abertas e as posições abertas em um único loop for() (da mesma forma que fazemos um loop de todas as ordens na MQL4 e depois verificamos se uma ordem já foi executada ou se é uma ordem pendente)?

Para calcular as POSIÇÕES e as ORDENS PENDENTES, você deve usar dois ciclos independentes. Um ciclo enumera as POSIÇÕES e o segundo ciclo enumera as ORDENS PENDENTES. Exemplo: Calcular posições e ordens pendentes

How to start with MQL5
How to start with MQL5
  • 2020.12.19
  • www.mql5.com
This thread discusses MQL5 code examples. There will be examples of how to get data from indicators, how to program advisors...
 

Sei que vocês não são mesmo de se preocupar com quem está começando na linguagem mql5, visto a comunidade forte que tem, apesar de muitas críticas, aqui vai mais uma:

A tradução e a própria redação do texto atrapalha o entendimento...suei, tive de ir longe para descobrir quem devia vir primeiro, visto que a própria documentação se contradiz, no texto:

  • Histórico de ordens

    Para obter informações sobre uma ordem a partir do histórico, é necessário primeiro criar o cache de histórico de ordens usando uma das três funções: HistorySelect(start, end), HistorySelectByPosition() ou HistoryOrderSelect(ticket). Se a execução for bem sucedida, o cache irá armazenar o número de ordens, retornado pela função HistoryOrdersTotal(). O acesso às propriedades dessas ordens é realizado por cada um dos elementos no bilhete, utilizando a função apropriada:

    1. HistoryOrderGetDouble(ticket_order, type_property)
    2. HistoryOrderGetInteger(ticket_order, type_property)
    3. HistoryOrderGetString(ticket_order, type_property)


Em contraponto com: https://www.mql5.com/pt/docs/trading/historyorderstotal abaixo transcrito.



HistoryOrdersTotal

Retorna o número de ordens no histórico. Antes de chamar HistoryOrdersTotal(), primeiro é necessário receber o histórico de negócios e ordens usando a função HistorySelect() ou a função HistorySelectByPosition().

int  HistoryOrdersTotal();

Valor do Retorno

Valor do tipo double.

Observação

Não confundir ordens de um histórico de negociação com as ordens pendentes que aparecem no separador "Comércio (Trade) da barra de "caixa de ferramentas" (Toolbox). A lista de ordens que foram cancelados ou levaram a uma transação, pode ser visto na aba "Histórico" da "caixa de ferramentas" do terminal do cliente.

Também Veja


No primeiro trecho se contradiz sozinho, não precisa de ajuda, mas o segundo vem e termina de complicar....: afinal, quem vem primeiro, HistoryOrdersTotal ou uma das três funções    HistorySelect(start, end) HistorySelectByPosition() ou HistoryOrderSelect(ticket), ou até mesmo a HistorySelectByPosition(), mencionada no segundo texto.

Foi difícil, poderia ser mais fácil...mas acho que em vem primeiro é uma das três  HistorySelect(start, end) HistorySelectByPosition() ou HistoryOrderSelect(ticket), ou até mesmo a HistorySelectByPosition(), mencionada no segundo texto...

Documentação sobre MQL5: Funções de Negociação / HistoryOrdersTotal
Documentação sobre MQL5: Funções de Negociação / HistoryOrdersTotal
  • www.mql5.com
HistoryOrdersTotal - Funções de Negociação - Referência MQL5 - Referência sobre algorítimo/automatização de negociação na linguagem para MetaTrader 5
 

Boa tarde,
pergunta para os desenvolvedores: vocês podem me dar uma informação aproximada de quanta memória o cache do histórico ocupa? aproximadamente kbytes para uma transação e um pedido.

Executei o script em um terminal com um pequeno histórico e obtive esse resultado:

void OnStart()
  {
   Print("TerminalInfoInteger(TERMINAL_MEMORY_USED) = ", TerminalInfoInteger(TERMINAL_MEMORY_USED));
   if(HistorySelect(0, INT_MAX))
     {
      Print("TerminalInfoInteger(TERMINAL_MEMORY_USED) = ", TerminalInfoInteger(TERMINAL_MEMORY_USED));
      Print("HistoryDealsTotal  = ", HistoryDealsTotal());
      Print("HistoryOrdersTotal = ", HistoryOrdersTotal());
     }
  }

2021.05.14 14:46:41.265	TestCashSize (Si-6.21,H1)	TerminalInfoInteger(TERMINAL_MEMORY_USED) = 488
2021.05.14 14:46:41.285	TestCashSize (Si-6.21,H1)	TerminalInfoInteger(TERMINAL_MEMORY_USED) = 489
2021.05.14 14:46:41.285	TestCashSize (Si-6.21,H1)	HistoryDealsTotal  = 1928
2021.05.14 14:46:41.285	TestCashSize (Si-6.21,H1)	HistoryOrdersTotal = 1116

Isso significa que, com um histórico de alguns milhões de negociações e um milhão de ordens, o cache ocupará cerca de um gigabyte?

E assim para cada programa mql?