MQL4/MQL5でenumとitemの長さを取得する方法は? - ページ 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

パラメータstartとstopに 適切な値を指定することが重要です。なぜなら、最小値から最大値までの整数サイクル(パラメータをスキップしたときにデフォルトで使用されます)は、内部で文字列関数が 使用されていることを考慮すると、あまりにも遅く実行されるからです。

 
   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のようなものを渡すと、アプリがクラッシュする可能性があることです。

渡されたdatatypeをチェックする方法はないと思う。

 
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のようなものを渡すと、アプリがクラッシュする可能性があることです。

渡されたdatatypeをチェックする方法はないと思います。

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とitemの長さを取得する方法は?

例えば、enumの定義がある。

enum ENUM_FRUIT {APPLE, BANANA, GRAPE};

次に、これをloopの中で使いたい。

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:
設計が悪いのか?

enumのメンバーストアの数を意味しますか?

 

この会話はかなり古いものですが、ここでは、任意のenum型の配列を埋める簡単な方法を紹介します。


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のエントリ 数を動的に把握することです。私は、配列のインデックスとしてenum値を持つ固定サイズの配列を作成するためにこれを知っておく必要があります。私がよくやるのは、enum の最後に予約値を追加して、長さの値としてのみ使用することです。以下はその例です。

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++) {

}

あるいは、enum の末尾にさらにエントリを追加しても、配列とループは機能します。

/*
 *  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...
理由: