Accueil Trading Systématique Publication

Téléchargez l'historique des ticks d'un symbole avec MetaTrader 5

Pièce jointe
56324.zip (3.28 KB, Télécharger 0 fois)

Ce code d'expert advisor va analyser la liste des symboles de votre courtier et télécharger tous les ticks disponibles, ou jusqu'à une date spécifiée.

Cela peut vous aider à récupérer l'historique des symboles pour vos backtests ou à créer un graphique personnalisé à partir de ces ticks.

Assurez-vous d'avoir suffisamment d'espace libre sur votre disque dur, car les ticks seront mis en cache dans le dossier de données de votre terminal.

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

La structure CDownloadManager contient toutes les informations nécessaires.

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

Voici ce que nous avons :

  • l'état du téléchargement (démarré/terminé)
  • la liste des symboles à scanner
  • le symbole courant
  • et l'index du symbole en cours de scan

Nous devrons également lire et écrire sur le disque dur. Comme nous travaillons avec des symboles, nous créons deux fonctions rapides pour écrire et lire des chaînes à partir de fichiers binaires.

La fonction d'écriture de chaîne dans un fichier :

void writeStringToFile(int f, string thestring) {
   // sauvegarder la chaîne du symbole
   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);
   }
}

Cette fonction reçoit :

  • le handle de fichier f, d'un fichier ouvert pour écriture avec les flags FILE_WRITE|FILE_BIN
  • la chaîne à écrire dans le fichier

Elle écrit d'abord un entier représentant la longueur de la chaîne, puis stocke chaque caractère de la chaîne.

La fonction de lecture de chaîne à partir d'un fichier :

string readStringFromFile(int f) {
   string result="";
   // charger la chaîne du symbole
   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 :

  • le handle de fichier f d'un fichier ouvert pour lecture avec les flags FILE_READ|FILE_BIN

Elle lit un entier représentant la longueur des caractères attendus dans le fichier, puis elle lit chaque caractère dans un tableau de caractères et crée une chaîne à partir de ce tableau.

Passons à la structure CDownloadManager. Nous avons besoin d'une méthode pour initialiser le gestionnaire et le remplir à partir de la liste des symboles :

//+------------------------------------------------------------------+
//| Récupérer les symboles de la liste des symboles |
//+------------------------------------------------------------------+
void grab_symbols() {
     //! seulement depuis la liste
     int s=SymbolsTotal(true);
     ArrayResize(m_symbols, s, 0);
     for(int i=0; i < ArraySize(m_symbols); i++) {
       m_symbols[i]=SymbolName(i, true);
    }
}

Assez simple :

  • demander combien de symboles sont dans la liste des symboles (actifs)
  • redimensionner notre tableau m_symbols pour les recevoir
  • boucler sur le total des symboles et demander le nom du symbole

Nous devons également gérer le téléchargement des données des symboles, donc nous aurons besoin d'une fonction qui est essentiellement le gestionnaire :

//+------------------------------------------------------------------+
//| Gérer le processus de téléchargement des symboles |
//+------------------------------------------------------------------+
void manage(string folder, string filename) {
     // essentiellement, cela démarre ou navigue vers le symbole suivant
     // si défini
     if(ArraySize(m_symbols) > 0) {
       // si pas encore démarré
       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("Terminé");
           ExpertRemove();
           return;
      }
    }
    }
    else {
       Print("Veuillez d'abord récupérer les symboles");
    }
    }

Voici comment fonctionne le système :

  • Le graphique s'ouvre ; nous avons besoin d'un graphique et d'un minuteur.
  • Ce minuteur s'exécute, nous annulons le minuteur.
  • 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 récupérant tous les symboles.
  • S'il s'agit d'un téléchargement continu, nous téléchargeons les données pour le symbole courant.

Voici la partie du code qui gère le téléchargement sur minuteur :

//+------------------------------------------------------------------+
//| 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)) {
         //--- système chargé, nous scannons un symbole ici
         Comment("Système chargé et nous traitons " + MANAGER.m_current);
         //--- chargement des ticks
         //--- trouver le tick le plus ancien disponible chez le courtier
         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("Veuillez patienter");
         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("Ancien Tick : " + TimeToString((datetime)(oldest/1000), TIME_DATE | TIME_MINUTES | TIME_SECONDS) + "\nCurseur(" + TimeToString((datetime)(cursorMSC/1000), TIME_DATE | TIME_MINUTES | TIME_SECONDS) + ")\nTentatives(" + IntegerToString(attempts) + ")\nVeuillez patienter pour la réponse...");
      }
       //--- à ce stade, nous avons le tick le plus ancien
       //--- commencer à demander des ticks du plus ancien au plus récent
       if(oldest!=LONG_MAX) {
             ArrayFree(receiver);
             datetime newest_tick=0;
             //--- recevoir le temps du dernier tick pour ce symbole
             datetime most_recent_candle=(datetime)SymbolInfoInteger(_Symbol, SYMBOL_TIME);
             while(newest_tick<most_recent_candle) {
               //--- demander un nouveau lot
               int pulled=CopyTicks(_Symbol, receiver, COPY_TICKS_ALL, oldest, tick_packets);
               if(pulled > 0) {
                 newest_tick=receiver[pulled-1].time;
                 oldest=receiver[pulled-1].time_msc;
                 ArrayFree(receiver);
                }
               //--- délai des requêtes serveur
               Sleep(44);
               Comment("Tiré jusqu'à " + TimeToString(newest_tick, TIME_DATE | TIME_MINUTES | TIME_SECONDS) + " jusqu'à présent");
          }
      }
       else {
             Alert("Veuillez fermer le terminal \n allez dans le dossier des ticks \n et supprimez les dossiers vides");
           ExpertRemove();
      }
       //--- mettre à jour le gestionnaire et passer à la suite
     MANAGER.manage(MANAGER_FOLDER, MANAGER_STATUS_FILE);
    }
    else {
       //--- récupérer les symboles pour commencer le téléchargement
     Comment("Récupération de la liste et démarrage");
     MANAGER.grab_symbols();
     MANAGER.manage(MANAGER_FOLDER, MANAGER_STATUS_FILE);
    }
  }
}

En résumé, ce code vous permet de télécharger l'historique des ticks pour une série de symboles directement depuis votre plateforme de trading. Une fois que vous avez tout configuré, le téléchargement se fait automatiquement, ce qui vous laisse plus de temps pour analyser vos données et prendre des décisions éclairées.

Articles connexes

Commentaire (0)