Voir comment télécharger gratuitement des robots de trading
Retrouvez-nous sur Twitter !
Rejoignez notre page de fans
Un script intéressant ?
Poster un lien vers celui-ci -
laisser les autres l'évaluer
Vous avez aimé le script ? Essayez-le dans le terminal MetaTrader 5
Experts

Download all ticks of a symbol's history - expert pour MetaTrader 5

Vues:
111
Note:
(5)
Publié:
MQL5 Freelance Besoin d'un robot ou d'un indicateur basé sur ce code ? Commandez-le sur Freelance Aller sur Freelance

Ce code de conseiller expert analysera la surveillance du marché du courtier de l'utilisateur et extraira les symboles pour lesquels il téléchargera tous les ticks disponibles, ou les ticks jusqu'à une date donnée.

Cela peut vous aider à télécharger tout l'historique des symboles pour votre backtest, ou à créer un graphique personnalisé à partir de ces ticks.

Les terminaux mettront les ticks en cache dans le dossier de données, assurez-vous donc que vous disposez de suffisamment d'espace sur votre disque dur.

Pour faciliter le téléchargement des symboles, nous avons d'abord besoin d'un gestionnaire de téléchargement.

La structure CDownloadManager contient toutes les informations que nous devrons conserver.

struct CDownloadManager
  {
   bool              m_started,m_finished;
   string            m_symbols[],m_current;
   int               m_index;

  • l'état du téléchargement (commencé/terminé)
  • la liste des symboles à analyser
  • le symbole actuel
  • et l'index du symbole en cours d'analyse

Nous aurons également besoin de lire et d'écrire sur le disque dur et, puisque nous travaillons avec des symboles, nous créons deux fonctions rapides pour écrire et lire des chaînes de caractères à partir de fichiers binaires.

La fonction "enregistrer une chaîne dans un fichier" :

void writeStringToFile(int f,string thestring)
  {
//sauvegarde de la chaîne de symboles
   char sysave[];
   int charstotal=StringToCharArray(thestring,sysave,0,StringLen(thestring),CP_ACP);
   FileWriteInteger(f,charstotal,INT_VALUE);
   for(int i=0;i<charstotal;i++)
     {
      FileWriteInteger(f,sysave[i],CHAR_VALUE);
     }
  }

Elle reçoit :

  • l'identifiant f, d'un fichier ouvert en écriture et les drapeaux binaires FILE_WRITE|FILE_BIN
  • la chaîne de caractères à écrire dans le fichier

Elle écrit une longueur entière correspondant au nombre de caractères contenus dans la chaîne, puis stocke chaque caractère dans la chaîne.

La fonction load string from file (charger la chaîne de caractères du fichier) :

string readStringFromFile(int f)
  {
   string result="";
//chargement de la chaîne de symboles
   char syload[];
   int charstotal=(int)FileReadInteger(f,INT_VALUE);
   if(charstotal>0)
     {
      ArrayResize(syload,charstotal,0);
      for(int i=0;i<charstotal;i++)
        {
         syload[i]=(char)FileReadInteger(f,CHAR_VALUE);
        }
      result=CharArrayToString(syload,0,charstotal,CP_ACP);
     }
   return(result);
  }

Elle reçoit :

  • l'identifiant f d'un fichier ouvert en lecture binaire, les drapeaux FILE_READ|FILE_BIN

Elle lit une longueur entière indiquant le nombre de caractères attendus à cet endroit du fichier. Elle lit chaque caractère dans un tableau de caractères, puis crée une chaîne de caractères à partir de ce tableau de caractères, qui est renvoyée en tant que résultat de la fonction load as a string (charger une chaîne de caractères).

Revenons à la structure CDownloadManager . Nous avons besoin d'un moyen d'initialiser le gestionnaire et de le remplir à partir de la veille du marché :

   //+------------------------------------------------------------------+
   //| saisir les symboles de la surveillance du marché|
   //+------------------------------------------------------------------+
   void              grab_symbols()
     {
      // ! uniquement à partir du mw !
      int s=SymbolsTotal(true);
      ArrayResize(m_symbols,s,0);
      for(int i=0;i<ArraySize(m_symbols);i++)
        {
         m_symbols[i]=SymbolName(i,true);
        }
     }

C'est assez simple :

  • demander le nombre de symboles présents dans la veille (actifs)
  • redimensionner notre tableau m_symbols pour les recevoir
  • faire une boucle dans le nombre total de symboles et demander le nom du symbole.

Nous sommes également responsables de la gestion du téléchargement des données des symboles, nous aurons donc besoin d'une fonction qui sera essentiellement le gestionnaire :

   //+------------------------------------------------------------------+
   //| Gérer le processus de téléchargement des symboles|
   //+------------------------------------------------------------------+
   void              manage(string folder,string filename)
     {
      //essentiellement, cela permet de démarrer ou de naviguer vers le symbole suivant
      //si défini
      if(ArraySize(m_symbols)>0)
        {
         //si elle n'est pas démarrée
         if(!m_started)
           {
            m_started=true;
            //Aller au premier symbole
            m_current=m_symbols[0];
            m_index=1;
            save(folder,filename);
            if(_Symbol!=m_current)
              {
               ChartSetSymbolPeriod(ChartID(),m_current,_Period);
              }
            else
              {
               ENUM_TIMEFRAMES new_period=PERIOD_M1;
               for(int p=0;p<ArraySize(TFS);p++)
                 {
                  if(_Period!=TFS[p])
                    {
                     new_period=TFS[p];
                     break;
                    }
                 }
               ChartSetSymbolPeriod(ChartID(),m_current,new_period);
              }
            return;
           }
         //si démarré
         else
           {
            m_index++;
            if(m_index<=ArraySize(m_symbols))
              {
               m_current=m_symbols[m_index-1];
               save(folder,filename);
               if(_Symbol!=m_current)
                 {
                  ChartSetSymbolPeriod(ChartID(),m_current,_Period);
                 }
               return;
              }
            else
              {
               m_finished=true;
               FileDelete(folder+"\\"+filename);
               Print("Finished");
               ExpertRemove();
               return;
              }
           }
        }
      else
        {
         Print("Please grab symbols first");
        }
      //si l'ensemble se termine ici
     }

Comment le système fonctionne-t-il ?

  • Le graphique s'ouvre, nous avons besoin d'un graphique, et un minuteur est mis en place.
  • Cette minuterie s'exécute, nous l'annulons.
  • Nous vérifions s'il s'agit d'un nouveau téléchargement ou d'un téléchargement continu.
  • S'il s'agit d'un nouveau téléchargement, nous le configurons en saisissant tous les symboles.
  • S'il s'agit d'un téléchargement continu, nous téléchargeons les données pour le symbole en cours.

Voici la partie du code qui exécute le téléchargement sur la minuterie :

//+------------------------------------------------------------------+
//|Timer|
//+------------------------------------------------------------------+
void OnTimer()
  {
//--- si synchronisé
   if(SymbolIsSynchronized(_Symbol)&&TerminalInfoInteger(TERMINAL_CONNECTED)==1)
     {
      EventKillTimer();
      //--- charger le système ici
      if(MANAGER.load(MANAGER_FOLDER,MANAGER_STATUS_FILE))
        {
         //--- le système est chargé, nous analysons donc un symbole ici
         Comment("System loaded and we are processing "+MANAGER.m_current);
         //--- tick load

         //--- recherche d'abord le plus ancien tick disponible dans le broker
         int attempts=0;
         int ping=-1;
         datetime cursor=flatten(TimeTradeServer());
         long cursorMSC=((long)cursor)*1000;
         long jump=2592000000;//60*60*24*30*1000 ;

         MqlTick receiver[];
         long oldest=LONG_MAX;
         Comment("PleaseWait");
         while(attempts<5)
           {
            ping=CopyTicks(_Symbol,receiver,COPY_TICKS_ALL,cursorMSC,1);
            if(ping==1)
              {
               if(receiver[0].time_msc==oldest)
                 {
                  attempts++;
                 }
               else
                 {
                  attempts=0;
                 }
               if(receiver[0].time_msc<oldest)
                 {
                  oldest=receiver[0].time_msc;
                 }
               cursorMSC-=jump;
               if(limitDate&&receiver[0].time<=oldestLimit)
                 {
                  break;
                 }
              }
            else
              {
               attempts++;
              }

            Sleep(44);
            Comment("Oldest Tick : "+TimeToString((datetime)(oldest/1000),TIME_DATE|TIME_MINUTES|TIME_SECONDS)+"\nCursor("+TimeToString((datetime)(cursorMSC/1000),TIME_DATE|TIME_MINUTES|TIME_SECONDS)+")\nAttempts("+IntegerToString(attempts)+")\nPlease wait for response...");
           }
         //--- à ce stade, nous avons la plus ancienne tique
         //--- commencer à demander des ticks du plus ancien au plus récent
         if(oldest!=LONG_MAX)
           {
            ArrayFree(receiver);
            datetime newest_tick=0;
            //--- reçoit l'heure du dernier tick pour ce symbole stocké dans symbol_time
            datetime most_recent_candle=(datetime)SymbolInfoInteger(_Symbol,SYMBOL_TIME);
            while(newest_tick<most_recent_candle)
              {
               //--- demande un nouveau lot à partir de l'heure la plus ancienne avec la limite de ticks spécifiée
               int pulled=CopyTicks(_Symbol,receiver,COPY_TICKS_ALL,oldest,tick_packets);
               if(pulled>0)
                 {
                  //--- si nous tirons un nouveau lot, nous mettons à jour les temps téléchargés
                  newest_tick=receiver[pulled-1].time;
                  oldest=receiver[pulled-1].time_msc;
                  ArrayFree(receiver);
                 }
               //--- délai d'attente pour les requêtes du serveur, modifiez-le si vous le souhaitez
               Sleep(44);
               Comment("Pulled up to "+TimeToString(newest_tick,TIME_DATE|TIME_MINUTES|TIME_SECONDS)+" so far");
              }
           }
         else
           {
            Alert("Please close the terminal \n head over to the ticks folder \n and delete the empty folders");
            ExpertRemove();
           }
         //--- mettre à jour le gestionnaire et continuer
         MANAGER.manage(MANAGER_FOLDER,MANAGER_STATUS_FILE);
        }
      else
        {
         //--- saisir les symboles de surveillance du marché pour commencer le téléchargement
         Comment("Grabbing MW and starting");
         MANAGER.grab_symbols();
         MANAGER.manage(MANAGER_FOLDER,MANAGER_STATUS_FILE);
        }
     }
  }


Traduit de l’anglais par MetaQuotes Ltd.
Code original : https://www.mql5.com/en/code/56324

Histogramme coloré MACD Histogramme coloré MACD

L'histogramme coloré MACD est une version améliorée de l'indicateur MACD (Moving Average Convergence Divergence) classique, conçu pour fournir une analyse visuelle plus claire et plus intuitive de la dynamique du marché. Cet indicateur combine les fonctionnalités traditionnelles du MACD avec un histogramme dynamique qui change de couleur en fonction de la relation entre la ligne MACD et la ligne de signal, ce qui permet aux traders d'identifier rapidement les tendances, les points de retournement et les moments d'indécision sur le marché.

MACD Histogram, multi-timeframe, multi-color [v03] MACD Histogram, multi-timeframe, multi-color [v03]

L'indicateur MACD avec histogramme peut être appliqué à n'importe quel horizon temporel (supérieur ou inférieur à l'horizon temporel du graphique actuel).

Functions to simplify work with orders Functions to simplify work with orders

Tout ce que nous voulons, c'est penser aux algorithmes et aux méthodes, et non à la syntaxe et aux valeurs permettant de passer des ordres. Vous trouverez ici des fonctions simples pour gérer les positions en MQL5.

RSI multi-timeframe [v03] RSI multi-timeframe [v03]

L'indicateur RSI peut être appliqué à n'importe quel horizon temporel (supérieur ou inférieur à l'horizon temporel du graphique actuel).