Como obter o comprimento do enumero e item em MQL4/MQL5 ? - página 4

 
Acho que ele está procurando uma maneira de capturar todas as entradas de indicadores
em um EA contornando a necessidade de valores de entrada para cada indicador.
A alternativa em seu backtester é editar manualmente todos os indicadores
com um buffer de sinal .
 

Tente isto um pouco mais direto, mas a única abordagem possível até agora.

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;
}

Saídas:

Elementos ENUM:

Contagem=3

0 x1=-10

1 x2=0

2 x3=11

É importante especificar valores razoáveis parainiciar eparar os parâmetros, pois o ciclo do valor inteiro mínimo ao máximo (que é usado por padrão quando os parâmetros são pulados) executa muito lentamente, levando em conta que as funções de string são usadas no interior.

 
   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);  
   }


Eu adicionei isto à classe CComboBox, para que eu pudesse passar em qualquer tipo de ENUM, e ele o adicionaria como uma caixa combinada.


Mas você pode mudá-lo para fazer o que você precisa.

O problema é que, se você não passar um ENUM e passar algo como um duplo ou um flutuador, você pode travar seu aplicativo.

Acho que não há nenhuma maneira de verificar o tipo de dado aprovado.

 
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);  
   }


Adicionei isto à classe CComboBox, para que eu pudesse passar em qualquer tipo de ENUM, e a adicionaria como uma caixa combinada.


Mas você pode mudá-lo para fazer o que você precisa.

O problema é que, se você não passar um ENUM e passar algo como um duplo ou um flutuador, você pode travar seu aplicativo.

Acho que não há nenhuma maneira de verificar o tipo de dado aprovado.

Receio que o tamanho do(enumIn) seja sempre igual a 4.
 

Sim, oops. Eu acabei de notar isso.

Acontece que quando eu fiz isto, o ENUM que eu estava usando na verdade tinha 4 propriedades:\ \

 

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

for(int i = 0; GetLastError()==0; i++) {
ComboBox1.ItemAdd(EnumToString(Combolist1(i)),Combolist1(0));
}
 
Xiangdong Guo: Como obter o comprimento do enumero e item em MQL4/MQL5 ?

Por exemplo, há uma definição enumerativa:

enum ENUM_FRUIT {APPLE, BANANA, GRAPE};

A seguir, quero usá-lo em loop:

for (int i = 0; i < length_of_enum; i++) {
  Print(EnumToString(get_enum_item(i)));
} 
Não há nenhuma maneira, você tem que codificá-lo.
Se não vai ser um input, eu uso este padrão
enum ENUM_FRUIT {APPLE, BANANA, GRAPE,
                 FRUIT_FIRST=APPLE, FRUIT_LAST=GRAPE};
for (ENUM_FRUIT i = APPLE; i <= FRUIT_LAST; ++i) {
  Print(EnumToString(i));
}
A sua utilização com um incremento (++i) pressupõe que eles são numericamente adjacentes.
Se vai ser um input, eu uso este padrão
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));
}
Se eles não forem numericamente 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:
Má concepção do que

significa o número de lojas associadas em enumeração ?

 

Eu sei que esta conversa é bastante antiga, mas aqui está uma maneira fácil de preencher um conjunto de qualquer tipo de enumeração.


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);
}
 

Apenas acrescentando minha solução para as gerações futuras sobre como resolvi isto.

Então o problema é saber dinamicamente o número de entradas no enum. Preciso saber isto para criar matrizes de tamanho fixo com valores de enumeração como o índice de array. O que eu tendo a fazer é adicionar um valor reservado no final do enumeral que só é usado como um valor de comprimento. Aqui está um exemplo.

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();       
}
Isto é bom e fácil porque você não precisa ser fixado na última entrada em todos os lugares como
// Fixed to last entry +1
ObjectType *entryArray[VERY_LARGE_ENTRY + 1];

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

}

ou você poderia adicionar mais entradas ao final do enumero e o array e o loop ainda funcionarão.

/*
 *  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...