Testen von 'CopyTicks' - Seite 41

 
Ich bin auf einen Fehler gestoßen, bei dem CopyTicksRange alle angeforderten Ticks korrekt zurückgibt, aber LastError == ERR_HISTORY_TIMEOUT(4403).


 
fxsaber:

Die tkc-Dateien sind nach Monaten aufgeschlüsselt. Fragen dazu

  1. Wenn das Terminal die Tickdaten noch nicht hochgeladen hat, woher weiß das Terminal beim Aufruf von CopyTicks, welche tkc-Dateien es ziehen soll?
Abrufe jeden Monat, beginnend mit dem aktuellen Monat.
  1. Ist CopyTicksRange auf der Grundlage von CopyTicks oder unabhängig davon implementiert?
Basierend auf CopyTicks, d.h. überhaupt nicht optimiert.
  1. Verstehe ich das richtig, dass das Abrufen von Ticks für September z. B. über CopyTicksRange immer schneller geht als über CopyTicks, weil CopyTicks über die Eingabeparameter nicht weiß, für welchen Monat Daten gezogen werden sollen?

Nein, CopyTicksRange wird wegen des oben genannten Punktes genauso langsam sein. Hier ist ein Skript, das die Absurdität der aktuellen Implementierung von CopyTicksRange zeigt

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

void OnStart()
{  
  
  MqlTick Ticks[];
  
  ResetLastError();
  
  Print(__FUNCTION__);
  Print(TOSTRING(CopyTicksRange(_Symbol, Ticks, COPY_TICKS_ALL, 1, 2)));
  Print(TOSTRING(_LastError));
}

Es scheint klar vorgegeben zu sein, welche tkc-Dateien gezogen werden müssen. Aber nein, es wird auf die gleiche Weise wie CopyTicks gezogen - alle tkc-Dateien. Und bei Zeitüberschreitung hört es auf zu funktionieren. Aber eigentlich sollte es fast sofort funktionieren.

  1. Sie müssen die Geschichte so schnell wie möglich in den Indikator aufnehmen. Es ist möglich, dies über CopyTicksRange anzufordern und eine -1 zu erhalten, bis alles heruntergeladen ist. Und wenn Sie nach Monaten anfragen: aktueller Monat, dann Vormonat, usw. Er wird nicht langsamer sein, aber der Indikator wird zumindest mit einer gewissen Historie arbeiten können. Oder?

Es macht keinen Unterschied, wie sich herausstellt (siehe oben).

 

CopyTicks funktioniert nicht in OnDeinit, wennUninitializeReason !=REASON_CHARTCHANGE

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

void TickTest()
{
  MqlTick Ticks[];

  ResetLastError();
  Print(TOSTRING(CopyTicks(_Symbol, Ticks)));
  Print(TOSTRING(_LastError));
}

void OnInit()
{
  Print("\n" + __FUNCTION__);
  
  TickTest();
}

void OnDeinit( const int )
{
  Print("\n" + __FUNCTION__);
  Print(TOSTRING(UninitializeReason()));
  
  TickTest();
}


Ergebnis (nach Entfernen des Expert Advisors)

OnInit
CopyTicks(_Symbol,Ticks) = 2000
_LastError = 0

OnDeinit
UninitializeReason() = 1
CopyTicks(_Symbol,Ticks) = -1
_LastError = 4401


Dies geschieht in Expert Advisors. Bei Indikatoren funktioniert CopyTicks normalerweise in OnDeinit.

 
Wenn Sie das Konto wechseln(auf einen anderen Handelsserver), müssen wir die letzten 2000 Ticks des alten Kontos in die Datei schreiben. Wie kann man das tun?


Das wird nicht funktionieren.

void OnDeinit( const int )
{
  MqlTick Ticks[];

  CopyTicks(_Symbol, Ticks); // Если была смена торгового сервера, то БД-тиков поменялась

  FileSave(__FILE__, Ticks);
}


Bitte erzeugen Sie das Ereignis CHARTEVENT_ACCOUNTCLOSING vor dem Kontowechsel, wenn die Verarbeitung (in OnChartEvent) noch nicht auf die neue Handelsumgebung umgestellt wurde.

 
fxsaber:
Bei einem Kontowechsel(anderer Handelsserver) ist es notwendig, die letzten 2000 Ticks des alten Kontos in die Datei zu schreiben. Wie kann ich das tun?


Das wird nicht funktionieren.


Bevor Sie das Konto wechseln, erzeugen Sie bitte das Ereignis CHARTEVENT_ACCOUNTCLOSING, bei dessen Verarbeitung (in OnChartEvent) die gesamte Handelsumgebung noch nicht auf das neue Konto umgestellt wurde.

Intelligenterweise sollten wir eine Rückmeldung hinzufügen, wie es in Windows gemacht wird.

Als Flag in einem Chart-Ereignis (oder auch nicht) wird beim Setzen des Flags das Ereignis selbst (in diesem Fall der Kontowechsel) rückgängig gemacht.

 

Lassen Sie es abrupt sein, aber es ist ärgerlich, dass Dutzende von Fehlerberichten, sie werden behoben, und neue tauchen immer wieder mit diesem CopyTicks.

Solche Tricks machen mich müde.

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

void OnStart()
{
  MqlTick Ticks[];

  if (CopyTicks(_Symbol, Ticks, COPY_TICKS_ALL, 0, 131072 + 1) > 0) // Если прибавлять не единицу, а ноль, то все будет работать
  {
    const ulong BeginTime = Ticks[0].time_msc;
    
    Print(TOSTRING(CopyTicksRange(_Symbol, Ticks, COPY_TICKS_INFO, BeginTime, LONG_MAX)));
    Print(TOSTRING(CopyTicksRange(_Symbol, Ticks, COPY_TICKS_INFO, BeginTime, (TimeCurrent() + 1) * 1000)));
  }
}


Ergebnis

CopyTicksRange(_Symbol,Ticks,COPY_TICKS_INFO,BeginTime,LONG_MAX) = 0
CopyTicksRange(_Symbol,Ticks,COPY_TICKS_INFO,BeginTime,(TimeCurrent()+1)*1000) = 131073


Entfernen Sie eine aus dem Quellcode

CopyTicksRange(_Symbol,Ticks,COPY_TICKS_INFO,BeginTime,LONG_MAX) = 131072
CopyTicksRange(_Symbol,Ticks,COPY_TICKS_INFO,BeginTime,(TimeCurrent()+1)*1000) = 131072


Vervielfältigt auf verschiedenen Charakteren und Handelsservern. Überprüft am freien Tag - die Quotierer stehen.


Wann werden die Bugs in diesem Thread beseitigt sein?

 

In der Tat, eine so interessante Funktion in der Sprache und sie funktioniert sofort...

Ich habe eine Frage. Ich habe die Ticks manuell (685.007 Ticks) über das Menü Symbole heruntergeladen. Ich brauche für EURUSD von 2016.11.01 00:00 bis 2016.11.08 00:00. Hier ist ein Bildschirmfoto.



Ich beantrage programmatisch wie folgt:

void OnStart()
  {
   string symbol="EURUSD";
   MqlTick ticks_array[];
   uint flags=COPY_TICKS_INFO;
   ulong from_msc,to_msc;
   from_msc=(ulong)D'01.11.2016 00:00';
   to_msc=(ulong)D'08.11.2016 00:00';
//--- получить тики - 20 попыток
   for(int att=0;att<20;att++)
     {
      int copied=CopyTicksRange(symbol,ticks_array,flags,from_msc,to_msc);
      if(copied>0)
         break;
      Sleep(100);
     }
//--- остановка
   DebugBreak();
  }


Die Ausgabe ist 0. Was ist los?

 
Dennis Kirichenko:

Die Ausgabe ist 0. Was ist los?

Multiplizieren Sie mit 1000 von und bis.

 
fxsaber:

Multiplizieren Sie mit 1.000 von und bis.


Schande über mich, ich habe mich geirrt. Danke, Mann.

 
Viel Zeit verloren, um diesen Fehler zu lokalisieren CopyTicksRange


template <typename T>
T MyPrint( const T Value, const string Str )
{
  static const bool IsDebug = MQLInfoInteger(MQL_DEBUG);

//  if (IsDebug)
  {
//    DebugBreak(); // если хочется посмотреть средствами дебага

    Print(Str + " = " + (string)Value);
  }
  
  return(Value);
}

#define _P(A) MyPrint(A, __FUNCSIG__ ", Line = " + (string)__LINE__ + ": " + #A)

int GetSymbolTicks( const string Symb, MqlTick &Ticks[] )
{
  const bool Selected = SymbolInfoInteger(Symb, SYMBOL_SELECT);

  const int Amount = SymbolInfoInteger(Symb, SYMBOL_CUSTOM) && (Selected || SymbolSelect(Symb, true)) ? _P(CopyTicksRange(Symb, Ticks, COPY_TICKS_INFO)) : -1; // здесь баг!
  
  if (!Selected)
    SymbolSelect(Symb, false);

  return(Amount);
}

bool TicksToSymbol( const string Symb, const MqlTick &Ticks[] )
{
  const int Size = ArraySize(Ticks);
  
  CustomTicksDelete(Symb, Ticks[0].time_msc, Ticks[Size - 1].time_msc);
  
  return(Size ? (_P(CustomTicksReplace(Symb, Ticks[0].time_msc, Ticks[Size - 1].time_msc, Ticks)) > 0) : false);
}

void OnStart()
{
  MqlTick Ticks[];
    
  if (CopyTicksRange(_Symbol, Ticks, COPY_TICKS_INFO, D'2017.12.01' * 1000, (TimeCurrent() + 1) * 1000) > 100) // Если поставить сегодня - D'2017.12.05', то баг не проявится
  {
    ArrayResize(Ticks, 100);
    
    static const string Name = _Symbol + "_Custom";
    
    CustomSymbolDelete(Name);
    
    if (CustomSymbolCreate(Name) && CustomSymbolSetInteger(Name, SYMBOL_DIGITS, _Digits))
    {    
      TicksToSymbol(Name, Ticks);
    
      MqlTick Ticks2[];
      
      GetSymbolTicks(Name, Ticks2);
    }

    CustomSymbolDelete(Name);
  }
}

Nach dem ersten Lauf auf EURUSD M1 MetaQuotes-Demo haben wir ein korrektes Ergebnis

bool TicksToSymbol(const string,const MqlTick&[]), Line = 36: CustomTicksReplace(Symb,Ticks[0].time_msc,Ticks[Size-1].time_msc,Ticks) = 100
int GetSymbolTicks(const string,MqlTick&[]), Line = 22: CopyTicksRange(Symb,Ticks,COPY_TICKS_INFO) = 100


Alle nächsten Durchläufe werden einen Fehler zeigen

bool TicksToSymbol(const string,const MqlTick&[]), Line = 36: CustomTicksReplace(Symb,Ticks[0].time_msc,Ticks[Size-1].time_msc,Ticks) = 100
int GetSymbolTicks(const string,MqlTick&[]), Line = 22: CopyTicksRange(Symb,Ticks,COPY_TICKS_INFO) = 0


Nach dem erneuten Laden des Terminals wiederholt sich die Situation: erster Durchlauf - gut, nächste Durchläufe - Fehler.


SZY Beachten Sie den hervorgehobenen Kommentar in der Quelle!