Diskussion zum Artikel "Universal Expert Advisor: Einbindung der Standard MetaTrader Module für Signale (Teil 7)" - Seite 3

 
Amy Liu:

Danke Vasiliy für deinen Beitrag. Ich habe eine Menge gelernt. Ich habe den ganzen Code heruntergeladen, aber er hat einen Kompilierungsfehler in der Datei Panel.mqh:

'At' - Objektzeiger erwartet Panel.mqh 210 39

'At' - Objektzeiger erwartet Panel.mqh 228 37

Können Sie das bitte überprüfen?


Hallo Amy. Ich habe gerade die Artikel von Vasiliy Sokolov durchgelesen. Wenn Sie immer noch daran interessiert sind, die Lösung herauszufinden. Bitte posten Sie das Fehlerprotokoll hier. Ich erinnere mich, dass ich über diesen Fehler gestolpert bin und festgestellt habe, dass es ein ".\Panel\Panel.mqh" in den Deklarationen der StrategiesList-Datei gibt. Panel.mqh existiert nicht. Versuchen Sie stattdessen, auf https://www.mql5.com/de/articles/2411 zu gehen und die Panel-Datei von dort herunterzuladen. Ich glaube, dort ist die Datei Panel.mqh vorhanden.

Diese Serie von Vasiliy's ist wirklich gut als Framework. Ich habe auch viel gelernt, aber wenn es Probleme mit einer Bibliothek gibt und der Autor keinen Support anbietet, kann man aufgeschmissen sein, wenn man kein guter Programmierer ist. Das ist der Punkt, den Alain Verleyen in Ihren anderen Diskussionen angesprochen hat. Aber diejenigen, die sich die Zeit nehmen, ihr Wissen und ihre Fähigkeiten hier mit anderen zu teilen, sind einfach großartig. Ich bin ihnen ewig dankbar.

Universal Expert Advisor: A Custom Trailing Stop (Part 6)
Universal Expert Advisor: A Custom Trailing Stop (Part 6)
  • 2016.06.16
  • Vasiliy Sokolov
  • www.mql5.com
The sixth part of the article about the universal Expert Advisor describes the use of the trailing stop feature. The article will guide you through how to create a custom trailing stop module using unified rules, as well as how to add it to the trading engine so that it would automatically manage positions.
 

Die Engine ist absolut wunderbar, vielen Dank. Es ist die erste OOP-MQL5-Engine, zu der ich mich entschlossen habe, zu wechseln.

Aber Manager.OnTick() ist leider sehr langsam. Tracing zeigt fast 100% an. Testen ist sehr langsam auf eine Minute Zeitrahmen und mit OHLC M1. Seit 3 Jahren - etwa 50 Sekunden. Und zur gleichen Zeit der Expert Advisor selbst tut nichts für die Prüfung, habe ich kommentiert alles, was es lädt. Das heißt, es sucht nur Bars.

Ich möchte wirklich den Code in Manager.OnTick() optimieren.

 
Edgar:

Die Engine ist absolut wunderbar, vielen Dank. Es ist die erste OOP-MQL5-Engine, zu der ich mich entschlossen habe, zu wechseln.

Aber Manager.OnTick() ist leider sehr langsam. Tracing zeigt fast 100% an. Testen ist sehr langsam auf eine Minute Zeitrahmen und mit OHLC M1. Seit 3 Jahren - etwa 50 Sekunden. Und zur gleichen Zeit der Expert Advisor selbst tut nichts für die Prüfung, habe ich kommentiert alles, was es lädt. Das heißt, es sucht nur Bars.

Ich möchte wirklich den Code in Manager.OnTick() optimieren.


Dies ist die Funktion, von der aus alles andere gestartet wird - natürlich wird sie 100%ig sein. Sehen Sie sich an, wofür die Zeit verwendet wird, und optimieren Sie sie. Sie können einen Screenshot veröffentlichen.

 
Edgar:

Die Engine ist absolut wunderbar, vielen Dank. Es ist die erste OOP-MQL5-Engine, zu der ich mich entschlossen habe, zu wechseln.

Aber Manager.OnTick() ist leider sehr langsam. Tracing zeigt fast 100% an. Testen ist sehr langsam auf eine Minute Zeitrahmen und mit OHLC M1. Seit 3 Jahren - etwa 50 Sekunden. Und zur gleichen Zeit der Expert Advisor selbst tut nichts für die Prüfung, habe ich kommentiert alles, was es lädt. Das heißt, es sucht nur Bars.

Ich möchte wirklich den Code in Manager.OnTick() optimieren.

Hier gibt es nichts Überraschendes. Diese Geschwindigkeit ist vergleichbar mit dem Leerlauf eines Strategie-Testers. OnTick bestimmt das Auftreten eines neuen Ticks und das Öffnen eines neuen Balkens. Diese Vorgänge erfordern nicht viele Ressourcen.

 

Hallo, Vasily.

Vielen Dank für alle Ihre Artikel.

Der Universal Expert Advisor ist wirklich beeindruckend, was die Komplexität und die Software-Architektur angeht.

Für diese spezielle Version möchte ich einen Punkt in diesem Stück Code hier ansprechen:

CAdapterMACD::CAdapterMACD(void)
{
   m_params.symbol = Symbol();
   m_params.period = Period();
   m_params.every_tick = false;
   m_params.signal_type = SIGNAL_MACD;
   m_params.magic = 1234;
   m_params.point = 1.0;
   m_params.usage_pattern = 2;
   CSignalMACD* macd = m_signal.CreateSignal(m_params);
   macd.PeriodFast(15);
   macd.PeriodSlow(32);
   macd.PeriodSignal(6);
}

Beachten Sie, dass wir nach der Erstellung des Signals die Konfiguration fortgesetzt haben, indem wir unsere eigene Periode des MACD-Indikators (15, 32, 6) festgelegt haben. Dies ist einfach zu tun, da die Methode CreateSignal das entsprechende Objekt zurückgegeben hat.<br/ translate="no">

Eigentlich haben die MacD-Parameter (15, 32 und 6) hier keine Wirkung, da die Methode CreateSignal() das MacD-Signal initialisiert, bevor die Parameter aktualisiert werden.

In diesem Fall würde ich vorschlagen, die Methode CSignalAdapter::CreateSignal() in zwei Teile aufzuteilen, wobei im ersten Teil das Signal tatsächlich erstellt und zurückgegeben wird, so wie es ist, und der zweite Teil wäre die Signalinitialisierung, nachdem alle "signalabhängigen" Parameter (in diesem Fall PeriodFast, PeriodSlow und PeriodSignal) gesetzt sind:

CExpertSignal* CSignalAdapter::CreateSignal(MqlSignalParams& params)
{
   DeleteSignal();
   switch(params.signal_type)
   {
      case SIGNAL_AO:
         m_signal = new CSignalAO();
         break;
      case SIGNAL_AC:
         m_signal = new CSignalAC();
         break;
      case SIGNAL_ADAPTIVE_MA:
         m_signal = new CSignalAMA();
         break;
      case SIGNAL_CCI:
         m_signal = new CSignalCCI();
         break;
      case SIGNAL_DeMARKER:
         m_signal = new CSignalDeM();
         break;
      case SIGNAL_DOUBLE_EMA:
         m_signal = new CSignalDEMA();
         break;
      case SIGNAL_ENVELOPES:
         m_signal = new CSignalEnvelopes();
         break;
      case SIGNAL_FRAMA:
         m_signal = new CSignalFrAMA();
         break;
      case SIGNAL_MA:
         m_signal = new CSignalMA();
         break;
      case SIGNAL_MACD:
         m_signal = new CSignalMACD();
         break;
      case SIGNAL_PARABOLIC_SAR:
         m_signal = new CSignalSAR();
         break;
      case SIGNAL_RSI:
         m_signal = new CSignalRSI();
         break;
      case SIGNAL_RVI:
         m_signal = new CSignalRVI();
         break;
      case SIGNAL_STOCHASTIC:
         m_signal = new CSignalStoch();
         break;
      case SIGNAL_TRIPLE_EA:
         m_signal = new CSignalTriX();
         break;
      case SIGNAL_TRIPLE_EMA:
         m_signal = new CSignalTEMA();
         break;
      case SIGNAL_WILLIAMS_PER_RANGE:
         m_signal = new CSignalWPR();
         break;
   }
   if(CheckPointer(m_signal)!= POINTER_INVALID)
      m_params = params;
   
   return m_signal;
}

bool CSignalAdapter::Init()
{
   if(m_params.symbol == "") /* CreateSignal method should be called first in order to update m_params */
      return false;
   m_info.Name(m_params.symbol);
   if(!m_signal.Init(GetPointer(m_info), m_params.period, m_params.point))
      return false;
   if(!m_signal.InitIndicators(GetPointer(m_indicators)))
      return false;
   m_signal.EveryTick(m_params.every_tick);
   m_signal.Magic(m_params.magic);
   
   m_open.Create(m_params.symbol, m_params.period);
   m_high.Create(m_params.symbol, m_params.period);
   m_low.Create(m_params.symbol, m_params.period);
   m_close.Create(m_params.symbol, m_params.period);
   
   m_times.Create(m_params.symbol, m_params.period);
   m_spread.Create(m_params.symbol, m_params.period);
   m_tik_vol.Create(m_params.symbol, m_params.period);
   m_real_vol.Create(m_params.symbol, m_params.period);
   
   m_signal.SetPriceSeries(GetPointer(m_open), GetPointer(m_high), GetPointer(m_low), GetPointer(m_close));
   //m_signal.SetOtherSeries(GetPointer(m_spread), GetPointer(m_times), GetPointer(m_tik_vol), GetPointer(m_real_vol));
   int mask = 1;
   mask = mask << m_params.usage_pattern;
   m_signal.PatternsUsage(mask);
   return true;
}

