Testen von 'CopyTicks' - Seite 18

 
fxsaber:
Wenn man NUR Band (COPY_TICKS_TRADE - time_msc, last, volume und flags) braucht, ist diese Lösung völlig geeignet - keine Bugs entdeckt.
Keine Wanzen gefunden! Ein weiterer Fehler entdeckt

Forum zum Thema Handel, automatische Handelssysteme und Testen von Handelsstrategien

Mysteriöser Aktienindikator

fxsaber, 2016.09.27 18:32

Alle Bremsen scheinen aktiviert zu sein, wenn der Eingang von CopyTicks nicht Null ist.

Scheint eine sehr krumme Implementierung von CopyTicks in diesem Modus zu sein, selbst wenn Ticks seit dem letzten Aufruf angefordert werden. Es sieht so aus, als sollte es fliegen, aber das tut es nicht.

 
Wartet auf die Beta dieser Woche, in der wir eine Reihe von Verbesserungen bei Ticks und Tumblr-Updates vorgenommen haben.
 
Renat Fatkhullin:
Wartet auf die Beta dieser Woche, in der wir eine Reihe von Verbesserungen an den Ticks und Tumblr-Updates vorgenommen haben.
1432 - viele Bugs behoben. Ich danke Ihnen!
 
fxsaber:
1432 - Viele Bugs behoben. Ich danke Ihnen!

Aber nicht alle.

Wenn die hinzugefügte Historie mit der tatsächlichen Historie verglichen wird, kommt es im Modus COPY_TICKS_ALL zu Diskrepanzen (TRADE und INFO - kein Problem). 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");
  }
}

Ergebnis

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:

Aber nicht alle.

Wenn die hinzugefügte Historie mit der tatsächlichen Historie verglichen wird, kommt es im Modus COPY_TICKS_ALL zu Diskrepanzen (TRADE und INFO - kein Problem). EA

Ergebnis

Ich habe den obigen Code hart protokolliert und die Gründe dafür herausgefunden. Wenn CopyTicks (von > 0) Ticks bis zum neuesten Tick empfängt, kann es sein, dass es einige verpasst.

Beispiel.

Angeforderte Zecken mit von = 2016.09.29 11:05:55.564. Erhielt drei Häkchen als Antwort

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

Einige Zeit später habe ich den Tickverlauf aus der Ferne angefordert und einen Tick erhalten, den CopyTicks zuvor übersehen hatte

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 

So eine Wanze!

Es scheint eine Art Konflikt zwischen dem parallelen Schreiben in und Lesen aus der Tickdatenbank zu geben.

 
Ein weiterer Fehler, jetzt in allen Modi COPY_TICKS_*

Forum zum Thema Handel, automatisierte Handelssysteme und Testen von Handelsstrategien

Mysteriöser Aktienindikator

fxsaber, 2016.09.30 15:09

Es ist mir gelungen, einen der Fehler zu lokalisieren, die zu Abweichungen im Indikator führen. Es geht wieder um CopyTicks.

Es stellt sich heraus, dass die Geschichte der Zecken, wenn wir sie in Teilen sammeln, nicht unbedingt mit der wirklichen Geschichte übereinstimmt. Der Expert Advisor zeigt es an

#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");
  }    
}

Das Ergebnis

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

Auch dieser EA weist eine Schwachstelle auf. Ich habe herausgefunden, dass in der in Teilen gesammelten Geschichte möglicherweise einige Teile fehlen, die mehrere Minuten dauern. Nur eine knappe und klare Wiedergabe in Form eines Codes ist nicht erfunden worden. Und es hat keinen Sinn, komplexe Texte zu posten, denn niemand wird sie sich ansehen.

Im Allgemeinen gibt es keine Möglichkeit, Fehler in CopyTicks zu beheben. Und beachten Sie, dass der Expert Advisor im Bandmodus arbeitet (COPY_TICKS_TRADE). Es kann also nicht einmal mit einem Farbband funktionieren.


 
fxsaber:
Ein weiterer Fehler, jetzt in allen Modi COPY_TICKS_*

Haben Sie versucht, Ticks sowohl ab einem bestimmten Punkt als auch ab einer bestimmten, z.B. festen Zahl zu erhalten?

Dem Code zufolge sieht es so aus, als ob eine bestimmte Zahl (100000) im letzten Moment erreicht wird. Und was ist, wenn Sie nur N Zecken bekommen. Wird es auch Auslassungen geben?

Ich möchte Ihnen gleich sagen, dass ich selbst noch nicht viel mit Zecken experimentiert habe...

 
Alexey Kozitsyn:

Haben Sie versucht, Ticks sowohl ab einem bestimmten Punkt als auch ab einer bestimmten, z.B. festen Zahl zu erhalten?

Dem Code zufolge sieht es so aus, als ob eine bestimmte Zahl (100000) im letzten Moment erreicht wird. Und was ist, wenn Sie nur N Zecken bekommen. Wird es auch Auslassungen geben?

Ich möchte Ihnen gleich sagen, dass ich selbst noch nicht viel mit Zecken experimentiert habe...

Ich habe es ausprobiert.

Heute versprechen sie ein neues Build für die Demo. Wir müssen also warten.

 
fxsaber:

Ich habe es ausprobiert.

Heute wird ein neuer Build für die Demo versprochen. Deshalb muss ich noch warten.

Ich hoffe, CopyTicks() wird korrigiert werden.

Übrigens, seit CopyTicks() aufgetaucht ist, habe ich die Entwickler gebeten, eine Überladungsfunktion wie in anderen Copy...() Funktionen hinzuzufügen. Sie haben mir gesagt, dass sie es tun werden. И... Schweigen...

 
Alexey Kozitsyn:

Übrigens, seit CopyTicks() aufgetaucht ist, habe ich die Entwickler gebeten, eine Überladungsfunktion hinzuzufügen, wie bei anderen Copy...() Funktionen. Sie haben mir gesagt, dass sie es tun werden. И... Schweigen...

Sie können Ihre eigenen Überlastungen hinzufügen.