Tiki em tempo real - página 14

 
Roman:

Eu não utilizo o comércio forex.
Você, no exemplo doCopyTick, recebe apenas um último elemento da estrutura, na verdade apenas os melhores preços.

O que o faz pensar que é apenas um item?

É isso mesmo, eu recebo absolutamente todos os carrapatos (e não apenas carrapatos, mas também mudanças no copo)

Verifique

//+------------------------------------------------------------------+
//|                                                   Ticks_test.mq5 |
//|                                      Copyright 2019 prostotrader |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019 prostotrader"
#property link      "https://www.mql5.com"
#property version   "1.00"
//---
bool is_book;
MqlTick ticks[], s_tick;
ulong last_time, mem_cnt, tot_cnt;
bool is_first;
int t_cnt, result;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
  tot_cnt = 0;
  is_book = MarketBookAdd(Symbol());
  result = CopyTicks(Symbol(), ticks, COPY_TICKS_ALL, 0, 1);
  if(result > 0)
  {
    last_time = ulong(ticks[0].time_msc); //запоминаем время последнего известного тика
    is_first = true;
  }
  else
  {
    is_first = false;
    Alert("No start time!");
    return(INIT_FAILED);
  } 
  ArraySetAsSeries(ticks, true);  
  return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+ 
//| возвращает строковое описание тика                               | 
//+------------------------------------------------------------------+ 
string GetTickDescription(MqlTick &tick) 
  { 
   string res = string(tick.time) + "." +  string(tick.time_msc%1000); 
// 
   bool buy_tick = ((tick.flags&TICK_FLAG_BUY)==TICK_FLAG_BUY); 
   bool sell_tick = ((tick.flags&TICK_FLAG_SELL)==TICK_FLAG_SELL); 
   bool ask_tick = ((tick.flags&TICK_FLAG_ASK)==TICK_FLAG_ASK); 
   bool bid_tick = ((tick.flags&TICK_FLAG_BID)==TICK_FLAG_BID); 
   bool last_tick = ((tick.flags&TICK_FLAG_LAST)==TICK_FLAG_LAST); 
   bool volume_tick = ((tick.flags&TICK_FLAG_VOLUME)==TICK_FLAG_VOLUME); 
// 
   if((buy_tick== true) || (sell_tick == true)) 
   { 
     res = res + (buy_tick?StringFormat(" Buy Tick: Last=%G Volume=%d ",tick.last,tick.volume):""); 
     res = res + (sell_tick?StringFormat(" Sell Tick: Last=%G Volume=%d ",tick.last,tick.volume):""); 
     res = res + (ask_tick?StringFormat(" Ask=%G ",tick.ask):""); 
     res = res + (bid_tick?StringFormat(" Bid=%G ",tick.bid):""); 
   } 
   else 
   { 
     res = res + (ask_tick?StringFormat(" Ask=%G ",tick.ask):""); 
     res = res + (bid_tick?StringFormat(" Bid=%G ",tick.bid):""); 
     res = res + (last_tick?StringFormat(" Last=%G ",tick.last):""); 
     res = res + (volume_tick?StringFormat(" Volume=%d ",tick.volume):""); 
   } 
   return res; 
  } 
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
  if(is_book == true) MarketBookRelease(Symbol());
}
//+------------------------------------------------------------------+
//| BookEvent function                                               |
//+------------------------------------------------------------------+
void OnBookEvent(const string &symbol)
{
  if(symbol != Symbol()) return;
  tot_cnt++;
  if(SymbolInfoTick(Symbol(), s_tick) == true)
  {
    Print("SymbolInfoTick: ",GetTickDescription(s_tick));
  }
  if(is_first == true)
  {
    result = CopyTicks(Symbol(), ticks, COPY_TICKS_ALL, last_time, 0); //копируем все вновь пришедшие тики от последнего известного времени
    if(result > 0)
    {
      t_cnt = 0;
      for(int i= 0; i<result; i++)
      {
        if(ticks[i].time_msc == ticks[0].time_msc) t_cnt++;             //Считаем кол-во тиков с одинаковым временем
        Print(__FUNCTION__, ": ",GetTickDescription(ticks[i]));
      }
    //  l_tick = ticks[0];
      is_first = false;
      last_time = ulong(ticks[0].time_msc);                             //Запоминаем время последнего тика
    } 
  }
  else
  {
    if(SymbolInfoTick(Symbol(), s_tick) == true)
    {
      Print("SymbolInfoTick: ",GetTickDescription(s_tick));
    }
    result = CopyTicks(Symbol(), ticks, COPY_TICKS_ALL, last_time, 0); //забираем тики из последнего (посчитанного пакета тикив и считываем тики из нового пакета)
    if(result > 0)
    {
     // l_tick = ticks[0];
      if(result > t_cnt)
      {
        mem_cnt = t_cnt;
        t_cnt = 0;
        for(int i= 0; i<(result - int(mem_cnt)); i++)
        {
          if(ticks[i].time_msc == ticks[0].time_msc) t_cnt++;           //Считаем кол-во тиков с одинаковым временем
          Print(__FUNCTION__, ": ",GetTickDescription(ticks[i]));
        } 
        if(last_time == ulong(ticks[0].time_msc))
        {
          t_cnt += int(mem_cnt);
        }
        else last_time = ulong(ticks[0].time_msc);
      }
      else
      {
        Print(__FUNCTION__, ": Pending order!");                          //Изменения стакана (добавлен/удален отложенный ордер)
      }
    }
    else
    {
      Print(__FUNCTION__, ": Pending order!");                          //Изменения стакана (добавлен/удален отложенный ордер)
    }
  }
}
//+------------------------------------------------------------------+
 

