如何在MQL4/MQL5中获得枚举和项目的长度? - 页 4

 
我认为他正在寻找一种方法来捕捉EA中所有的指标输入
,以规避对每个指标输入值的需求。
在他的回测器 中的替代方法是用信号缓冲器手动编辑每个指标
 

试试这个有点直截了当,但也是目前唯一可能的办法。

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

输出。

ENUM元素。

Count=3

0 x1=-10

1 x2=0

2 x3=11

为参数startstop 指定合理的值是很重要的,因为考虑到里面使用的是字符串函数,从最小到最大的整数值的循环(当参数被跳过时默认使用)执行得太慢。

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


我把它添加到CComboBox 类中,所以我可以传入任何ENUM类型,它就会把它作为一个组合框加入。


但你可以改变它来做你需要的事情。

问题是,如果你不传一个ENUM,而传一个像double或float的东西,你的应用程序可能会崩溃。

我不认为有任何方法可以检查传递的数据类型。

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


我在CComboBox类中加入了这一点,所以我可以传入任何ENUM类型,它就会把它作为一个组合框加入。


但你可以改变它来做你需要的事情。

问题是,如果你不传一个ENUM,而传一个像double或float的东西,你的应用程序可能会崩溃。

我不认为有任何方法可以检查传递的数据类型。

我担心sizeof(enumIn)总是等于4。
 

是的,是的,哎呀。我刚刚注意到了这一点。

刚好我做这个的时候,我使用的ENUM实际上有4个属性:()。

 

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

for(int i = 0; GetLastError()==0; i++) {
ComboBox1.ItemAdd(EnumToString(Combolist1(i)),Combolist1(0))。
}
 
Xiangdong Guo: 如何在MQL4/MQL5中获得枚举和项目的长度?

例如,这里有一个枚举定义。

enum ENUM_FRUIT {APPLE, BANANA, GRAPE};

接下来,我想在循环中使用它。

for (int i = 0; i < length_of_enum; i++) {
  Print(EnumToString(get_enum_item(i)));
} 
没有任何方法,你必须编码。
如果它不打算成为一个输入,我使用这个模式
enum ENUM_FRUIT {APPLE, BANANA, GRAPE,
                 FRUIT_FIRST=APPLE, FRUIT_LAST=GRAPE};
for (ENUM_FRUIT i = APPLE; i <= FRUIT_LAST; ++i) {
  Print(EnumToString(i));
}
与增量(++i)一起使用,假设它们在数字上是相邻的。
如果它将成为一个输入,我使用这个模式
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));
}
如果它们在数字上不相邻
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:
糟糕的设计是什么

它是指枚举中的成员存储数量?

 

我知道这个话题已经很老了,但这里有一个简单的方法来填充任何枚举类型的数组。


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

我只是把我的解决方案加进去,供后人 了解我是如何解决这个问题的。

所以问题是动态地知道枚举中的条目 数,并能增加或删除 枚举值。我需要知道这一点来创建以枚举值为数组索引的固定大小的数组。我倾向于做的是在枚举的最后添加一个保留值,这个保留值只用作长度值。这里有一个例子。

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();       
}
这样做很好,也很简单,因为你不需要到处固定在最后一个条目上,就像
// Fixed to last entry +1
ObjectType *entryArray[VERY_LARGE_ENTRY + 1];

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

}

或者你可以在枚举的末尾添加更多的条目,数组和循环仍然可以工作。

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