Discussion de l'article "Extension de la bibliothèque standard MQL5 et réutilisation du code" - page 2

 
Tango_X:


Aidez-moi à comprendre comment la direction d'indexation du tableau de tampons d'indicateurs est définie ici, c'est-à-dire de la même manière que ArraySetAsSeries. La direction par défaut est de présent à passé, mais j'ai besoin de le faire de passé à présent. Je me débats avec cette question depuis hier, à l'aide !

Il n'en a pas besoin, car il utilise le ZigZag standard.

//--- créer
   m_handle=iCustom(symbol,period,"zigzag",depth,deviation_create,backstep);

Cherchez l'endroit où la direction est définie dans ce ZigZag , mais la raison pour laquelle vous en avez besoin n'est toujours pas claire - vous pouvez changer la direction de l'indexation vous-même à tout moment - https://www.mql5.com/fr/docs/series.

Документация по MQL5: Доступ к таймсериям и индикаторам
Документация по MQL5: Доступ к таймсериям и индикаторам
  • www.mql5.com
Доступ к таймсериям и индикаторам - справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 
Rashid Umarov:

Il n'en a pas besoin, car il utilise le ZigZag standard

Dans ce ZigZag , cherchez l'endroit où la direction est définie. Mais la raison pour laquelle vous en avez besoin n'est toujours pas claire - vous pouvez changer la direction de l'indexation vous-même à tout moment - https://www.mql5.com/fr/docs/series.


Merci pour ces informations, nous allons nous pencher sur la question !

 
Rashid Umarov:

Il n'en a pas besoin, car il utilise le ZigZag standard.

Dans ce ZigZag , cherchez l'endroit où la direction est définie. Mais on ne voit toujours pas pourquoi vous en avez besoin - vous pouvez changer la direction d'indexation vous-même à tout moment - https://www.mql5.com/fr/docs/series.


Je suis désolé, mais il n'est toujours pas clair comment changer la direction d'indexation, par exemple, si vous n'avez pas accès à la source Zigzag. Le sens d'indexation est défini par ArraySetAsSeries() - où le paramètre d'entrée est un tableau par référence,

mais nous n'avons pas ce tableau, mais seulement un pointeur sur le tableau de la mémoire tampon de l'indicateur sous la forme de

//--- créer des tampons
      ((CIndicatorBuffer*)At(0)).Name("ZIGZAG");
      ((CIndicatorBuffer*)At(1)).Name("HIGH");
      ((CIndicatorBuffer*)At(2)).Name("LOW");
 
//+------------------------------------------------------------------+
//|OOO_ZIGZAG.mq5 |
//| Copyright 2017, MetaQuotes Software Corp.
//|https ://www.mql5.com
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window
#include <..\Include\Indicators\Indicator.mqh>


//--- paramètres d'entrée
input ENUM_TIMEFRAMES   EAPeriod=PERIOD_CURRENT; /Période de programmation
input string            CurrencyPair="EURUSD.m"; //Symbole

//+------------------------------------------------------------------+
//| Classe CiZigZag.|
//| Objet : Classe d'indicateur ZigZag.
//| Sortie de la classe CIndicator.|
//+------------------------------------------------------------------+
class CiZigZag : public CIndicator
  {
protected:
   int               m_depth;
   int               m_deviation;
   int               m_backstep;

public:
                     CiZigZag(void);
                    ~CiZigZag(void);
   //--- méthodes d'accès aux données protégées
   int               Depth(void)          const { return(m_depth);      }
   int               Deviation(void)      const { return(m_deviation);  }
   int               Backstep(void)       const { return(m_backstep);   }
   //--- méthode de création
   bool              Create(const string symbol,const ENUM_TIMEFRAMES period,
                            const int depth,const int deviation_create,const int backstep);
   //--- méthodes d'accès aux données de l'indicateur
   double            ZigZag(const int index) const;
   double            High(const int index) const;
   double            Low(const int index) const;
   //--- méthode d'identification
   virtual int       Type(void) const { return(IND_CUSTOM); }

protected:
   //--- méthodes de personnalisation
   virtual bool      Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam &params[]);
   bool              Initialize(const string symbol,const ENUM_TIMEFRAMES period,
                                const int depth,const int deviation_init,const int backstep);
  };
//+------------------------------------------------------------------+
//| Constructeur|
//+------------------------------------------------------------------+
CiZigZag::CiZigZag(void) : m_depth(-1),
                         m_deviation(-1),
                         m_backstep(-1)
  {
  }
//+------------------------------------------------------------------+
//| Destructeur|
//+------------------------------------------------------------------+
CiZigZag::~CiZigZag(void)
  {
  }
//+------------------------------------------------------------------+
//|| Créer l'indicateur "Zig Zag".|
//+------------------------------------------------------------------+
bool CiZigZag::Create(const string symbol,const ENUM_TIMEFRAMES period,
                      const int depth,const int deviation_create,const int backstep)
  {
//--- vérifier l'historique
   if(!SetSymbolPeriod(symbol,period))
      return(false);
//--- créer
   m_handle=iCustom(symbol,period,"Examples\\ZigZag",depth,deviation_create,backstep);
//--- vérifier le résultat
   if(m_handle==INVALID_HANDLE)
      return(false);
//--- l'indicateur a été créé avec succès
   if(!Initialize(symbol,period,depth,deviation_create,backstep))
     {
      //--- erreur d'initialisation
      IndicatorRelease(m_handle);
      m_handle=INVALID_HANDLE;
      return(false);
     }
//--- ok
   return(true);
  }
//+------------------------------------------------------------------+
//| Initialiser l'indicateur avec les paramètres universels |
//+------------------------------------------------------------------+
bool CiZigZag::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam &params[])
  {
   return(Initialize(symbol,period,(int)params[0].integer_value,(int)params[1].integer_value,(int)params[2].integer_value));
  }
//+------------------------------------------------------------------+
//| Initialiser l'indicateur avec des paramètres spéciaux |
//+------------------------------------------------------------------+
bool CiZigZag::Initialize(const string symbol,const ENUM_TIMEFRAMES period,
                        const int depth,const int deviation_init,const int backstep)
  {
   if(CreateBuffers(symbol,period,3))
     {
      //--- ligne d'état de rendu
      m_name  ="ZigZag";
      m_status="("+symbol+","+PeriodDescription()+","+
               IntegerToString(depth)+","+IntegerToString(deviation_init)+","+
               IntegerToString(backstep)+") H="+IntegerToString(m_handle);
      //--- enregistrer les paramètres
      m_depth=depth;
      m_deviation=deviation_init;
      m_backstep=backstep;       
      //--- créer des tampons
      ((CIndicatorBuffer*)At(0)).Name("ZIGZAG");
      ((CIndicatorBuffer*)At(1)).Name("HIGH");
      ((CIndicatorBuffer*)At(2)).Name("LOW");
      //--- ok
      return(true);
     }
//--- erreur
   return(false);
  }
//+------------------------------------------------------------------+
//| Accès au tampon ZigZag de l'indicateur "Zig Zag" |
//+------------------------------------------------------------------+
double CiZigZag::ZigZag(const int index) const
  {
   CIndicatorBuffer *buffer=At(0);
//--- vérifier
   if(buffer==NULL)
      return(EMPTY_VALUE);
//---
   return(buffer.At(index));
  }
//+------------------------------------------------------------------+
//| Accès au tampon High de l'indicateur "Zig Zag" |
//+------------------------------------------------------------------+
double CiZigZag::High(const int index) const
  {
   CIndicatorBuffer *buffer=At(1);
   //--- vérifier
   if(buffer==NULL)
      return(EMPTY_VALUE);
//---
   return(buffer.At(index));
  }
//+------------------------------------------------------------------+
//| Accès à la mémoire tampon basse de l'indicateur "Zig Zag" |
//+------------------------------------------------------------------+
double CiZigZag::Low(const int index) const
  {
   CIndicatorBuffer *buffer=At(2);
//--- vérifier
   if(buffer==NULL)
      return(EMPTY_VALUE);
//---
   return(buffer.At(index));
  }
//+------------------------------------------------------------------+



CiZigZag *Zig;
//+------------------------------------------------------------------+
//| Fonction d'initialisation de l'indicateur personnalisé
//+------------------------------------------------------------------+
int OnInit()
  {
//--- cartographie des tampons d'indicateurs
   Zig=new CiZigZag;
   Zig.Create(CurrencyPair,EAPeriod,12,5,3);
//---
   return(INIT_SUCCEEDED);
  }
void OnDeinit(const int reason)
  {
   delete(Zig);
  }  
//+------------------------------------------------------------------+
//| Fonction d'itération de l'indicateur personnalisée
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   int limit;
   if(prev_calculated==0)limit=0;
   else
     limit=prev_calculated-1; 
     
   for(int i=limit;i<rates_total && !IsStopped();i++)
      {
       Zig.Refresh();
       if (Zig.ZigZag(i)!=0) Print(Zig.ZigZag(i)," ",time[i]);  
      }
//--- valeur de retour de prev_calculated pour l'appel suivant
   return(rates_total);
  }
//+------------------------------------------------------------------+

Voici le code complet de l'indicateur, où la sortie des valeurs de l'indicateur se fait du présent vers le passé - et vice versa.

 
Tango_X:

Désolé, mais je ne sais toujours pas comment changer le sens de l'indexation, par exemple, s'il n'y a pas d'accès à la source Zigzag. Le sens d'indexation est défini par ArraySetAsSeries() - où le paramètre d'entrée est un tableau par référence,

mais nous ne disposons pas de ce tableau, mais seulement d'un pointeur sur le tableau de la mémoire tampon de l'indicateur sous la forme d'un pointeur sur le tableau de la mémoire tampon de l'indicateur.

La classe de base CIndicator possède une méthode GetData, qui peut être utilisée pour obtenir des données de la mémoire tampon de l'indicateur.

Récupère les données de la mémoire tampon de l'indicateur par la position de départ et le numéro

int GetData(
const intstart_pos, // position
const intcount, // nombre
const int buffer_num, // numéro de la mémoire tampon
double&buffer[]// tableau
) const



Ensuite, définissez la direction d'indexation souhaitée pour votre tableau à l'aide de ArraySetAsSeries

 
Rashid Umarov:

La classe de base CIndicator possède une méthode GetData qui peut être utilisée pour obtenir des données de la mémoire tampon de l'indicateur.

Cette méthode permet d'obtenir les données de la mémoire tampon de l'indicateur en fonction de la position de départ et du nombre de

int GetData(
const intstart_pos, // position
const intcount, // nombre
const int buffer_num, // numéro de tampon
double&buffer[]// tableau
) const



Ensuite, définissez la direction d'indexation souhaitée pour votre tableau.

Il s'agit donc d'accéder deux fois à la mémoire tampon de l'indicateur, mais de manière différente ? Après tout, nous avons déjà accès aux valeurs de la mémoire tampon de l'indicateur ci-dessous ? Nous obtenons un tableau intermédiaire double &buffer[] si j'ai bien compris ?

//+------------------------------------------------------------------+
//| Accès au tampon ZigZag de l'indicateur "Zig Zag" |
//+------------------------------------------------------------------+
double CiZigZag::ZigZag(const int index) const
  {
   CIndicatorBuffer *buffer=At(0);
//--- vérifier
   if(buffer==NULL)
      return(EMPTY_VALUE);
//---
   return(buffer.At(index));
  }
 
Rashid Umarov:

La classe de base CIndicator possède une méthode GetData qui peut être utilisée pour obtenir des données de la mémoire tampon de l'indicateur.

Cette méthode permet d'obtenir les données de la mémoire tampon de l'indicateur en fonction de la position de départ et du nombre de

int GetData(
const intstart_pos, // position
const intcount, // nombre
const int buffer_num, // numéro de tampon
double&buffer[]// tableau
) const



Ensuite, définissez la direction d'indexation souhaitée pour votre tableau à l'aide de ArraySetAsSeries

Ai-je bien compris ?

CiZigZag *Zig;
double ArrZig[];
//+------------------------------------------------------------------+
//| Fonction d'initialisation de l'indicateur personnalisé
//+------------------------------------------------------------------+
int OnInit()
  {
//--- cartographie des tampons d'indicateurs
   Zig=new CiZigZag;
   Zig.Create(CurrencyPair,EAPeriod,12,5,3);

   SetIndexBuffer(0,ArrZig,INDICATOR_CALCULATIONS);
   ArraySetAsSeries(ArrZig,false);

//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//||
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   delete(Zig);
  }
//+------------------------------------------------------------------+
//| Fonction d'itération de l'indicateur personnalisée
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   int limit;
   if(prev_calculated==0) limit=0;
   else
      limit=prev_calculated-1;

   Zig.Refresh();
   Zig.GetData(0,rates_total-1,0,ArrZig);

   for(int i=limit;i<rates_total-1 && !IsStopped();i++)
     {

      //si (Zig.ZigZag(i)!=0) Print(Zig.ZigZag(i)," ",time[i]) ; 
      if(ArrZig[i]!=0) Print(ArrZig[i]," ",time[i]);
     }
//--- valeur de retour de prev_calculated pour l'appel suivant
   return(rates_total);
  }
//+------------------------------------------------------------------+
Il s'avère que vous devez copier l'ensemble de l'historique à chaque tic-tac ?
 
Tango_X:

Est-ce que je vous ai bien compris ?

Il s'avère qu'il est nécessaire de copier l'ensemble de l'historique sur chaque tic ?

1. Vous pouvez le faire à l'ouverture d'une nouvelle barre.

2. pourquoi faut-il récupérer toutes les valeurs des indicateurs à chaque fois, et en même temps s'occuper de la direction de l'indexation ? quelle est la tâche en fait ?

 

Pourquoi envelopper un simple indicateur dans une classe s'il est utilisé plus tard dans un graphique ou via iCustom ?

Второе решение лучше, потому что является объектно-ориентированным

La POO pour la POO, d'accord.

 
Rashid Umarov:

1. Il est possible d'ouvrir une nouvelle barre

2. pourquoi faut-il récupérer toutes les valeurs des indicateurs à chaque fois, et en même temps se soucier de la direction de l'indexation ? quelle est la tâche en fait ?


Le problème a été résolu par les conditions de la boucle, maintenant tout fonctionne comme souhaité. merci !