English Русский 中文 Español 日本語 Português
preview
Erstellen eines EA, der automatisch funktioniert (Teil 04): Manuelle Auslöser (I)

Erstellen eines EA, der automatisch funktioniert (Teil 04): Manuelle Auslöser (I)

MetaTrader 5Handel | 2 März 2023, 08:59
611 0
Daniel Jose
Daniel Jose

Einführung

Im vorangegangenen Artikel „Erstellen eines EA, der automatisch funktioniert (Teil 03): Neue Funktionen“ wir haben das Auftragssystem fertiggestellt. Wenn Sie ihn nicht gelesen haben oder seinen Inhalt nicht ganz verstehen, schlage ich vor, dass Sie sich diesen Artikel noch einmal ansehen. Wir werden hier nicht mehr auf das Auftragssystem eingehen. Wir werden zu anderen Dingen übergehen, insbesondere zu den Auslösern.

Das Auslösesystem ist wahrscheinlich der schwierigste Teil. Dies führt zu Verwirrung, Zweifeln und Problemen, da es keine 100%ig fehlerfreie Methode gibt. Alle Methoden haben ihre eigenen Nachteile und Probleme. Einige von ihnen haben eine höhere Fehlerwahrscheinlichkeit, andere eine geringere. Aber denken Sie immer an die folgende Regel: Verlassen Sie sich nicht auf Auslöser, egal welcher Art, da sie versagen können, wenn Sie es am wenigsten erwarten. Wenn das Triggersystem versagt, können Sie eine gute Gelegenheit verpassen oder große Verluste erleiden. Daher sollten Sie mit Triggern immer sehr vorsichtig sein.

Aber sehen wir uns einige Details dieses Systems an. Erstens: Was ist der Zweck des Systems? Das Auslösesystem dient einer Reihe von Zwecken, einschließlich der Anzeige, wann der Break-Even erreicht ist oder wann eine Trailing-Stop-Bewegung ausgelöst werden soll. Dies sind die einfachsten Beispiele. Das Triggersystem kann auch anzeigen, wann der EA eine Position öffnen oder schließen sollte.

Alle diese Vorgänge laufen völlig automatisch ab: Der Händler muss nichts tun. Wir weisen den EA lediglich an, welcher Auslöser das Ereignis aktivieren soll. Dann ist keine menschliche Beteiligung erforderlich, außer wenn der EA in eine Endlosschleife eintritt, denn dann muss der Händler ihn sofort deaktivieren.

Um diese Ideen und Konzepte besser zu verstehen, werden wir einen manuellen EA programmieren müssen. Aber hier werden wir etwas ganz anderes tun als das, was wir normalerweise als manueller EA tun. In dem EA, den wir in dieser Serie als Beispiel verwenden, werden wir eine Möglichkeit hinzufügen, schwebende Aufträge (pending orders) zu platzieren oder eine Order zu senden, um eine Marktposition zu eröffnen. Da der EA zu Demonstrations- und Lernzwecken gedacht ist, rate ich jedem, der darüber nachdenkt, ihn zu nutzen, dies mit einem DEMO-Konto zu tun. Verwenden Sie den EA nicht auf einem realen Konto, da die Gefahr besteht, dass er stecken bleibt oder auf verrückte Art und Weise läuft.


Übermittlung von Aufträgen und Eröffnung von Marktpositionen

Meiner Meinung nach ist die beste Art, auf einem Chart zu handeln, die Verwendung der Maus in Kombination mit der Tastatur. Dies ist gut für die Platzierung von schwebenden Aufträgen, während Marktaufträge nur über die Tastatur platziert werden können. Die Frage ist nur, wie man den Code implementiert, der nicht so kompliziert ist, dass er schwer zu erklären ist, denn das System für die Übermittlung von Aufträgen mit Maus und Tastatur kann recht schwierig zu entwickeln sein.

Nachdem ich eine Weile darüber nachgedacht hatte, beschloss ich, mir ein ideales System für den Artikel auszudenken, etwas ganz Einfaches. Verwenden Sie dieses System also nicht für ein echtes Konto. Es soll mir nur helfen, ein paar Dinge über Auslöser zu erklären, damit Sie verstehen, wie ein Auslöser implementiert wird und wie er gehandhabt werden sollte.

Der Code ist der einfachste, den Sie erstellen können, aber er ist für den Rest dieser Artikelserie ausreichend. Schauen wir uns also an, wie der Code implementiert wird.

