Test des "CopyTicks". - page 41

 
J'ai rencontré un problème où CopyTicksRange retourne correctement tous les ticks demandés, mais LastError == ERR_HISTORY_TIMEOUT(4403).


 
fxsaber:

Les fichiers tkc sont ventilés par mois. Des questions à cause de cela

  1. Si le terminal n'a pas encore téléchargé les données tick, lorsque vous appelez CopyTicks, comment le terminal sait-il quels fichiers tkc extraire ?
Extrait tous les mois, en commençant par le mois en cours.
  1. CopyTicksRange est-il implémenté sur la base de CopyTicks ou indépendamment ?
Basé sur CopyTicks, c'est-à-dire pas du tout optimisé.
  1. Ai-je raison de comprendre que l'obtention de ticks pour le mois de septembre, par exemple, sera toujours plus rapide avec CopyTicksRange qu'avec CopyTicks, parce que CopyTicks ne sait pas, via les paramètres d'entrée, pour quel mois il faut extraire les données ?

Non, CopyTicksRange sera tout aussi lent à cause du point ci-dessus. Voici un script qui montre l'absurdité de l'implémentation actuelle de CopyTicksRange.

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

Il semble que les informations sur les fichiers tkc qui doivent être retirés soient clairement données. Mais non, il tirera de la même manière que CopyTicks - tous les fichiers tkc. Et il s'arrêtera de fonctionner au bout d'un certain temps. Mais en fait, cela devrait fonctionner presque instantanément.

  1. Vous devez mettre l'historique dans l'indicateur aussi vite que possible. Il est possible de le demander via CopyTicksRange et d'obtenir un -1 jusqu'à ce que tout soit téléchargé. Et si vous demandez par mois : le mois en cours, puis le mois précédent, etc. Il ne sera pas plus lent, mais l'indicateur sera prêt à fonctionner avec au moins un historique. N'est-ce pas ?

Il s'avère que cela ne fait aucune différence (voir les points ci-dessus).

 

CopyTicks ne fonctionne pas dans OnDeinit siUninitializeReason !=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();
}


Résultat (après la suppression du conseiller expert)

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

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


Cela se produit dans les conseillers experts. Dans les indicateurs, CopyTicks fonctionne normalement dans OnDeinit.

 
Lorsque vous changez de compte(vers un autre serveur de trading), nous devons écrire dans le fichier les 2000 derniers ticks de l'ancien compte. Comment faire ?


Cela ne fonctionnera pas.

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

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

  FileSave(__FILE__, Ticks);
}


Veuillez générer l'événement CHARTEVENT_ACCOUNTCLOSING avant le changement de compte, lorsque vous le traitez (dans OnChartEvent) tout l'environnement de trading n'a pas encore basculé vers le nouveau.

 
fxsaber:
Lors d'un changement de compte(autre serveur de trading), il est nécessaire d'écrire dans le fichier les 2000 derniers ticks de l'ancien compte. Comment je fais ça ?


Cela ne fonctionnera pas.


Avant de changer de compte, veuillez générer l'événement CHARTEVENT_ACCOUNTCLOSING, lorsque vous le traitez (dans OnChartEvent), tout l'environnement de trading n'a pas encore basculé vers le nouveau compte.

Intelligemment, nous devrions ajouter un feedback, comme cela se fait dans Windows.

Comme un drapeau dans un événement graphique (ou non), lorsqu'il est activé, l'événement lui-même (dans ce cas, le changement de compte) est annulé.

 

Qu'il soit abrupt, mais il est ennuyeux que des dizaines de rapports de bogues, ils sont corrigés, et de nouveaux continuent à apparaître avec ce CopyTicks.

Ça me fatigue tellement de faire des tours.

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


Résultat

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


Retirer un du code source

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


Reproduit sur différents personnages et serveurs commerciaux. Vérifié le jour de congé - les quoters sont debout.


Quand les bugs seront-ils vaincus dans ce fil ?

 

En effet, c'est une fonctionnalité intéressante du langage et elle fonctionne dès le départ...

Voici une question. J'ai téléchargé les ticks manuellement (685 007 ticks) via le menu Symboles. J'ai besoin pour EURUSD de 2016.11.01 00:00 à 2016.11.08 00:00. Voici une capture d'écran.



Je fais une demande par programme comme ceci :

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();
  }


La sortie est 0. Quel est le problème ?

 
Dennis Kirichenko:

La sortie est de 0. Quel est le problème ?

Multiplier par 1000 de et à.

 
fxsaber:

Multipliez par 1 000 de et à.


Honte à moi, je me suis trompé. Merci, mec.

 
Perdu beaucoup de temps à localiser ce bug 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);
  }
}

Après la première exécution sur EURUSD M1 MetaQuotes-Demo nous avons un résultat correct.

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


Toutes les prochaines exécutions montreront un bug

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


La situation se répète après le rechargement du terminal : première exécution - bien, exécutions suivantes - bug.


SZY Notez le commentaire surligné dans la source !