CustomTicksAdd

Ajoute les données d'un tableau de données de type MqlTick à l'historique des prix d'un symbole personnalisé. Le symbole personnalisé doit être sélectionné dans la fenêtre du Market Watch.

int  CustomTicksAdd(
   const string     symbol,             // Nom du symbole
   const MqlTick&   ticks[],            // Le tableau de ticks à appliquer au symbole personnalisé
   uint             count=WHOLE_ARRAY   // nombre d'éléments du tableau ticks[] à utiliser
   );

Paramètres

symbol

[in]  Le nom du symbole personnalisé.

ticks[]

[in]   Un tableau de ticks du type MqlTick ordonnés par date, du plus récent au plus ancien, c'est à dire ticks[k].time_msc <= ticks[n].time_msc, avec k<n.

count=WHOLE_ARRAY

[in]  Nombre d'éléments du tableau ticks[] à utiliser pour l'ajout. WHOLE_ARRAY signifie que tous les éléments du tableau ticks[] doivent être utilisés.

Valeur de Retour

Le nombre de ticks ajoutés ou -1 en cas d'erreur.

Note

La fonction CustomTicksAdd ne fonctionne que pour les symboles personnalisés ouverts dans la fenêtre du Market Watch. Si le symbole n'est pas sélectionné dans le Market Watch, vous devez ajouter les ticks avec CustomTicksReplace.

La fonction CustomTicksAdd permet de transmettre des ticks comme s'ils avaient été émis par le serveur du courtier. Les données sont envoyées dans la fenêtre du Market Watch au lieu d'être écrites directement dans la base de données des ticks. Le terminal sauvegarde ensuite les ticks depuis le Market Watch dans une base de données. Si trop de données sont transmises à un appel de la fonction, son comportement est modifié pour réduire l'utilisation des ressources. Si plus de 256 ticks sont passés, les données sont divisées en deux parties. La première, c'est à dire la partie la plus grande, est écrite directement dans la base de données des ticks (comme cela est fait dans CustomTicksReplace). La deuxième partie, contenant 128 ticks, est passée à la fenêtre du Market Watch, à partir de laquelle le terminal sauvegarde les ticks dans une base de données.

La structure MqlTick a deux champs temporels : time (l'heure du tick en secondes) et  time_msc (l'heure du tick en millisecondes), qui sont comptées depuis le 1er janvier 1970. Ces champs des ticks ajoutés sont traités dans l'ordre suivant :

  1. Si ticks[k].time_msc!=0, le champ est utilisé pour remplir ticks[k].time field, c'est à dire que ticks[k].time=ticks[k].time_msc/1000 (division entière) est défini pour le tick
  2. Si ticks[k].time_msc==0 et ticks[k].time!=0, l'heure en millisecondes est obtenue en multipliant par 1000, c'est à dire que ticks[k].time_msc=ticks[k].time*1000
  3. Si ticks[k].time_msc==0 et ticks[k].time==0, l'heure atuelle du serveur de trades plus 1 milliseconde au moment de l'appel à CustomTicksAdd est écrit dans ces champs.

Si la valeur de ticks[k].bid, ticks[k].ask, ticks[k].last ou ticks[k].volume est supérieure à zéro, la combinaison des flags correspondants est écrite dans le champ ticks[k].flags :

  • TICK_FLAG_BID — le tick a changé le prix bid
  • TICK_FLAG_ASK  — le tick a changé le prix ask
  • TICK_FLAG_LAST — le tick a changé le prix de la dernière transaction
  • TICK_FLAG_VOLUME — le tick a changé le volume

Si la valeur d'un champ est inférieure ou égale à zéro, le flag correspondant n'est pas écrit dans le champ ticks[k].flags.

 

Les flags TICK_FLAG_BUY et TICK_FLAG_SELL ne sont pas ajoutés à l'historique d'un symbole personnalisé.

 

Exemple :

//+------------------------------------------------------------------+
//|                                               CustomTicksAdd.mq5 |
//|                                  Copyright 2024, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
 
