Question sur l'indicateur - page 3

 
Agent86:
.

De toute façon, j'essayais de faire en sorte que les fractales hautes ne se forment que lorsqu'une autre condition se produit, comme le croisement d'un iMACD, d'une EMA ou d'un autre indicateur.
Ainsi, les fractales n'apparaîtront sur l'indicateur que lorsque toutes les conditions seront remplies.


Je n'étais pas sûr de ce que vous essayez de faire mais essayez ceci, remarquez les entrées externes.

#property indicator_chart_window      extern bool condition1 = true;
#property indicator_buffers 3         extern bool condition2 = true;
#property indicator_color1 Red
#property indicator_color2 Blue
#property indicator_color3 White

//---- buffers
double v1[];
double v2[];
double v3[];
double val1;
double val2;
double val3;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int init()
  {
//----
   IndicatorBuffers(3);

   SetIndexArrow(0, 111);
   SetIndexStyle(0,DRAW_ARROW,STYLE_DOT,1,Blue);
   SetIndexBuffer(0, v1);
   SetIndexLabel(0,"Resistance");

   SetIndexArrow(1, 111);
   SetIndexStyle(1,DRAW_ARROW,STYLE_DOT,1,Red);
   SetIndexBuffer(1, v2);
   SetIndexLabel(1,"Support");

   SetIndexArrow(2, 111);
   SetIndexStyle(2,DRAW_ARROW,STYLE_DOT,1,White);
   SetIndexBuffer(2, v3);
   SetIndexLabel(2,"High A"); 
//----
   return(0);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int start()
  {
    
   double   faster = iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,1), //MODE_MAIN
            slower = iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,1); //MODE_SIGNAL
           
            
   int bars = Bars;
//----
  
   for(int i=bars; i>=0; i--)
    {
     if(condition1)
       {
        val1=iFractals(NULL, 0, MODE_UPPER,i);
        if (val1 > 0) v1[i]=High[i];       
       }   
     if(condition2)
       {      
        val2=iFractals(NULL, 0, MODE_LOWER,i);
        if (val2 > 0) v2[i]=Low[i];
       }
     }    
//----
   return(0);
  }
//+------------------------------------------------------------------+
 
WHRoeder:
Comment êtes-vous arrivé à cette conclusion exactement et quelle est la différence fonctionnelle ?

J'en suis arrivé à cette conclusion, parce que j'ai probablement regardé du point de vue de la POO. Oui, ce n'est pas vrai pour le cas de MQL4, je m'en souviens maintenant. Bien que cela puisse être une bonne pratique ?



 

Ou peut-être quelque chose comme ceci ?

vous devriez vraiment utiliser IndicatorCounted(), parce que si vous le faites comme ça, votre indicateur redessine tous ces objets à chaque nouveau tick au lieu de les dessiner tous en une seule fois et d'en ajouter de nouveaux au fur et à mesure que les barres se forment.

#property indicator_chart_window
#property indicator_buffers 3
#property indicator_color1 Red
#property indicator_color2 Blue
#property indicator_color3 White

//---- buffers
double v1[];
double v2[];
double v3[];
double val1;
double val2;
double val3;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int init()
  {
//----
   IndicatorBuffers(3);

   SetIndexArrow(0, 111);
   SetIndexStyle(0,DRAW_ARROW,STYLE_DOT,1,Blue);
   SetIndexBuffer(0, v1);
   SetIndexLabel(0,"Resistance");

   SetIndexArrow(1, 111);
   SetIndexStyle(1,DRAW_ARROW,STYLE_DOT,1,Red);
   SetIndexBuffer(1, v2);
   SetIndexLabel(1,"Support");

   SetIndexArrow(2, 111);
   SetIndexStyle(2,DRAW_ARROW,STYLE_DOT,1,White);
   SetIndexBuffer(2, v3);
   SetIndexLabel(2,"High A"); 
//----
   return(0);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int start()
  {
    
   double   faster=0;
   double   slower=0;         
   int      bars = Bars;
//----
  
   for(int i=bars; i>=0; i--)
    {
     faster = iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,i); //MODE_MAIN
     slower = iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,i); //MODE_SIGNAL
     val1=iFractals(NULL, 0, MODE_UPPER,i);
     val2=iFractals(NULL, 0, MODE_LOWER,i);
     
     if(faster > 0)
      {
       if (val1 > 0) v1[i]=High[i];
      }
      
     if(faster < 0)
      {
       if (val2 > 0) v2[i]=Low[i];
      }        
    }   
//----
   return(0);
  }
//+------------------------------------------------------------------+
 
diostar:
Je suis arrivé à cette conclusion, parce que probablement, je regardais du point de vue de la POO. Oui, ce n'est pas vrai pour le cas de MQL4, je me souviens maintenant. Bien que cela puisse être une bonne pratique ?

C'est toujours une bonne pratique de limiter la portée. C'est toujours une bonne pratique de définir les variables/objets là où ils sont utilisés et de les initialiser à ce moment-là.

Définir un objet en dehors de la boucle résulte en une construction par défaut plus N affectations. Défini à l'intérieur de la boucle résulte en N constructions avec valeur - généralement plus rapide.

Ne vous préoccupez jamais des optimisations tant que vous ne pouvez pas prouver que le changement fait une différence.

 
WHRoeder:

C'est toujours une bonne pratique de limiter la portée. C'est toujours une bonne pratique de définir les variables/objets là où ils sont utilisés et de les initialiser à ce moment-là.

Définir un objet en dehors de la boucle résulte en une construction par défaut plus N affectations. Défini à l'intérieur de la boucle résulte en N constructions avec valeur - généralement plus rapide.

Ne vous préoccupez jamais des optimisations tant que vous ne pouvez pas prouver que le changement fait une différence.

Ceci devrait également s'appliquer à son itérateur. for (int i=0 ;. ...
 
diostar:
Cela devrait également s'appliquer à son itérateur. for (int i=0 ;.. ..
Je suis d'accord, mais je n'ai pas écrit ce code.
 
Ok, il semble que j'ai quelques variantes d'un code qui fonctionne maintenant, merci.

Cependant, je suis légèrement confus quant à la raison pour laquelle la déclaration des variables (plus rapide et plus lente) en dehors de la boucle n'est pas bonne alors qu'elle est correcte à l'intérieur de la boucle.

Et pourtant l'int i = Bars fonctionne en dehors de la boucle ou à l'intérieur de la boucle ?


Quoi qu'il en soit, il est bon de voir que certaines de mes idées sur lesquelles je travaillais sont déjà postées dans ce fil de discussion, c'est donc une bonne nouvelle et cela signifie que je me rapproche un peu plus de la possibilité de coder quelque chose par moi-même un jour. Un petit progrès, c'est mieux que rien. Merci

Donc maintenant je peux travailler sur la comparaison de certains temps d'indicateur, je vais essayer de comprendre cela maintenant.

Par exemple :
Comparer v1[i] à v2[i] Temps des indicateurs actuellement formés && / || if(v1[i] time is > v2[i] time) et d'autres comparaisons de ce genre.

Merci pour tous les conseils, cela a été d'une grande aide.
 
WHRoeder:

C'est toujours une bonne pratique de limiter la portée. C'est toujours une bonne pratique de définir les variables/objets là où ils sont utilisés et de les initialiser à ce moment-là.

Définir un objet en dehors de la boucle résulte en une construction par défaut plus N affectations. Défini à l'intérieur de la boucle résulte en N constructions avec valeur - généralement plus rapide.

Ne vous préoccupez jamais des optimisations tant que vous ne pouvez pas prouver que le changement fait une différence.

Je suppose que c'est vrai pour tous, et pas seulement pour les indicateurs / indicateurs personnalisés?
 
Agent86:
Ok, il semble que j'ai quelques variantes d'un code qui fonctionne maintenant, merci.

Cependant, je suis un peu confus quant à la raison pour laquelle la déclaration des variables (plus rapide et plus lente) en dehors de la boucle n'est pas bonne alors qu'elle est correcte à l'intérieur de la boucle.

Et pourtant l'int i = Bars fonctionnera en dehors de la boucle ou à l'intérieur de la boucle ?


Vous devez considérer ce que vous faites, lorsque vous créez un indicateur, vous appliquez votre code à chaque barre du graphique, ce qui signifie que vous devez obtenir la valeur de l'indicateur macd telle qu'elle était pour chacune de ces barres historiques.

C'est ce que vous avez fait dans votre code original :

double   faster = iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,1), 
le dernier paramètre 1 est la valeur du macd telle qu'elle était à la barre 1 du graphique, la barre précédente à la barre actuelle qui est indexée comme barre 0

Il est évident que vous ne voulez pas utiliser cette seule valeur de l'indicateur macd dans votre opérateur conditionnel sur l'ensemble du graphique historique.

Vous devez indexer le macd au même indice de barre que chaque barre, donc par exemple à la barre 500 vous avez besoin de ceci

faster = iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,500) 

ce dernier paramètre doit changer pour correspondre au numéro de la barre sur laquelle votre indicateur applique ses algorithmes.

C'est pourquoi vous en avez besoin à l'intérieur de la boucle, afin que vous puissiez utiliser l'itérateur de cycle de boucle ( i ) pour le dernier paramètre. Ainsi, vous obtenez votre valeur macd telle qu'elle était pour chaque barre du graphique historique.

faster = iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,i), 

J'espère que cela aidera à clarifier un peu les choses.

 
WHRoeder:
Essayez ce changement
Pourquoi for(int i = Bars-1 ?

Et pourquoi est-ce mieux que for(int i = Bars ?) ?

Veuillez me conseiller, merci.