MQL4/MQL5'te numaralandırma ve öğe uzunluğu nasıl elde edilir? - sayfa 4

 
Sanırım tüm gösterge girdilerini yakalamanın bir yolunu arıyor.
Her gösterge için girdi değerlerine duyulan ihtiyacı ortadan kaldıran bir EA'da.
Geri test cihazındaki alternatif, her göstergeyi manuel olarak düzenlemektir.
bir sinyal tamponu ile.
 

Bunu biraz basit deneyin, ancak şu ana kadar mümkün olan tek yaklaşım.

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

Çıktılar:

ENUM öğeleri:

Sayı=3

0 x1=-10

1 x2=0

2x3=11

start ve stop parametreleri için makul değerler belirtmek önemlidir, çünkü minimumdan maksimum tamsayı değerine (parametreler atlandığında varsayılan olarak kullanılır) döngü çok yavaş yürütülür, çünkü dize işlevlerinin içeride kullanıldığı dikkate alınır.

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


Bunu CComboBox sınıfına ekledim, böylece herhangi bir ENUM türünü geçebilirim ve onu birleşik giriş kutusu olarak eklerdi.


Ama ihtiyacınız olanı yapmak için değiştirebilirsiniz.

Sorun şu ki, bir ENUM'u geçmezseniz ve çift veya kayan nokta gibi bir şey iletirseniz, uygulamanızın çökmesine neden olabilirsiniz.

Geçilen veri türünü kontrol etmenin bir yolu olduğunu sanmıyorum.

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


Bunu CComboBox sınıfına ekledim, böylece herhangi bir ENUM türünü geçebilirim ve onu birleşik giriş kutusu olarak eklerdi.


Ama ihtiyacınız olanı yapmak için değiştirebilirsiniz.

Sorun şu ki, bir ENUM'u geçmezseniz ve çift veya kayan nokta gibi bir şey iletirseniz, uygulamanızın çökmesine neden olabilirsiniz.

Geçilen veri türünü kontrol etmenin bir yolu olduğunu sanmıyorum.

Korkarım sizeof(enumIn) her zaman 4'e eşittir.
 

Evet öyle, ayy. Bunu yeni fark ettim.

Bunu yaptığımda, kullandığım ENUM'un aslında 4 özelliği vardı:\

 

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'te numaralandırma ve öğe uzunluğu nasıl elde edilir?

Örneğin, bir enum tanımı vardır:

 enum ENUM_FRUIT {APPLE, BANANA, GRAPE};

Sonra, onu döngüde kullanmak istiyorum:

 for ( int i = 0 ; i < length_of_enum; i++) {
   Print ( EnumToString (get_enum_item(i)));
} 
Hiçbir yolu yok, kodlamanız gerekiyor.
Bir girdi olmayacaksa, bu kalıbı kullanırım
enum ENUM_FRUIT {APPLE, BANANA, GRAPE,
                 FRUIT_FIRST=APPLE, FRUIT_LAST=GRAPE};
for (ENUM_FRUIT i = APPLE; i <= FRUIT_LAST; ++i) {
   Print ( EnumToString (i));
}
Bir artışla (++i) kullanmak, sayısal olarak bitişik olduklarını varsayar.
Bir girdi olacaksa, bu kalıbı kullanırım
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));
}
Sayısal olarak bitişik değilse
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 :
Neyin kötü tasarımı

enum'daki üye mağaza sayısı anlamına mı geliyor?

 

Bu konuşmanın oldukça eski olduğunu biliyorum ama burada herhangi bir enum türünden bir diziyi doldurmanın kolay bir yolu var.


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

Bunu nasıl çözdüğüme gelecek nesiller için çözümümü ekliyorum.

Bu nedenle sorun, enum değerleri ekleme veya kaldırma yeteneği ile enumdaki girişlerin sayısını dinamik olarak bilmektir. Dizi dizini olarak enum değerlerine sahip sabit boyutlu diziler oluşturmak için bunu bilmem gerekiyor. Yapmaya meyilli olduğum şey, numaralandırmanın sonuna yalnızca uzunluk değeri olarak kullanılan ayrılmış bir değer eklemek. İşte bir örnek.

 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();       
}
Bu güzel ve kolaydır çünkü her yerde son girişe sabitlenmenize gerek yoktur.
 // Fixed to last entry +1
ObjectType *entryArray[VERY_LARGE_ENTRY + 1 ];

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

}

ya da numaralandırmanın sonuna daha fazla giriş ekleyebilirsiniz ve dizi ve döngü çalışmaya devam eder.

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