MQL4 ve MQL5 ile ilgili herhangi bir acemi sorusu, algoritmalar ve kodlar hakkında yardım ve tartışma - sayfa 600

 
Vasiliy Sokolov :

Burası bir telepat kulübü değil. Kodunuzu eklemediniz, bu nedenle silme işlemini nereye yapacağınızı düşünün.

Doğru değil.

İşte kod, başka neye ihtiyacınız var? Yanlışsa doğru nedir?

Teşekkür ederim.

 
Artyom Trishkin :

Ek, her şeyi yanlış anladın. Görevin yanlış planlanması sadece bu tür sonuçlara yol açar.

Nesneler bir sınıfta yaratılmışsa, çalışmasının sonunda onları yıkıcısında silmelidir. Diğer sınıflar, bir nesneye bir işaretçi almadan önce geçerliliğini kontrol etmelidir. Ve prensipte, böyle iç içe ilişkiler olmamalıdır. Bir çeşit top dokunmuştu. Zor demek kalite demek değildir. Her şey şeffaf ve izlenebilir olmalıdır. Her şeyden önce, senin için.

Kodu daha iyi gösterelim.

Burada, programın başlangıcında bir dosyadan bazı verileri okuyorum.

 CCandlesOneRules candles_one_rules;

while (! FileIsEnding (file_handle))
     {
      CCandleCondition *candle_cond= new CCandleCondition();
      string_num++;      
       string str= FileReadString (file_handle);
       int len= StringLen (str);
       if (len<= 0 )
         continue ;
       string cand_num_str= "" ;
       string rule_str= "" ;
       string rule_descr= "" ;
       string shift_str= "" ;
       string value_int_str= "" ;
       string value_enum_str= "" ;
       string status_str= "" ;
       int start_ind= 0 ;
       int status_ind=- 1 ;
       //--- status
       for ( int i=start_ind;i<len;i++)
        {
         ushort ch= StringGetCharacter (str,i);
         if (ch==Separator)
           {
            start_ind=i+ 1 ;
             break ;
           }
         status_str+= CharToString (( uchar )ch);
         status_ind=i;
        }      
       int status=( int ) StringToInteger (status_str);
       if (!init_flag && status!= 0 )
         continue ;
       //--- candle number
       for ( int i=start_ind;i<len;i++)
        {
         ushort ch= StringGetCharacter (str,i);
         if (ch==Separator)
           {
            start_ind=i+ 1 ;
             break ;
           }
         cand_num_str+= CharToString (( uchar )ch);
        }      
       //--- rule    
       for ( int i=start_ind;i<len;i++)
        {
         ushort ch= StringGetCharacter (str,i);
         if (ch==Separator)
           {
            start_ind=i+ 1 ;
             break ;
           }
         rule_str+= CharToString (( uchar )ch);
        }
       //--- shift
       for ( int i=start_ind;i<len;i++)
        {
         ushort ch= StringGetCharacter (str,i);
         if (ch==Separator)
           {
            start_ind=i+ 1 ;
             break ;
           }
         shift_str+= CharToString (( uchar )ch);
        }
       //--- value
       for ( int i=start_ind;i<len;i++)
        {
         ushort ch= StringGetCharacter (str,i);
         if (ch==Separator)
           {
            start_ind=i+ 1 ;
             break ;
           }
         value_int_str+= CharToString (( uchar )ch);
        }
       //--- rule description
       for ( int i=start_ind;i<len;i++)
        {
         ushort ch= StringGetCharacter (str,i);
         if (ch==Separator)
           {
            start_ind=i+ 1 ;
             break ;
           }
         rule_descr+= CharToString (( uchar )ch);
        }
       //--- enum value 
       for ( int i=start_ind;i<len;i++)
        {
         ushort ch= StringGetCharacter (str,i);
         if (ch==Separator)
           {
            start_ind=i+ 1 ;
             break ;
           }
         value_enum_str+= CharToString (( uchar )ch);
        }                  
       int candN=( int ) StringToInteger (cand_num_str);
       int ruleN=( int ) StringToInteger (rule_str);
       int shift=( int ) StringToInteger (shift_str);
      candle_cond.Create(candN,ruleN,shift,value_int_str,rule_descr);
       if ( CheckPointer (candle_cond))
        {
         if (candles_one_rules.AddCondition( GetPointer (candle_cond)))
           {
             if ( StringToInteger (value_int_str)> 0 )
              {
               Print ( __FUNCTION__ + ": candle one #: " ,candle_cond.GetCandNumber(), ", rule: " ,candle_cond.GetRuleNumber(), ", shift: " ,candle_cond.GetShift(), ", description: " ,candle_cond.GetDescription(), ", value: " ,candle_cond.GetValueStr());
              }
             Print ( __FUNCTION__ + ": size of condition: " , sizeof (candle_cond));
           }           
        }
     ...
    } 