#define   CUSTOM_SYMBOL_NAME     Symbol()+".C"     // nom du symbole personnalisé
#define   CUSTOM_SYMBOL_PATH     "Forex"           // nom du groupe dans lequel le symbole sera créé
#define   CUSTOM_SYMBOL_ORIGIN   Symbol()          // nom d'un symbole sur lequel le symbole personnalisé sera construit
 
#define   DATATICKS_TO_COPY      UINT_MAX          // nombre de ticks copiés
#define   DATATICKS_TO_PRINT     20                // nombre de ticks envoyé dans le journal
 
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- obtient le code d'erreur lors de la création d'un symbole personnalisé
   int create=CreateCustomSymbol(CUSTOM_SYMBOL_NAMECUSTOM_SYMBOL_PATHCUSTOM_SYMBOL_ORIGIN);
   
//--- si le code d'erreur est différent de 0 (symbole créé avec succès) et pas 5304 (le symbole a déjà été créé) - on sort
   if(create!=0 && create!=5304)
      return;
 
//--- obtient les ticks du symbole standard, dans le tableau MqlTicks
   MqlTick array[]={};
   if(!GetTicksToArray(CUSTOM_SYMBOL_ORIGINDATATICKS_TO_COPYarray))
      return;
   
//--- affiche les heures du premier et du dernier tick du symbole standard
   int total=(int)array.Size();
   PrintFormat("First tick time: %s.%03u, Last tick time: %s.%03u",
               TimeToString(array[0].timeTIME_DATE|TIME_MINUTES|TIME_SECONDS), array[0].time_msc%1000,
               TimeToString(array[total-1].timeTIME_DATE|TIME_MINUTES|TIME_SECONDS), array[total-1].time_msc%1000);
               
//--- affiche dans le journal les DATATICKS_TO_PRINT derniers ticks du symbole standard
   PrintFormat("\nThe last %d ticks for the standard symbol '%s':"DATATICKS_TO_PRINTCUSTOM_SYMBOL_ORIGIN);
   for(int i=total-DATATICKS_TO_PRINTi<totali++)
     {
      if(i<0)
         continue;
      PrintFormat("  %dth Tick: %s"iGetTickDescription(array[i]));
     }
   
//--- ajoute un symbole personnalisé à la fenêtre du Market Watch
   ResetLastError();
   if(!SymbolSelect(CUSTOM_SYMBOL_NAMEtrue))
     {
      Print("SymbolSelect() failed. Error "GetLastError());
      return;
     }
     
//--- ajoute le tableau des ticks à l'historique des prix du symbole personnalisé
   Print("...");
   uint start=GetTickCount();
   PrintFormat("Start of adding %u ticks to the history of the custom symbol '%s'"array.Size(), CUSTOM_SYMBOL_NAME);
   int added=CustomTicksAdd(CUSTOM_SYMBOL_NAMEarray);
   PrintFormat("Added %u ticks to the history of the custom symbol '%s' in %u ms"addedCUSTOM_SYMBOL_NAMEGetTickCount()-start);
   
//--- obtient les ticks du symbole personnalisé, dans le tableau MqlTicks
   Print("...");
   if(!GetTicksToArray(CUSTOM_SYMBOL_NAMEarray.Size(), array))
      return;
   
//--- affiche les heures du premier et du dernier tick du symbole personnalisé
   total=(int)array.Size();
   PrintFormat("First tick time: %s.%03u, Last tick time: %s.%03u",
               TimeToString(array[0].timeTIME_DATE|TIME_MINUTES|TIME_SECONDS), array[0].time_msc%1000,
               TimeToString(array[total-1].timeTIME_DATE|TIME_MINUTES|TIME_SECONDS), array[total-1].time_msc%1000);
               
//--- affiche dans le journal les DATATICKS_TO_PRINT derniers ticks du symbole personnalisé
   PrintFormat("\nThe last %d ticks for the custom symbol '%s':"DATATICKS_TO_PRINTCUSTOM_SYMBOL_NAME);
   for(int i=total-DATATICKS_TO_PRINTi<totali++)
     {
      if(i<0)
         continue;
      PrintFormat("  %dth Tick: %s"iGetTickDescription(array[i]));
     }
 