Aí está, isso é bom.

Prometi contar-lhes outra vantagem da OnTick, em comparação com a OnBook. É porque o OnBook tem garantia de ser entregue, se ele tiver até mesmo um pouco de cálculos pesados (ou, Deus nos livre, o comércio), ele pode acumular uma fila bastante grande de eventos que não fazem sentido(eles não contêm informações relacionadas a eventos). É aqui que a vantagem se torna uma desvantagem, como muitas vezes acontece.

Neste caso, a OnTick simplesmente ignorará os eventos que chegaram no momento do cálculo, e acionará o primeiro novo e relevante. Na variante OnBook, para liberar a fila (pular eventos inúteis), você tem que fazer suas próprias muletas.

 
Andrey Khatimlianskii:

Aí está, isso é bom.

Prometi contar-lhes outra vantagem da OnTick, em comparação com a OnBook. É porque o OnBook tem garantia de ser entregue, se ele tiver até mesmo um pouco de cálculos pesados (ou, Deus nos livre, o comércio), ele pode acumular uma fila bastante grande de eventos que não fazem sentido(eles não contêm informações relacionadas a eventos). É aqui que a vantagem se torna uma desvantagem, como muitas vezes acontece.

Neste caso, a OnTick simplesmente ignorará os eventos que chegaram no momento do cálculo, e acionará o primeiro novo e relevante. Na variante do OnBook, para liberar a fila (pular eventos inúteis), você tem que fazer suas próprias muletas.

Pessoalmente, uso ordens assíncronas em operações comerciais.

A questão é (se você negocia seriamente na Bolsa), você precisa de todas as mudanças no mercado,

e quanto mais cedo este evento chegar - melhor.

Além disso, você precisa pedir e licitar volumes...

Eu, por mim mesmo, não vejo alternativa ao OnBook

 
Roman:

Eu não uso o comércio forex.
Vocêsó obtém um último elemento da estrutura no exemplo doCopyTick, na verdade apenas os melhores preços.

Executando o código acima, acontece que

 if(SymbolInfoTick(Symbol(), s_tick) == true)
  {
    Print("SymbolInfoTick: ",GetTickDescription(s_tick));
  }
s_tick.flags = 0

:)