Zunächst habe ich eine Header-Datei namens C_Mouse.mqh hinzugefügt. Der Code in der Datei beginnt wie folgt:

#property copyright "Daniel Jose"
//+------------------------------------------------------------------+
#define def_MouseName "MOUSE_H"
//+------------------------------------------------------------------+
#define def_BtnLeftClick(A)     ((A & 0x01) == 0x01)
#define def_SHIFT_Press(A)      ((A & 0x04) == 0x04)
#define def_CTRL_Press(A)       ((A & 0x08) == 0x08)
//+------------------------------------------------------------------+

Sie legt den Namen des grafischen Objekts fest, das wir erstellen - die horizontale Linie, die die Preisposition anzeigt, an der sich der Mauszeiger im Chart befindet. Wir haben auch drei Definitionen erstellt, um einen leichteren Zugang zu einigen Informationen zu haben, die ein Mausereignis erzeugt. Auf diese Weise können Sie Klick- und Tastendruckereignisse testen. Wir werden diese Zugriffsdefinitionen später in der WA verwenden, während die Definition des Objektnamens am Ende der Datei mit der folgenden Zeile abgeschlossen wird:

//+------------------------------------------------------------------+
#undef def_MouseName
//+------------------------------------------------------------------+

Durch Hinzufügen dieser Zeile am Ende der Header-Datei wird sichergestellt, dass diese Definition nirgendwo anders im Code auftaucht. Wenn Sie versuchen, diese Definition zu verwenden, ohne sie an anderer Stelle als in dieser Header-Datei neu zu deklarieren, gibt der Compiler eine entsprechende Warnung aus.

Beginnen wir nun mit dem Schreiben des Codes der Klasse, die für die Operationen mit der Maus zuständig ist. Sie beginnt wie folgt:

class C_Mouse
{
        private :
                struct st00
                {
                        long    Id;
                        color   Cor;
                        double  PointPerTick,
                                Price;
                        uint    BtnStatus;
                }m_Infos;
//+------------------------------------------------------------------+
                void CreateLineH(void)
                        {
                                ObjectCreate(m_Infos.Id, def_MouseName, OBJ_HLINE, 0, 0, 0);
                                ObjectSetString(m_Infos.Id, def_MouseName, OBJPROP_TOOLTIP, "\n");
                                ObjectSetInteger(m_Infos.Id, def_MouseName, OBJPROP_BACK, false);
                                ObjectSetInteger(m_Infos.Id, def_MouseName, OBJPROP_COLOR, m_Infos.Cor);
                        }
//+------------------------------------------------------------------+
inline double AdjustPrice(const double value)
                        {
                                return MathRound(value / m_Infos.PointPerTick) * m_Infos.PointPerTick;
                        }
//+------------------------------------------------------------------+

Lassen Sie sich von diesem Code nicht abschrecken, dieser Teil ist nur ein kleines Beispiel. Alles, was wir tun, ist die Deklaration der Datenstruktur, die einige globale Variablen innerhalb der Klasse enthalten wird, die aber für die Klasse privat sind. Danach verwenden wir die Prozedur, mit der das Chart-Objekt in der MetaTrader 5-Plattform erstellt wird. Bei diesem Objekt handelt es sich um eine horizontale Linie, für die wir einige Eigenschaften festlegen und dann weitermachen werden..

Was diese Funktion betrifft, so haben Sie sie bereits im vorherigen Artikel gesehen. Falls nicht, sollten Sie zuerst die vorherigen Artikel dieser Reihe lesen, da sie ebenfalls wichtig für das sind, was wir jetzt tun werden.

Sehen wir uns nun die Prozeduren an, die in unserer Klasse C_Mouse öffentlich sein werden. Beginnen wir mit dem Klassenkonstruktor:

                C_Mouse(const color cor)
                        {
                                m_Infos.Id = ChartID();
                                m_Infos.Cor = cor;
                                m_Infos.PointPerTick = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);
                                ChartSetInteger(m_Infos.Id, CHART_EVENT_MOUSE_MOVE, true);
                                ChartSetInteger(m_Infos.Id, CHART_EVENT_OBJECT_DELETE, true);
                                CreateLineH();
                        }

Er hat zwei Zeilen, die Ihnen vielleicht seltsam vorkommen, wenn Sie mit MQL5 nicht sehr vertraut sind. Ich werde sie also kurz erklären. Diese Zeile teilt der MetaTrader 5-Plattform mit, dass unser Code bzw, unser EA Mausereignisse empfangen möchte. Es gibt noch eine andere Art von Ereignissen, die ebenfalls von der Maus erzeugt werden und bei der Verwendung des Bildlaufs auftreten. Aber wir werden es nicht verwenden, weil dieser Ereignistyp schon ausreicht.

Diese Zeile informiert MetaTrader 5, dass wir wissen wollen, ob ein Objekt aus dem Chart entfernt wurde. Wenn dies geschieht, wird das Ereignis erzeugt, das uns darüber informiert, welches Element aus dem Chart entfernt wurde. Diese Art von Ereignissen kann nützlich sein, wenn wir bestimmte kritische Elemente für die perfekte Ausführung der Aufgabe speichern wollen. Wenn der Nutzer dann versehentlich ein kritisches Element löscht, informiert MetaTrader 5 den Code (in diesem Fall den EA) darüber, dass das Element entfernt wurde, damit wir es neu erstellen können. Schauen wir uns nun den Code des Klassen-Destruktors an:

                ~C_Mouse()
                        {
                                ChartSetInteger(m_Infos.Id, CHART_EVENT_OBJECT_DELETE, false);
                                ObjectDelete(m_Infos.Id, def_MouseName);
                        }

In diesem Code tun wir zwei Dinge. Zunächst teilen wir MetaTrader 5 mit, dass wir keine Benachrichtigungen mehr erhalten möchten, wenn ein Element aus dem Chart gelöscht wird. Es ist wichtig, dies zu tun, bevor wir fortfahren, denn wenn wir versuchen, ein Element zu entfernen, erzeugt MetaTrader 5 ein Ereignis, das uns darüber informiert, dass etwas aus dem Chart entfernt wurde. Genau das werden wir als Nächstes tun: Wir löschen die Zeile, die wir erstellt haben, um anzuzeigen, in welcher Preisspanne sich der Mauszeiger befindet.

Als Nächstes müssen wir eine Möglichkeit schaffen, die Daten innerhalb der Klasse zu lesen, damit wir die Mausposition und den Zustand der Schaltflächen kennen. Zu diesem Zweck wird die folgende Funktion verwendet:

const void GetStatus(double &Price, uint &BtnStatus) const
                        {
                                Price = m_Infos.Price;
                                BtnStatus = m_Infos.BtnStatus;
                        }

Ich möchte etwas erklären, das unter Menschen mit weniger Erfahrung in objektorientierter Programmierung sehr verbreitet ist. Bei der Verwendung von Klassen darf kein Code außerhalb der Klasse direkten Zugriff auf die Klassenvariablen oder -prozeduren haben, und es muss immer geprüft werden, was in die Klasse eingegeben wird.

Es ist ein schwerwiegender Fehler, Variablen oder Prozeduren in einer Klasse zu verwenden und zuzulassen, dass sie einen Wert erhalten, der nicht ordnungsgemäß geprüft wurde, da dies auf lange Sicht zu Problemen führen wird. Irgendwann kann man im Code den Wert einer kritischen Variablen, die in der Klasse verwendet wird, ändern, und wenn es zur Verwendung kommt, kann dies den gesamten Code gefährden. Außerdem ist es äußerst kompliziert, mit dieser Art von Situation umzugehen und das Problem später zu beheben.

Befolgen Sie also immer diese Praxis, wenn Sie ein guter Programmierer sein wollen: Wenn Sie den Inhalt einer Klasse lesen wollen, lassen Sie zu, dass er gelesen und nicht verändert wird; dies geschieht sehr häufig, insbesondere bei Verwendung eines Zeigers. Sie fordern das Lesen einer Variablen und geben einen Zeigers zurück. In diesem Moment ist Ihr Code gefährdet, denn wenn Sie einen Zeiger verwenden, wissen Sie, wo Sie in den Speicher schreiben müssen, und das ist sehr gefährlich. Sehen Sie sich an, wie Game Cheats erstellt werden (kleine Programme zum Schummeln in elektronischen Spielen). Sie schreiben einfach mit einem Zeiger auf eine bestimmte Speicherstelle.

