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
- Utiliser MQL5 Wizard pour Créer un Expert Advisor Basé sur les Modèles de Chandeliers Englobants et MFI
- Développez un Expert Advisor avec MQL5 : Signaux de Trading 3 Corbeaux Noirs / 3 Soldats Blancs + RSI
- Lazy Bot MT5 : L'EA idéal pour le trading quotidien sur MetaTrader 5
- Découvrez CoensioTrader1V06 : Votre nouvel allié sur MetaTrader 5
- Découvrez Exp5-VirtualTradePad : L'outil incontournable pour MetaTrader 5