新人对MQL4和MQL5的任何问题,对算法和代码的帮助和讨论 - 页 600

 
Vasiliy Sokolov:

这不是一个心灵感应的俱乐部。你没有附上你的代码,所以由你来决定把删除放在哪里。

错了。

好了,这里是代码,你还需要什么?如果它不正确怎么办?

谢谢你。

 
Artyom Trishkin:

你把这一切都搞混了。对任务的不正确规划正是导致这些后果的原因。

如果在一个类中创建了对象,它必须在完成后在其析构器中删除它们。另一方面,其他类在获得一个对象的指针之前,应该检查其有效性。而在原则上,不应该有这样的交织关系。这是个有点纠结的问题。复杂并不意味着质量。一切都应该是透明的和可追溯的。首先,最重要的是为了你。

让我们展示一下代码。

这里,我在程序开始时从一个文件中读取一些数据。

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

也就是说,我在迭代时创建一个CCandleCondition *candle_cond对象,然后将其加入candles_one_rules集合。

这里是CCandlesOneRules类的AddCondition方法。

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
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只是一个条件的容器类。我在规则中加入条件,在CCandlesOneRules中加入规则,而CCandlesOneRules....。

但这个while循环在启动时失败了,并以内存不足的错误崩溃。而且这些条件不是太多,只有7个是在停止前读到的。如果我们减少读取文件中的数据数量,它就能工作,没有任何错误、未删除的对象等等。

 
请原谅我。CCandleCondition对象的数量(从CObject 继承的简单类)91831。之后,就没了记忆。
 
Juer:

让我们更好地展示一下这段代码。

我开始失去耐心了。

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

添加法的定义在哪里?

从代码来看,你完全不了解你在做什么。

 
Vasiliy Sokolov:

我开始失去耐心了。

添加法的定义在哪里?

从代码来看,你完全误解了你在做什么。

CCandleOneRules, CCandlesOneRules, CCandleRule都是继承自CArrayObj的类。

从你的一般性回答来看,你就是不明白我的问题。关于带有CArrayObj的数组,你还是没有正确回答。我将再次重复这个问题。有一个类,在类的方法中,该类的 全局对象 被添加到数组(CArrayObj类型的对象)中,该方法在那里声明。在这个方法中,一些动作在这个数组中被执行。完成后,不需要数组对象,需要的是数组成员。如何正确摆脱这个数组对象,保留数组成员?如果你不把它处理掉,你会在日志中得到一个类似未删除对象的信息。我给了你我的解决方案;你说得不对。它是如何正确的?如果这个数组对象只在类的方法中可见,我如何在OnDeinit(或在将被OnDeinit调用的类的Deinit方法)中放置删除?

此外,如果对象只在OnDeinit中被删除,在程序的执行/测试过程中,你也会遇到内存不足的情况。

 

同事们好。

请帮助我解决这个问题。我应该在哪里使用ArraySetAsSeries()函数来指定指标缓冲区中元素的编号顺序?在终端预装的指标中,我经常注意到它被用在OnCalculate()里面。但指标缓冲区是全局声明的。在这种情况下,在OnInit()里面使用ArraySetAsSeries() 进行一次调用不是很合理吗?还是因为用新的元素补充指标缓冲区,编号的顺序可能会丢失,有必要在OnCalculate()中每次调用ArraySetAsSeries()?我想写一个最佳的代码,没有不必要的函数调用,当它没有必要时。我将感谢您的帮助。

 
Oleg Remizov:

同事们好。

请帮助我解决这个问题。我应该在哪里使用ArraySetAsSeries()函数来指定指标缓冲区中元素的编号顺序?在终端预装的指标中,我经常注意到它被用在OnCalculate()里面。但指标缓冲区是全局声明的。在这种情况下,在OnInit()里面使用ArraySetAsSeries() 进行一次调用,不是很合理吗?还是因为用新的元素补充指标缓冲区,编号的顺序可能会丢失,有必要在OnCalculate()中每次都调用ArraySetAsSeries()?我想写一个最佳的代码,没有不必要的函数调用,当它没有必要时。我将感谢您的帮助。

IMHO,我在写指标时根本不需要这些函数(当然,如果从零开始)。对于缓冲区--在OnInit(),对于时间序列--在OnCalculate()。

而且,为了谈论最佳代码,你需要知道这个函数需要多长时间来执行。因此,分析器应该首先进行,然后才是性能问题。

 
Alexey Kozitsyn:

IMHO,我在写指标时根本不需要这些函数(当然,如果从头开始的话)。但对于缓冲区--在OnInit(),对于时间序列--在OnCalculate()。

而且,为了谈论最佳代码,你需要知道这个函数需要多长时间来执行。因此,分析器应该首先进行,然后才是性能问题。

这就是我所倾向的结论。谢谢你的提示。

 

下午好。我有一个问题:为什么当我把博林格应用于MACD时,我取的是信号线 的值而不是直方图本身?

 
Виктор:

下午好。我有一个问题:为什么当我将博林格条应用于MACD时,我取的是信号线 的值而不是直方图本身?

你是否有可能指定使用哪种图形缓冲器进行计算?