Testare 'CopyTicks'. - pagina 18

 
fxsaber:
Se uno ha bisogno SOLO del nastro (COPY_TICKS_TRADE - time_msc, last, volume e flags), questa soluzione è completamente adatta - nessun bug rilevato.
Nessun bug trovato! Un altro bug rivelato

Forum sul trading, sistemi di trading automatico e test di strategie di trading

Misterioso indicatore di azioni

fxsaber, 2016.09.27 18:32

Tutti i freni sembrano essere attivi quando l'input da CopyTicks non è zero.

Sembra essere un'implementazione molto storta di CopyTicks in questa modalità, anche se vengono richiesti i tick dall'ultima chiamata. Sembra che dovrebbe volare, ma non è così.

 
Aspetta la beta di questa settimana, dove abbiamo fatto una serie di miglioramenti negli aggiornamenti di tick e tumblr.
 
Renat Fatkhullin:
Aspetta la beta di questa settimana, dove abbiamo apportato una serie di miglioramenti agli aggiornamenti di tick e tumblr.
1432 - molti bug risolti. Grazie!
 
fxsaber:
1432 - Molti bug risolti. Grazie!

Ma non tutti.

Se la storia aggiunta viene confrontata con la storia reale, ci sono discrepanze in modalità COPY_TICKS_ALL (TRADE e INFO - nessun problema). EA

#include <TypeToBytes.mqh> // https://www.mql5.com/ru/code/16280

string GetTickFlag( uint tickflag )
{
  string flag = "";

#define  TICKFLAG_MACRO(A) flag += ((bool)(tickflag & TICK_FLAG_##A)) ? " TICK_FLAG_" + #A : "";
  TICKFLAG_MACRO(BID)
  TICKFLAG_MACRO(ASK)
  TICKFLAG_MACRO(LAST)
  TICKFLAG_MACRO(VOLUME)
  TICKFLAG_MACRO(BUY)
  TICKFLAG_MACRO(SELL)
#undef  TICKFLAG_MACRO

  if (flag == "")
    flag = " FLAG_UNKNOWN (" + (string)tickflag + ")";
     
  return(flag);
}

#define  TOSTRING(A) " " + #A + " = " + (string)Tick.A

string TickToString( const MqlTick &Tick )
{
  return(TOSTRING(time) + "." + (string)IntegerToString(Tick.time_msc %1000, 3, '0') +
         TOSTRING(bid) + TOSTRING(ask) + TOSTRING(last)+ TOSTRING(volume) + GetTickFlag(Tick.flags));
}

// Дописывает свежие тики после предыдущего запуска
int AddFreshTicks( MqlTick &Ticks[], const string Symb = NULL, const uint flags = COPY_TICKS_ALL )
{
  int Res = 0;
  const int Amount = ArraySize(Ticks);
  
  MqlTick NewTicks[];  
  const int NewAmount = (Amount == 0) ? CopyTicks((Symb == NULL)? Symbol() : Symb, NewTicks, flags, (ulong)(TimeCurrent() - 100) * 1000) :
                                        CopyTicks((Symb == NULL)? Symbol() : Symb, NewTicks, flags, Ticks[Amount - 1].time_msc);
  
  if (NewAmount > 0)
  {
    if (Amount > 0)
    {
      // Взяли крайнее время из предыдущей истории
      const long LastTime = Ticks[Amount - 1].time_msc;
      
      int Count = 1;
      
      // Находим (Count) в предыдушей истории количество тиков со временем LastTime
      for (int i = Amount - 2; i >= 0; i--)
      {
        if (Ticks[i].time_msc < LastTime)
          break;
          
        Count++;
      }

      if ((Count < Amount) && (Count < NewAmount))      
        Res = ArrayCopy(Ticks, NewTicks, Amount, Count);
    }
    else
      Res = ArrayCopy(Ticks, NewTicks);
  }
  
  return(Res);
}

#define  TOSTRING2(A) #A + " = " + (string)(A) + " "

template <typename T>
bool ArrayEqual( const T &Array1[], const T &Array2[] )
{
  const int Amount = MathMin(ArraySize(Array1), ArraySize(Array2));
  bool Res = (Amount > 0);

  if (Res)
    for (int i = 0; i < Amount; i++)
      if (_R(Array1[i]) != Array2[i]) // https://www.mql5.com/ru/code/16280
      {
        Print(TOSTRING2(i) + TOSTRING2(ArraySize(Array1)) +TOSTRING2(ArraySize(Array2)));
        Print(TOSTRING2(TickToString(Array1[i])) + "\n" + TOSTRING2(TickToString(Array2[i])) + "\n");
        
        Res = false;

        break;
      }

  return(Res);
}

void OnTick( void )
{
 static MqlTick PrevTicks[];
  
  // Дописываем свежие тики после предыдущего вызова
  AddFreshTicks(PrevTicks, _Symbol, COPY_TICKS_ALL);
  
  MqlTick Ticks[];
  
  if (ArraySize(PrevTicks) > 0)
  {
    // Взяли историю тиков
    Print(CopyTicks(_Symbol, Ticks, COPY_TICKS_ALL, PrevTicks[0].time_msc, 100000));
    
    // Проверка на совпадение собираемой истории с самой историей
    Print(ArrayEqual(Ticks, PrevTicks) ? "Equal" : "Not Equal");
  }
}

Risultato

2016.09.29 10:36:23.722 Test10 (Si-12.16,M1)    Not Equal
2016.09.29 10:36:23.722 Test10 (Si-12.16,M1)    
2016.09.29 10:36:23.722 Test10 (Si-12.16,M1)    TickToString(Array2[i]) =  time = 2016.09.29 10:36:20.547 bid = 64353.0 ask = 64354.0 last = 64353.0 volume = 4 TICK_FLAG_BID 
2016.09.29 10:36:23.722 Test10 (Si-12.16,M1)    TickToString(Array1[i]) =  time = 2016.09.29 10:36:20.546 bid = 64353.0 ask = 64354.0 last = 64353.0 volume = 1 TICK_FLAG_LAST TICK_FLAG_VOLUME TICK_FLAG_SELL 
2016.09.29 10:36:23.722 Test10 (Si-12.16,M1)    i = 57 ArraySize(Array1) = 59 ArraySize(Array2) = 58 
2016.09.29 10:36:23.722 Test10 (Si-12.16,M1)    59
 
fxsaber:

Ma non tutti.

Se la storia aggiunta viene confrontata con la storia reale, ci sono discrepanze in modalità COPY_TICKS_ALL (TRADE e INFO - nessun problema). EA

Risultato

Ho registrato il codice qui sopra e ho scoperto le ragioni. Se CopyTicks (da > 0) riceve i tick fino a quello più recente, potrebbe mancarne qualcuno.

Esempio.

Tick richiesti con da = 2016.09.29 11:05:55.564. Ho ricevuto tre tick in risposta

2016.09.29 11:05:58.724 Test10 (Si-12.16,M1)    2:  time = 2016.09.29 11:05:55.580 bid = 64380.0 ask = 64382.0 last = 64381.0 volume = 4 TICK_FLAG_BID TICK_FLAG_ASK
2016.09.29 11:05:58.724 Test10 (Si-12.16,M1)    1:  time = 2016.09.29 11:05:55.576 bid = 64379.0 ask = 64381.0 last = 64381.0 volume = 4 TICK_FLAG_LAST TICK_FLAG_VOLUME TICK_FLAG_BUY
2016.09.29 11:05:58.724 Test10 (Si-12.16,M1)    0:  time = 2016.09.29 11:05:55.564 bid = 64379.0 ask = 64381.0 last = 64380.0 volume = 1 TICK_FLAG_BID TICK_FLAG_ASK

Qualche tempo dopo ho richiesto la cronologia dei tick da lontano e ho ottenuto un tick, che CopyTicks ha mancato prima

2016.09.29 11:05:58.732 Test10 (Si-12.16,M1)    time = 2016.09.29 11:05:55.579 bid = 64380.0 ask = 64382.0 last = 64381.0 volume = 16 TICK_FLAG_LAST TICK_FLAG_VOLUME TICK_FLAG_BUY 

Un tale insetto!

Sembra che ci sia una sorta di conflitto tra la scrittura e la lettura del database delle zecche in parallelo.

 
Un altro bug, ora in tutte le modalità COPY_TICKS_*

Forum sul trading, sistemi di trading automatico e test di strategie di trading

Misterioso indicatore di azioni

fxsaber, 2016.09.30 15:09

È stato in grado di localizzare uno dei bug che causa la divergenza nell'indicatore. Si tratta di nuovo di CopyTicks.

Si scopre che se raccogliamo la storia delle zecche in parti, può non coincidere con la storia reale. L'Expert Advisor lo mostra

#include <TypeToBytes.mqh> // https://www.mql5.com/ru/code/16280

long LastTime = 0; // time_msc-время последнего тика (самого свежего), полученного из истории
int Count = 0;     // Количество тиков в последенем запросе, у которых time_msc == LastTime

