Fragen von Neueinsteigern zu MQL4 und MQL5, Hilfe und Diskussion über Algorithmen und Codes - Seite 600

 
Vasiliy Sokolov:

Dies ist kein telepathischer Club. Da Sie Ihren Code nicht beigefügt haben, müssen Sie selbst entscheiden, wo Sie ihn löschen wollen.

Falsch.

Nun, hier ist der Code, was brauchen Sie noch? Was ist, wenn sie falsch ist?

Ich danke Ihnen.

 
Artyom Trishkin:

Du bringst das alles durcheinander. Eine fehlerhafte Planung der Aufgabe ist genau das, was zu diesen Folgen führt.

Wenn in einer Klasse Objekte erstellt werden, muss sie diese nach Abschluss in ihrem Destruktor löschen. Andere Klassen hingegen sollten, bevor sie einen Zeiger auf ein Objekt erhalten, dessen Gültigkeit überprüfen. Und im Prinzip sollte es eine solche Verflechtung nicht geben. Es ist ein bisschen verwirrend. Kompliziert ist nicht gleichbedeutend mit Qualität. Alles sollte transparent und nachvollziehbar sein. In erster Linie für Sie.

Lassen Sie uns stattdessen den Code zeigen.

Hier lese ich beim Start des Programms einige Daten aus einer Datei.

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

Das heißt, ich erstelle bei der Iteration ein CCandleCondition *candle_cond-Objekt und füge es dann der Sammlung candles_one_rules hinzu.

Hier ist die AddCondition-Methode der Klasse 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));
//--- 
  }

CCandleRule ist lediglich eine Containerklasse für Bedingungen. Ich füge Bedingungen zu Regeln und Regeln zu CCandlesOneRules hinzu, die wiederum zu CCandlesOneRules....

Aber diese while-Schleife schlägt beim Start fehl und stürzt mit dem Fehler "kein Speicher" ab. Und es gibt nicht allzu viele dieser Bedingungen, nur 7 werden vor dem Stopp gelesen. Wenn wir die Anzahl der Daten in der gelesenen Datei reduzieren, funktioniert es, ohne Fehler, ungelöschte Objekte und so weiter.

 
Entschuldigen Sie bitte. Anzahl der CCandleCondition-Objekte (einfache Klasse, geerbt von CObject) 91831. Danach ist der Speicher leer.
 
Juer:

Lassen Sie sich den Code besser zeigen.

Ich verliere allmählich die Geduld.

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

Wo ist die Definition der Add-Methode?

Nach dem Code zu urteilen, haben Sie überhaupt keine Ahnung, was Sie tun.

 
Vasiliy Sokolov:

Ich verliere allmählich die Geduld.

Wo ist die Definition der Add-Methode?

Nach dem Code zu urteilen, haben Sie ein völlig falsches Verständnis von dem, was Sie tun.

CCandleOneRules, CCandlesOneRules, CCandleRule sind alle von CArrayObj geerbte Klassen.

Ihren allgemeinen Antworten nach zu urteilen, verstehen Sie meine Fragen einfach nicht. Auf Array mit CArrayObj haben Sie immer noch nicht die richtige Antwort gegeben. Ich werde dieses Problem noch einmal wiederholen. Es gibt eine Klasse, in der Klassenmethode werden globale Objekte der Klasse dem Array (Objekt vom Typ CArrayObj) hinzugefügt, das dort in dieser Methode deklariert wird. Bei dieser Methode werden einige Aktionen in diesem Array durchgeführt. Nach der Fertigstellung wird das Array-Objekt nicht benötigt, sondern die Array-Mitglieder. Wie wird man dieses Array-Objekt korrekt los, wobei die Array-Elemente erhalten bleiben? Wenn Sie sie nicht loswerden, erhalten Sie eine Meldung wie ungelöschte Objekte im Protokoll. Ich habe Ihnen meine Lösung genannt; Sie haben sie falsch formuliert. Wie ist das richtig? Wie kann ich löschen in OnDeinit (oder in Deinit-Methode der Klasse, die von OnDeinit aufgerufen wird), wenn dieses Array-Objekt nur innerhalb der Klasse Methode sichtbar ist?

Wenn außerdem Objekte nur in OnDeinit gelöscht werden, kann es bei der Ausführung/Testung des Programms auch zu Speichermangel kommen...

 

Hallo Kollegen.

Bitte helfen Sie mir bei dieser Frage. Wo sollte ich die Funktion ArraySetAsSeries() verwenden, um die Reihenfolge der Elemente Nummerierung in den Indikator Puffer angeben? In den Indikatoren, die im Terminal vorinstalliert sind, habe ich oft festgestellt, dass sie innerhalb von OnCalculate() verwendet wird. Der Indikatorpuffer wird jedoch global deklariert. Ist es in diesem Fall nicht logisch , ArraySetAsSeries() innerhalb von OnInit() für einen einzigen Aufruf zu verwenden? Oder kann durch das Auffüllen des Indikatorpuffers mit neuen Elementen die Reihenfolge der Aufzählung verloren gehen und es ist notwendig, ArraySetAsSeries() jedes Mal in OnCalculate() aufzurufen? Ich möchte einen optimalen Code ohne unnötige Funktionsaufrufe schreiben, wenn dies nicht notwendig ist. Ich bin für jede Hilfe dankbar.

 
Oleg Remizov:

Hallo Kollegen.

Bitte helfen Sie mir bei dieser Frage. Wo sollte ich die Funktion ArraySetAsSeries() verwenden, um die Reihenfolge der Elemente Nummerierung in den Indikator Puffer angeben? In den Indikatoren, die im Terminal vorinstalliert sind, habe ich oft festgestellt, dass sie innerhalb von OnCalculate() verwendet wird. Der Indikatorpuffer wird jedoch global deklariert. Ist es in diesem Fall nicht logisch , ArraySetAsSeries() innerhalb von OnInit() für einen einzigen Aufruf zu verwenden? Oder kann durch das Auffüllen des Indikatorpuffers mit neuen Elementen die Reihenfolge der Aufzählung verloren gehen und es ist notwendig, ArraySetAsSeries() jedes Mal in OnCalculate() aufzurufen? Ich möchte einen optimalen Code ohne unnötige Funktionsaufrufe schreiben, wenn dies nicht notwendig ist. Ich bin für jede Hilfe dankbar.

IMHO würde ich Indikatoren ganz ohne diese Funktionen schreiben (wenn auch von Null an, natürlich). Bei Puffern - in OnInit(), bei Zeitreihen - in OnCalculate().

Und um über optimalen Code zu sprechen, müssen Sie wissen, wie lange die Ausführung dieser Funktion dauert. Der Profiler sollte also an erster Stelle stehen, und erst dann die Leistungsfragen.

 
Alexey Kozitsyn:

IMHO würde ich Indikatoren ganz ohne diese Funktionen schreiben (wenn natürlich von Grund auf). Aber für Puffer - in OnInit(), für Zeitreihen - in OnCalculate().

Und um über optimalen Code zu sprechen, müssen Sie wissen, wie lange die Ausführung dieser Funktion dauert. Der Profiler sollte also an erster Stelle stehen, und erst dann die Leistungsfragen.

Das ist die Schlussfolgerung, zu der ich tendiert habe. Danke für den Hinweis.

 

Guten Tag. Ich habe eine Frage: warum, wenn ich die Bolinger-Balken auf den MACD anwende, nehme ich die Werte der Signallinie und nicht das Histogramm selbst?

 
Виктор:

Guten Tag. Ich habe eine Frage: warum, wenn ich die Bolinger-Balken auf den MACD anwende, nehme ich die Werte der Signallinie und nicht das Histogramm selbst?

Haben Sie die Möglichkeit anzugeben, welcher Grafikpuffer für die Berechnung verwendet werden soll?

Grund der Beschwerde: