Strategietester dreht durch - Seite 3

 
Carl Schreiber:

Zwei Möglichkeiten:

  1. Durch falsch gesetzte Klammern sind die Variablen nicht (mehr) sichtbar.
  2. Die Datenabfrage geschieht vor deren Deklaration, wie zB. CandleCounter in Deinem Bild.

zu 1. Habe nichts an den Klammern geändert
zu 2. habe schon 10 5M-Candles via F5 durchgeklickt

 

wie gesagt, du musst dich mal mit den Grundlagen befassen, sonst wird das nix

und codes so ganz ohne leerzeilen sind sowas von unübersichtlich

void OnTick()
  {
   if(started)
      SimpleTradeProcessor();
   else
      InitCounters();

   if(StopAtDate.Check("2020.04.01", "02:47"))
      DebugBreak();

   double Ask=NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   double Bid=NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
   MqlRates PriceInfo[];
   ArraySetAsSeries(PriceInfo,true);
   int PriceData = CopyRates(_Symbol,_Period,0,3,PriceInfo);				// die Integer zu verwenden ohne abzufragen ob es auch Funktioniert ist sinnlos, da reicht CopyBuffer allein auch
   string signal="";									// was ist das? soll dann Buy und Sell reinkommen? nehm an von den Bedingungen her kann es eine Buy und Sell order gar nicht gleichzeitig geben
   double myMovingAverageArray[];
   ArraySetAsSeries(myMovingAverageArray,true);						// --> hat in der On Tick nix verloren
   int movingAverageDefinition = iMA(_Symbol,_Period,20,0,MODE_SMA,PRICE_CLOSE);	// --> hat in der On Tick nix verloren
   CopyBuffer(movingAverageDefinition,0,0,3,myMovingAverageArray);
   if(PriceInfo[1].close < myMovingAverageArray[1])					
      if(PriceInfo[0].close > myMovingAverageArray[0])					// warum verwendest Du nicht && wenn Du 2 Bedingungen haben willst? 2x If ist unübersichtlich
        {
         signal = "buy";								// Ein String für eine Bedingung ist pfui, das muss man ja durchprogrammieren, und wo gehts dann weiter?
        }
   if(PriceInfo[1].close > myMovingAverageArray[1])
      if(PriceInfo[0].close < myMovingAverageArray[0])					// warum verwendest Du nicht && wenn Du 2 Bedingungen haben willst? 2x If ist unübersichtlich
        {
         signal = "sell";								// Ein String für eine Bedingung ist pfui, das muss man ja durchprogrammieren, und wo gehts dann weiter?
        }
 
amando:

wie gesagt, du musst dich mal mit den Grundlagen befassen, sonst wird das nix

und codes so ganz ohne leerzeilen sind sowas von unübersichtlich

Danke für Deine Inputs, die mir einleuchten. Ich habe den Überblick verloren, ist klar, dass Deklarationen in OnTick nix verloren haben.
Ebenso klar, dass ich das Doppelt-if besser durch && ersetze, gut; hatte ich übernommen ohne drüber nachzudenken; hatte halt über anderes nachgedacht =)
String für Bedingung als Pfui stimme ich auch zu, kommt komisch, andererseits wo ist der Unterschied zu einem bool? Ich kann buysig und sellsig auf true/false setzen, kommt mir auch richtiger vor, aber letztlich egal, oder?

Mein ganzer (Chaos)Code hängt auf der Seite davor an, oder auf der ersten. Aber schau Du dir den besser nicht an, sonst läufst Du aggro =)

Ich gebe mir Mühe, versprochen! Der Code ist für mich eigentlich Nebensache, für mich ist die grobe Logik entscheidend und was rauskommt. Aber ich sehe schon, dass aufräumen Sinn macht..

 
lindomatic:

Danke für Deine Inputs, die mir einleuchten. Ich habe den Überblick verloren, ist klar, dass Deklarationen in OnTick nix verloren haben.
Ebenso klar, dass ich das Doppelt-if besser durch && ersetze, gut; hatte ich übernommen ohne drüber nachzudenken; hatte halt über anderes nachgedacht =)
String für Bedingung als Pfui stimme ich auch zu, kommt komisch, andererseits wo ist der Unterschied zu einem bool? Ich kann buysig und sellsig auf true/false setzen, kommt mir auch richtiger vor, aber letztlich egal, oder?

Mein ganzer (Chaos)Code hängt auf der Seite davor an, oder auf der ersten. Aber schau Du dir den besser nicht an, sonst läufst Du aggro =)

Ich gebe mir Mühe, versprochen! Der Code ist für mich eigentlich Nebensache, für mich ist die grobe Logik entscheidend und was rauskommt. Aber ich sehe schon, dass aufräumen Sinn macht..

Du wirst ohne aufräumen keinen vernünftigen code zusammenbekommen

wie gesagt, huerst hausaufgaben, was gehört wohin

dann überlegen wo man einsteigt und wie

 

Ich hab jetzt ein Grundgerüst für einen EA erstellt, so wie meine EAs funktionieren.

Alles modular und jeder Modul leicht austauschbar. Vor Allem ein Signalmodul!

Die Klassen CTradeExt und CSignal sollten auf alle Fälle ausgelagert werden.

Das Signal unbedingt als enum definieren. Stringfunktionen sind auch auf heutigen PC langsam, und switch kann man mit Strings auch nicht verwenden!

//+------------------------------------------------------------------+
//| abbreviations & definitions                                      |
//+------------------------------------------------------------------+
#ifndef POSTYPE #define POSTYPE ENUM_POSITION_TYPE       \ #endif    // abbreviation for ENUM_POSITION_TYPE
#ifndef ORDTYPE #define ORDTYPE ENUM_ORDER_TYPE          \ #endif    // abbreviation for ENUM_ORDER_TYPE

//+------------------------------------------------------------------+
//| eine abgeleitete Klasse von CTrade, sollte ausgelagert werden    |
//+------------------------------------------------------------------+
#include <Trade\Trade.mqh>

class CTradeExt
{
   public:
      double   Ask,Bid;
      bool     PosOpened;
      POSTYPE  PosType;
      void OnTick()
          {
            Ask=NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
            Bid=NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
            PosOpened=PositionSelect(_Symbol);
            PosType = (POSTYPE)PositionGetInteger(POSITION_TYPE);

          }
};

CTradeExt Trade;  // Instanz von CTradeExt

//+------------------------------------------------------------------+
//| Signalmodul, sollte in eine separate mqh ausgelagert werden      |
//+------------------------------------------------------------------+
enum SIGNAL
  {
     SIG_NONE,
     SIG_BUY,
     SIG_SELL
  };

class CSignal
{
   private:
      MqlRates PriceInfo[];   // Kerzendaten(bars)
      int      handleSMA;     // Handle für den SMA
      double   bufferSMA[];   // Buffer für den SMA
      int      toCopy;        // Anzahl der zu kopierenden Kerzen(bars)
   
   public:
      bool OnInit(void)
         {
            ArraySetAsSeries(PriceInfo,true);                           // Zugriffsart einstellen. Hier wird nix sortiert wie Herr R.B. behauptet
            ArraySetAsSeries(bufferSMA,true);
            toCopy=3;
            handleSMA = iMA(_Symbol,_Period,20,0,MODE_SMA,PRICE_CLOSE); // Handle für den iMA erzeugen
            if(HandleError(handleSMA,"iMA"))                            // Handle überprüfen 1
               return(false);
            
            return(true);
         }
      bool OnTick()
         {
            if(CopyRates(_Symbol,_Period,0,toCopy,PriceInfo)!=toCopy) return(false);
            if(CopyBuffer(handleSMA,0,   0,toCopy,bufferSMA)!=toCopy) return(false);
            return(true);
         }
      SIGNAL Signal(void)
         {
            if(PriceInfo[1].close < bufferSMA[1])
               if(PriceInfo[0].close > bufferSMA[0])
                  return(SIG_BUY);

            if(PriceInfo[1].close > bufferSMA[1])
               if(PriceInfo[0].close < bufferSMA[0])
                  return(SIG_SELL);

            return(SIG_NONE);
         }
         
};

CSignal Signal;   // Instanz von CSignal

//+------------------------------------------------------------------+
//| Hier gehören Programmschritte rein, die nur einmal ausgeführt werden müssen
//+------------------------------------------------------------------+
int OnInit()
{
   if(!Signal.OnInit())
      return(INIT_FAILED);

   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| und das bleibt über vom Hauptprogramm                            |
//+------------------------------------------------------------------+
void OnTick()
{
   Trade.OnTick();
   if(!Signal.OnTick())
      return;
   
   if(Trade.PosOpened)              // Position existiert
      switch(Trade.PosType)
        {
         case POSITION_TYPE_BUY :
                                    // Buy Position verwalten
           break;
         case POSITION_TYPE_SELL:
                                    // Sell Position verwalten
           break;
        }
   else                             // es ist keine position offen
      switch(Signal.Signal())
        {
         case SIG_BUY :
                                    // kaufen
           break;
         case SIG_SELL:
                                    // verkaufen
           break;
        }
  
}

//+------------------------------------------------------------------+
//| Hilfsfunktionen                                                  |
//+------------------------------------------------------------------+
bool HandleError(int aHandle, string aName)
{
   if(aHandle==INVALID_HANDLE)
      {
         Alert("*ERROR* creating ",aName," handle.");
         return(true); 
      }
   return(false);
}

Da dreht der Tester nicht mehr durch;)

Ich häng da eine komplette TradeExt.mqh dran.

Dateien:
 
Otto Pauser:

Ich häng da eine komplette TradeExt.mqh dran.

Sieht schick aus .CSymbol und CAccount mit eingebaut. Gefällt mir.

Aber ich denke, das ist zu viel "Hightech" für lindomatic.

 
Christian:

Sieht schick aus .CSymbol und CAccount mit eingebaut. Gefällt mir.

Aber ich denke, das ist zu viel "Hightech" für lindomatic.

Ja, es ist "Hightech", aber große Projekte kann man nur modular zusammenstellen, sonst wird es "Spagetticode".

MQL5 bietet sehr gute Möglichkeiten, incl. input-Variablen, um modular zu programmieren.

Leider hat die Benutzeroberfläche und der Tester(visuell) viele Fehler, und es ist es nicht möglich mit MQ zu kommunizieren. Aber da habe ich mich daran gewöhnt.

 
Otto Pauser:

Ich hab jetzt ein Grundgerüst für einen EA erstellt, so wie meine EAs funktionieren.

Alles modular und jeder Modul leicht austauschbar. Vor Allem ein Signalmodul!

Die Klassen CTradeExt und CSignal sollten auf alle Fälle ausgelagert werden.

Das Signal unbedingt als enum definieren. Stringfunktionen sind auch auf heutigen PC langsam, und switch kann man mit Strings auch nicht verwenden!

Da dreht der Tester nicht mehr durch;)

Ich häng da eine komplette TradeExt.mqh dran.

Danke, Otto. Die TradeExtSimple.mqh hattest Du ja schon mehrmals angehängt, die liegt hier auch noch immer in Hardcopy auf meinem Tisch.. irgendwie hatte mich mein eigener EA abgelenkt.

Ja, sieht super sauber aus und perfekt strukturiert; da stecken an die 10 Jahre mql-Erfahrung drin? Aber es ist ja nicht mql, es ist ja OOP im allgemeinen. Ich meine schon (kann mich natürlich irren), dass ich das Konzept allmählich verstehe, wenn mir auch die Nachverfolgung noch immer schwer fällt, bspw. hier mit PosType, das frustriert mich, es nicht zu verstehen: Du definierst die Abkürzung POSTYPE zu ENUM_POSITION_TYPE, gut. (oder auch nicht, mich verwirren alle zusätzlichen "Begriffe"..)
In Deiner CTradeExt Class unter public "deklarierst" (?) Du  POSTYPE  PosType; Aber ENUM_POSITION_TYPE ist doch eine PositionProperty, das ist doch kein Typ, den man deklarieren kann, das verstehe ich nicht.

Dann nutzt Du switch case um die Positionen zu verwalten, wie Du kommentierst, aber wo findet die Verwaltung statt, wo führen diese cases hin?

@Christian: Du verstehst mich, das ist sehr hartes Brot für mich, aber ich will es ja lernen und verstehen; aber ich weiß nicht, welcher Weg dahin führt. Immer wieder Code ansehen und Kopfschmerzen machen? Ich bezweifle, dass diese Schmerzen einen Lerneffekt haben. Ich bräuchte da ein paar Schulungsstunden, das ist, meine ich, via Forum/Chat/eMail kaum möglich. Ich bin eher Autodidakt, aber hier müsste mir das jemand am Biemer zeigen: "Hierdurch springen wir hierhin, mit diesen Werten/Parametern, die kommen hier an und machen dann das..."

Aber gänzlich verzweifeln tue ich auf der Suche nach den von Dir gelobten Classes CSymbol und CAccount, wo bitte sind die denn?! 

 
lindomatic: @Christian: Aber gänzlich verzweifeln tue ich auf der Suche nach den von Dir gelobten Classes CSymbol und CAccount, wo bitte sind die denn?! 

Diese Klassen sind in die CTtradeExt.mqh eingebunden. Naja, nicht wirklich, ich habe Programmcode daraus entnommen und hier eingearbeitet.

Nur Geduld, du wirst das schaffen. Ich programmiere seit 35 Jahren und mit MQL5 habe ich mich sicher mehr als 10.000 Stunden beschäftigt

 
Otto Pauser:

Diese Klassen sind in die CTtradeExt.mqh eingebunden. Naja, nicht wirklich, ich habe Programmcode daraus entnommen und hier eingearbeitet.

Nur Geduld, du wirst das schaffen. Ich programmiere seit 35 Jahren und mit MQL5 habe ich mich sicher mehr als 10.000 Stunden beschäftigt

Danke, Otto. Tja, siehste.. Beschäftigen ist eine Sache, Verstehen eine anderes; die Frage ist wann und wodurch der Groschen fällt.. und es muss ja ständig einer fallen.
Ist es die Beschäftigung mit Code, den man zunächst nicht versteht? Sollte ich ggfs. doch das Buch von Andrew Young Seite um Seite durcharbeiten? Ich bin davon abgekommen und habe mich in der online-Doku verloren.
Verrätst Du mir noch, wo Dein TradeHandling versteckt ist? Wo werden Stops gesetzt und nachgezogen?