Yani, yinelemede CCandleCondition *candle_cond nesnesini oluşturuyorum ve ardından onu candle_one_rules koleksiyonuna ekliyorum.

CCandlesOneRules sınıfının AddCondition yöntemi:

 //+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool CCandlesOneRules::AddCondition(CCandleCondition *cond)
  {
   for ( int i= 0 ;i<Total();i++)
     {
      CCandleOneRules *candle_one_r=At(i);
       if (! CheckPointer (candle_one_r))
         continue ;
       if (cond.GetCandNumber()!=candle_one_r.GetCandOneNumber())
         continue ;
//--- if candle one rules object with the same candle one number as the new condition is found         
       for ( int j= 0 ;j<candle_one_r.Total();j++)
        {
         CCandleRule *candle_rule=candle_one_r.At(j);
         if (! CheckPointer (candle_rule))
             continue ;            
         if (candle_rule.GetRuleNumber()!=cond.GetRuleNumber())
             continue ;
//--- if candle rule with the same rule number as the new condition is found            
         for ( int k= 0 ;k<candle_rule.Total();k++)         
           {
            CCandleCondition *rule_cond=candle_rule.At(k);
             if (! CheckPointer (rule_cond))
               continue ;
             if (rule_cond.GetShift()!=cond.GetShift())
               continue ;
//--- if rule condition with the same shift as the new condition is found
//--- update rule condition               
             return candle_rule.Update(k, GetPointer (cond));
           }
//--- if rule condition with the same shift as the new condition not found
//--- add the new condition
         return candle_rule.Add( GetPointer (cond));
        }
//--- if rule with the same rule number as the new condition not found        
//--- create new rule
      CCandleRule *new_rule= new CCandleRule(cond.GetCandNumber(),cond.GetRuleNumber());
      new_rule.Add( GetPointer (cond));
       return candle_one_r.Add( GetPointer (new_rule));
     }
//--- if candle one rules object with the same candle one number as the new condition not found
//--- create new candle one rule object
   if (cond.GetCandNumber()>m_candles_one_total)
      m_candles_one_total=cond.GetCandNumber();
   CCandleOneRules *new_cand_one_r= new CCandleOneRules(cond.GetCandNumber());
   CCandleRule *new_rule= new CCandleRule(cond.GetCandNumber(),cond.GetRuleNumber());
   new_rule.Add( GetPointer (cond));
   new_cand_one_r.Add( GetPointer (new_rule));
   return Add( GetPointer (new_cand_one_r));
//--- 
  }

CCandleRule, koşullar için yalnızca bir kapsayıcı sınıfıdır. Kurallara koşulları ve CCandleOneRules'daki kuralları ekliyorum, bunlar da CCandlesOneRules'da...

Bu while döngüsü başlangıçta çalışmaz, yetersiz bellek hatasıyla çöker. Üstelik bu koşullardan çok fazla yok, durmadan önce sadece 7 tanesi okunuyor. Okunabilir bir dosyadaki veri sayısını azaltırsanız, silinmemiş nesneler vb. herhangi bir hata olmadan çalışır.

 
Affınıza sığınırım. CCandleCondition nesnelerinin sayısı ( CObject öğesinden türetilen basit bir sınıf) 91831'dir. Bundan sonra, bellek yetersiz.
 
Juer :

Kodu daha iyi gösterelim.

sabrımı kaybetmeye başlıyorum.

new_cand_one_r.Add( GetPointer (new_rule));
return Add( GetPointer (new_cand_one_r));

Add yönteminin tanımı nerede?

Koda bakılırsa, ne yaptığınızı tamamen yanlış anlıyorsunuz.

 
Vasiliy Sokolov :

sabrımı kaybetmeye başlıyorum.

Add yönteminin tanımı nerede?

Koda bakılırsa, ne yaptığınızı tamamen yanlış anlıyorsunuz.

CCandleOneRules, CCandlesOneRules, CCandleRule, tümü CArrayObj'den devralınan sınıflardır.

Genel cevaplarınıza bakılırsa, sorularımı anlamıyorsunuz. CArrayObj içeren bir dizide hala doğru yolu yanıtlamadınız. O görevi tekrar edeyim. Bir sınıf var, sınıf yönteminde, sınıfın genel nesneleri diziye eklenir (CARrayObj türünde bir nesne), bu yöntemde orada bildirilir. Bu yöntemde bazı işlemler bu dizide gerçekleştirilir. Tamamlandığında, dizi nesnesine ihtiyaç yoktur, dizi üyelerine ihtiyaç vardır. Dizi üyelerini korurken bu dizi nesnesinden kurtulmanın doğru yolu nedir? Ondan kurtulmazsanız, günlükte silinmemiş nesneler gibi mesajlar alacağız. Çözümümü verdim, yanlış dedin. Nasıl doğru? Belirtilen dizi nesnesi yalnızca sınıf yönteminde görünür durumdaysa, silmeyi OnDeinit'e (veya OnDeinit'ten çağrılacak Deinit sınıf yöntemine) nasıl yerleştirebilirim?

Ayrıca, nesneler yalnızca OnDeinit'te silinirse, program yürütme / test etme sırasında da bellek yetersiz kalabilir ...

 

Merhaba meslektaşlarım.

Bu sorunu çözmeme yardım et. Gösterge arabelleği öğelerinin numaralandırma sırasını belirtmek için ArraySetAsSeries() işlevini kullanmak en mantıklı nerede? Terminalde önceden kurulu olan göstergelerde, genellikle OnCalculate() içinde kullanıldığını gözlemledim. Ancak gösterge arabelleği global olarak bildirilir. Bu durumda, tek bir çağrı için OnInit() işlevinin içinde bir kez ArraySetAsSeries() işlevini kullanmak mantıklı değil mi? Veya, gösterge arabelleğinin yeni öğelerle yenilenmesi nedeniyle, numaralandırma sırası kaybolabilir ve OnCalculate() içinde her seferinde ArraySetAsSeries()'i çağırmaya gerek var mı? Gerekmediğinde ekstra işlev çağrılarının olmadığı optimum kodu yazmak istiyorum. Yardım için minnettar olacağım.

 
Oleg Remizov :

Merhaba meslektaşlarım.

Bu sorunu çözmeme yardım et. Gösterge arabelleği öğelerinin numaralandırma sırasını belirtmek için ArraySetAsSeries() işlevini kullanmak en mantıklı nerede? Terminalde önceden kurulu olan göstergelerde, genellikle OnCalculate() içinde kullanıldığını gözlemledim. Ancak gösterge arabelleği global olarak bildirilir. Bu durumda, tek bir çağrı için OnInit() işlevinin içinde bir kez ArraySetAsSeries() işlevini kullanmak mantıklı değil mi? Veya, gösterge arabelleğinin yeni öğelerle yenilenmesi nedeniyle, numaralandırma sırası kaybolabilir ve OnCalculate() içinde her seferinde ArraySetAsSeries()'i çağırmaya gerek var mı? Gerekmediğinde ekstra işlev çağrılarının olmadığı optimum kodu yazmak istiyorum. Yardım için minnettar olacağım.

IMHO, bu işlevler olmadan göstergeler yazardım (tabii ki sıfırdan). Ve böylece - arabellekler için - OnInit()'te, zaman serileri için - OnCalculate()'de.

Ve optimal kod hakkında konuşmak için, bu fonksiyonun ne kadar sürede yürütüldüğünü bilmeniz gerekir. Bu nedenle, önce profil oluşturucu ve ancak ondan sonra performans soruları başlamalıdır.

 
Alexey Kozitsyn :

IMHO, bu işlevler olmadan göstergeler yazardım (tabii ki sıfırdan). Ve böylece - arabellekler için - OnInit()'te, zaman serileri için - OnCalculate()'de.

Ve optimal kod hakkında konuşmak için, bu fonksiyonun ne kadar sürede yürütüldüğünü bilmeniz gerekir. Bu nedenle, önce profil oluşturucu ve ancak ondan sonra performans soruları başlamalıdır.

Bu sonuca doğru eğildim. Bahşiş için teşekkürler.

 

Tünaydın. Aşağıdaki soru ortaya çıktı: neden MACD'ye bolinger bantları uyguladığımda, histogramın kendisi değil sinyal hattının değerleri alınır?

 
Виктор :

Tünaydın. Aşağıdaki soru ortaya çıktı: neden MACD'ye bolinger bantları uyguladığımda, histogramın kendisi değil sinyal hattının değerleri alınır?

Hesaplama için hangi grafik arabelleğinin kullanılacağını belirleme olanağınız var mı?