Seien Sie sehr vorsichtig bei der Verwendung von Zeigern. Im Zweifelsfall sollten Sie immer lieber eine Funktion als eine Prozedur verwenden. Der Unterschied zwischen den beiden ist, dass die Funktion in der Regel einen Wert zurückgibt, aber dennoch darauf achten, dass kein Zeiger zurückgegeben wird.

Aber wenn Sie keine andere Möglichkeit haben, dann machen Sie es so, wie ich es oben gezeigt habe. Das mag nach übertriebener Vorsicht aussehen, aber wenn man die Deklaration einer Prozedur oder einer Funktion mit dem reservierten Wort const beginnt, ist garantiert, dass der Aufrufer den Wert in den Variablen niemals ändern kann, da der Compiler jeden Wert als eine Konstante behandelt, die nicht geändert werden kann.

Wenn Sie die Deklaration einer Prozedur oder Funktion mit dem reservierten Wort const abschließen, ist gewährleistet, dass Sie als Programmierer nicht versehentlich oder unwissentlich einen Wert innerhalb der Prozedur oder Funktion ändern. Dies ist wahrscheinlich die beste Programmierpraxis, die es gibt, auch wenn sie vielen seltsam vorkommen mag. Damit werden einige Programmierfehler vermieden, vor allem in der OOP (Object Oriented Programming), aber wir werden später noch einmal darauf zurückkommen, mit einem klareren Beispiel, das Ihnen helfen wird, das Problem des Abschlusses einer Deklaration mit dem Wort const zu verstehen.

Die letzte Prozedur, die wir brauchen, ist unten dargestellt:

                void DispatchMessage(const int id, const long &lparam, const double &dparam, const string &sparam)
                        {
                                int w;
                                datetime dt;
                                
                                switch (id)
                                        {
                                                case CHARTEVENT_OBJECT_DELETE:
                                                        if (sparam == def_MouseName) CreateLineH();
                                                        break;
                                                case CHARTEVENT_MOUSE_MOVE:
                                                        ChartXYToTimePrice(m_Infos.Id, (int)lparam, (int)dparam, w, dt, m_Infos.Price);
                                                        ObjectMove(m_Infos.Id, def_MouseName, 0, 0, m_Infos.Price = AdjustPrice(m_Infos.Price));
                                                        m_Infos.BtnStatus = (uint)sparam;
                                                        ChartRedraw();
                                                        break;
                                        }
                        }

Das ist sehr interessant, weil viele Programmierer den Code in das Ereignis OnChartEvent zur Nachrichtenverarbeitung einfügen möchten. Aber ich möchte Ereignisse innerhalb der Objektklasse behandeln. Dies hilft oft, etwas Bestimmtes nicht zu vergessen oder auf eine besondere Art und Weise zu behandeln, wodurch man oft überprüfen kann, ob der Code funktioniert oder nicht. Wenn wir diese Aufgaben innerhalb der Klasse erledigen, haben wir auf lange Sicht mehr Vertrauen. Denn wenn wir die Klasse verwenden, wissen wir, dass das Nachrichtenverarbeitungssystem der Klasse wie erwartet funktioniert. Dadurch wird die Erstellung neuer Programme erheblich beschleunigt. Dies ist auch der Weg zur Wiederverwendung: einmal programmieren und immer verwenden.

Mal sehen, was in diesem Nachrichtensystem passiert. Hier werden genau die Daten repliziert, die von der Ereignisbehandlung OnChartEvent empfangen werden, was absichtlich so gemacht wird, da wir diese Ereignisse hier innerhalb der Klasse behandeln wollen.

Sobald dies definiert ist, müssen wir festlegen, welche Ereignisse wir behandeln wollen. Das erste ist das Ereignis, wenn ein Objekt entfernt wird. Das wird erzeugt, weil wir MetaTrader 5 zuvor mitgeteilt haben, dass wir informiert werden möchten, wenn ein Objekt aus dem Chart entfernt wird. Wenn das entfernte Objekt die Mauslinie war, wird das Objekt sofort neu erstellt.

Das nächste Ereignis, mit dem wir uns hier innerhalb der Klasse beschäftigen wollen, sind die Mausbewegungsereignisse. Auch dieses Ereignis wird erzeugt, weil wir MetaTrader 5 mitgeteilt haben, dass wir wissen wollen, was mit der Maus passiert. Hier wandeln wir einfach die vom MetaTrader 5 gelieferten Werte in Zeit- und Kurswerte um. Danach positionieren wir das horizontale Linienobjekt an der Preisposition, sodass es sich an der richtigen Stelle befindet. Bitte beachten Sie, dass der Punkt nicht im Bildschirmkoordinatensystem, sondern im Preischart liegt. Von dort aus speichern wir den Wert der Schaltflächen und erzwingen eine sofortige Neuzeichnung des Charts.