Und natürlich muss die neu erstellte Init-Methode aufgerufen werden:

CAdapterMACD::CAdapterMACD(void)
{
   m_params.symbol = Symbol();
   m_params.period = Period();
   m_params.every_tick = false;
   m_params.signal_type = SIGNAL_MACD;
   m_params.magic = 1234;
   m_params.point = 1.0;
   m_params.usage_pattern = 2;
   CSignalMACD* macd = m_signal.CreateSignal(m_params);
   macd.PeriodFast(15);
   macd.PeriodSlow(32);
   macd.PeriodSignal(6);
   m_signal.Init(); /* This call is going to create the CSignalMACD object with the custom parameters */
}


Vielen Dank für die großartige Arbeit und noch mehr dafür, dass du sie geteilt hast, Vasily!


Prost!

Rodrigo Haller

 

Der Autor hat eine Menge Respekt. wieder einmal habe ich die Tatsache konfrontiert, dass praktisch etwas getan, fand ich praktisch das gleiche bereits vor getan), wie sie sagen, alles wurde vor uns erfunden).

Ein Moment, den ich beachten möchte - in der Arbeit der Signale zu mir von Anfang an war wild, dass der gewichtete Durchschnitt der Signale zu kaufen und zu verkaufen, ist es nicht mit der Logik der Entscheidungsfindung in der kanonischen Form (Entscheidungsbaum, der bereits hier erwähnt wird) passen, und ich habe so - der Progenitor von Signalen enthält zusätzlich zu den eigentlichen Liste der Signale, aus denen die Richtung genommen wird (von -100 bis 100) Slots für Signale auf UND, ANDNOT, XOR. in diesem Fall ist die übliche OR, nicht nur boolesche. Die gesamte Logik der Verarbeitung dieser Slots ist eindeutig und in der Vorgängerklasse verankert. D.h. um eine Strategie zu konstruieren, muss man nur das Hauptsignal zum Expert Advisor hinzufügen und Signale zu den entsprechenden Logik-Slots, nach dem gleichen Prinzip wie ursprünglich, d.h. für jeden bis zu 64 zusätzliche Filter. Ich halte diese Lösung für die einfachste und leicht umsetzbare. Wenn Sie an der Idee interessiert sind und etwas nicht verstehen, nehmen Sie bitte Kontakt mit mir auf und ich werde Ihnen mehr dazu sagen.

 

Wie ist es möglich, die Klasse CSignalMACD in einem Skript zu verwenden?

Ich habe versucht, Signal Ergebnis nur an Ort und Stelle zu erhalten, aber immer bekam 0:

void OnStart()
{
   CSignalMACD       m_signal_macd;
   CSymbolInfo       m_info;
   CiOpen            m_open;
   CiHigh            m_high;
   CiLow             m_low;
   CiClose           m_close;
   CIndicators       m_indicators;

   m_signal_macd.Pattern_0(0);
   m_signal_macd.Pattern_1(0);
   m_signal_macd.Pattern_2(0);
   m_signal_macd.Pattern_3(100);
   m_signal_macd.Pattern_4(0);
   m_signal_macd.Pattern_5(0);
   m_info.Name(Symbol());                                  // Initialisierung des Objekts, das das Handelssymbol der Strategie darstellt
   m_signal_macd.Init(GetPointer(m_info), Period(), 10);   // Initialisierung des Signalmoduls durch das Handelssymbol und den Zeitrahmen
   m_signal_macd.InitIndicators(GetPointer(m_indicators)); // Erstellen der erforderlichen Indikatoren im Signalmodul auf der Grundlage der leeren Liste der Indikatoren m_indicators
   //m_signal_macd.EveryTick(true); // Testmodus
   m_signal_macd.Magic(42);                     // Magische Zahl
   m_signal_macd.PatternsUsage(8);                         // Mustermaske
   m_open.Create(Symbol(), Period());                      // Initialisierung der Zeitreihe der Eröffnungskurse
   m_high.Create(Symbol(), Period());                      // Initialisierung der Zeitreihe der Höchstpreise
   m_low.Create(Symbol(), Period());                       // Initialisierung der Zeitreihe der Niedrigpreise
   m_close.Create(Symbol(), Period());                     // Initialisierung der Zeitreihe der Schlusskurse
   m_signal_macd.SetPriceSeries(GetPointer(m_open),        // Initialisierung des Signalmoduls durch Zeitreihenobjekte
                              GetPointer(m_high),
                              GetPointer(m_low),
                              GetPointer(m_close));
                              
   m_indicators.Refresh();
   m_signal_macd.SetDirection();
   int power_sell = m_signal_macd.ShortCondition();
   int power_buy = m_signal_macd.LongCondition();
   printf("PowerSell: " + (string)power_sell + " PowerBuy: " + (string)power_buy);
                                    
  }