//--- affiche une infobulle sur les touches de fin de script dans le commentaire du graphique
   Comment(StringFormat("Press 'Esc' to exit or 'Del' to delete the '%s' symbol and exit"CUSTOM_SYMBOL_NAME));
//--- attend que la touche Echap ou Suppr soit appuyée pour sortir de la boucle sans fin
   while(!IsStopped() && TerminalInfoInteger(TERMINAL_KEYSTATE_ESCAPE)==0)
     {
      Sleep(16);
      //--- si on appuie sur la touche Suppr, efface le symbole personnalisé créé et ses données
      if(TerminalInfoInteger(TERMINAL_KEYSTATE_DELETE)<0)
        {
         //--- efface les données de la barre
         int deleted=CustomRatesDelete(CUSTOM_SYMBOL_NAME0LONG_MAX);
         if(deleted>0)
            PrintFormat("%d history bars of the custom symbol '%s' were successfully deleted"deletedCUSTOM_SYMBOL_NAME);
         
         //--- efface les données du tick
         deleted=CustomTicksDelete(CUSTOM_SYMBOL_NAME0LONG_MAX);
         if(deleted>0)
            PrintFormat("%d history ticks of the custom symbol '%s' were successfully deleted"deletedCUSTOM_SYMBOL_NAME);
         
         //--- supprime le symbole
         if(DeleteCustomSymbol(CUSTOM_SYMBOL_NAME))
            PrintFormat("Custom symbol '%s' deleted successfully"CUSTOM_SYMBOL_NAME);
         break;
        }
     }
