//+------------------------------------------------------------------+
//| Test_ChartSaveTemplate.mq5 |
//| Copyright 2000-2024, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2000-2024, MetaQuotes Ltd."
#property link "https://www.mql5.com"
#property version "1.00"
#property script_show_inputs
//--- input parameters
input string symbol="GBPUSD"; // le symbole d'un nouveau graphique
input ENUM_TIMEFRAMES period=PERIOD_H3; // le timeframe d'un nouveau graphique
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- tout d'abord attachons les indicateurs au graphique
int handle;
//---préparons l'indicateur à l'utilisation
if(!PrepareZigzag(NULL,0,handle)) return; // la tentative a échoué, sortons
//--- attachons l'indicateur sur le graphique actuel, mais dans une fenêtre séparée
if(!ChartIndicatorAdd(0,1,handle))
{
PrintFormat("On n'a pas réussi à ajouter %s/%s l'indicateur avec le handle =%d sur le graphique. Code de l'erreur %d",
_Symbol,
EnumToString(_Period),
handle,
GetLastError());
//--- cessons avant terme le travail du programme
return;
}
//--- ordonnons au graphique de mettre à jour pour voir tout de suite l'indicateur attaché
ChartRedraw();
//--- trouvons deux dernières fractures du zigzag
double two_values[];
datetime two_times[];
if(!GetLastTwoFractures(two_values,two_times,handle))
{
PrintFormat("On n'a pas réussi à trouver deux dernières fractures dans l'indicateur Zigzag!");
//--- cessons avant terme le travail du programme
return;
}
//--- maintenant attachons le canal de la divergence standard
string channel="StdDeviation Channel";
if(!ObjectCreate(0,channel,OBJ_STDDEVCHANNEL,0,two_times[1],0))
{
PrintFormat("On n'a pas réussi à créer l'objet %s. Code de l'erreur %d",
EnumToString(OBJ_STDDEVCHANNEL),GetLastError());
return;
}
else
{
//--- le canal est créé, définissons le deuxième point d'appui
ObjectSetInteger(0,channel,OBJPROP_TIME,1,two_times[0]);
//--- spécifions le texte de l'infobulle au canal
ObjectSetString(0,channel,OBJPROP_TOOLTIP,"Demo from MQL5 Help");
//--- mettons à jour le graphique
ChartRedraw();
}
//--- sauvegardons le résultat dans un modèle
ChartSaveTemplate(0,"StdDevChannelOnZigzag");
//--- ouvrons un nouveau graphique et y attachons un modèle sauvegardé
long new_chart=ChartOpen(symbol,period);
//--- activons la démonstration des infobulles émergentes pour les objets graphiques
ChartSetInteger(new_chart,CHART_SHOW_OBJECT_DESCR,true);
if(new_chart!=0)
{
//--- attachons un modèle sauvegardé sur un nouveau graphique
ChartApplyTemplate(new_chart,"StdDevChannelOnZigzag");
}
Sleep(10000);
}
//+--------------------------------------------------------------------+
//| Créé le handle du zigzag et assure la disponibilité de ses données |
//+--------------------------------------------------------------------+
bool PrepareZigzag(string sym,ENUM_TIMEFRAMES tf,int &h)
{
ResetLastError();
//--- l'indicateur Zigzag doit être dans le dossier le répertoire_des données_du terminal\MQL5\Examples
h=iCustom(sym,tf,"Examples\\Zigzag");
if(h==INVALID_HANDLE)
{
PrintFormat("%s: On n'a pas réussi à créer le handle de l'indicateur Zigzag. Code de l'erreur %d",
__FUNCTION__,GetLastError());
return false;
}
//--- pendant la création du handle de l'indicateur dont il aura besoin de temps pour calculer les valeurs
int k=0; // la quantité de tentatives pour attendre le calcul de l'indicateur
//--- attendons le calcul dans la boucle, faisons la pause de 50 millisecondes, si le calcul n'est pas encore prêt
while(BarsCalculated(h)<=0)
{
k++;
//--- déduisons le nombre de tentatives
PrintFormat("%s: k=%d",__FUNCTION__,k);
//--- attendons 50 millisecondes, alors que l'indicateur sera calculé
Sleep(50);
//--- Si est fait plus de 100 tentatives, alors quelque chose ne va pas
if(k>100)
{
//--- informons sur le problème
PrintFormat("On n'a pas réussi à calculer l'indicateur pour%d de tentatives!");
//--- cessons avant terme le travail du programme
return false;
}
}
//--- tout est prêt, l'indicateur est créé et les valeurs sont calculées
return true;
}
//+------------------------------------------------------------------+
//| Cherche deux dernières fractures du zigzag et place aux tableaux |
//+------------------------------------------------------------------+
bool GetLastTwoFractures(double &get_values[],datetime &get_times[],int handle)
{
double values[]; // le tableau pour la réception des valeurs du zigzag
datetime times[]; // le tableau pour recevoir le temps
int size=100; // la taille des tableaux
ResetLastError();
//--- copions les dernières 100 valeurs de l'indicateur
int copied=CopyBuffer(handle,0,0,size,values);
//--- vérifions combien on a été copié
if(copied<100)
{
PrintFormat("%s: On n'a pas réussi à copier %d valeurs de l'indicateur avec le handle=%d. Code de l'erreur %d",
__FUNCTION__,size,handle,GetLastError());
return false;
}
//--- définissons l'ordre de l'accès au tableau comme dans une série temporelle
ArraySetAsSeries(values,true);
//--- inscrivons ici les numéros des barres, sur lesquelles sont trouvés les fractures
int positions[];
//--- spécifions les tailles des tableaux
ArrayResize(get_values,3); ArrayResize(get_times,3); ArrayResize(positions,3);
//--- compteurs
int i=0,k=0;
//--- commençons la recherche des fractures
while(i<100)
{
double v=values[i];
//--- les valeurs vides ne nous intéressent pas
if(v!=0.0)
{
//--- rappelons le numéro de la barre
positions[k]=i;
//--- rappelez la valeur du zigzag dans la fracture
get_values[k]=values[i];
PrintFormat("%s: Zigzag[%d]=%G",__FUNCTION__,i,values[i]);
//--- augmentons le compteur
k++;
//--- si on a trouvé deux fractures, nous cassons la boucle
if(k>2) break;
}
i++;
}
//--- définissons l'ordre de l'accès aux tableaux comme dans une série temporelle
ArraySetAsSeries(times,true); ArraySetAsSeries(get_times,true);
if(CopyTime(_Symbol,_Period,0,size,times)<=0)
{
PrintFormat("%s: On n'a pas réussi à copier %d valeurs de CopyTime(). Code de l'erreur %d",
__FUNCTION__,size,GetLastError());
return false;
}
//--- trouvons le temps de l'ouverture des barres, sur lesquelles il y avait 2 dernières fractures
get_times[0]=times[positions[1]];// la valeur avant-dernière sera inscrite par la première fracture
get_times[1]=times[positions[2]];// la troisième valeur de la fin sera la deuxième fracture
PrintFormat("%s: le premier=%s, le deuxième=%s",__FUNCTION__,TimeToString(get_times[1]),TimeToString(get_times[0]));
//--- tout a réussi
return true;
}
|