Características úteis da KimIV - página 2

 
Que tal:
if (err===146)
{
while (IsTradeContextBusy())
{
if (IsTradeAllowed()) break;
else
Sleep(1000*1,1);
}}}}
Acho que esta é uma solução mais rápida. Por favor, compartilhe seus comentários.
Obrigado.
 
Red.Line писал (а): Obrigado pelo tópico útil, embora eu seja sobre tortas queimadas, mas ainda assim talvez alguém tenha enfrentado o problema de estocagem e amostragem a partir de grandes conjuntos de dados em µl. µl e bancos de dados? Alguém já pensou nessa direção?
Certamente uma solução simples, mas alguma coisa. https://forum.mql4.com/ru/9377
 
zhuki:
Como você se sentiria em relação a esta variante?
if (err==146)
{
  while (IsTradeContextBusy())
  {
    if (IsTradeAllowed()) break;
    else 
    Sleep(1000*1,1);
  }
}
Esta parece-me ser uma solução mais rápida, trabalho desta forma. Comente.
Obrigado.

Por mim, tudo bem. Com compreensão. A pausa é menor, funciona mais rápido... Mas há alguma redundância injustificada em sua versão.

A função IsTradeContextBusy retorna a bandeira de ocupação do fio comercial. Essa função não existia antes da construção do 195º. Assim, usamos a função IsTradeAllowed que retorna um sinal de que a EA está autorizada a negociar e o fluxo comercial é livre.

Permitimos que a EA negocie, marcando a caixa "Allow EA to trade" na caixa de diálogo de propriedades da EA (tecla F7).

O erro 146 (Trade Stream está ocupado) não tem nada a ver com permitir que o Expert Advisor possa negociar. Portanto, vejamos as propriedades da função IsTradeAllowed na medida em que se relacionam apenas com o fio condutor do comércio.

Portanto, o fio comercial é livre e a função IsTradeAllowed retorna True. O fio comercial está ocupado, a função IsTradeAllowed retorna Falso. Agora vamos ver os valores retornados pela função IsTradeContextBusy. O fio comercial é livre, a função IsTradeContextBusy retorna Falso. O fio comercial está ocupado, a função IsTradeContextBusy retorna True. Podemos ver que para os mesmos estados de fluxo comercial, os valores das funções IsTradeAllowed e IsTradeContextBusy são opostos. Além disso, essas funções se duplicam em vez de se complementarem em relação aos estados de fluxo comercial. Portanto, um deles pode ser excluído. Qual deles? A função IsTradeAllowed, como já mencionei acima, além da bandeira do estado do fluxo comercial, também devolve a bandeira permitindo que a EA negocie o que, nesta situação, ou seja, quando se trata de erro 146 (o fluxo comercial está ocupado), não é necessário para nós. Portanto, será necessário e suficiente utilizar apenas uma função IsTradeContextBusy. Se você executar as abreviações acima, seu código será reduzido ao meu:

if (err==146) while (IsTradeContextBusy()) Sleep(1000*1,1);
com a única diferença sendo o tamanho da pausa. Mas isto é uma questão de gosto, preferência pessoal, estilo comercial e assim por diante. Você poderia fazer uma pausa de 0,1 segundo. Não é um grande problema... Eu só prefiro 11 segundos.
 
Mas, por precisão, ainda prefiro fazer uma pausa entre todos os tipos de operações comerciais de 5 segundos até a liberação do fio. Obrigado.
 

Dois erros foram encontrados na função SetOrder:

  1. Uso incorreto da função MarketInfo. Deveria ter sido chamado DEPOIS de verificar o parâmetro sy, não ANTES de verificar o parâmetro sy.
  2. A correção dos níveis de ajuste do pedido funcionou incorretamente. Além disso, os níveis de preços das paradas e aquisições não foram corrigidos. Agora ele é fixo e funciona perfeitamente. Há muito tempo venho testando esta coisa usando o roteiro de teste que mostrarei um pouco mais tarde.

Atenção! O posto com a função SetOrder para comércio on-line foi corrigido. A função é um pouco mais longa. Não cabia em todo o posto, então teve que ser movido para o trailer.

 

Neste posto decidi dar os principais pontos explicando como funciona a função SetOrder. Eu mesmo não trabalho com ordens, ou seja, estou no território de outra pessoa aqui. Talvez alguém que saiba como funciona a função SetOrder sugira melhorias ou encontre erros.

