Neuer Artikel Cross-Platform Expert Advisor: Signals ist veröffentlicht worden:
Autor: Enrico Lambino
Hallo Enrico. Ich habe mir gerade deine Arbeit angesehen, um eine Lösung für mein Problem zu finden. Beim Kompilieren der Klasse StopBase erhalte ich eine Liste von Fehlern, siehe unten
implicit conversion from 'number' to 'string' OrderStopBase.mqh 395 25 implicit conversion from 'number' to 'string' OrderStopBase.mqh 467 26 implicit enum conversion OrderStopBase.mqh 468 33 implicit enum conversion OrderStop.mqh 37 33 implicit conversion from 'number' to 'string' OrderStop.mqh 44 43 'COrderBase' - import not defined OrderStop.mqh 54 7 'else' - semicolon expected OrderStop.mqh 81 4 ')' - unexpected token OrderStop.mqh 81 46 implicit conversion from 'number' to 'string' StopBase.mqh 767 22 implicit conversion from 'number' to 'string' StopBase.mqh 774 28 implicit conversion from 'number' to 'string' StopBase.mqh 796 22 implicit conversion from 'number' to 'string' StopBase.mqh 803 28 implicit conversion from 'number' to 'string' StopBase.mqh 698 36 'OrderType' - cannot convert enum Stop.mqh 227 52 'StopLossCustom' - no one of the overloads can be applied to the function call Stop.mqh 228 61 could be one of 2 function(s) Stop.mqh 228 61 double CStopBase::StopLossCustom(const string,const ENUM_ORDER_TYPE,const double) StopBase.mqh 136 22 bool CStopBase::StopLossCustom() StopBase.mqh 99 22 'OrderType' - cannot convert enum Stop.mqh 215 71 'TakeProfitCustom' - no one of the overloads can be applied to the function call Stop.mqh 215 98 could be one of 2 function(s) Stop.mqh 215 98 double CStopBase::TakeProfitCustom(const string,const ENUM_ORDER_TYPE,const double) StopBase.mqh 140 22 bool CStopBase::TakeProfitCustom() StopBase.mqh 111 22 implicit conversion from 'number' to 'string' Stop.mqh 250 39 implicit enum conversion Stop.mqh 291 31 implicit conversion from 'number' to 'string' Stop.mqh 292 36
Wenn ich die Warnungen ignoriere, scheinen die Fehler von Problemen mit dem Auftragstyp zu kommen. Auch die Kompilierung Ihres Beispiels signal_ma führt zu folgenden Fehlern
'GetPointer' - parameter conversion not allowed OrderStopVirtualBase.mqh 51 39 'GetPointer' - parameter conversion not allowed OrderStopVirtualBase.mqh 58 41 '=' - type mismatch OrderStopsBase.mqh 106 23 '=' - type mismatch OrderStopsBase.mqh 108 23 '=' - type mismatch OrderStopsBase.mqh 110 23 '=' - type mismatch OrderStopsBase.mqh 180 20 '=' - type mismatch OrderStopsBase.mqh 182 20 '=' - type mismatch OrderStopsBase.mqh 184 20
Woher kommen diese Fehler, und wie kann ich sie beheben? Zu einem verwandten Thema: Soweit ich weiß, schreibt die Liskov-Substitution vor, dass wir auf eine Schnittstelle programmieren sollten, da die Superklasse durch ihre Basisklasse ersetzt werden kann. Warum haben Sie sich dafür entschieden, Objekte an die Funktionen (die an sich Schnittstellen sind) zu übergeben, anstatt ihre Basisklassen zu verwenden? Vielleicht irre ich mich, aber ich glaube, das wäre doch die beste Vorgehensweise, oder nicht?
Vielen Dank für Ihre Hilfe im Voraus und für die großartige Arbeit, die Sie geleistet haben.Hallo Shephard, vielen Dank für Ihren Kommentar. Bezüglich Ihrer Fragen:
- Leider gibt es zur Zeit keine Möglichkeit, StopBase.mqh selbst zu kompilieren. Die MQL4- und MQL5-Compiler akzeptieren zwar Forward-Deklarationen, geben aber einen Fehler aus, wenn Sie versuchen, auf eine Methode oder ein Mitglied der Klasse zuzugreifen, das Forward deklariert wurde. Sie müssen StopBase.mqh mit einer viel größeren Klasse kompilieren, wie z.B. COrderManager oder CExpertAdvisor (CStop und CStops ist eine Komponente dieser beiden Klassen).
- Was die Type-Mismatch-Fehler angeht, so habe ich sie in den Originaldateien nicht gefunden (wurden die Quellen bei Ihnen geändert?).
- Ich denke, in den meisten Fällen können die Basisklassen ohne Probleme an Klassenmethoden übergeben werden. Wenn Kodierungsexperten die Bibliothek verwenden, wäre es einfacher, davon auszugehen, dass die Basisklasse überhaupt nicht existiert. Einige Objekte haben jedoch sowohl neue virtuelle Methoden als auch nicht-virtuelle Methoden. Auf diese beiden Gruppen von Methoden kann die Basisklasse allein nicht zugreifen. Wenn Sie die abgeleiteten Klassen anstelle der Basisklasse verwenden, ist der Compiler in der Lage, die richtige Version der abgeleiteten Klassen auszuwählen, so dass die Verwendung der abgeleiteten Klassen umfassender ist als die Verwendung der Basisklassen allein.
Hallo Shephard, vielen Dank für Ihren Kommentar. Bezüglich Ihrer Fragen:
- Leider gibt es zur Zeit keine Möglichkeit, StopBase.mqh selbst zu kompilieren. Die MQL4- und MQL5-Compiler akzeptieren zwar Forward-Deklarationen, geben aber einen Fehler aus, wenn Sie versuchen, auf eine Methode oder ein Mitglied der Klasse zuzugreifen, das Forward deklariert wurde. Sie müssen StopBase.mqh mit einer viel größeren Klasse kompilieren, wie z.B. COrderManager oder CExpertAdvisor (CStop und CStops ist eine Komponente dieser beiden Klassen).
- Was die Type-Mismatch-Fehler angeht, so habe ich sie in den Originaldateien nicht gefunden (wurden die Quellen bei Ihnen geändert?).
- Ich denke, in den meisten Fällen können die Basisklassen ohne Probleme an Klassenmethoden übergeben werden. Bei der Programmierung von Experten, die die Bibliothek verwenden, wäre es einfacher, davon auszugehen, dass die Basisklasse überhaupt nicht existiert. Einige Objekte haben jedoch sowohl neue virtuelle Methoden als auch nicht-virtuelle Methoden. Auf diese beiden Gruppen von Methoden kann die Basisklasse allein nicht zugreifen. Wenn Sie die abgeleiteten Klassen anstelle der Basisklasse verwenden, ist der Compiler in der Lage, die richtige Version der abgeleiteten Klassen auszuwählen, so dass die Verwendung der abgeleiteten Klassen umfassender ist als die Verwendung der Basisklassen allein.
Hallo Enrico,
vielen Dank für deine schnelle Antwort. Ich verstehe, warum Sie konkrete Klassen anstelle ihrer Basisklassen übergeben. Bestimmte Implementierungen, die in C++ einfach sind, sind in MQL einfach nicht möglich, aber so ist es nun einmal.
Was die Typinkongruenz betrifft, so habe ich nichts geändert. Ich habe einfach heruntergeladen und kompiliert. Ich habe mir Ihre Arbeit auf der Suche nach einem lästigen Problem angesehen, das ich in meinem eigenen System hatte. Ihr Ansatz ist wirklich großartig.
Ich habe mein System auf diese Weise entwickelt. Ich habe ein System, das Signale ausgibt, als Strategie betrachtet. Angenommen, ich habe ein MA-Crossover-System. Wenn ich ein Objekt davon mit, sagen wir, EURUSD erstelle, ist dies eine Strategie. Ich füge diese Strategie in eine Liste von Strategien ein. Ich kann eine weitere Strategie erstellen und sie der Liste hinzufügen. Aber die Strategien werden nicht durch OnTick aufgerufen, sondern sind Teil eines Observer-Musters. Sie werden aktualisiert oder aufgerufen, wenn bestimmte Ereignisse eintreten, z. B. ein neuer 5-Minuten-Balken, ein neuer 10-Pip-Renko-Balken usw. Ich hatte Probleme mit den Stops, die meine Forschung ausgelöst haben.
Nochmals vielen Dank, dass Sie sich die Zeit genommen haben, Ihr Wissen und Ihre Fähigkeiten mit mir zu teilen, und für Ihre schnelle Antwort.
Hallo Shephard,
vielen Dank für deine Vorschläge und Einblicke.
Ich halte das, woran Sie arbeiten, für eine großartige Idee. Ich arbeite gerade an den letzten Artikeln dieser Serie (einschließlich Orderstopps und Stops). Ich bin mir nicht sicher, ob die Stops-Klassen eine gute Lösung sind (es hängt von Ihrer Implementierung ab). Wenn Sie sie unabhängig vom Order Manager arbeiten lassen können, wäre das gut, denn es würde helfen, Ihre Klassenobjekte zu vereinfachen. Aber ich hoffe, dass sie Ihnen bei Ihrer Arbeit nützlich sein werden.
Bezüglich der Kompilierung:
- Nur Hauptquell-/Kopfdateien und Basisklassendateien können fehlerfrei kompiliert werden (mit Ausnahme derjenigen, die Forward-Deklarationen verwenden). Aus diesem Grund habe ich in den Beispielen die #include-Direktive in den Header-Dateien für die Basisdateien verwendet (nicht für die sprachspezifischen Dateien).
- Sie sollten den richtigen Compiler verwenden (das Kompilieren einer mq5-Datei mit einem MQL4-Compiler wird zu Compilerfehlern führen).
Hallo Enrico,
ich teste dein Signalmodul. Ich habe ein Signal SHORT und ein Signal NEUTRAL. Wie kommt es, dass ich schließlich CMD_VOID bekomme? Wann erscheint CMD_VOID?
Eigentlich erscheint dies in CSignalsBase::Check
if(signal.Entry()) { if(m_signal_open>CMD_VOID) { ENUM_CMD signal_open=signal.SignalOpen(); if(m_signal_open==CMD_NEUTRAL) { m_signal_open=signal_open; } else if(m_signal_open!=signal_open) { m_signal_open=CMD_VOID; } } }
Es gibt nur 2 Signale. Das vorherige Signal war CMD_SHORT. Das aktuelle Signal ist CMD_NEUTRAL. Können Sie bestätigen, dass CMD_SHORT und CMD_NEUTRAL als Ergebnis CMD_VOID ergeben?
Wenn mein erstes Signal CMD_NEUTRAL und das zweite Signal CMD_SHORT wäre, würde das Gesamtsignal CMD_SHORT lauten. Aber wenn das erste Signal CMD_SHORT und das zweite CMD_NEUTRAL ist, ergibt es CMD_VOID.
Ich vermute, dass es so sein muss:
if(signal.Entry()) { if(m_signal_open>CMD_VOID) { ENUM_CMD signal_open=signal.SignalOpen(); if(m_signal_open==CMD_NEUTRAL) { m_signal_open=signal_open; } else if(m_signal_open!=signal_open && signal_open!=CMD_NEUTRAL) { m_signal_open=CMD_VOID; } } }
if(m_new_signal) { if(m_signal_open==m_signal_open_last) m_signal_open = CMD_NEUTRAL; if(m_signal_close==m_signal_close_last) m_signal_close= CMD_NEUTRAL; }
Dies ist in Bezug auf die Schluss-Signale nicht ganz korrekt. Warum kann es nicht zwei aufeinanderfolgende gleichgerichtete Abschluss-Signale geben?
Ich habe zum Beispiel ein Einstiegssignal Short, das nächste Ausstiegssignal Long (Schließung Short), das nächste Einstiegssignal Long, das nächste Einstiegssignal Short, das nächste Ausstiegssignal Long. Das letzte Signal für den Ausstieg aus der Short-Position funktioniert also nicht, da es in dieselbe Richtung wie das vorherige Ausstiegssignal geht.
Dies ist in Bezug auf die Schluss-Signale nicht ganz korrekt. Warum kann es nicht zwei aufeinanderfolgende gleichgerichtete Abschluss-Signale geben?
Ich habe zum Beispiel ein Einstiegssignal Short, das nächste Ausstiegssignal Long (Schließung Short), das nächste Einstiegssignal Long, das nächste Einstiegssignal Short, das nächste Ausstiegssignal Long. Das letzte Signal für den Ausstieg aus der Short-Position wird also nicht funktionieren, da es in dieselbe Richtung wie das vorherige Ausstiegssignal geht.
Es hängt davon ab, was Sie erreichen wollen, wie die Signale ausgewertet werden sollen.
Der letzte Code, den Sie gepostet haben, wird nur ausgeführt, wenn das Klassenmitglied m_new_signal auf true gesetzt ist. Dies ist nur für den Handel mit neuen Signalen gedacht. Sie können dieses geschützte Klassenmitglied mit Hilfe der in der Klasse verfügbaren Methode NewSignal setzen.
Es hängt davon ab, was Sie erreichen wollen, wie die Signale ausgewertet werden sollen.
Der letzte Code, den Sie gepostet haben, wird nur ausgeführt, wenn das Klassenmitglied m_new_signal auf true gesetzt ist. Dies ist nur für den Handel mit neuen Signalen gedacht. Sie können dieses geschützte Klassenmitglied mit Hilfe der in der Klasse verfügbaren Methode NewSignal setzen.
Das ist mir bekannt. Aber wenn ich es auf false setze, wird es auch meine Einstiegssignale beeinflussen. Für Einstiegssignale ist es in Ordnung, aber nicht für Ausstiegssignale, da die Ausstiegsregeln unterschiedlich sein können. Es kann eine Umkehrung oder ein Ausstiegssignal sein, so dass 2 gleichgerichtete Ausstiegssignale eine normale Sache sind.
Hallo mbjen,
Hallo Enrico,
ich teste gerade dein Signalmodul. Ich habe ein Signal SHORT und ein Signal NEUTRAL. Wie kommt es, dass ich schließlich CMD_VOID bekomme? Wann erscheint CMD_VOID?
Eigentlich erscheint dies in CSignalsBase::Check
Es gibt nur 2 Signale. Das vorherige Signal war CMD_SHORT. Das aktuelle Signal ist CMD_NEUTRAL. Können Sie bestätigen, dass CMD_SHORT und CMD_NEUTRAL als Ergebnis CMD_VOID ergeben?
Wenn mein erstes Signal CMD_NEUTRAL und das zweite Signal CMD_SHORT wäre, würde das Gesamtsignal CMD_SHORT lauten. Aber wenn das erste Signal CMD_SHORT und das zweite CMD_NEUTRAL ist, ergibt es CMD_VOID.
Ich vermute, dass es so sein muss:
Es tut mir leid, dass ich Ihre erste Frage übersehen habe. Ich hatte sie bis jetzt nicht bemerkt. Es war eine sehr gute Rückmeldung.
Vielen Dank für den Hinweis. Ja, Sie haben Recht. Ich werde den Code aktualisieren und den Artikel überarbeiten.
Das ist mir klar. Aber wenn ich es auf false setze, wird es auch meine Einstiegssignale beeinflussen. Es ist ok für Einstiegssignale, aber nicht für Ausstiegssignale, da die Ausstiegsregeln unterschiedlich sein können. Es kann eine Umkehrung oder ein Ausstiegssignal sein, so dass 2 gleichgerichtete Ausstiegssignale eine normale Sache sind.
Sie haben hier einen Punkt. Aber wenn ich zum Beispiel nur ein Ausstiegssignal bei einem MA-Crossover geben möchte, wäre dies erforderlich. Ich denke, die Trennung wäre eine bessere Option als der aktuelle Code:
if(m_new_signal) { if(m_signal_open==m_signal_open_last) m_signal_open = CMD_NEUTRAL; } if(m_new_signal_close) { if(m_signal_close==m_signal_close_last) m_signal_close= CMD_NEUTRAL; }
Es sieht so aus, dass in m_signal_close der vorherige Signalwert in SignalBase.mqh gespeichert wird. Ich habe zum Beispiel ein Ausstiegssignal. Wenn es überprüft wird und die Calculate()-Methode false zurückgibt, gibt es den letzten Signalwert, der beim vorherigen Ausgang war.
Die Calculate-Methode ist eine virtuelle Methode. Wenn die Methode false zurückgeben soll, sollten Sie diese Klassenmitglieder in der Methode selbst auf neutral zurücksetzen.
- Freie Handelsapplikationen
- Über 8.000 Signale zum Kopieren
- Wirtschaftsnachrichten für die Lage an den Finanzmärkte
Sie stimmen der Website-Richtlinie und den Nutzungsbedingungen zu.
Neuer Artikel Cross-Platform Expert Advisor: Signale :
Dieser Artikel beschreibt die Klassen CSignal und CSignals, die in Cross-Plattform Expert Advisor verwendet werden. Es werden die Unterschiede zwischen MQL4 und MQL5 untersucht, wie sie jeweils auf bestimmte Daten zum Ermitteln eines Handelssignals zugreifen, um einen Code zu schreiben, der für beide Kompiler kompatible ist.
Die folgenden Screenshots zeigen die Testergebnisse des Expert Advisors in MetaTrader 4 und MetaTrader 5. Wie man sieht, wird der Indikator unterschiedlich auf dem Chart dargestellt, trotzdem folgen beide der gleichen Logik und der Expert Advisor kann beide Versionen für seine Handelslogik verwenden:
(MT4)
Autor: Enrico Lambino