//--- efface le graphique avant de sortir
   Comment("");
   /*
   résultat :
   Requested 4294967295 ticks to download tick history for the symbol 'EURUSD'
   The tick history for the 'EURUSDsymbol is received in the amount of 351183943 ticks in 56454 ms
   First tick time2011.12.19 00:00:08.000Last tick time2024.06.20 21:18:12.010
   
   The last 20 ticks for the standard symbol 'EURUSD':
     351183923th Tick2024.06.20 21:17:46.380 Bid=1.07124 (Info tick)
     351183924th Tick2024.06.20 21:17:47.779 Ask=1.07125 Bid=1.07125 (Info tick)
     351183925th Tick2024.06.20 21:17:48.584 Ask=1.07124 Bid=1.07124 (Info tick)
     351183926th Tick2024.06.20 21:17:49.481 Ask=1.07125 (Info tick)
     351183927th Tick2024.06.20 21:17:49.985 Ask=1.07122 Bid=1.07122 (Info tick)
     351183928th Tick2024.06.20 21:17:50.482 Ask=1.07124 Bid=1.07124 (Info tick)
     351183929th Tick2024.06.20 21:17:51.584 Ask=1.07123 Bid=1.07123 (Info tick)
     351183930th Tick2024.06.20 21:17:52.786 Ask=1.07124 Bid=1.07124 (Info tick)
     351183931th Tick2024.06.20 21:17:53.487 Ask=1.07125 Bid=1.07125 (Info tick)
     351183932th Tick2024.06.20 21:17:53.989 Ask=1.07126 Bid=1.07126 (Info tick)
     351183933th Tick2024.06.20 21:17:55.789 Ask=1.07125 Bid=1.07125 (Info tick)
     351183934th Tick2024.06.20 21:17:58.495 Ask=1.07126 Bid=1.07126 (Info tick)
     351183935th Tick2024.06.20 21:18:00.102 Bid=1.07126 (Info tick)
     351183936th Tick2024.06.20 21:18:00.698 Ask=1.07129 Bid=1.07129 (Info tick)
     351183937th Tick2024.06.20 21:18:03.699 Bid=1.07129 (Info tick)
     351183938th Tick2024.06.20 21:18:04.699 Ask=1.07128 Bid=1.07128 (Info tick)
     351183939th Tick2024.06.20 21:18:05.901 Ask=1.07129 Bid=1.07129 (Info tick)
     351183940th Tick2024.06.20 21:18:07.606 Ask=1.07128 Bid=1.07128 (Info tick)
     351183941th Tick2024.06.20 21:18:11.512 Ask=1.07127 Bid=1.07127 (Info tick)
     351183942th Tick2024.06.20 21:18:12.010 Ask=1.07126 Bid=1.07126 (Info tick)
   ...
   Start of adding 351183943 ticks to the history of the custom symbol 'EURUSD.C'
   Added 351183943 ticks to the history of the custom symbol 'EURUSD.Cin 269890 ms
   ...
   Requested 351183943 ticks to download tick history for the symbol 'EURUSD.C'
   The tick history for the 'EURUSD.Csymbol is received in the amount of 351183943 ticks in 116407 ms
   First tick time2011.12.19 00:00:08.000Last tick time2024.06.20 21:18:12.010
   
   The last 20 ticks for the custom symbol 'EURUSD.C':
     351183923th Tick2024.06.20 21:17:46.380 Ask=1.07124 Bid=1.07124 (Info tick)
     351183924th Tick2024.06.20 21:17:47.779 Ask=1.07125 Bid=1.07125 (Info tick)
     351183925th Tick2024.06.20 21:17:48.584 Ask=1.07124 Bid=1.07124 (Info tick)
     351183926th Tick2024.06.20 21:17:49.481 Ask=1.07125 Bid=1.07125 (Info tick)
     351183927th Tick2024.06.20 21:17:49.985 Ask=1.07122 Bid=1.07122 (Info tick)
     351183928th Tick2024.06.20 21:17:50.482 Ask=1.07124 Bid=1.07124 (Info tick)
     351183929th Tick2024.06.20 21:17:51.584 Ask=1.07123 Bid=1.07123 (Info tick)
     351183930th Tick2024.06.20 21:17:52.786 Ask=1.07124 Bid=1.07124 (Info tick)
     351183931th Tick2024.06.20 21:17:53.487 Ask=1.07125 Bid=1.07125 (Info tick)
     351183932th Tick2024.06.20 21:17:53.989 Ask=1.07126 Bid=1.07126 (Info tick)
     351183933th Tick2024.06.20 21:17:55.789 Ask=1.07125 Bid=1.07125 (Info tick)
     351183934th Tick2024.06.20 21:17:58.495 Ask=1.07126 Bid=1.07126 (Info tick)
     351183935th Tick2024.06.20 21:18:00.102 Ask=1.07126 Bid=1.07126 (Info tick)
     351183936th Tick2024.06.20 21:18:00.698 Ask=1.07129 Bid=1.07129 (Info tick)
     351183937th Tick2024.06.20 21:18:03.699 Ask=1.07129 Bid=1.07129 (Info tick)
     351183938th Tick2024.06.20 21:18:04.699 Ask=1.07128 Bid=1.07128 (Info tick)
     351183939th Tick2024.06.20 21:18:05.901 Ask=1.07129 Bid=1.07129 (Info tick)
     351183940th Tick2024.06.20 21:18:07.606 Ask=1.07128 Bid=1.07128 (Info tick)
     351183941th Tick2024.06.20 21:18:11.512 Ask=1.07127 Bid=1.07127 (Info tick)
     351183942th Tick2024.06.20 21:18:12.010 Ask=1.07126 Bid=1.07126 (Info tick)
   */
  }
//+------------------------------------------------------------------+
//| Crée un symbole personnalisé, retourne un code d'erreur          |
//+------------------------------------------------------------------+
int CreateCustomSymbol(const string symbol_nameconst string symbol_pathconst string symbol_origin=NULL)
  {
//--- définit le nom du symbole à partir duquel le symbole personnalisé sera construit
   string origin=(symbol_origin==NULL ? Symbol() : symbol_origin);
   
//--- si le symbole personnalisé n'a pas pu être créé et que le code de l'erreur n'est pas 5304, rapporte cette erreur dans le journal
   ResetLastError();
   int error=0;
   if(!CustomSymbolCreate(symbol_namesymbol_pathorigin))
     {
      error=GetLastError();
      if(error!=5304)
         PrintFormat("CustomSymbolCreate(%s, %s, %s) failed. Error %d"symbol_namesymbol_pathoriginerror);
     }
//--- succès
   return(error);
  }