1. Nas primeiras linhas de código, são declaradas variáveis locais e algumas delas são inicializadas. Por exemplo, em lsComm, o nome da EA e o nome do prazo retornado pela função GetNameTF são escritos. A propósito, não vou me deter em funções como GetNameOP, GetNameTF, Mensagem, etc., somente se alguém tiver perguntas sobre elas.

string   lsComm=WindowExpertName()+" "+GetNameTF(Period());

2. Verificação dos parâmetros recebidos. Se o sy estiver vazio, ele é inicializado com o nome da ferramenta atual. A variável para a cor do ícone na tabela é rubricada pelo tipo de operação. Se o tempo de expiração não zero do pedido for menor que o tempo atual, ele é reposto a zero.

if (sy=="" || sy=="0") sy=Symbol();
msl=MarketInfo(sy, MODE_STOPLEVEL);
if (op==OP_BUYLIMIT || op==OP_BUYSTOP) clOpen=clOpenBuy; else clOpen=clOpenSell;
if (ex>0 && ex<TimeCurrent()) ex=0;

3. O corpo do ciclo de tentativas de negociação, cujo número é limitado pelo valor da variável global NumberOfTry. As operações realizadas dentro do laço principal da função SetOrder vão mais longe.

for (it=1; it<=NumberOfTry; it++)

4. Se a função SetOrder não for executada no testador, temos a oportunidade de encerrar sua operação. A espera pelo ciclo de liberação do fluxo comercial é realizada aqui. As variáveis do ambiente de mercado são atualizadas e a hora atual é registrada.

if (!IsTesting() && (!IsExpertEnabled() || IsStopped())) {
  Print("SetOrder(): Остановка работы функции");
  break;
}
while (!IsTradeAllowed()) Sleep(5000);
RefreshRates();
ot=TimeCurrent();

5. Envio de um pedido a um servidor comercial. Se o bilhete for positivo, a função SetOrder é encerrada.