Es ist wichtig, dass dieses Neuzeichnen des Charts entweder hier in der Ereignisbehandlung der Klasse oder in der von OnChartEvent erfolgt. Wenn dies nicht geschieht, haben Sie möglicherweise den Eindruck, dass der Code die Plattform langsam macht, da sich die Kurslinie seltsam bewegt.

Damit ist unsere C_Mouse-Klasse fertig und wir können nun schwebende Aufträge direkt im Chart platzieren. Kehren wir nun zu unserem EA-Code zurück und fügen die Klasse C_Mouse hinzu, um Ereignisse zu erzeugen und schwebende Aufträge zu senden. So wird es gemacht:

#include <Generic Auto Trader\C_Orders.mqh>
#include <Generic Auto Trader\C_Mouse.mqh>
//+------------------------------------------------------------------+
C_Orders *manager;
C_Mouse *mouse;
//+------------------------------------------------------------------+
input int       user01   = 1;           //Lot increase
input double    user02   = 100;         //Take Profit ( FINANCEIRO )
input double    user03   = 75;          //Stop Loss ( FINANCEIRO )
input bool      user04   = true;        //Day Trade ?
input color     user05  = clrBlack;     //Color Mouse
//+------------------------------------------------------------------+
#define def_MAGIC_NUMBER 987654321
//+------------------------------------------------------------------+
int OnInit()
{
        manager = new C_Orders(def_MAGIC_NUMBER);
        mouse = new C_Mouse(user05);
        
        return INIT_SUCCEEDED;
}
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
        delete mouse;
        delete manager;
}
//+------------------------------------------------------------------+
void OnTick()
{
}
//+------------------------------------------------------------------+

Der obige Ausschnitt beschreibt die Schritte, wie wir die Dinge produzieren werden. Alles ist so gestaltet, dass die Klasse C_Mouse leicht entfernt werden kann. Da für einen automatisierten EA hat es keine Verwendung, aber jetzt brauchen wir einen Weg, um unsere EA zu testen, und der beste Weg, dies zu tun, ohne das Hinzufügen von Triggern, ist mit der C_Mouse-Klasse, die wir gerade erstellt haben. Wir fügen also diese Klasse ein, damit der Compiler den Code für uns hinzufügen kann. Wir definieren eine Farbe, die für die horizontale Preislinie verwendet werden soll.

Wir initialisieren die Klasse C_Order, sodass alle Aufträge die gleiche magische Zahl für diesen EA haben werden. Bitte beachten Sie, dass Sie für jeden EA immer eine andere magische Zahl einstellen sollten. Der Grund dafür ist, dass Sie, wenn Sie mehr als einen EA zur gleichen Zeit und für den gleichen Vermögenswert verwenden, die Möglichkeit haben, sie zu trennen, sodass jeder EA seine eigenen Aufträge verwaltet, durch diese magische Zahl. Wenn zwei EAs mit der gleichen magischen Zahl arbeiten, können Sie sie nicht voneinander trennen, und einer von ihnen kann die Aufträge des anderen beeinträchtigen. Jeder EA muss also seine eigene magische Zahl haben.

Danach initialisieren wir die Klasse C_Mouse und damit ist der EA einsatzbereit. Vergessen Sie nicht, die Destruktoren am Ende des EA aufzurufen. Wenn Sie jedoch vergessen, dies selbst zu tun, übernimmt dies normalerweise der Compiler für Sie. Dennoch ist es gute Praxis, dies im Code zu tun, damit jeder weiß, wo er aufhören muss, auf eine Klasse zu verweisen.

Obwohl ich gesagt habe, dass der EA bereits einsatzbereit ist, fehlt noch eine Sache: das System zur Behandlung von Chartereignissen. Sie hat das folgende Format:

void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
{
        uint    BtnStatus;
        double  Price;
        static double mem = 0;
        
        (*mouse).DispatchMessage(id, lparam, dparam, sparam);
        (*mouse).GetStatus(Price, BtnStatus);
        if (def_SHIFT_Press(BtnStatus) != def_CTRL_Press(BtnStatus))
        {
                if (def_BtnLeftClick(BtnStatus) && (mem == 0)) (*manager).CreateOrder(def_SHIFT_Press(BtnStatus) ? ORDER_TYPE_BUY : ORDER_TYPE_SELL, mem = Price, user03, user02, user01, user04);
        }else mem = 0;
}

Hier ist es, ganz einfach. Ich möchte nicht, dass ein EA, den wir für eine automatisiertes Arbeiten erstellen, zu einem manuellen EA wird. Aus diesem Grund wird der EA keine Kurslinien erstellen, die die Grenzen von Take-Profit und Stop-Loss definieren. Aber schauen wir mal, wie dieser Code funktioniert. Hier fehlt noch etwas.

Wenn MetaTrader 5 feststellt, dass ein Ereignis auf dem Chart eingetreten ist, was auch immer es sein mag, generiert es einen Aufruf des obigen Codes. Sobald dieser Code aktiviert ist und den Prozessor zur Ausführung erhält, ruft er die Prozedur zur Behandlung von Nachrichten aus der Klasse C_Mouse auf. Auf diese Weise werden die mit der Maus verknüpften Ereignisse korrekt und immer auf dieselbe Weise behandelt.

Wenn die Nachrichtenbehndlung der Klasse C_Mouse beendet ist, erfassen wir den Mausstatus, um ihn hier in dieser Funktion verwenden zu können.

Überprüfen wir nun den Zustand der Umschalt- und Strg-Tasten anhand der Definitionen in der Header-Datei C_Mouse.mqh. Sie zeigen an, ob es sich um einen Kauf- oder Verkaufsauftrag handelt. Aus diesem Grund müssen sie unterschiedliche Werte haben. Sollte dies der Fall sein, werden wir einen neuen Test durchführen.

Aber dieses Mal prüfen wir , ob die linke Maustaste angeklickt wurde oder nichtWenn dies der Fall ist und der Speicherpreis gleich Null ist, wird ein schwebender Auftrag an den Server gesendet, wobei die vom Nutzer angegebenen Daten verwendet werden. Das Kaufen oder Verkaufen wird durch die Umschalt- und Strg-Taste bestimmt: Die Umschalttaste steht für Kaufen, während die Strg-Taste für Verkaufen steht. Wir können also so viele Aufträge erteilen, wie wir brauchen, um das System zu testen, aber wie oben erwähnt, fehlt hier noch etwas.

Im vorigen Artikel habe ich Ihnen eine praktische Aufgabe gestellt: Versuchen Sie, einen Code für einen Handel auf dem Markt zu erstellen. Wenn es Ihnen nicht gelungen ist, ist das in Ordnung. Aber es wäre toll, wenn Sie die Aufgabe selbst erledigen könnten und nicht auf meine Lösung schauen würden. Die Lösung finden Sie weiter unten im aktualisierten Code von OnChartEvent.