//+------------------------------------------------------------------+
//| Supprime un symbole personnalisé                                 |
//+------------------------------------------------------------------+
bool DeleteCustomSymbol(const string symbol_name)
  {
//--- cache le symbole de la fenêtre du Market Watch
   ResetLastError();
   if(!SymbolSelect(symbol_namefalse))
     {
      PrintFormat("SymbolSelect(%s, false) failed. Error %d"GetLastError());
      return(false);
     }
      
//--- en cas d'échec de la suppression du symbole personnalisé, rapporte cette erreur dans le journal et retourne 'false'
   ResetLastError();
   if(!CustomSymbolDelete(symbol_name))
     {
      PrintFormat("CustomSymbolDelete(%s) failed. Error %d"symbol_nameGetLastError());
      return(false);
     }
//--- succès
   return(true);
  }
//+------------------------------------------------------------------+
//| Récupère le nombre spécifié de ticks dans le tableau             |
//+------------------------------------------------------------------+
bool GetTicksToArray(const string symbolconst uint countMqlTick &array[])
  {
//--- notification du début du chargement des données de l'historique
   PrintFormat("Requested %u ticks to get tick history for the symbol '%s'"countsymbol);
   
//--- tente 3 fois de récupérer les ticks
   int attempts=0;
   while(attempts<3)
     {
      //--- mesure l'heure de début avec de récupérer les ticks
      uint start=GetTickCount();
      
      //--- demande l'historique depuis le 1970.01.01 00:00.001 (paramètre from=1 ms)
      int received=CopyTicks(symbolarrayCOPY_TICKS_ALL1count);
      if(received!=-1)
        {
         //--- affiche le nombre de ticks et le temps passé
         PrintFormat("The tick history for the '%s' symbol is received in the amount of %u ticks in %d ms"symbolreceivedGetTickCount()-start);
         
         //--- si l'historique des ticks est synchronisé, le code d'erreur est égal à 0 - retourne 'true'
         if(GetLastError()==0)
            return(true);
 
         PrintFormat("%s: Ticks are not synchronized yet, %d ticks received for %d ms. Error=%d"
                     symbolreceivedGetTickCount()-startGetLastError());
        }
      //--- compte le nombre de tentatives
      attempts++; 
      //--- pause d'1 seconde pour attendre la fin de la synchronisation de la base de données des ticks
      Sleep(1000);
     }
//--- échec de la copie des ticks en 3 tentatives
   return(false);
  }
//+------------------------------------------------------------------+ 
//| Retourne la description textuelle d'un tick                      |
//+------------------------------------------------------------------+ 
string GetTickDescription(MqlTick &tick
  { 
   string desc=StringFormat("%s.%03u "TimeToString(tick.timeTIME_DATE|TIME_MINUTES|TIME_SECONDS),tick.time_msc%1000);
   
//--- vérifie les flags du tick
   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); 
   
//--- vérifie le flag de trading en premier (il n'y en a pas pour CustomTicksAdd())
   if(buy_tick || sell_tick
     { 
      //--- construit une sortie pour un tick de trading
      desc += (buy_tick ? StringFormat("Buy Tick: Last=%G Volume=%d "tick.lasttick.volume)  : ""); 
      desc += (sell_tickStringFormat("Sell Tick: Last=%G Volume=%d ",tick.lasttick.volume) : ""); 
      desc += (ask_tick ? StringFormat("Ask=%G "tick.ask) : ""); 
      desc += (bid_tick ? StringFormat("Bid=%G "tick.ask) : ""); 
      desc += "(Trade tick)"
     } 
   else 
     { 
      //--- construit une sortie un peu différente pour un tick d'information
      desc += (ask_tick   ? StringFormat("Ask=%G ",  tick.ask)    : ""); 
      desc += (bid_tick   ? StringFormat("Bid=%G ",  tick.ask)    : ""); 
      desc += (last_tick  ? StringFormat("Last=%G "tick.last)   : ""); 
      desc += (volume_tickStringFormat("Volume=%d ",tick.volume): ""); 
      desc += "(Info tick)"
     } 
//--- retourne la description du tick 
   return(desc); 
  } 

 

Voir aussi

CustomRatesDelete, CustomRatesUpdate, CustomTicksReplace, CopyTicks, CopyTicksRange