ticket=OrderSend(sy, op, ll, pp, Slippage, sl, tp, lsComm, mn, ex, clOpen);
if (ticket>0) {
  if (UseSound) PlaySound(NameFileSound); break;
 

6. Se o bilhete for negativo, o processamento dos erros de execução é realizado.
7. No caso de erros 128 (o tempo de espera para a execução do negócio expirou), 142 (a ordem é enfileirada) e 143 (a ordem é aceita pelo revendedor para execução), fazemos uma pausa de 66 segundos. Após a pausa, usando a função ExistOrders (que descreveremos mais tarde), verificamos se a ordem já foi definida durante o período de tempo entre o pedido do servidor e o momento atual. Se a ordem tiver sido definida, saia da função.

err=GetLastError();
if (err==128 || err==142 || err==143) {
  Sleep(1000*66);
  if (ExistOrders(sy, op, mn, ot)) {
    if (UseSound) PlaySound(NameFileSound); break;
  }
  Print("Error(",err,") set order: ",ErrorDescription(err),", try ",it);
  continue;
}

8. O tamanho do item e os preços Bid and Ask são armazenados nas variáveis locais.

mp=MarketInfo(sy, MODE_POINT);
pa=MarketInfo(sy, MODE_ASK);
pb=MarketInfo(sy, MODE_BID);

9. Em caso de erro 130 (Paradas incorretas), os níveis de preço do pedido, parar e retirar são corrigidos, se possível.

// Неправильные стопы
if (err==130) {
  switch (op) {
    case OP_BUYLIMIT:
      if (pp>pa-msl*mp) pp=pa-msl*mp;
      if (sl>pp-(msl+1)*mp) sl=pp-(msl+1)*mp;
      if (tp>0 && tp<pp+(msl+1)*mp) tp=pp+(msl+1)*mp;
      break;
    case OP_BUYSTOP:
      if (pp<pa+(msl+1)*mp) pp=pa+(msl+1)*mp;
      if (sl>pp-(msl+1)*mp) sl=pp-(msl+1)*mp;
      if (tp>0 && tp<pp+(msl+1)*mp) tp=pp+(msl+1)*mp;
      break;
    case OP_SELLLIMIT:
      if (pp<pb+msl*mp) pp=pb+msl*mp;
      if (sl>0 && sl<pp+(msl+1)*mp) sl=pp+(msl+1)*mp;
      if (tp>pp-(msl+1)*mp) tp=pp-(msl+1)*mp;
      break;
    case OP_SELLSTOP:
      if (pp>pb-msl*mp) pp=pb-msl*mp;
      if (sl>0 && sl<pp+(msl+1)*mp) sl=pp+(msl+1)*mp;
      if (tp>pp-(msl+1)*mp) tp=pp-(msl+1)*mp;
      break;
  }
  Print("SetOrder(): Скорректированы ценовые уровни");
}

10. As informações que podem ajudar a resolver o problema ou a encontrar o erro mais tarde são exibidas no relatório.

Print("Error(",err,") set order: ",ErrorDescription(err),", try ",it);
Print("Ask=",pa,"  Bid=",pb,"  sy=",sy,"  ll=",ll,"  op=",GetNameOP(op),
      "  pp=",pp,"  sl=",sl,"  tp=",tp,"  mn=",mn);
if (pa==0 && pb==0) Message("SetOrder(): Проверьте в обзоре рынка наличие символа "+sy);

No final, processamos outros erros. Alguns deles mostram uma longa pausa (5 minutos), outros bloqueiam o Expert Advisor, outros permitem novas tentativas de comércio, etc.

É isso aí! Fim da descrição!

 

A função ExistOrders().

Devolve uma bandeira para a existência de uma ordem. Responde à pergunta se a ordem está definida ou não. Você pode usar esta função para solicitar qualquer pedido, bem como pedidos mais específicos. O filtro de solicitação é configurado utilizando os parâmetros da função:

  • sy - Impõe uma restrição ao nome do instrumento. O parâmetro padrão é "" - sem restrições, ou seja, qualquer instrumento. Se você aprovar o NULL, a seleção do pedido será limitada pelo símbolo atual.
  • op - coloca uma restrição sobre o tipo de pedido. Nenhuma restrição por padrão, ou seja, qualquer tipo de pedido é verificado. Os valores válidos do parâmetro são -1, OP_BUYLIMIT, OP_BUYSTOP, OP_SELLLIMIT e OP_SELLSTOP.
  • mn - coloca um limite no número de identificação ("mágico") do pedido. Nenhuma restrição por padrão, ou seja, a ordem com qualquer número mágico é verificada.
  • ot - coloca um limite no tempo de estabelecimento do pedido. É verificado para garantir que a ordem foi definida mais tarde do que o valor deste parâmetro. Por padrão, não há limite, ou seja, uma ordem com qualquer tempo de ajuste é verificada.
//+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. aka KimIV,  http://www.kimiv.ru                   |
//+----------------------------------------------------------------------------+
//|  Версия   : 12.03.2008                                                     |
//|  Описание : Возвращает флаг существования ордеров.                         |
//+----------------------------------------------------------------------------+
//|  Параметры:                                                                |
//|    sy - наименование инструмента   (""   - любой символ,                   |
//|                                     NULL - текущий символ)                 |
//|    op - операция                   (-1   - любой ордер)                    |
//|    mn - MagicNumber                (-1   - любой магик)                    |
//|    ot - время открытия             ( 0   - любое время установки)          |
//+----------------------------------------------------------------------------+
bool ExistOrders(string sy="", int op=-1, int mn=-1, datetime ot=0) {
  int i, k=OrdersTotal(), ty;
 
  if (sy=="0") sy=Symbol();
  for (i=0; i<k; i++) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
      ty=OrderType();
      if (ty>1 && ty<6) {
        if ((OrderSymbol()==sy || sy=="") && (op<0 || ty==op)) {
          if (mn<0 || OrderMagicNumber()==mn) {
            if (ot<=OrderOpenTime()) return(True);
          }
        }
      }
    }
  }
  return(False);
}
 

Exemplos de como usar a função ExistOrders().

1. Verifique a disponibilidade de qualquer pedido

ExistOrders();

2. Verificar a disponibilidade de qualquer pedido em qualquer instrumento da tabela atual

ExistOrders(NULL);

3. Verifique a presença do pedido BuyLimit em qualquer instrumento

ExistOrders("", OP_BUYLIMIT);

4. Verifique se há um pedido SellStop com o número mágico 123456 em EURUSD

ExistOrders("EURUSD", OP_SELLSTOP, 123456);

5. Verificar a disponibilidade de qualquer pedido com um tempo de preparação de 2 horas ou menos

ExistOrders("", -1, -1, TimeCurrent()-2*60*60);
No trailer há um roteiro para testar a função ExistOrders. Os 4 primeiros exemplos no roteiro são comentados.

Arquivos anexados:
 

Advertência! No correio de 12.03.2008 07:24 substituí o anexo SetOrder.mq4

Razão: