Comment obtenir la longueur d'un enum et d'un item dans MQL4/MQL5 ? - page 4

 
Je pense qu'il cherche un moyen de capturer toutes les entrées des indicateurs
dans un EA en contournant le besoin de valeurs d'entrée pour chaque indicateur.
L'alternative dans son backtester est de modifier manuellement chaque indicateur
avec un tampon de signal.
 

Essayez ceci : c'est un peu direct, mais c'est la seule approche possible jusqu'à présent.

enum XXX {x1 = -10, x2 = 0, x3 = 11};

template<typename E>
int EnumToArray(E dummy, int &values[], const int start = INT_MIN, const int stop = INT_MAX)
{
  string t = typename(E) + "::";
  int length = StringLen(t);
  
  ArrayResize(values, 0);
  int count = 0;
  
  for(int i = start; i < stop && !IsStopped(); i++)
  {
    E e = (E)i;
    if(StringCompare(StringSubstr(EnumToString(e), 0, length), t) != 0)
    {
      ArrayResize(values, count + 1);
      values[count++] = i;
    }
  }
  return count;
}

int OnInit()
{
  Print("ENUM elements:");
  XXX a;
  int result[];
  int n = EnumToArray(a, result, -100, 100);
  Print("Count=", n);
  for(int i = 0; i < n; i++)
  {
    Print(i, " ", EnumToString((XXX)result[i]), "=", result[i]);
  }
  
  return 0;
}

Sorties :

Eléments ENUM :

Compte=3

0 x1=-10

1 x2=0

2 x3=11

Il est important de spécifier des valeurs raisonnables pour les paramètresstart etstop, car le cycle de la valeur minimale à la valeur maximale (qui est utilisé par défaut lorsque les paramètres sont ignorés) s'exécute trop lentement si l'on tient compte du fait que des fonctions string sont utilisées à l'intérieur.

 
   template<typename ENUMTYPE>
   bool              AddEnum(ENUMTYPE enumIn) {
      enumIn = 0;
      
      //iterate through enum and add as combo box
      for(int i = 0; i<sizeof(enumIn); i++, enumIn++) {
         m_list.AddItem(EnumToString(enumIn),i);
         PrintFormat("adding %i = %s", i, EnumToString(enumIn));            
       }
      return(0);  
   }


J'ai ajouté ceci à la classe CComboBox, afin que je puisse passer n'importe quel type ENUM, et qu'il l'ajoute comme une boîte combo.


Mais vous pouvez le modifier pour faire ce dont vous avez besoin.

Le problème est que si vous ne passez pas un ENUM et passez quelque chose comme un double ou un float, vous risquez de planter votre application.

Je ne pense pas qu'il y ait un moyen de vérifier le type de données passé.

 
dazamate:
   template<typename ENUMTYPE>
   bool              AddEnum(ENUMTYPE enumIn) {
      enumIn = 0;
      
      //iterate through enum and add as combo box
      for(int i = 0; i<sizeof(enumIn); i++, enumIn++) {
         m_list.AddItem(EnumToString(enumIn),i);
         PrintFormat("adding %i = %s", i, EnumToString(enumIn));            
       }
      return(0);  
   }


J'ai ajouté ceci à la classe CComboBox, afin que je puisse passer n'importe quel type ENUM, et qu'il l'ajoute comme une boîte combo.


Mais vous pouvez le modifier pour faire ce dont vous avez besoin.

Le problème est que si vous ne passez pas un ENUM et passez quelque chose comme un double ou un float, vous risquez de planter votre application.

Je ne pense pas qu'il y ait un moyen de vérifier le type de données passé.

Je crains que sizeof(enumIn) ne soit toujours égal à 4.
 

Oui, c'est vrai, oups. Je viens de le remarquer.

Il se trouve que lorsque j'ai fait ça, le ENUM que j'utilisais avait en fait 4 propriétés:-)

 

enum Combolist1{item1, item2, item3, item4, item5} ;

for(int i = 0 ; GetLastError()==0 ; i++) {
ComboBox1.ItemAdd(EnumToString(Combolist1(i)),Combolist1(0)) ;
}
 
Xiangdong Guo: Comment obtenir la longueur d'un enum et d'un item en MQL4/MQL5 ?

Par exemple, il y a une définition d'un enum :

enum ENUM_FRUIT {APPLE, BANANA, GRAPE};

Ensuite, je veux l'utiliser dans une boucle :

for (int i = 0; i < length_of_enum; i++) {
  Print(EnumToString(get_enum_item(i)));
} 
Il n'y a pas de moyen, vous devez le coder.
Si ce n'est pas une entrée, j'utilise ce modèle.
enum ENUM_FRUIT {APPLE, BANANA, GRAPE,
                 FRUIT_FIRST=APPLE, FRUIT_LAST=GRAPE};
for (ENUM_FRUIT i = APPLE; i <= FRUIT_LAST; ++i) {
  Print(EnumToString(i));
}
L'utiliser avec un incrément (++i) suppose qu'ils sont numériquement adjacents.
S'il s'agit d'une entrée, j'utilise ce schéma
enum ENUM_FRUIT {APPLE, BANANA, GRAPE}
#define FRUIT_FIRST APPLE
#define FRUIT_LAST  GRAPE
for (ENUM_FRUIT i = APPLE; i <= FRUIT_LAST; ++i) {
  Print(EnumToString(i));
}
Si elles ne sont pas numériquement adjacentes
const ENUM_TIMEFRAMES  gcPeriods[]={   PERIOD_CURRENT,
   PERIOD_M1,  PERIOD_M2,  PERIOD_M3,  PERIOD_M4,  PERIOD_M5,  PERIOD_M6,
   PERIOD_M10, PERIOD_M12, PERIOD_M15, PERIOD_M20, PERIOD_M30, PERIOD_H1,
   PERIOD_H2,  PERIOD_H3,  PERIOD_H4,  PERIOD_H6,  PERIOD_H8,  PERIOD_H12,
   PERIOD_D1,  PERIOD_W1,  PERIOD_MN1};
ENUM_TIMEFRAMES  next(ENUM_TIMEFRAMES curr){
   for(int i=0; gcPeriods[i] != curr; ++i){}
   return gcPeriods[i+1];
}
 
Lorentzos Roussos:
Mauvaise conception de ce qui

cela signifie le nombre de membres dans un enum ?

 

Je sais que cette conversation est assez ancienne mais voici un moyen facile de remplir un tableau de n'importe quel type d'énumération.


void OnStart()
{
   ENUM_TIMEFRAMES array[];
   int total_elements = enumFillArray(array);
   printf("There are %d elements in the ENUM_TIMEFRAMES array.",
      total_elements
   );
   
   for(int i=0;i<total_elements;i++)
      Print(EnumToString(array[i]));
}
   
template<typename T>
int enumFillArray(T& res_array[])
{
   ArrayResize(res_array,0);
   int iter = 100000;
   for(int i=-iter;i<iter;i++)
      if(StringFind(EnumToString((T)i),"::")<0)
      {
         int index = ArrayResize(res_array,ArraySize(res_array)+1)-1;
         res_array[index] = (T)i;
      }
   return ArraySize(res_array);
}
 

J'ajoute juste ma solution pour les générations futures sur la façon dont j'ai résolu ce problème.

Le problème est donc de connaître le nombre d'entrées de l'énumération de façon dynamique avec la possibilité d'ajouter ou de supprimer des valeurs de l'énumération. J'ai besoin de le savoir pour créer des tableaux de taille fixe avec des valeurs d'énumération comme index de tableau. Ce que j'ai tendance à faire, c'est d'ajouter une valeur réservée à la fin de l'énumération qui n'est jamais utilisée que comme valeur de longueur. Voici un exemple.

enum ENUM_ENTRIES
{
        SMALL_ENTRY = 0,
        MEDIUM_ENTRY,
        LARGE_ENTRY,
        VERY_LARGE_ENTRY,
        _ENUM_ENTRIES
};

ObjectType *entryArray[_ENUM_ENTRIES];

// Setting individual entries
entryArray[MEDIUM_ENTRY] = new ObjectType();
entryArray[LARGE_ENTRY] = new ObjectType();

// Looping through the array
for(int i = 0; i < _ENUM_ENTRIES; i++) {

        entryArray[i] = new ObjectType();       
}
C'est agréable et facile parce que vous n'avez pas besoin d'être fixé à la dernière entrée partout comme
// Fixed to last entry +1
ObjectType *entryArray[VERY_LARGE_ENTRY + 1];

for(int i = 0; i <= VERY_LARGE_ENTRY; i++) {

}

Vous pouvez aussi ajouter plus d'entrées à la fin de l'énumération et le tableau et la boucle fonctionneront toujours.

/*
 *  Expanded enum entries
 */
enum ENUM_ENTRIES
{
        SMALL_ENTRY = 0,
        MEDIUM_ENTRY,
        LARGE_ENTRY,
        VERY_LARGE_ENTRY,
        EXTRA_LARGE_ENTRY,
        EXTREMELY_LARGE_ENTRY,
        _ENUM_ENTRIES
};

/* 
 * Previous code untouched and still works
 */

ObjectType *entryArray[_ENUM_ENTRIES];

// Setting individual entries
entryArray[MEDIUM_ENTRY] = new ObjectType();
entryArray[LARGE_ENTRY] = new ObjectType();

// Looping through the array
for(int i = 0; i < _ENUM_ENTRIES; i++) {

        entryArray[i] = new ObjectType();       
}
Documentation on MQL5: Constants, Enumerations and Structures / Environment State / Symbol Properties
Documentation on MQL5: Constants, Enumerations and Structures / Environment State / Symbol Properties
  • www.mql5.com
To obtain the current market information there are several functions: SymbolInfoInteger(), SymbolInfoDouble() and SymbolInfoString(). The first parameter is the symbol name, the values of the second function parameter can be one of the identifiers of ENUM_SYMBOL_INFO_INTEGER, ENUM_SYMBOL_INFO_DOUBLE and ENUM_SYMBOL_INFO_STRING. Some symbols...