2020.02.03 19:28:14.656 Ticks_test (GOLD-3.20,M1)       OnTick: 2020.02.03 19:28:13.160 Bid=1581.9 
2020.02.03 19:28:14.656 Ticks_test (GOLD-3.20,M1)       SymbolInfoTick: 2020.02.03 19:28:13.160
2020.02.03 19:28:14.656 Ticks_test (GOLD-3.20,M1)       SymbolInfoTick: 2020.02.03 19:28:13.160
2020.02.03 19:28:14.656 Ticks_test (GOLD-3.20,M1)       OnBookEvent: 2020.02.03 19:28:13.160 Bid=1581.9 

O mesmo tick e ao chamarSymbolInfoTick- sem bandeira :)

Adicionado

if(tick.flags == 0)
   {
     res = res + " ask = " + string(tick.ask) + "; bid = " + string(tick.bid);
   }

Recebemos um carrapato, mas não sabemos quem o "criou".

2020.02.03 19:36:56.576 Ticks_test (GOLD-3.20,M1)       OnTick: 2020.02.03 19:36:54.735 Bid=1583 
2020.02.03 19:36:56.576 Ticks_test (GOLD-3.20,M1)       SymbolInfoTick: 2020.02.03 19:36:55.61 ask = 1583.3; bid = 1583.0
2020.02.03 19:36:56.576 Ticks_test (GOLD-3.20,M1)       SymbolInfoTick: 2020.02.03 19:36:55.61 ask = 1583.3; bid = 1583.0
2020.02.03 19:36:56.576 Ticks_test (GOLD-3.20,M1)       OnBookEvent: 2020.02.03 19:36:54.735 Bid=1583 

O que está acontecendo com os tempos de carrapato?

Parece um absurdo. Recebemos carrapatos de novos pacotes com o tempo19:36:54.735, mas oSymbolInfoTick recebeu o tique "à frente" por 900 ms.

Da ajudaSymbolInfoTick

[out]  Ссылка на структуру типа MqlTick, в которую будут помещены текущие цены и время последнего обновления цен.
 

Lindo tema, muitas coisas interessantes, obrigado rapazes.

Sem brincadeiras e sem brincadeiras...

Só não decifre o código, eu o levarei em consideração...

 
prostotrader:

Afinal de contas, o que está acontecendo com o tempo de ticking?

É um absurdo. Recebemos carrapatos de novos pacotes com o tempo19:36:54.735, mas ao chamarSymbolInfoTick, nós recebemos carrapatos "à frente" por 900 ms???

De Referência

Realmente estranho, o valor da licitação é o mesmo para todos, mas o tempo SymbolInfoTick é diferente.

 
Roman:

Realmente estranho, o valor da licitação é o mesmo para todos, mas o tempo SymbolInfoTick é diferente.

Parece que o terminal organiza o tempo "como ele quer" :)

2020.02.03 21:56:44.409 Ticks_test (GOLD-3.20,M1)       OnTick: 2020.02.03 21:56:42.776 Sell Tick: Last=1582.9 Volume=2 
2020.02.03 21:56:48.122 Ticks_test (GOLD-3.20,M1)       SymbolInfoTick: 2020.02.03 21:56:42.780 ask = 1583.1; bid = 1582.9
2020.02.03 21:56:48.122 Ticks_test (GOLD-3.20,M1)       SymbolInfoTick: 2020.02.03 21:56:42.780 ask = 1583.1; bid = 1582.9
2020.02.03 21:56:48.122 Ticks_test (GOLD-3.20,M1)       OnBookEvent: 2020.02.03 21:56:42.776 Sell Tick: Last=1582.9 Volume=2 

Passaram quase 4 segundos pela hora local!

Isso certamente não pode ser!

E aqui tudo é normal.