// Возвращает следующие тики (после предыдущего вызова)
int GetFreshTicks( MqlTick &Ticks[], const uint flags = COPY_TICKS_TRADE, const uint count = 100000 )
{
  int Res = 0;

  MqlTick NewTicks[];
  const int NewAmount = CopyTicks(Symbol(), NewTicks, flags, LastTime, count);

  if ((NewAmount > 0) && (Count < NewAmount))
  {
    Res = ArrayCopy(Ticks, NewTicks, 0, Count);

    // Взяли крайнее время из текущей истории
    LastTime = Ticks[Res - 1].time_msc;
    Count = 1;

    // Находим (Count) в текущей истории количество тиков со временем LastTime
    for (int i = Res - 2; i >= 0; i--)
    {
      if (Ticks[i].time_msc < LastTime)
        break;

      Count++;
    }
  }
  
  return(ArrayResize(Ticks, Res));
}

// Сравнение двух массивов
template <typename T>
bool ArrayEqual( const T &Array1[], const T &Array2[] )
{
  const int Amount = MathMin(ArraySize(Array1), ArraySize(Array2));
  bool Res = (Amount > 0);

  if (Res)
    for (int i = 0; i < Amount; i++)
      if (_R(Array1[i]) != Array2[i]) // https://www.mql5.com/ru/code/16280
      {
        Res = false;
        
        ExpertRemove();

        break;
      }

  return(Res);
}

void OnTick()
{
  // возьмем тики с начала утренней сессии
  Count = 0;
  LastTime = (TimeCurrent() - (TimeCurrent() % (24 * 3600))) * 1000;
  
  MqlTick Ticks[];    // История, собранная по частям
  MqlTick NewTicks[]; // массив для следующей части тиков
  
  // Собираем историю по частям  
  while (GetFreshTicks(NewTicks, COPY_TICKS_TRADE, 100000) > 0)
    ArrayCopy(Ticks, NewTicks, ArraySize(Ticks));
    
  if (ArraySize(Ticks) > 0)    
  {
    // Взяли ВСЮ историю тиков
    Print(CopyTicks(_Symbol, NewTicks, COPY_TICKS_TRADE, Ticks[0].time_msc, 10000000)); // 10000000 - большое число, чтобы все выкачать.
    
    // Проверка на совпадение собранной по частям истории с самой историей
    Print(ArrayEqual(NewTicks, Ticks) ? "Equal" : "Not Equal");
  }    
}

Il risultato

2016.09.30 16:02:54.661 Test (Si-12.16,M1)      Not Equal
2016.09.30 16:02:54.661 Test (Si-12.16,M1)      ExpertRemove() function called
2016.09.30 16:02:54.621 Test (Si-12.16,M1)      333740
2016.09.30 16:02:54.121 Test (Si-12.16,M1)      Equal
2016.09.30 16:02:54.071 Test (Si-12.16,M1)      333736
2016.09.30 16:02:53.791 Test (Si-12.16,M1)      Equal
2016.09.30 16:02:53.741 Test (Si-12.16,M1)      333723

Questo EA mostra anche un bug debole. Ho scoperto che la storia raccolta in parti può mancare di alcune parti che durano diversi minuti. Solo una riproduzione concisa e chiara sotto forma di codice non è stata inventata. E non c'è motivo di pubblicarne di complessi, perché nessuno li guarderà mai.

In generale, non c'è modo di sconfiggere i bug in CopyTicks. E notate che l'Expert Advisor lavora in modalità nastro (COPY_TICKS_TRADE). Quindi, non può nemmeno funzionare con il nastro.


 
fxsaber:
Un altro bug, ora in tutte le modalità COPY_TICKS_*

Avete provato a ottenere ticchettii sia partendo da un certo punto che da un certo numero, per esempio fisso?

Dal codice, sembra un certo numero (100000) dell'ultimo momento. E cosa succede se si ottengono solo N zecche. Ci saranno anche i salti?

Lasciatemi dire subito che io stesso non ho ancora sperimentato molto con le zecche...

 
Alexey Kozitsyn:

Avete provato a ottenere ticchettii sia partendo da un certo punto che da un certo numero, per esempio fisso?

Dal codice, sembra un certo numero (100000) dell'ultimo momento. E cosa succede se si ottengono solo N zecche. Ci saranno anche i salti?

Lasciatemi dire subito che io stesso non ho ancora sperimentato molto con le zecche...

Provato.

Oggi promettono una nuova build per la demo. Quindi dobbiamo aspettare.

 
fxsaber:

Provato.

Oggi promettono una nuova build per la demo. Ecco perché devo aspettare.

Spero che CopyTicks() venga corretto.

A proposito, da quando è apparsa CopyTicks() ho chiesto agli sviluppatori di aggiungere la funzione di overloading come nelle altre funzioni Copy...(). Mi hanno detto che lo faranno. И... silenzio...

 
Alexey Kozitsyn:

A proposito, da quando è apparsa CopyTicks(), ho chiesto agli sviluppatori di aggiungere una funzione di sovraccarico, come per le altre funzioni Copy...(). Mi hanno detto che lo faranno. И... silenzio...

Potete aggiungere i vostri sovraccarichi.
Motivazione: