Voir comment télécharger gratuitement des robots de trading
Retrouvez-nous sur Telegram !
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
Vues:
37
Note:
(7)
Publié:
2025.06.14 11:57
MQL5 Freelance Besoin d'un robot ou d'un indicateur basé sur ce code ? Commandez-le sur Freelance Aller sur Freelance

L'installation

Nous aurons besoin de :

  • 1 graphique en zigzag
  • 2 tampons de données pour les hauts et les bas
  • des paramètres d'entrée
  • un ensemble continu de variables système qui se réinitialisent à chaque fois que l'indicateur recalcule.

#property indicator_buffers 2
#property indicator_plots 1
input double retracement=23.6;//Montant du retracement
input double minSizeInAtrUnits=0.0;//Taille minimale des vagues en unités d'atr
input int rollingAtrPeriod=14;//Période de l'ATR
input color Color=clrDodgerBlue;//couleur de l'onde
input int Width=3;//Largeur d'onde
input ENUM_LINE_STYLE Style=STYLE_SOLID;//style vague
//+------------------------------------------------------------------+




//| Fonction d'initialisation de l'indicateur personnalisé
//+------------------------------------------------------------------+
//--- les vagues montantes et les vagues descendantes
  double upWaves[],dwWaves[];

Le tableau upWaves stockera les sommets et le tableau dwWaves stockera les creux.

Variables système :

nous devons connaître le type de la dernière vague, où elle a commencé, où elle s'est terminée, la distance en barres entre le début et la fin.

Ensuite, nous avons besoin d'une variable locale haute et d'une variable locale basse, ainsi que des distances en barres à partir de chaque point.

//--- suivi du zigzag
  //--- le type de vague que nous avons [0] aucun [1] en hausse [2] en baisse
    int wave_type=0;
  //--- le prix de la vague (prix de départ) 
    double wave_start_price=0.0;
  //--- le prix de la vague (prix final)
    double wave_end_price=0.0;
  //--- la distance en barres depuis le prix de départ
    int wave_start_distance=0;
  //--- la distance en barres à partir du prix final
    int wave_end_distance=0;
  //--- suivi des prix élevés
    double high_mem=0.0;
    int distance_from_high=0;
  //--- suivi des prix bas
    double low_mem=0.0;
    int distance_from_low=0;
  //--- rolling atr
    double rollingAtr=0.0;
       int rollingAtrs=0;

Enfin, l'unité rolling atr et le nombre d'unités calculées.

Nous créons ensuite une fonction de réinitialisation du système :

void resetSystem(){
ArrayFill(upWaves,0,ArraySize(upWaves),0.0);
ArrayFill(dwWaves,0,ArraySize(dwWaves),0.0);
wave_type=0;
wave_start_price=0.0;
wave_end_price=0.0;
wave_start_distance=0;
wave_end_distance=0;
high_mem=0.0;
low_mem=0.0;
distance_from_high=0;
distance_from_low=0;
rollingAtr=0.0;
rollingAtrs=0;
}

Nous créons ensuite une fonction de réinitialisation du système, qui remplit les tableaux avec des zéros et réinitialise les variables du système.

Oninit nous configurons les tampons, le tracé, et nous appelons reset pour la première fois :

  SetIndexBuffer(0,upWaves,INDICATOR_DATA);
  SetIndexBuffer(1,dwWaves,INDICATOR_DATA);
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
   PlotIndexSetInteger(0,PLOT_DRAW_TYPE,DRAW_ZIGZAG);
   PlotIndexSetInteger(0,PLOT_LINE_COLOR,0,Color);
   PlotIndexSetInteger(0,PLOT_LINE_WIDTH,Width);
   PlotIndexSetInteger(0,PLOT_LINE_STYLE,Style);
  resetSystem();

Passons donc directement aux calculs.

La première chose dont nous devons nous occuper est le rolling atr.

Tant que nous n'avons pas collecté plus de barres que la période de l'atr, nous ne ferons rien d'autre.

La partie qui gère le rolling atr est la suivante :

  • si nous n'avons pas collecté plus de barres que la période, nous continuons à ajouter la plage des barres trouvées à une sommation
  • une fois la période atteinte, nous effectuons la première division (moyenne)
  • Ensuite, nous enlevons une partie de l'ATR mobile, qui est l'ATR/période, puis nous ajoutons une nouvelle partie qui est la fourchette de la barre/période.
nous plaçons la dernière partie en premier parce qu'elle se produit plus souvent et que nous n'avons pas besoin d'accéder à deux instructions if.

     //--- gérer l'atr
       rollingAtrs++;
       if(rollingAtrs>rollingAtrPeriod){
       double new_portion=((high[i]-low[i])/_Point)/((double)rollingAtrPeriod);
       //--- nous supprimons une ancienne partie et ajoutons une nouvelle partie
       rollingAtr=(rollingAtr)-(rollingAtr/((double)rollingAtrPeriod))+new_portion;
       }
       else if(rollingAtrs<=rollingAtrPeriod){
         rollingAtr+=(high[i]-low[i])/_Point;
         if(rollingAtrs==rollingAtrPeriod){
           rollingAtr/=((double)rollingAtrs);
           //--- démarrer la mémoire pour les hauts et les bas et le système
             high_mem=high[i];
             low_mem=low[i];
             distance_from_high=0;
             distance_from_low=0;
           }
         }

Génial, maintenant, il y a un autre problème.

La base de ce zig zag est un retracement.

Mais pour qu'un retracement se produise, il doit y avoir au moins une vague.

Mais quel sera le retracement de la première vague ? xD

Pour cette raison, nous ferons ce qui suit :

  • dès que l'atr se remplit (atr collecté = période) , nous saisissons le plus haut et le plus bas dans nos variables système
  • Le côté qui réussit à former une vague qui a une taille valide en unités d'atr, et qui forme un nouveau haut (vague ascendante) ou un nouveau bas (vague descendante) gagne.

De cette façon, nous n'avons pas de retracement comme vague initiale, mais nous devons commencer la séquence d'une manière ou d'une autre.

Nous aurions également pu opter pour une approche fractale classique pour la première vague seulement et continuer ensuite avec des retracements.

C'est ce que nous faisons tant que nous n'avons pas de vague :

   //--- si nous n'avons pas encore de type de vague
     else{
       //--- si nous avons cassé le plus haut et pas le plus bas
         if(high[i]>high_mem&&low[i]>=low_mem){
         double new_wave_size_in_atr_units=((high[i]-low_mem)/_Point)/rollingAtr;
         //--- si la nouvelle taille de la vague est valide
         if(new_wave_size_in_atr_units>=minSizeInAtrUnits){
           //--- commencer une nouvelle vague ascendante 
             wave_type=1;
           //--- le prix de départ est le prix le plus bas 
             wave_start_price=low_mem;
             wave_start_distance=distance_from_low;
           //--- le prix final est le nouveau maximum
             wave_end_price=high[i];
             wave_end_distance=0;
           //--- dessiner la vague 
             dwWaves[i-wave_start_distance]=low_mem;
             upWaves[i]=high[i];
           //--- changer le niveau élevé
             high_mem=high[i];
             distance_from_high=0;
           //--- changer le bas 
             low_mem=low[i];
             distance_from_low=0;
           }
           } 
       //--- si nous avons cassé le plus bas et non le plus haut
         else if(low[i]<low_mem&&high[i]<=high_mem){
         double new_wave_size_in_atr_units=((high_mem-low[i])/_Point)/rollingAtr;
         //--- si la nouvelle taille de la vague est valide
         if(new_wave_size_in_atr_units>=minSizeInAtrUnits){         
           //--- commencer une nouvelle vague de baisse 
             wave_type=-1;
           //--- le prix de départ est le prix le plus élevé 
             wave_start_price=high_mem;
             wave_start_distance=distance_from_high;
           //--- le prix final est le nouveau prix le plus bas
             wave_end_price=low[i];
             wave_end_distance=0;
           //--- dessiner la vague 
             upWaves[i-wave_start_distance]=high_mem;
             dwWaves[i]=low[i];
           //--- changer le niveau élevé
             high_mem=high[i];
             distance_from_high=0;
           //--- changer le bas 
             low_mem=low[i];
             distance_from_low=0;
           }
           }
       //--- si nous avons cassé les deux
         else if(low[i]<low_mem&&high[i]>high_mem){
           //--- les modifier
             high_mem=high[i];
             low_mem=low[i];
             distance_from_high=0;
             distance_from_low=0;
           }
       }

Très bien. Maintenant, la dernière étape.

  • Si nous avons une vague haussière :
  1. si un nouveau sommet est atteint, déplacez le zigzag de la position du sommet précédent à la position du nouveau sommet, ce que nous pouvons faire puisque nous conservons les distances entre les barres. Nous mettons également à jour le creux et la distance par rapport au creux. Nous faisons cela afin de pouvoir attraper le creux le plus bas depuis le sommet et vérifier s'il retrace suffisamment pour commencer un nouveau creux.
  2. si un nouveau plus bas est atteint, ou si un nouveau plus bas est fixé, nous calculons la distance entre le pic et le plus bas et la divisons par la taille de la vague. Ainsi, si la taille de la vague est de 100 points et que le retracement est de 24 points, nous obtenons 24/100 0,24, puis x 100 24%. Si la taille de la nouvelle vague qui retrace la précédente est également valide par rapport aux unités de l'ATR, nous commençons une nouvelle vague descendante, nous fixons les nouveaux hauts et bas locaux, nous fixons les distances entre les barres.

Voici le code correspondant à ce qui précède :

       //--- si nous avons une vague ascendante 
         if(wave_type==1){
           //--- si l'onde s'étend vers le haut 
             if(high[i]>wave_end_price){
               //--- supprimer le prix final précédent de sa position dans le tableau (0.0=vide)
                upWaves[i-wave_end_distance]=0.0;
               //--- le placer sur la nouvelle position
                upWaves[i]=high[i];
                wave_end_price=high[i];
                wave_end_distance=0;
               //--- changer le niveau élevé
                high_mem=high[i];
                distance_from_high=0;
               //--- changer le bas 
                low_mem=low[i];
                distance_from_low=0;
               }
           //--- vérifier le retracement
             if(low[i]<low_mem||distance_from_low==0){
               low_mem=low[i];
               distance_from_low=0;
               double size_of_wave=(wave_end_price-wave_start_price)/_Point;
               double size_of_retracement=(wave_end_price-low_mem)/_Point;
               if(size_of_wave>0.0){
                 double retraced=(size_of_retracement/size_of_wave)*100.0;
                 double new_wave_size_in_atr_units=((wave_end_price-low_mem)/_Point)/rollingAtr;
               //--- si la nouvelle taille de la vague est valide
               if(new_wave_size_in_atr_units>=minSizeInAtrUnits){
                 //--- si le retracement est significatif, commencer une vague de baisse
                   if(retraced>=retracement){
                    //--- commencer une nouvelle vague de baisse 
                      wave_type=-1;
                    //--- le prix de départ est le prix le plus élevé 
                      wave_start_price=high[i-distance_from_high];
                      wave_start_distance=distance_from_high;
                    //--- le prix final est le nouveau prix le plus bas
                      wave_end_price=low[i];
                      wave_end_distance=0;
                    //--- dessiner la vague 
                      upWaves[i-wave_start_distance]=high_mem;
                      dwWaves[i]=low[i];
                    //--- changer le niveau élevé
                      high_mem=high[i];
                      distance_from_high=0;
                    //--- changer le bas 
                      low_mem=low[i];
                      distance_from_low=0;                     
                     }
                   }
                 }
               }
           }

Nous faisons l'inverse lorsque nous avons une vague descendante.

Et nous avons terminé, notre zig zag de retracement est prêt.

Voici le zigzag avec un retracement de 23,6% et une taille de vague de 0,0 min en unités d'atr.


et voici le même zig zag avec des vagues de taille 3 min en unités atr






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

TradeReportExporter TradeReportExporter

Le script TradeReportExporter est conçu pour exporter l'historique des transactions (trades) dans un fichier CSV pratique. Il recueille automatiquement les données relatives à toutes les transactions effectuées au cours de l'année écoulée pour l'instrument sur lequel il est installé. Le fichier comprend des données telles que la date et l'heure, le type de transaction (achat/vente), le prix, le volume, la commission et le profit/perte. Le résultat est enregistré dans un fichier qui peut être ouvert dans Excel ou tout autre tableur.

A Really Random Robot A Really Random Robot

Ce robot utilise un générateur de nombres aléatoires pour simuler un simple jeu de pile ou face afin de décider de la direction de chaque transaction. Il fournit un exemple de conseiller expert minimal programmé dans un style orienté objet. Il fournit également une base pour quantifier la valeur ajoutée des méthodes alternatives d'entrée.

Indice de la force relative de la volatilité Indice de la force relative de la volatilité

L'IFR est calculé à partir des valeurs de l'écart-type.

Fichier Ticks Fichier Ticks

Un Expert Advisor qui vous permet non seulement de sauvegarder les informations sur les ticks dans un fichier, mais aussi d'enregistrer les ticks modélisés par le testeur.