void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
{
        uint    BtnStatus;
        double  Price;
        static double mem = 0;
        
        (*mouse).DispatchMessage(id, lparam, dparam, sparam);
        (*mouse).GetStatus(Price, BtnStatus);
        if (TerminalInfoInteger(TERMINAL_KEYSTATE_CONTROL))
        {
                if (TerminalInfoInteger(TERMINAL_KEYSTATE_UP))  (*manager).ToMarket(ORDER_TYPE_BUY, user03, user02, user01, user04);
                if (TerminalInfoInteger(TERMINAL_KEYSTATE_DOWN) (*manager).ToMarket(ORDER_TYPE_SELL, user03, user02, user01, user04);
        }
        if (def_SHIFT_Press(BtnStatus) != def_CTRL_Press(BtnStatus))
        {
                if (def_BtnLeftClick(BtnStatus) && (mem == 0)) (*manager).CreateOrder(def_SHIFT_Press(BtnStatus) ? ORDER_TYPE_BUY : ORDER_TYPE_SELL, mem = Price, user03, user02, user01, user04);
        }else mem = 0;
}

Dies ist eine Möglichkeit, Marktaufträge an einen Handelsserver zu senden. Wir haben das folgende Verhalten: Wenn die STRG-Taste gedrückt wird, ist die Bedingung hier erfüllt, und jetzt können wir die zweite Bedingung überprüfen. Diese zweite Bedingung gibt an, ob wir zum Marktpreis kaufen oder zum Marktpreis verkaufen. Hierfür werden wir die Pfeiltasten verwenden. Wenn die Tasten STRG + Pfeil nach oben gedrückt werden, führen wir einen Kauf zum Marktpreis durch, gemäß den im Nutzerinteraktionsbereich angegebenen Parametern. Wenn STRG + Pfeil nach unten gedrückt werden, ist dies ein Verkauf zum Marktpreis, die ebenfalls auf den Parametern basiert.

Diese Leitlinien sind in Abbildung 01 dargestellt:

Abbildung 1

Abbildung 01. EA-Einstellungen.


Schlussfolgerung

Was ich gerade über das Ereignissystem erklärt habe und wie es implementiert wurde, ist eine Art Auslösemechanismus. In diesem Fall ist der Mechanismus jedoch manuell, d.h. er erfordert das Eingreifen den handelnden Menschen: Ein Auftrag zur Eröffnung einer Position oder zur Platzierung eines schwebenden Auftrags wird durch die Interaktion des EA-Nutzers mit dem EA selbst ausgeführt. In diesem Fall gibt es keinen automatischen Mechanismus für die Platzierung eines Auftrags im Orderbuch oder die Eröffnung einer Position, sondern alles hängt vom Händler ab.

Sobald der Auftrag jedoch im Orderbuch steht, ist das System nicht mehr vom Händler abhängig. Der Auftrag wird zu einer Position, sobald der Preis den im Auftrag angegebenen Punkt erreicht, und die Position wird geschlossen, wenn einer der Ausstiegspreise erreicht wird. Sie müssen jedoch vorsichtig sein, da es einen Moment hoher Volatilität geben kann, der zu einem Kurssprung führen kann. In diesem Fall bleibt die Position so lange offen, bis sie vom Broker zwangsweise geschlossen wird oder bis das Zeitlimit im Falle von Tagesgeschäften aufgrund von Marktschluss abläuft. Sie sollten also immer vorsichtig mit der offenen Position sein.

Die beigefügte Datei enthält den Code in seiner aktuellen Form. Im nächsten Artikel werden wir diesen Code ändern, um die Verwendung des EA im manuellen Modus zu erleichtern, da wir einige Änderungen vornehmen müssen. Diese Änderungen werden jedoch interessant sein.


Übersetzt aus dem Portugiesischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/pt/articles/11232

Beigefügte Dateien |
Experimente mit neuronalen Netzen (Teil 3): Praktische Anwendung Experimente mit neuronalen Netzen (Teil 3): Praktische Anwendung
In dieser Artikelserie entwickle ich mit Hilfe von Experimenten und unkonventionellen Ansätzen ein profitables Handelssystem und prüfe, ob neuronale Netze für Trader eine Hilfe sein können. MetaTrader 5 ist als autarkes Werkzeug für den Einsatz neuronaler Netze im Handel konzipiert.
Erstellen eines EA, der automatisch funktioniert (Teil 03): Neue Funktionen Erstellen eines EA, der automatisch funktioniert (Teil 03): Neue Funktionen
Heute werden wir sehen, wie man einen Expert Advisor erstellt, der einfach und sicher im automatischen Modus arbeitet. Im vorherigen Artikel haben wir begonnen, ein Auftragssystem zu entwickeln, das wir in unserem automatisierten EA verwenden werden. Wir haben jedoch nur eine der benötigten Funktionen geschaffen.
Algorithmen zur Optimierung mit Populationen Fledermaus-Algorithmus (BA) Algorithmen zur Optimierung mit Populationen Fledermaus-Algorithmus (BA)
In diesem Artikel werde ich den Fledermaus-Algorithmus (Bat-Algorithmus, BA) betrachten, der gute Konvergenz bei glatten Funktionen zeigt.
Erstellen eines EA, der automatisch funktioniert (Teil 02): Erste Schritte mit dem Code Erstellen eines EA, der automatisch funktioniert (Teil 02): Erste Schritte mit dem Code
Heute werden wir sehen, wie man einen Expert Advisor erstellt, der einfach und sicher im automatischen Modus arbeitet. Im vorigen Artikel haben wir die ersten Schritte besprochen, die jeder verstehen muss, bevor er einen Expert Advisor für den automatischen Handel erstellen kann. Wir haben uns Gedanken über die Konzepte und die Struktur gemacht.