2020.02.03 21:57:02.294 Ticks_test (GOLD-3.20,M1)       OnTick: 2020.02.03 21:57:00.671 Sell Tick: Last=1582.9 Volume=5 
2020.02.03 21:57:02.294 Ticks_test (GOLD-3.20,M1)       SymbolInfoTick: 2020.02.03 21:57:00.671 Sell Tick: Last=1582.9 Volume=5 
2020.02.03 21:57:02.294 Ticks_test (GOLD-3.20,M1)       SymbolInfoTick: 2020.02.03 21:57:00.671 Sell Tick: Last=1582.9 Volume=5 
2020.02.03 21:57:02.294 Ticks_test (GOLD-3.20,M1)       OnBookEvent: 2020.02.03 21:57:00.671 Sell Tick: Last=1582.9 Volume=5 
 
prostotrader:

Parece que o terminal é o próprio tempo "como lhe apetece" :)

Quase 4 segundos se passaram pela hora local!

Isso não pode estar certo!


O registro mostra que o OnTick pegou o mesmo tick 4 segundos mais rápido que o OnBookEvent

1  2020.02.03 21:56:44.409 Ticks_test (GOLD-3.20,M1)       OnTick:            2020.02.03 21:56:42.776 Sell Tick: Last=1582.9 Volume=2 
   2020.02.03 21:56:48.122 Ticks_test (GOLD-3.20,M1)       SymbolInfoTick:    2020.02.03 21:56:42.780 ask = 1583.1; bid = 1582.9
   2020.02.03 21:56:48.122 Ticks_test (GOLD-3.20,M1)       SymbolInfoTick:    2020.02.03 21:56:42.780 ask = 1583.1; bid = 1582.9
2  2020.02.03 21:56:48.122 Ticks_test (GOLD-3.20,M1)       OnBookEvent:       2020.02.03 21:56:42.776 Sell Tick: Last=1582.9 Volume=2 
 
Yuriy Zaytsev:

De acordo com o registro, acontece que o OnTick pegou o mesmo tick mais rápido em 4 segundos que o OnBookEvent

Este definitivamente não pode ser o caso na realidade,

porque os carrapatos já estão no terminal (ou seja, um novo pacote de carrapatos já chegou)

 
prostotrader:

Este definitivamente não pode ser o caso na realidade,

porque os carrapatos já estão no terminal (ou seja, um novo pacote de carrapatos já chegou)

Mas eu olho para o tronco, e o tronco um e o mesmo carrapato com uma diferença de 4 segundos veio.

p.s.

Eu realmente não gosto da frase "não pode ser", eu me acostumei ao fato de que tudo pode acontecer.

A propósito, talvez esteja longe do assunto, mas uma vez sobre a afirmação de que a terra também é redonda, disse algo assim - "não pode ser".

Em geral, estou sempre em dúvida até que eu verifique e, em seguida, verifique novamente e, de preferência, outra pessoa verifique novamente algumas vezes.


Você tem certeza de que seu código não está estragando - o que forma o registro, processa os dados?


este código produziu milagres com uma diferença de 4 segundos ?


//+------------------------------------------------------------------+
//|                                                   Ticks_test.mq5 |
//|                                      Copyright 2019 prostotrader |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019 prostotrader"
#property link      "https://www.mql5.com"
#property version   "1.00"
//---
bool is_book;
MqlTick ticks[], s_tick;
ulong last_time, mem_cnt, tot_cnt;
bool is_first;
int t_cnt, result;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
  tot_cnt = 0;
  is_book = MarketBookAdd(Symbol());
  result = CopyTicks(Symbol(), ticks, COPY_TICKS_ALL, 0, 1);
  if(result > 0)
  {
    last_time = ulong(ticks[0].time_msc); //запоминаем время последнего известного тика
    is_first = true;
  }
  else
  {
    is_first = false;
    Alert("No start time!");
    return(INIT_FAILED);
  } 
  ArraySetAsSeries(ticks, true);  
  return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+ 
//| возвращает строковое описание тика                               | 
//+------------------------------------------------------------------+ 
string GetTickDescription(MqlTick &tick) 
  { 
   string res = string(tick.time) + "." +  string(tick.time_msc%1000); 
// 
   bool buy_tick = ((tick.flags&TICK_FLAG_BUY)==TICK_FLAG_BUY); 
   bool sell_tick = ((tick.flags&TICK_FLAG_SELL)==TICK_FLAG_SELL); 
   bool ask_tick = ((tick.flags&TICK_FLAG_ASK)==TICK_FLAG_ASK); 
   bool bid_tick = ((tick.flags&TICK_FLAG_BID)==TICK_FLAG_BID); 
   bool last_tick = ((tick.flags&TICK_FLAG_LAST)==TICK_FLAG_LAST); 
   bool volume_tick = ((tick.flags&TICK_FLAG_VOLUME)==TICK_FLAG_VOLUME); 
// 
   if((buy_tick== true) || (sell_tick == true)) 
   { 
     res = res + (buy_tick?StringFormat(" Buy Tick: Last=%G Volume=%d ",tick.last,tick.volume):""); 
     res = res + (sell_tick?StringFormat(" Sell Tick: Last=%G Volume=%d ",tick.last,tick.volume):""); 
     res = res + (ask_tick?StringFormat(" Ask=%G ",tick.ask):""); 
     res = res + (bid_tick?StringFormat(" Bid=%G ",tick.bid):""); 
   } 
   else 
   { 
     res = res + (ask_tick?StringFormat(" Ask=%G ",tick.ask):""); 
     res = res + (bid_tick?StringFormat(" Bid=%G ",tick.bid):""); 
     res = res + (last_tick?StringFormat(" Last=%G ",tick.last):""); 
     res = res + (volume_tick?StringFormat(" Volume=%d ",tick.volume):""); 
   } 
   return res; 
  } 
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
  if(is_book == true) MarketBookRelease(Symbol());
}
//+------------------------------------------------------------------+
//| BookEvent function                                               |
//+------------------------------------------------------------------+
void OnBookEvent(const string &symbol)
{
  if(symbol != Symbol()) return;
  tot_cnt++;
  if(SymbolInfoTick(Symbol(), s_tick) == true)
  {
    Print("SymbolInfoTick: ",GetTickDescription(s_tick));
  }
  if(is_first == true)
  {
    result = CopyTicks(Symbol(), ticks, COPY_TICKS_ALL, last_time, 0); //копируем все вновь пришедшие тики от последнего известного времени
    if(result > 0)
    {
      t_cnt = 0;
      for(int i= 0; i<result; i++)
      {
        if(ticks[i].time_msc == ticks[0].time_msc) t_cnt++;             //Считаем кол-во тиков с одинаковым временем
        Print(__FUNCTION__, ": ",GetTickDescription(ticks[i]));
      }
    //  l_tick = ticks[0];
      is_first = false;
      last_time = ulong(ticks[0].time_msc);                             //Запоминаем время последнего тика
    } 
  }
  else
  {
    if(SymbolInfoTick(Symbol(), s_tick) == true)
    {
      Print("SymbolInfoTick: ",GetTickDescription(s_tick));
    }
    result = CopyTicks(Symbol(), ticks, COPY_TICKS_ALL, last_time, 0); //забираем тики из последнего (посчитанного пакета тикив и считываем тики из нового пакета)
    if(result > 0)
    {
     // l_tick = ticks[0];
      if(result > t_cnt)
      {
        mem_cnt = t_cnt;
        t_cnt = 0;
        for(int i= 0; i<(result - int(mem_cnt)); i++)
        {
          if(ticks[i].time_msc == ticks[0].time_msc) t_cnt++;           //Считаем кол-во тиков с одинаковым временем
          Print(__FUNCTION__, ": ",GetTickDescription(ticks[i]));
        } 
        if(last_time == ulong(ticks[0].time_msc))
        {
          t_cnt += int(mem_cnt);
        }
        else last_time = ulong(ticks[0].time_msc);
      }
      else
      {
        Print(__FUNCTION__, ": Pending order!");                          //Изменения стакана (добавлен/удален отложенный ордер)
      }
    }
    else
    {
      Print(__FUNCTION__, ": Pending order!");                          //Изменения стакана (добавлен/удален отложенный ордер)
    }
  }
}
//+------------------------------------------------------------------+