Quaisquer perguntas de recém-chegados sobre MQL4 e MQL5, ajuda e discussão sobre algoritmos e códigos - página 600

 
Vasiliy Sokolov:

Este não é um clube telepático. Você não anexou seu código, então cabe a você decidir onde colocar a exclusão.

Errado.

Bem, aqui está o código, o que mais você precisa? E se estiver incorreto?

Obrigado.

 
Artyom Trishkin:

Você tem tudo isso misturado. O planejamento incorreto da tarefa é exatamente o que leva a estas conseqüências.

Se os objetos são criados em uma classe, ela deve apagá-los em seu destruidor após a conclusão. Outras classes, por outro lado, antes de colocar um ponteiro em um objeto, devem verificar sua validade. E, em princípio, não deveria haver uma relação tão entrelaçada. É um pouco emaranhado. Complicado não significa qualidade. Tudo deve ser transparente e rastreável. Antes de mais nada, para você.

Vamos antes mostrar o código.

Aqui, estou lendo alguns dados de um arquivo no início do programa.

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

Isto é, eu crio um objeto CCandleCondition *candle_cond na iteração e depois o adiciono à coleção de velas_uma_regras.

Aqui está o método AddCondition da classe CCandlesOneRules:

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

O CCandleRule é apenas uma classe de contêineres para condições. Adiciono condições às regras e regras do CCandlesOneRules, que por sua vez ao CCandlesOneRules....

Mas isto enquanto o loop falha na partida e falha com erro de memória fora da memória. E não há muitas destas condições, apenas 7 são lidas antes de parar. Se reduzirmos o número de dados no arquivo lido, ele funciona, sem nenhum erro, objetos não apagados e assim por diante.

 
Desculpe-me. Número de objetos CCandleCondition (classe simples herdada de CObject) 91831. Depois disso, fora da memória.
 
Juer:

Vamos ter uma melhor exibição do código.

Estou começando a perder a paciência.

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

Onde está a definição do método Add?

A julgar pelo código, você tem uma completa falta de compreensão do que está fazendo.

 
Vasiliy Sokolov:

Estou começando a perder a paciência.

Onde está a definição do método Add?

A julgar pelo código, você tem um completo mal-entendido do que está fazendo.

CCandleOneRules, CCandlesOneRules, CCandleRule são todas as classes herdadas do CArrayObj.

A julgar por suas respostas genéricas, você simplesmente não entende minhas perguntas. Na matriz com CArrayObj você ainda não respondeu da maneira correta. Mais uma vez, vou repetir esse problema. Há uma classe, no método de classe os objetos globais da classe são adicionados ao array (objeto do tipo CArrayObj), que é declarado neste método. Neste método, algumas ações são realizadas nesta matriz. Após a conclusão, o objeto da matriz não é necessário, os membros da matriz são necessários. Como se livrar corretamente deste objeto de matriz, mantendo os membros da matriz? Se você não se livrar dele, você receberá uma mensagem como objetos não removidos no diário de bordo. Eu lhe dei minha solução; você a disse de forma incorreta. Como é correto? Como posso colocar a exclusão no OnDeinit (ou no método de classe Deinit que será chamado a partir do OnDeinit), se este objeto de matriz é visível apenas dentro do método de classe?

Além disso, se os objetos forem apagados apenas no OnDeinit, você também pode ficar sem memória...

 

Olá colegas.

Por favor, me ajude com esta pergunta. Onde devo usar a função ArraySetAsSeries() para especificar a ordem de numeração dos elementos no buffer de indicadores? Nos indicadores, que são pré-instalados no terminal, tenho notado com freqüência que ele é usado dentro da OnCalculate(). Mas o tampão indicador é declarado globalmente. Não é lógico usar o ArraySetAsSeries() dentro do OnInit() para uma única chamada neste caso? Ou por causa do reabastecimento do buffer indicador com novos elementos a ordem de numeração pode ser perdida e é necessário chamar o ArraySetAsSeries() cada vez dentro da OnCalculate()? Quero escrever um código ideal sem chamadas de função desnecessárias, quando não for necessário. Serei grato pela ajuda.

 
Oleg Remizov:

Olá colegas.

Por favor, me ajude com esta pergunta. Onde devo usar a função ArraySetAsSeries() para especificar a ordem de numeração dos elementos no buffer de indicadores? Nos indicadores, que são pré-instalados no terminal, tenho observado com freqüência que ele é usado dentro da OnCalculate(). Mas o tampão indicador é declarado globalmente. Não é lógico usar o ArraySetAsSeries() dentro do OnInit() para uma única chamada neste caso? Ou por causa do reabastecimento do buffer indicador com novos elementos a ordem de numeração pode ser perdida e é necessário chamar o ArraySetAsSeries() cada vez dentro da OnCalculate()? Quero escrever um código ideal sem chamadas de função desnecessárias, quando não for necessário. Serei grato pela ajuda.

IMHO, eu escreveria indicadores sem estas funções (se de zero, é claro). Para amortecedores - em OnInit(), para séries de tempo - em OnCalculate().

E, para falar em código ideal, é preciso saber quanto tempo esta função leva para ser executada. Portanto, o perfilador deve ir primeiro, e só depois as questões de desempenho.

 
Alexey Kozitsyn:

IMHO, eu escreveria indicadores sem estas funções (se do zero, é claro). Mas para amortecedores - em OnInit(), para séries de tempo - em OnCalculate().

E, para falar de código ideal, você precisa saber quanto tempo esta função leva para ser executada. Portanto, o perfilador deve ir primeiro, e só depois as questões de desempenho.

Essa é a conclusão para a qual eu estava inclinado. Obrigado pela dica.

 

Boa tarde. Tenho uma pergunta: por que, quando aplico as barras de pressão no MACD, eu tomo os valores da linha de sinal e não o histograma em si?

 
Виктор:

Boa tarde. Tenho uma pergunta: por que quando aplico as barras de pressão no MACD, eu tomo os valores da linha de sinal e não o histograma em si?

Você tem a possibilidade de especificar qual buffer gráfico usar para o cálculo?