![Mein erster Gral](https://c.mql5.com/i/articles/overlay.png)
Mein erster Gral
".. Kunst kann man nicht programmieren,
zwei Bedeutungen von Poesie kann man nicht schaffen. Talente
kann man nicht im Beet
ziehen. Sie werden geboren. Sie sind
nationaler Reichtum, wie Ablagerungen von Radium,
September in Sigulda, oder heilende Kraft ..."
(A.A.Voznesensky)
Der Heilige Gral wird allgemein als der Kelch angesehen, welcher der Person Kraft, Macht und Unsterblichkeit gibt, die daraus mal etwas getrunken hat. Mehr darüber können Sie hier erfahren oder Sie können mithilfe irgendeiner Suchmaschine Informationen darüber im Internet finden.
Das Wort "Gral" wird heutzutage oft unter den modernen Programmierer ironisch verwendet. Das bedeutet für sie die Unmöglichkeit, ein "universelles" Programm für alle Gelegenheiten zu schaffen. In Bezug auf die Programmierung mit MQL4 bezeichnet das Wort die Unmöglichkeit, einen Experten zu erstellen, der fantastische Ergebnisse im realen Handel erzielt.
In Wirklichkeit spiegelt der Währungsmarkt ein komplexes Gemisch von Gegebenheiten wider – ökonomische und industrielle Verhältnisse, menschliche Charaktere, politische Ereignisse. Überdies, und das ist sogar noch wichtiger, kann es nicht einfach in eine Form gepresst werden. Erfahrene Trader empfehlen, nur dann in den Markt einzutreten, wenn es drei oder sogar mehr Zeichen gibt, die den möglichen Trend anzeigen.
Gleichzeitig, können die bisher festgesetzten Gesetzmäßigkeiten keine profunde Basis für Marktvorhersagen mit hoher Erfolgswahrscheinlichkeit liefern. Die widersprüchlichen Prognosen von führenden Marktanalytikern wichtiger Banken und Finanzorganisationen bestätigen dies. Ohne Ausnahme können alle Analytiker Ereignisse, die bereits stattgefunden haben, sehr gut interpretieren, aber nur wenige von ihnen können eine Reihe von wirklich zuverlässigen Prognosen machen.
Aber seien wir gerecht: diese Menschen tun das, was sie können, sie haben meistens eine lange Erfahrung als Trader und haben Wissen, um das wir sie nur beneiden können. Aber Lassen Sie uns Dinge mit seinen Namen nennen: Sie machen praktisch alle Fehler. Sie mögen großartig sein, eine mehr oder weniger große Popularität genießen, manchmal ein schönes Vermögen ansammeln ("Gurus" verschiedener Art werden wirklich gut in Alexander Elders Buch mit dem Titel "Trading for a Living" beschrieben) die Tatsache ist aber immer noch die - dass sich sogar erfahrene Analytiker oft irren.
Welche Chance hat dann ein Programmier-Anfänger unter solchen Bedingungen, wenn er bloß erste Schritte im Markt Forex macht? Verfolgen wir mal den Weg des Anfängers auf seiner Suche nach dem "Gral".
1. Woraus der “Gral” besteht
Nach formaler Logik wird der Verweis auf eine Autorität nicht als Beweis angesehen. Mit dem Wissen denkt der Programmier-Anfänger ungefähr so: "Können Sie mir beweisen, dass es unmöglich ist, den "Gral" zu erstellen? Nein? Und wenn nicht, dann ist es möglich!". Der Anfänger berücksichtigt nicht, dass die Möglichkeit so etwas zu erschaffen genauso wenig bewiesen wurde. Auch ohne Rücksicht auf die Erfahrungen anderer "Goldgräber", und alleine nur mit seiner Begeisterung inspiriert: "Ich schaffe es!" der ausschließlich auf seine Begeisterung und Unwissenheit vertraut, macht er sich ans Programmieren.
1.1. Formale Strategie
In den meisten Fällen wird der Programmier-Anfänger sich nicht die Aufgabe stellen, innerhalb kurzer Zeit eine äußerst gewinnbringende Trading-Strategie zu entwickeln. Getrieben von der Hoffnung auf große und schnelle Gewinne auf dem Devisenmarkt wird er dennoch erkennen, dass für einen profitablen Experten eine Reihe von Trading-Kriterien erforderlich sind.
Um gute Kriterien zu finden, öffnet unser Programmier den MetaTrader 4 Client-Terminal und schaut auf den EURUSD Chart in dem Timeframe von M1. Man kann sehr leicht erkennen, dass sich der Währungskurs in Wellen ändert: auf und ab, auf und ab. Der Programmierer beschließt, auf Basis dieser Schwankungen Gewinne zu machen. Aber um eine Welle “einzufangen”, muss man irgendwie wissen, dass die Welle gestoppt hat, zum Beispiel, wenn sie nach dem Aufsteigen wieder absteigt.
- •Beachten Sie, dass der Markt während der Abwärtsbewegung (Sell) betreten werden muss, wenn sich der Kurs eine bestimmte Anzahl von Punkten aufwärts bewegt hat, z.B. 10 bis 15 (Bewegung A-B in Abb.1), und dann wieder ein paar Punkte nach unten gegangen ist (Bewegung B-C in Abb.1) um, sagen wir mal, 3 Punkte. Dabei wird der Rückwärtstrend des Marktes prognostiziert (C-D in Abb.1). Dasselbe Kriterium ist zu benutzen, um den Buy zu schließen.
-
•Beachten Sie, dass der Markt während der Aufwärtsbewegung (Buy) betreten werden muss, wenn sich der Kurs eine bestimmte Anzahl von Punkten (z.B.) 10 bis 15, (Bewegung C – D in Fig.1) abwärts bewegt hat. Dasselbe Kriterium ist zu benutzen, um den Sell zu schließen. Dabei wird der Aufwärtstrend des Marktes prognostiziert (E-F in Abb.1). Dasselbe Kriterium ist zu benutzen, um den Sell zu schließen.
![](https://c.mql5.com/2/13/graal_pic_1_1.png)
in Abb.1. Trading-Kriterien für den Experten Gral_1 (Gral 1).
Nun ja, das Leben hält manchmal erstaunliche und unerwartete Erfahrungen für uns bereit. In nur drei Tagen hat der frischgebackene Programmierer seinen ersten “Gral” geschaffen.
extern int TP=100; extern int SL=100; extern int lim=1; extern int prodvig=3; extern double Prots= 10; int total, bb=0,ss=0; double max,min,lmax,lmin,Lot; int start(){ total=OrdersTotal(); if (total==0){bb=0;ss=0;} if (max<Bid) max=Bid;if (min>Ask) min=Ask; if (((max-Bid)>=lim*Point)&&(Bid>lmax )) { for (int i=total;i>=0;i--) { if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true && OrderType()==OP_BUY) {OrderClose(OrderTicket(),OrderLots(),Bid,3,CLR_NONE); bb=0;}} Strateg(1); } if (((Ask-min)>=lim*Point)&&(lmin>Ask )) { for (i=total;i>=0;i--) { if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true && OrderType()==OP_SELL) {OrderClose(OrderTicket(),OrderLots(),Ask,3,CLR_NONE);ss=0;}} Strateg(2);}return;} void Strateg (int vv) {if (vv==1 && ss==0) {OrderSend(Symbol(),OP_SELL,Lots(),Bid,3,Bid+SL*Point,Bid-TP*Point,"",0,0,Red); ss=1;} if (vv==2 && bb==0) {OrderSend(Symbol(),OP_BUY, Lots(),Ask,3,Ask-SL*Point,Ask+TP*Point,"",0,0,Blue);bb=1;} lmax=Ask+prodvig*Point; lmin=Bid-prodvig*Point; return; } double Lots(){ Lot=NormalizeDouble(AccountEquity()*Prots/100/1000,1); double Min_Lot = MarketInfo(Symbol(), MODE_MINLOT); if (Lot==0 ) Lot=Min_Lot; return(Lot); }
So ist also die Situation. Seien wir nachsichtig – dies ist die erste Erfahrung des neuen Programmierers, der seinen Stil noch nicht gefunden hat. Und wir respektieren es, da er funktioniert und ein wirklich fantastisches Ergebnis zeigt.
//------------------------------------------------------------------------------------------- // Graal_1.mq4. // wird als Beispiel im Artikel "Mein erster Graal" verwendet. // Sergey Kowaljow, Dnepropetrovsk (Ukraine), sk@mail.dnepr.net, ICQ 64015987, http://autograf.dp.ua/. //------------------------------------------------------------------------------------------- extern int TP = 100; // Takeprofit der Order extern int SL = 100; // Stoploss der Order extern int lim= 1; // Der Abstand des Kursrückgangs extern int prodvig=3; // Der Abstand des Kursaufgangs extern double Prots= 10; // Der Prozentanteil von verfügbaren Mittel //-------------------------------------------------------------------------------------------- int total, // Die Anzahl der Lots bb=0, // 1 = Bestätigt die Tatsache, dass die Buy-Order in vorhanden ist ss=0; // 1 = Bestätigt die Tatsache, dass die Sell-Order in vorhanden ist //-------------------------------------------------------------------------------------------- double max, // Der Höchst-preis auf dem Höhepunkt (abs) min, // Der Mindestpreis ist im niedrigsten Punkt(abs) lmax, // Der Limit des Preises, nachdem // man es verkaufen kann (abs) lmin, // Das gleiche gilt für den Kauf Lot; // Die Anzahl der Lots //------------------------------------------------------------------------------------------- int start() { //------------------------------------------------------------------------------------------- total=OrdersTotal(); // Die Anzahl der Lots if (total==0) // Wenn es keinee Orders gibt, .. { bb=0; // .. dann gibt es keine Buys ss=0; // .. dann gibt es keine Sells } if (max<Bid) max=Bid; // Berechnen wir den maximalen Preis am Höhepunkt if (min>Ask) min=Ask; // Berechnen wir den minimalen Preis im niedrigsten Punkt //------------------------------------------------------------- Der Preis hat den Wendepunkt, und geht nach unten ---- if (((max-Bid)>=lim*Point)&&(Bid>lmax )) // Die Preis-wende ist im höhen Limit { for (int i=total;i>=0;i--) // über allen Orders { if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true && OrderType()==OP_BUY) { OrderClose(OrderTicket(),OrderLots(),Bid,3,CLR_NONE);// Schließen wir Buy bb=0; // Es gibt keine Buys mehr } } Strateg(1); // Die Öffnungsfunktion } //------------------------------------------------------------ Der Preis hat den Wendepunkt, und geht nach oben ---- if (((Ask-min)>=lim*Point)&&(lmin>Ask )) // Die Preis-wende ist ganz unten { for (i=total;i>=0;i--) // über allen Orders { if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true && OrderType()==OP_SELL) { OrderClose(OrderTicket(),OrderLots(),Ask,3,CLR_NONE);// Schließen wir Sell ss=0; // Es gibt keine Sells mehr } } Strateg(2); // Die Öffnungsfunktion } //------------------------------------------------------------------------------------------- return; } //------------------------------------------------------------------------------------------- void Strateg (int vv) // Die Öffnungsfunktion { //------------------------------------------------------------------------------------------- if (vv==1 && ss==0) // Die Situation für Sells und man hat keine Sells mehr { OrderSend(Symbol(),OP_SELL,Lots(),Bid,3,Bid+SL*Point,Bid-TP*Point,"",0,0,Red);// Öffnen wir es ss=1; // Nun gibt es eine Sell } //-------------------------------------------------------------------------------------------- if (vv==2 && bb==0) // Die Situation für Buys und man hat keine Buy mehr { OrderSend(Symbol(),OP_BUY, Lots(),Ask,3,Ask-SL*Point,Ask+TP*Point,"",0,0,Blue);// Öffnen wir es bb=1; // Nun gibt es eine Buy } //-------------------------------------------------------------------------------------------- lmax=Ask+prodvig*Point; // Lassen Sie uns neue Grenze-Limite .. lmin=Bid-prodvig*Point; // .. für Eröffnung und Schließung der Positionen vorbestimmen //------------------------------------------------------------------------------------------- return; } //------------------------------------------------------------------------------------------- double Lots() // Berechnung der Lots { //------------------------------------------------------------------------------------------- Lot=NormalizeDouble(AccountEquity()*Prots/100/1000,1);// Berechnen wir die Anzahl der Lots double Min_Lot = MarketInfo(Symbol(), MODE_MINLOT); // Der eingestellte Mindestpreis der Lots if (Lot == 0 ) Lot = Min_Lot; // Zum Test auf konstanten minimalen Lots //------------------------------------------------------------------------------------------- return(Lot); } //-------------------------------------------------------------------------------------------
Im Allgemeinen ist der Inhalt des Experten gut verständlich.
Im oberen Teil, vor der Funktion start() werden die Variablen gesammelt. In der start() Funktion wird die aktuelle Kursposition auf ihrem Weg zu einem Höchst- oder Tiefpunkt zuerst berechnet und dann wird die Situation analysiert, um zu sehen, ob Handels-Kriterien aktiviert werden. Und, wenn diese aktiviert werden, wird die schon durchgeführte Order geschlossen. Zwei weitere Funktionen werden im Experten benutzt. Strateg(), um neue Orders zu öffnen, und Lots(), um die Anzahl der Lots zu bestimmen. Mithilfe der Variablen ss und bb werden eröffnete Orders registriert.
Der Strategy Tester ist ein sehr wichtiges Werkzeug im MetaTrader 4 Client Terminal. Unser Progrmmierer hat den Experten gründlich getestet, um die Inputs zu optimieren und eines der besten Ergebnisse ist das Folgende.![](https://c.mql5.com/2/13/graal_pic_2.gif)
Wir können uns die Freude des Programmierers gut vorstellen: Er hat dieses Kunstwerk eigenhändig geschaffen! Hier ist es: neu, durchaus beachtlich, glänzend mit all seinen perfekten Facetten, sein erster “Gral”! Und unser Programmierer kommt zu einem einfachen Schluss: "Ich allein!"
1.2. Fortgeschrittene Investitionen.
![](https://c.mql5.com/2/13/graal_pic_3.gif)
in Abb. 3. Aggressives Investment kann zu unnötigen Verlusten führen.
Unser Programmier war von diesem Ergebnis sehr überrascht. Er dachte: “Wenn der Experte profitabel ist , dann bekommst du umso mehr, je mehr du investierst!". Doch Tester haben bewiesen, dass dies nicht immer der Fall ist.
1.2.1. Geometrische Progression.
Lot=NormalizeDouble(AccountEquity()*Prots/100/1000,1);// Berechnen wir die Anzahl der Lots double Min_Lot = MarketInfo(Symbol(), MODE_MINLOT); // Der eingestellte Mindestpreis der Lots if (Lot == 0 ) Lot = Min_Lot; // Zum Test auf konstanten minimalen Lots
Dieser Algorithmus stellt eine geometrische Progression dar. Die Prots- (Prozentsatz) Variable erlaubt es, den Orderwert je nach der aktuellen Höhe der liquiden Mittel zu regulieren. Diese Methode die Orderwerte zu berechnen ist nicht ganz korrekt, weil sie nicht die Margenerfordernisse bei der Arbeit mit einem bestimmten Dealer berücksichtigt. Gleichzeitig erlaubt das obige Code-Fragment die Lösung des Hauptproblems – das Problem proportionaler Investitionen. Auf diese Weise hängt der Wert jeder folgenden Order proportional von den erzielten Ergebnissen ab: Er wächst nach jedem profitablen Trade und sinkt nach jedem nicht profitablen Trade. Der Orderwert in dem obigen Graal_1.mq4 (Grail 1)-Code macht 10% der liquiden Mittel aus.
Setzen wir mal den Wert der Prots-Variablen auf 0 und testen den Experten gemäß dem folgenden Code
if (Lot == 0 ) Lot = Min_Lot; // Zum Test auf konstanten minimalen Lots
bei einem gleichbleibenden Orderwert.
In diesem Fall wird das Ergebnis wie folgt sein:
![](https://c.mql5.com/2/13/graal_pic_4.png)
in Abb. 4. Testergebnisse für den Experten Graal_1.mq4 (Grail 1) bei konstanten Lot-Werten.
Der Ausschluss von progressiven Orderwerten zeigt die wahre Natur der Veränderungen der Balancekurve – Wogen, Abstürze, etc.
1.2.2. Aggressives Reinvestieren.
Jeder profitable Experte wird zwischen Profit und Verlust immer auf der Jagd nach seinem Vorteil sein. Derzeit gibt es keine Technologie, die es erlauben würde, nur profitable Trades zu machen. Bei Trades Verluste zu machen ist normal bei jeder wirklich funktionierenden Trading-Strategie. Es geht nur darum, wie das Verhältnis zwischen profitablen und nicht profitablen Operationen ist.
B. Unten steht ein Beispiel für die sehr wahrscheinlichen Situationen mit nicht gleichbleibenden Trades während des realen Tradings:
Oben wird eine Serie von 5 aufeinanderfolgenden Verlusten angezeigt, obwohl eine solche Serie auch noch länger sein kann. ( Beachten Sie, dass in diesem Fall das Verhältnis zwischen profitablen und nicht profitablen Orders 3:1 beträgt).
Wohin kann also dieser reguläre Zufall führen? Die Antwort auf diese Frage hängt von der Qualität der vom Trader gewählten Trading-Strategie ab. Eine Sache ist es, wenn der Trader bewusst tradet und dabei vernünftige Vorsichtsmaßnahmen ergreift, bei denen der Gesamtwert seiner Orders 10% bis 15% der Einlage nicht übersteigt; und eine ganz andere Sache ist es wenn der Trader aggressive Reinvestments, zulässt: Er investiert den größten Teil seiner Einlage, und zwar nur einmal, aber jedes Mal, wenn er Profit macht.
-
• Alternative 1. Der Wert einer Order beträgt 10% der liquiden Mittel (Prots=10;). Unter solchen Bedingungen erlauben die Tests dem Experten, das Arbeitstempo zu erhöhen, wobei das Guthaben bewusst, aber permanent gesteigert wird. Das Entwicklungsergebnis dieser Balance können Sie für diese Alternative auf diesem Bild Abb.2 sehen. Auf dem Bild sieht man, dass der Experte seine Arbeit während der langen Periode fortsetzt (etwa 10 000 Orders)
-
• Alternative №2. Der Wert einer Order beträgt 70% der liquiden Mittel (Prots=70;). Die Testergebnisse werden in Abb.3 gezeigt. Zwei oder drei Serien von nicht profitablen Orders haben dazu geführt, dass die Einlage vollständig aufgebraucht worden ist, bevor der Experte 400 Trades machen konnte.
Beachten Sie bitte den Bericht über die Testergebnisse: Die maximale Anzahl aufeinanderfolgender Verluste (eine Serie von Verlust-Orders) für den Experten Graal_1.mq4 (Grail 1) beträgt nur 10. Es gab auch andere Verlust-Serien während der gesamten Test-Periode, aber die Anzahl der Verlust-Orders überstieg in keinem Fall 10. Diese Verlust-Serien beeinflussten das Gesamtergebnis in Alternative 1 nicht wesentlich, hatten bei Alternative 2 aber eine katastrophale Wirkung.
So kann eine kurze Serie von falschen Investitionen schon zu einer Katastrophe führen. Es gibt ein effektives System, das für richtiges Kapitalmanagement entwickelt wurde – Money Management. Nach diesem System sollte der Wert einer Order 15% der gesamten Bilanzsummme nicht übersteigen und der Gesamtbetrag der Investitionen sollte nicht über 50% dieser Summe liegen. Dieses System bietet auch noch mehr nützliche Regeln, die unser Programmierer gelesen hat.
Nachdem er sich so seinen “Gral” “zusammengefummelt” und sich vergewissert hat, dass alles gut funktioniert, eröffnet unser Programmierer ein wirkliches Konto und beginnt, “Geld zu machen”. Nachdem einige Orders erfolgreich eröffnet und geschlossen worden sind, stellt sich heraus, dass die Bilanz nicht ansteigt, sondern stetig fällt. Obendrein hat das Personal des Dealing-Centers den Experten unseres Programmierers am Abend deaktiviert.
Unser Programmierer ist wirklich verärgert. Er fragt nach den Gründen für diese Ungerechtigkeit der Dealer und akzeptiert keine ihrer Erklärungen. Er rätselt: Was für “technische Beschränkungen”? Was hat das mit “Verzögerung” zu tun?! Seine erste Erfahrung mit dem reellen Trading lässt ihn zu dem Schluss kommen, dass dies ein “schlechtes Dealing-Center” ist und er einfach reingelegt worden ist. Er beendet den Vertrag mit dem Dealing-Center.
Unser Programmierer gibt jedoch nicht auf und beschließt, sich genau zu informieren und kontaktiert die erfahreneren Kollegen in dem Fachforum auf MQL4, wo man ihn erst einmal bittet, den Code zu zeigen. Er zeigt den Code nur ungern, tut es am Ende aber doch, da der Experte sowieso nicht profitabel zu sein scheint. Nach einigen Diskussionen im Forum hat der Programmierer Folgendes verstanden.
1.3. Fehler
Meta Editor hat ständig bestätigt, dass keine Fehler aufgetreten sind,
![](https://c.mql5.com/2/13/graal_pic_5.gif)
aber dennoch waren welche aufgetreten.
1.3.1. Abweichung von der Formalen Strategie
Auch wenn der Experte mit einer auf Sachkenntnis beruhenden Strategie geschaffen worden war, wurde er doch während des Codierens und der Optimierung generischer Variablen essentiell verändert. So liegt die ursprüngliche Idee nun in einer wirklich “abgespeckten” Form vor. IIn der Tat bestand die Idee darin, Wellen von 15 bis 20 Punkten Länge zu machen, aber dieser Parameter bekommt in der aktuellen “Gral”-Version einen miserablen Wert von 3. Wer kann hier von Gipfeln und Tälern sprechen?
Beachten Sie, wofür die Orders in den Variablen ss und bb gehalten werden. Diese Art, die Variablen zu betrachten ist falsch. Die Order wird schon als geöffnet angesehen, wenn sie erst erstellt wird. Doch man kann doch nicht schon vorher wissen, ob die Order geöffnet wird. Um sicher zu sein, muss man auf die Antwort des Servers warten und dann die Verfügbarkeit der Order im Terminal überprüfen. Für das reelle Trading sollte dieser Teil des Codes neu geschrieben werden, obwohl die voreingestellte Modifikation meistens anwendbar ist, auch im Strategie-Tester (siehe den Artikel Die Orders-Berechnung in einem großen Programm ).
1.4. Technische Einschränkungen
Der Experte wurde in dem Zeitrahmen getestet, für den er gedacht war: für eine Minute (M1). Man muss sehr genau aufpassen, wenn man das Traden mit Experten in einem M1-Zeitrahmen modelliert, besonders bei preissensitiven Experten.
Der Hauptunterschied zwischen einem Testmodell und einer Strategie im reellen Trading besteht darin, dass es beim Testmodell keine Verzögerung und kein Requoting (wenn der Dealer einen anderen Preis als den in der Order des Traders angegebenen macht) gibt.
Verschiedene Dealing-Center arbeiten mit verschiedenen Datenquellen (dies behandeln wir später). Je mehr und je öfter sich der Kurs ändert, desto wahrscheinlicher ist es, dass der Dealer dem Trader vorschlägt, die Order zu einem anderen Preis auszuführen. Andererseits, je “glatter” der Verkehr zu sein scheint, desto weniger wahrscheinlich ist ein neuer Preisvorschlag, aber desto kleiner ist auch der Raum für den Experten, der oft, aber mit kleinen Gewinnen handelt.
Unser Programmierer hat Graal_1 (Grail 1) an einem einminütigen Verlauf eines anderen Dealing-Centers (mit dem gleichen Spread) getestet und hat mit eigenen Augen gesehen, dass das Ergebnis größtenteils von der Art des Verkehrs abhängt.
![](https://c.mql5.com/2/13/graal_pic_6_1_1.gif)
in Abb. 6. Testergebnisse für Graal_1.mq4 (Grail 1) in einem M1-Verlauf von EURUSD vom 4. April bis zu 26. Juli 2006 auf dm FX Integralbank Demoserver bei konstanten Orderwerten,das Vorhandensein tiefer Drawdowns und einer instabilen Profitentwicklung zeigt
, dass der Experte am Rande eines Verlusts steht.
In der Regel unterscheiden sich die neu gesetzten Preis um 1 oder 2 Punkt (obwohl es auf einem schnellen Markt auch mehr sein können). Dieses Phänomen kann den Erfolg des Experten nicht wesentlich beeinflussen, wenn sein erwarteter viel größer ist, z.B. 10 – 15. Doch bei einem Experten mit einem geringen erwarteten Payoff, besonders wenn dieser weniger als 2 beträgt, kann man nicht im Ernst mit allgemeinem Erfolg rechnen, da dieser besonders von der Art der Quote und deren betreffenden Anpassung abhängig ist.
Ob der jeweilige Dealer bei dem aktuellen Tick den Preis anpasst oder nicht, ist eine andere Frage und kann nur durch den Dealer selbst beantwortet werden. Doch wenn man anfängt auf dem reellen Markt zu arbeiten, dann muss man akzeptieren, dass Preisanpassungen ein normales und natürliches Phänomen sind und eine Trading-Technologie, die mit einem realen Konto arbeitet, muss dies berücksichtigen.
1.5. Wirtschaftliche Aspekte
- Orders zu kleinen Preisen.
Situationen, wenn der Trader voll auf sein Trading-Account und die entsprechenden Ereignisse, einschließich Trading-Strategien, Experten, etc., konzentriert ist, kommen häufig vor. Jedoch ist da außer dem Interesse des Traders auch noch das wirtschaftliche Interesse des Dealers.
Bei normalem Trading können beide Parteien gewinnen: der Trader, der eine gut durchdachte Strategie anwendet, und der Dealer, der einen Prozentsatz der von dem Trader durchgeführten Operationen erhält. In diesem Fall haben beide Parteien Interesse aneinander und sind bereit, sich gegenseitig zu unterstützen.
Allerdings können sich Situationen ergeben, wo die Aktivitäten der einen Partei den Interessen der anderen Partei gegenüberstehen. Zum Beispiel, wenn der Dealer den Spread erhöht, das automatisierte Trading deaktiviert oder einseitig Orders nicht zu dem anfangs eingegebenen Preis eröffnet (schließt), steht dies den Interessen des Traders entgegen.
Gleichzeitig gibt es einige Traderaktivitäten, die im Widerspruch zu den wirtschaftlichen Interessen des Dealers stehen. Zu diesen Aktivitäten gehören häufige Trades mit kleinen Geldbeträgen.
Die Arbeit des Dealers ist alles in allem ziemlich einfach. Der Dealer sammelt die Kaufs- und Verkaufsorders der Trader und kontaktiert eine Bank oder ein anderes Finanzinstitut, um die Preisdifferenzen. Wir untersuchen mal ein einfaches Beispiel. Angenommen, der Dealer arbeitet für insgesamt 100 Trader, 60 von ihnen haben für 1 Lot EURUSD gekauft und 40 haben das gleiche Währungspaar für 1 Lot verkauft. In diesem Fall muss der Dealer 20 Lots (den Unterschied zwischen 60 und 40) von der Bank kaufen. Dabei ist es dem Dealer gleichgültig, in welche Richtung sich der Kurs bewegt. In jedem Fall bekommt der Dealer den vollen Spread von 80 Lots (40+40) und einen anteiligen Spread von 20 Lots (einen Teil bekommt die Bank für ihren Service).
In diesem Fall ist die Quelledes Profits/Verlusts für 40 Trader der Verlust/Profit der anderen 40 Trader. Die Quelle des Profits/Verlusts für die übrigen 20 Trader ist die Bank oder, genauer gesagt, juristische Personen, welche die Dienstleistungen der Bank in Anspruch nehmen, um Devisen für ihre Export-/Importgeschäfte zu kaufen/verkaufen. Dies ist die normale Art und Weise, wie die Teilnehmer auf dem Geldmarkt zueinander in Verbindung stehen.
Aber in der Interaktion des Dealers mit der Bank oder dem Finanzinstitut gibt es noch ein weiteres Detail. Es ist so, dass der Dealer nicht jedes Mal, wenn der Trader einen unbedeutenden Geldbetrag verkauft oder kauft, mit der Bank in Kontakt tritt. Trading-Operationen zwischen dem Dealer und der Bank werden ein bisschen weniger häufig ausgeführt, als die Klicks der Traders im MT4-Terminal. Normalerweise übersteigt der Mindestbetrag in den Transaktionen zwischen dem Dealer und der Bank nicht 50.000 US$, was, umgerechnet in den Bestellpreis mit einem Leverage-Effekt von 1:100, 0,5 Lot macht. . Deshalb handelt der Trader, wenn er immer mit einem kleinen Geldbetrag arbeitet, eigentlich mit dem Dealer. In diesem Fall ist das Geld des Dealers die Quelle für den Profit des Traders!
Der Dealer ist ebenso sehr ein Teilnehmer des Geldmarkts wie alle anderen. Der Dealer muss die Arbeit aller Trader beobachten und analysieren. Natürlich können Dealer, wenn es in ihrem wirtschaftlichen Interesse liegt, wiederholt unregelmäßige Investitionen dulden, wenn sie für den Trader zu offensichtlichen Verlusten führen oder sie insgesamt für einen gewissen Zeitraum (z.B. für einen Tag) neutral ausfallen. Doch kein vernünftiger Dealer wird erlauben, dass Beziehungen fortgeführt werden, die ihm selbst Verluste einbringen. In diesem Fall muss der Dealer irgendwie reagieren, sonst hat er einfach nichts auf dem Wirtschaftsterritorium des Devisenmarkts zu suchen.
Bitte beachten Sie, dass die moderne Routine auf dem Gelmarkt nicht einer Laune oder dem bösen Willen des Dealers entspringen. Die Beziehungen des Dealers mit der Bank sind auch vertraglich geregelt. Und der Dealer ist bestrebt, den Spread mit fairen Mitteln zu verdienen (Das Thema Missbrauch seitens des Dealers würde den Rahmen dieses Artikels sprengen). Wahrscheinlich würde der Dealer sehr gerne jede Sekunde mit der Bank handeln, aber momentan ist so etwas noch nicht möglich.
Wenn ein Händler häufig kleine Trading-Operationen durchführt, muss der Dealer Maßnahmen ergreifen. Das kann eine mündliche Benachrichtigung an den Trader sein, dass die Arbeit dieses speziellen Händlers grenzwertig ist. Der Dealer kann auch einfach das automatisierte Trading für diesen Trader deaktivieren oder die Anzahl der Preisanpassungen erhöhen.
- Hohe Preise von Orders.
Es gibt noch eine weitere Einschränkung, die reelles Trading vom Testen oder Traden auf einem Demokonto unterscheidet. Das ist der Maximalwert eines Lot-Preises. Kein Dealing-Center, sei es eine Bank, ein Buchmacher-Büro oder ein Finanzinstitut, kann praktisch mit sehr hohen Geldbeträgen arbeiten.
Wenn Orders ungefähr 10.000 bis 20.000 US$ kosten (bitte beachten Sie einen Leverage-Effekt, der normalerweise gleich 100 ist), wird das Dealing-Center circa 1.000.000 US$ verkaufen/kaufen. Dies ist ein sehr hoher Betrag, aber Dealer haben gelernt, mit solch hohen Geldbeträgen zu arbeiten, und zwar mit Erfolg.
Einige Schwierigkeiten können auftreten in einem mittelgroßen Finanzinstitut, wenn der Orderpreis 50.000 US$ oder sogar 100.000 US$ erreicht . In diesem Fall erscheint der Betrag von 5 bis 10 Millionen US-Dollar auf dem Interbankenmarkt. . Diese Geldsumme ist nicht so leicht auf einmal zu verkaufen/kaufen.
GErnsthafte Schwierigkeiten können auftreten, wenn der Order-Preis den Betrag von US$ 300.000 bis US$ 500.000 übersteigt. In diesem Fall wird das Dealing-Center sicherlich individuell mit dem Trader arbeiten. Ok, 50 Millionen Dollar sind ein wirklich großer Betrag für jede Institution.
Im Falle von hohen Order-Preisen kann die Firma des Dealing-Centers keinerlei Garantien geben und das Trading selbst wird auf der Grundlage dessen durchgeführt, dass der Trader dies versteht und akzeptiert. (Welcher Dealer kann sich schon die Freiheit nehmen, eine Order zu eröffnen, die beim ersten Mal eine riesige Menge Geld kostet, wenn es auf dem Markt unerwartete und starke Bewegungen gibt?).
Aus diesem Grund ist ein Trader mit Millionen mit scalpings Experten ein Beweis für einen Riesenfehler des Traders und hat nichts zu tun mit dem wirklichen Leben.
Diese Überlegungen haben unser Programmier zur Idee gebracht, dass er die erste 100 "kilobucks" hier verdient, und später findet er schon "ein besseres Center", und kam ruhig zum Schluss, dass "alles unter Kontrolle" ist.
Vergessen wir auch nicht, dass die Dealers alle normale Menschen mit ihren Bildungs- und Kulturniveaus sind, die nach ihrer Art ihre Geschäfte führen. Eine dasselbe Technologie für Dealer kann direkt bei einigen als unrentabel festgestellt werden, wo eigentlich auch Analytikern effektiv arbeiten und kann bei einigen Dealers lange nicht erkannt werden, weil sie keine reichende Erfahrungen haben oder haben kein Software dafür. Aber meistens waren Dealers auch wie "Grailers", und sie haben ihre eigene Erfahrung mit dem Traiding und kennen viele Kleinigkeiten des Handelns im Währungsmarkt, darunter der geometrischen Progression, wirtschaftlicher Betroffenheit, aggressive Reinvestieren , niedrige und hohe Preise der Orders. Im Allgemeinen muss jeder Händler von der positiven Aussage ausgehen, dass die Qualifikationen der Dealers viel höher ist als bei ihm selbst, und jede Meinung des Traders hat eine Grundlage.
Beurteilen Sie selbst. Welche (unter den oben genannten wirtschaftlichen und technischen Bedingungen) Arbeitsergebnisse ein Experte haben kann, der mehr als 20 000 Orders pro Jahr öffnet?
![](https://c.mql5.com/2/13/graal_pic_7_2.png)
Von allen diesen Ticken, Bars, Punkten, Spreads, Händler und Banken dreht sich schon alles bei unserem Programmier, deshalb hat er Details und "Einzelfragen" nicht klargestellt. Sein Verständnis war ihm dabei genug - "Der Tester und das reale Handeln fallen nicht zusammen". Und er hat entschieden, dass er die passende Technologie auf Basis von den Pendigs-Orders programmieren muss. "Da kriegen sie mich nicht hin!",- dachte er.
2. Der zweite "Graal".
2.1 Strategie.
Die Idee, den Experten auf Pending-Orders aufzubauen kam unserem Programmierer in den Sinn, nachdem er das Verhalten der Cross Rates EURGBP und EURCHG in einminütigen Charts studiert hatte.
![](https://c.mql5.com/2/13/graal_pic_8.png)
in Abb. 8. Langer Cross-Raten-Verlauf mit bedeutenden Preisabweichungen (Spikes).
Wie man nachts, wenn die europäische Sitzung schon vorbei ist und die asiatische noch nicht begonnen hat, leicht sehen kann, enthalten einige Symbol-Charts Bars mit unerwarteten Preisen, die sich total von einer “normalen” Preisbewegung unterscheiden.
//------------------------------------------------------------------------------------------- // Graal_2.mq4. // wird als Beispiel im Artikel "Mein erster Graal" verwendet. // Sergey Kowaljow, Dnepropetrovsk (Ukraine), sk@mail.dnepr.net, ICQ 64015987, http://autograf.dp.ua/. //------------------------------------------------------------------------------------------- extern int TakeProfit=5; // TakeProfit der Order extern int StopLoss= 29; // StopLoss der Order extern int Distan = 2; // Der Abstand von der Mittellinie MA extern int Cls = 2; // Schließen bei ** Punkten des Gewinns extern int period_MA=16; // Die Periode der MA //extern int Time_1 = 0; // Anfangszeit der Arbeit //extern int Time_2 = 0; // Die Zeit des Arbeitendes extern int Prots = 0; // Prozentanteil von verfügbaren Mittels //-------------------------------------------------------------------------------------------- int Nom_bl, // Die Nummer der Order BuyLimit Nom_sl, // Die Nummer der Order SellLimit total, // Die Anzahl der Lots bl = 0, // 1 = Bestätigt die Tatsache, dass die BuyLimit in vorhanden ist sl = 0, // 1 = Bestätigt die Tatsache, dass die SellLimit in vorhanden ist b = 0, // 1 = Bestätigt die Tatsache, dass die Buy-Order in vorhanden ist s = 0; // 1 = Bestätigt die Tatsache, dass die Sell-Order in vorhanden ist //-------------------------------------------------------------------------------------------- double OP, // OpenPrice (absolute Punkte) SL, // StopLoss der Order (relative Punkte) TP, // TakeProfit der Order (relative Punkte) dist, // Der Abstand von der Mittellinie MA(relative Punkte) Level, // Der mindestens tolerierbaren Abstand zum Setzen von Pending Orders OP_bl, // OpenPrice BuyLimit (absolute Punkte) OP_sl, // OpenPrice SellLimit(absolute Punkte) cls, // Schließen bei ** Punkten des Gewinns (absolute Punkte) MA, // Der Wert der MA (Kurs) spred, // des Spreads (absolute Punkte) Lot; // Die Anzahl der Lots //------------------------------------------------------------------------------------------- int init() { Level=MarketInfo(Symbol(),MODE_STOPLEVEL); // Prüfen wir, was uns der Server zeigt Level=(Level+1)*Point; // ?:) SL=StopLoss*Point; // StopLoss der Order (relative Punkte) TP=TakeProfit*Point; // TakeProfit der Order (relative Punkte) dist=Distan*Point; // Der Abstand von der Mittellinie MA(relative Punkte) cls=Cls*Point; // Schließen bei ** Punkten des Gewinns(absolute Punkte) spred=Ask-Bid; // des Spreads (absolute Punkte) return; } //------------------------------------------------------------------------------------------- int start() { //------------------------------------------------------------------------------------------- total=OrdersTotal(); // Die Anzahl der Lots bl=0; // Am Anfang, bevor wir durchgehen, setzen wir es auf 0 zurück sl=0; // Am Anfang, bevor wir durchgehen, setzen wir es auf 0 zurück b=0; // Am Anfang, bevor wir durchgehen, setzen wir es auf 0 zurück s=0; // Am Anfang, bevor wir durchgehen, setzen wir es auf 0 zurück //-------------------------------------------------------------------------------------------- for (int i=total; i>=0; i--) // über allen Orders { if (OrderSelect(i,SELECT_BY_POS)==true && // Wählen wir die Order aus OrderSymbol()==Symbol()) { //-------------------------------------------------------------------------------------------- if (OrderType()==OP_BUY) // Die Order Buy { b =1; // Es gibt eine solche Order Close_B(OrderTicket(),OrderLots()); // Schließen wir die Order (die Funktion entscheidet, ob es notwendig ist) } //-------------------------------------------------------------------------------------------- if (OrderType()==OP_SELL) // Die Order Sell { s =1; // Es gibt eine solche Order Close_S(OrderTicket(),OrderLots()); // Schließen wir die Order (wenn es notwendig ist) } //-------------------------------------------------------------------------------------------- if (OrderType()==OP_BUYLIMIT) // Die Order BuyLimit { OP_bl=NormalizeDouble(OrderOpenPrice(),Digits);//OpenPrice BuyLimit(absolute Punkte) Nom_bl=OrderTicket(); bl=1; // Es gibt eine solche Order } //-------------------------------------------------------------------------------------------- if (OrderType()==OP_SELLLIMIT) // Order SellLimit { OP_sl=NormalizeDouble(OrderOpenPrice(),Digits);//OpenPrice SellLimit(absolute Punkte) Nom_sl=OrderTicket(); sl=1; // Es gibt eine solche Order } //-------------------------------------------------------------------------------------------- } } //-------------------------------------------------------------------------------------------- MA = iMA(NULL,0, period_MA, 0,MODE_LWMA, PRICE_TYPICAL, 0);// Der aktuelle Wert MA Modify_order(); // Aktivieren die Modifikation Open_order() ; // Aktivieren die Eröffnung //------------------------------------------------------------------------------------------- return; } //------------------------------------------------------------------------------------------- void Close_B(int Nomber, double lots) // Schließung der Orders Buy { //------------------------------------------------------------------------------------------- if (NormalizeDouble(Bid-OrderOpenPrice(),Digits)>=cls)// Wenn der voreingestellte Profit erreicht wurde { OrderClose( Nomber, lots, Bid, 1, Yellow); // Schließen wir es b = 0; // Es gibt keine Buy mehr } //------------------------------------------------------------------------------------------- return; } //------------------------------------------------------------------------------------------- void Close_S(int Nomber, double lots) // Schließung der Orders Sell { //------------------------------------------------------------------------------------------- if (NormalizeDouble(OrderOpenPrice()-Ask,Digits)>=cls)// Wenn der voreingestellte Profit erreicht wurde { OrderClose( Nomber, lots, Ask, 1, Yellow); // Schließen wir es s = 0; // und es gibt keine Sell mehr } //------------------------------------------------------------------------------------------- return; } //------------------------------------------------------------------------------------------- void Modify_order() // Die Modifizierung der Orders { //------------------------------------------------------------------------------------------- if (bl==1) // Wenn es Buy-Limit gibt { OP=MA-dist; // muss er hier sein if (MathAbs(OP_bl-OP)>0.5*Point) // Und wenn er nicht da ist { OrderModify(Nom_bl,OP,OP-SL,OP+TP,0,DeepSkyBlue);// Die Modifizierung der Order } } //-------------------------------------------------------------------------------------------- if (sl==1) // Wenn es Sell-Limit gibt { OP=MA+spred+dist; // muss er hier sein if (MathAbs(OP_sl-OP)>0.5*Point) // Und wenn er nicht da ist { OrderModify( Nom_sl, OP, OP+SL, OP-TP, 0, Pink);// Die Modifizierung der Order } } //------------------------------------------------------------------------------------------- return; } //------------------------------------------------------------------------------------------- void Open_order() // Die Öffnungsfunktion { // int Tek_Time=TimeHour(CurTime()); // Um den Test mit der Zeit durchzuführen // if (Tek_Time>Time_2 && Tek_Time<Time_1) return; // Um den Test mit der Zeit durchzuführen //------------------------------------------------------------------------------------------- if (b==0 && bl==0) // Es gibt keine Buys, öffnen wir bl {F OP=MA-dist; // Der Eröffnungskurs der Order bl if(OP>Ask-Level) OP=Ask-Level; // Die Präzisierung OP entsprechend dem Möglichen OP=NormalizeDouble(OP,Digits); // Die Normalisierung (MA gibt das fünfte Zeichen) OrderSend(Symbol(),OP_BUYLIMIT, Lots(),OP,3,OP-SL,OP+TP,"",0,0,Blue);// Öffnen wir es bl=1; //Nun gibt es eine Buy } //-------------------------------------------------------------------------------------------- if (s==0 && sl==0) // Es gibt keine Sells, öffnen wir sl { OP=MA+spred+dist; // Der Eröffnungskurs der Order sl if(OP<Bid+Level) OP=Bid+Level; // Die Präzisierung OP entsprechend dem Möglichen OP=NormalizeDouble(OP,Digits); // Die Normalisierung (MA gibt das fünfte Zeichen) OrderSend(Symbol(),OP_SELLLIMIT,Lots(),OP,3,OP+SL,OP-TP,"",0,0,Red);// Öffnen wir es sl=1; // Nun gibt es sl } ///------------------------------------------------------------------------------------------- return; } //------------------------------------------------------------------------------------------- double Lots() // Berechnung der Lots { //------------------------------------------------------------------------------------------- Lot=NormalizeDouble(AccountEquity()*Prots/100/1000,1);// Berechnen wir die Anzahl der Lots double Min_Lot = MarketInfo(Symbol(), MODE_MINLOT); // Der eingestellte Mindestpreis der Lots if (Lot == 0 ) Lot = Min_Lot; // Zum Test auf konstanten minimalen Lots //------------------------------------------------------------------------------------------- return(Lot); } //-------------------------------------------------------------------------------------------
Als die generische Variablen wurden StopLoss, TakeProfit, Distan ausgesucht (Der Abstand, den die Order "entlang" des Kurses hält), Cls (Mindestbetrag von Punkten, die über Order gewonnen wurde, bei denen die Order schon geschlossen werden muss), period_MA (MA Periode, die eine Mittellinie von Kursen über der History anbietet) und Prots (Der Anteil der verfügbaren Mittels, die Orders-Preise). Das reicht schon, die Pläne zu verwirklichen.
-
In der speziellen Funktion start() wird eine Art von der Analyse der Orders durchgeführt (Die Berechnungsmethoden der Orders finden Sie hier) und zu gleich werden dabei Entscheidungen bezüglich einiger von ihnen getroffen. Wenn es im Terminal eine geöffnete Order gibt, dann wird direkt die entsprechende Funktion Close_*() aufgerufen, in der die Notwendigkeit der Orders-Schließung analysiert wird und falls es notwendig ist, werden sie da geschlossen.
-
Am Ende der Funktion start() werden die Funktionen Modify_order() und Open_order() für die Modifizierung und Eröffnung der Pending Orders des Typs Limit aufgerufen. Die Eröffnung der eindeutigen Orders steht nicht zur Verfügung.
-
In der Funktion Modify_order() wird die Position berechnet, wo die Order sein muss (mit einem Abstand von der Mitte),und, wenn sie nicht in der Position ist, dann wird sie in die Position verschoben.
-
In der Funktion Open_order() wird auch die gewünschte Eröffnung-Position der Pending-Orders bestimmt, dabei werden Einschränkungen des Servers berücksichtigt, und wenn es keine Order gibt, dann wird sie gesetzt.
![](https://c.mql5.com/2/13/graal_pic_9.gif)
in Abb. 9. Das Ergebnis wurde beim Experten-Test Graal_2.mq4 bekommen, im Zeit-verlauf von März 2005 bis Juni 2006 in M1 EURUSD unter Handelsbedigungen des Demo-Servers von MIG Investments.
2.2. Geometrische Progression.
![](https://c.mql5.com/2/13/graal_pic_10.gif)
in Abb. 10. Das Test-Ergebnis des Experten Graal_2.mq4 im Zeit-verlauf von März 2005 bis Juni 2006 in M1 des Währungswerkzeuges EURUSD ist unter Handelsbedigungen des Demo-Servers MIG Investments unter dem konstanten Preis der Orders.
Am Anfang wollte unser Programmier nur in der Nacht verdienen, aber später hat er erstaunlich und glücklich festgestellt, dass der Experte auch erfolgreich den ganzen Tag funktionieren kann. Muss man dazu noch sagen, dass er nach diesem Erfolg wieder entschieden hat "Ich allein!" und hat wieder angefangen zu "Geld zu machen". hatte aber wieder Pech.. Diesmal musste er schon den "Blowout" ("Spikes") erfahren.
2.3. Fehler
In dem obigen Experten gibt es eine große Menge von Defekten und Fehlprogrammierungen. In Modify_order() wird der minimale Abstand für die Pending Orders nicht berücksichtigt, wurde die Berechnung der geöffneten Orders falsch gesetzt, wird TakeProfit nicht modifiziert, zwecks den Profit mit Cls zu "vergleichen", der analytische Teil des Experten ist auf dem gesamten Code "verschmiert" und etc.
Falsche und dennoch nachlässige Programmierung führt oft zu versteckten Fehler, und manchmal sogar zu ihrer Replikation, wenn der Code in anderen Experten integriert wird.
2.4. Technische Beschränkungen (Spikes).
Alle Einschränkungen, entweder technische oder organisatorische, werden in der Regel schließlich zu wirtschaftlichen Verlusten führen. Die Frage ist, wer die Kosten dieser Verlusten nehmen wird.
Ein normales Kerzen-Chart, das der Trader im Monitor sieht, ist ein durchschnittliches Entwicklungsergebnis des Marktes, das aus einem bestimmen Gebiet kommt (zum Beispiel,unter den europäischen Banken). Man kann die Natur der Kursveränderungen auf dem kurzen History-Intervall bei verschiedenen Händlern analysieren. Dabei ist es einfach, zu bemerken, dass alle diese Charts zwar etwas, aber unterschiedlich sind. Einige Dealers haben dann zahlreiche lange gegenseitig eingerichtete Kerzen, und zu gleich andere Dealers haben in der gleichen Periode "Ruhe und Frieden".
Ein Tick-Chart ist auch eine Aufgabe des Kaufs oder Verkaufs. Das ist ein Arbeitsergebnis eines Verarbeitungsprogramms, welches die unnötigen und unnatürlichen Preise-Ticks filtert. Und sie (unnatürlichen Preise-Ticks) tauchen auf. Das passiert, wenn ein Objekt eine Summe in einer Bank aus irgendwelchen Gründen (wer weißt, es war vielleicht ein sehr dringendes Deal ) weit von dem Marktpreis verkauft oder gekauft hat. Die Information über dieses Ergebnis wird vom Verarbeitungsprogramm übernommen, und wenn das Deal nur einmal stattfindet, wird es nicht in der Bildung des endgültigen Diagramm berücksichtigt. In einigen Fällen ist kompliziert für das Programm, zu berechnen, welcher Preis "normal" ist, und welcher - nicht. Aus diesem Grund entstehen manchmal in Chart einzige Kerzen mit unterschiedlichen Hohen (abhängig vom Algorithmus des Verarbeitungsprogramms ). Die heißen eben Spikes. In verschiedenen Arten entstehen sie, sie zeigen nicht die aktuelle Lage im Währungsmarkt.
Es ist einfach, den Experten so zu programmieren, damit er solche "pins", "spines", "spikes" fängt und öffnete Orders auf dem profitabelsten Preis. Aber man muss klar verstehen, dass unter Vertragsbedingungen zwischen dem Dealer und der Bank, wird die Bank solche Deals nicht bezahlen, das heißt, der Trader wird Geld wieder aus der Dealers Tasche kassieren! Das lässt der Dealer gar nicht zu, deshalb kämpft er gegen Traders, damit sie die Handelnoperationen nur über den "normalen" Marktpreis durchführen.
Als Instrumenten, die dem Dealer eine solche Möglichkeit anbieten, ist das Dealers-recht im Vertrag zwischen dem Dealer und dem Trader , darunter kann der Dealer eine andere Preisnotierung anbieten, hat keine Garantie für die Eröffnung der Orders während der starken Preisbewegungen, keine Garantie für die Eröffnung der Pending-Orders bei der zweiten Berührung des Preises und andere Vorsichtsmaßnahmen. In machen Fällen kann der Dealer bereits die geöffnete Order annullieren, wenn es ihm scheint, dass die Order in Spik geöffnet wurde.
Der gleiche Fall war mit unserem Programmier. Wie gut der "Graal" auf dem Demo-Konto scheine , aber das Leben bringt wieder seine Korrektur. Diesmal hat er das Telefon nicht aufgelegt, sondern hat sehr aufmerksam die Dealerserklärungen über die zwangsweise Schließung der Orders gehört. Aber als sein Expert-Advisor wieder deaktiviert wurde, hat er es nicht geduldet und er hat den Vertrag mit dem Dealer aufgehoben.
Er hat die Schuld an den minutigen Timeframes gefunden, welche nach seiner Meinung Menschen irritieren. Er hat etwas Forums gelesen, und hat nach den Diskussionen mit anderen Traders bemerkt, dass sie meistens in gleichen Währungswerkzeugen mit größeren Timeframes arbeiten. "Vielleicht hat es einen Sinn", - dachte unser Programmier. Er kam langsam darauf "Ich bin da auch Mozart " und hat voller Energie angefangen, sein drittes Kunstwerk zu schaffen - diesmal schon nicht auf M1 ("Nie wieder-nie!").
3. Der dritte "Graal"
3.1 Die formale Strategie
Fleißig und sorgfältig hat unser Programmier das Chart für EUR|USD in H1 geguckt,er hat für die Analyse verschiedene Indikatoren verwendet, und hat eine attraktive Regelmäßigkeit entdeckt. Er hat bemerkt, wenn MA (Moving Average) mit einer wenigen Periode MA mit einer größeren Perode kreuzt, dann bewegt sich der Markt in der Regel in die Richtung, wohin MA mit der wenigen Periode geht.![](https://c.mql5.com/2/13/graal_pic_11.png)
in Abb. 11. Die grafische Darstellung der Strategie, die auf Basis der MA-Kreuzung mit unterschiedlichen Perioden ist.
Der Programmier hat auch bemerkt, dass die Regelmäßigkeit in allen Timeframes gibt, aber er hat entschieden, nur mit großen Timeframes zu arbeiten. Er muss jetzt bloß dieses wohlverdientes Wissen in MQL4 einsetzen, um den Experten zu informieren, in welche Richtung und unter welchen Bedienungen er Orders öffnen muss. Und wenn der Experte bereit ist, muss er noch Parameter optimieren - die am effektivsten MA Größe aussuchen, richtig StopLoss und TakeProfit setzen.
Dieses Mal hat er den Experten geschaffen:
//------------------------------------------------------------------------------------------- // Graal_3.mq4. // wird als Beispiel im Artikel "Mein erster Graal" verwendet. // Sergey Kowaljow, Dnepropetrovsk (Ukraine), sk@mail.dnepr.net, ICQ 64015987, http://autograf.dp.ua/. //------------------------------------------------------------------------------------------- // // //------------------------------------------------------------------------------------------- extern int MA1 = 11; // Die Periode der 1-ste MA extern int MA2 = 23; // Die Periode der 2-ste MA extern double TP = 50; // Takeprofit der Order extern double SL = 15; // Stoploss der Order extern double Prots= 0; // Der Prozentanteil von verfügbaren Mittel //-------------------------------------------------------------------------------------------- int ret, // Die Richtung der Kreuzung total; // Die Anzahl der geöffneten Orders //-------------------------------------------------------------------------------------------- double Lot, // Die Anzahl der Lots Pred, // Der vorherige Wert der 1-ste MA (rot) Tek, // Der aktuelle Wert der 1-ste MA (rot) Golub; // Der aktuelle Wert der 2-ste MA(blau) //------------------------------------------------------------------------------------------- int init() { //------------------------------------------------------------------------------------------- SL = SL*Point; // Stoploss in Punkten TP = TP*Point; // TakeProfit in Punkten return; //------------------------------------------------------------------------------------------- } //------------------------------------------------------------------------------------------- int start() { //------------------------------------------------------------------------------------------- total=OrdersTotal(); // Die Gesamtmenge der Orders if (total==2)return; // Die beide Orders sind bereits geöffnet //-------------------------------------------------------------------------------------------- Tek =iMA(NULL,0, MA1, 0,MODE_LWMA, PRICE_TYPICAL, 0);// Der aktuelle Wert der 1-ste MA Pred =iMA(NULL,0, MA1, 0,MODE_LWMA, PRICE_TYPICAL, 1);// Der vorherige Wert der 2-te MA Golub=iMA(NULL,0, MA2, 0,MODE_LWMA, PRICE_TYPICAL, 0);// Der aktuelle Wert der 2-te MA //-------------------------------------------------------------------------------------------- if (Peresechenie()==1) Open_Buy(); // Bewegung von unten nach oben = die Öffnung Buy if (Peresechenie()==2) Open_Sell(); // Bewegung von oben nach unten = die Öffnung Sell //------------------------------------------------------------------------------------------- return; } //------------------------------------------------------------------------------------------- int Peresechenie() // Die Funktion der Bestimmung der Kreuzung { //------------------------------------------------------------------------------------------- if ((Pred<=Golub && Tek> Golub) || (Pred< Golub && Tek>=Golub) ) ret=1; // Die Kreuzung von unten nach oben //-------------------------------------------------------------------------------------------- if ((Pred>=Golub && Tek< Golub) || (Pred> Golub && Tek<=Golub) ) ret=2; // Die Kreuzung von oben nach unten //------------------------------------------------------------------------------------------- return(ret); // Liefern wir die Richtung der Kreuzung } //------------------------------------------------------------------------------------------- int Open_Buy() // Die Funktion der Eröffnung Buy { //------------------------------------------------------------------------------------------- if (total==1) // Wenn es nur eine Order gibt.. { // .. dann können wir noch eine andere öffnen OrderSelect(0, SELECT_BY_POS); // Wählen wir die Order aus if (OrderType()==0)return; // wenn es buy ist, dann öffnen wir es nicht } OrderSend(Symbol(),0, Lots(), Ask, 0, Ask-SL, Ask+TP, "", 0, 0, Blue);// Öffnen wir es //------------------------------------------------------------------------------------------- return; } //------------------------------------------------------------------------------------------- int Open_Sell() // Die Funktion der Eröffnung Sell { //------------------------------------------------------------------------------------------- if (total==1) // Wenn es nur eine Order gibt.. { // .. dann können wir noch eine andere öffnen OrderSelect(0, SELECT_BY_POS); // Wählen wir die Order aus if (OrderType()==1)return; // Wenn es sell ist, dann öffnen wir es nicht } OrderSend(Symbol(),1, Lots(), Bid, 0, Bid+SL, Bid-TP, "", 0, 0, Red);// Öffnen wir es //------------------------------------------------------------------------------------------- return; } //------------------------------------------------------------------------------------------- double Lots() // Berechnung der Lots { //------------------------------------------------------------------------------------------- Lot=NormalizeDouble(AccountEquity()*Prots/100/1000,1);// Berechnen wir die Anzahl der Lots double Min_Lot = MarketInfo(Symbol(), MODE_MINLOT); // Der eingestellte Mindestpreis der Lots if (Lot == 0 ) Lot = Min_Lot; // Zum Test auf konstanten minimalen Lots //------------------------------------------------------------------------------------------- return(Lot); } //-------------------------------------------------------------------------------------------
Dieser Experte, genauso wie vorherige, ist unkompliziert geworden..
Am Anfang des Experten gibt es den Block aus der Definition der Variablen. In der Funktion start() bestimmen wir die Gesamtmenge der Orders, und auch den Wert der MA mit der kleinen Periode und der großen Periode. Falls die Kreuzung der MA stattgefunden hat, wird die entsprechende Funktion Open_*() für die Orderseröffnung aufgerufen. Um die Tatsache zu bestimmen, dass die Kreuzung der MA stattgefunden hat, wird die Funktion Peresechenie() verwendet, und um die Preise der Lots zu bestimmen - wird die Funktion Lots() verwendet.
![](https://c.mql5.com/2/13/graal_pic_12.gif)
Drei Millionen innerhalb von fünf Monaten. Wunderbar! Aber irgendwas hat unser Programmier an die vorherige bittere Erfahrung denken lassen. Und er hat entschieden, sich nicht zu beeilen.
3.2. Progression.
Nach dem Test unter dem konstanten Wert der Orders des gleichen Experten hat er ein Balance-Chart bekommen:
![](https://c.mql5.com/2/13/graal_pic_13.gif)
Sechstausend Punkten innerhalb von fünf Monaten - das ist spürbar. Über ein tausend Punkten im Monat! Aber unser Programmier hat gezweifelt - soll er den Experten zum echten Handeln verwenden oder nicht? Denn er hatte schon zweimal Pech..
![](https://c.mql5.com/2/13/graal_pic_14.png)
3.3. Fehler
"Was für seltsame Nachrichten! Es stimmt nicht sicher mit MetaEditor!", - war sein erster Gedanke. Aber dann allmählich hat er gründlich seinen Code untersucht und hat wieder Fehler gefunden. Schauen wir mal auch.
3.3.1 Exkurs von der Anfangsstrategie - algorithmische Fehler.
//------------------------------------------------------------------------------------------- int Peresechenie() // Die Funktion der Bestimmung der Kreuzung { //------------------------------------------------------------------------------------------- if ((Pred<=Golub && Tek> Golub) || (Pred< Golub && Tek>=Golub) ) ret=1; // Die Kreuzung von unten nach oben //-------------------------------------------------------------------------------------------- if ((Pred>=Golub && Tek< Golub) || (Pred> Golub && Tek<=Golub) ) ret=2; // Die Kreuzung von oben nach unten //------------------------------------------------------------------------------------------- return(ret); // Liefern wir die Richtung der Kreuzung } //-------------------------------------------------------------------------------------------
if (Peresechenie()==1) Open_Buy(); // Bewegung von unten nach oben = die Öffnung Buy if (Peresechenie()==2) Open_Sell(); // Bewegung von oben nach unten = die Öffnung SellUm die Korrektur hinzuzufügen, reicht es am Anfang der Funktion Peresechenie(), die Variable ret auf 0 zurückzusetzen. Unser Programmier hat sich gefreut, dass er den algorithmischen Fehler gefunden hat, und hat zu gleich ein Fragment geschrieben, welches eine Eröffnung nur auf einer Bar zu lässt. Jetzt sieht sein Experte so aus:
//------------------------------------------------------------------------------------------- // Graal_31.mq4. // wird als Beispiel im Artikel "Mein erster Graal" verwendet. // Sergey Kowaljow, Dnepropetrovsk (Ukraine), sk@mail.dnepr.net, ICQ 64015987, http://autograf.dp.ua/. //------------------------------------------------------------------------------------------- // // //------------------------------------------------------------------------------------------- extern int MA1 = 11; // Die Periode der 1-ste MA extern int MA2 = 23; // Die Periode der 2-ste MA extern double TP = 50; // Takeprofit der Order extern double SL = 15; // Stoploss der Order extern double Prots= 0; // Der Prozentanteil von verfügbaren Mittel //-------------------------------------------------------------------------------------------- int New_Bar, // 0/1 Die Tatsache, dass der neue Bar entstanden ist Time_0, // Die Anfangszeit des neuen Bars ret, // Die Richtung der Kreuzung total; // Die Anzahl der geöffneten Orders //-------------------------------------------------------------------------------------------- double Lot, // Die Anzahl der Lots Pred, // Der vorherige Wert der 1-ste MA (rot) Tek, // Der aktuelle Wert der 1-ste MA (rot) Golub; // Der aktuelle Wert der 2-ste MA(blau) //------------------------------------------------------------------------------------------- int init() { //------------------------------------------------------------------------------------------- SL = SL*Point; // SL in Punkten TP = TP*Point; // TP in Punkten return; //------------------------------------------------------------------------------------------- } //------------------------------------------------------------------------------------------- int start() { //------------------------------------------------------------------------------------------- total=OrdersTotal(); // Die Gesamtmenge der Orders if (total==2)return; // Die beide Orders sind bereits geöffnet //----------------------------------------------------------------------------- Der neue Bar ---- New_Bar=0; // Erstmal auf 0 zurücksetzen if (Time_0 != Time[0]) // Wenn es schon die andere Anfangszeit des Bars ist { New_Bar= 1; // Und hier ist das neue Bar Time_0 = Time[0]; // Beachten Wir die neue Anfangszeit des neuen Bars } //-------------------------------------------------------------------------------------------- Tek =iMA(NULL,0, MA1, 0,MODE_LWMA, PRICE_TYPICAL, 0);// Der aktuelle Wert der 1-ste MA Pred =iMA(NULL,0, MA1, 0,MODE_LWMA, PRICE_TYPICAL, 1);// Der vorherige Wert der 2-te MA Golub=iMA(NULL,0, MA2, 0,MODE_LWMA, PRICE_TYPICAL, 0);// Der aktuelle Wert der 2-te MA //-------------------------------------------------------------------------------------------- if (Peresechenie()==1 && New_Bar==1) Open_Buy(); // Bewegung von unten nach oben = die Öffnung Buy if (Peresechenie()==2 && New_Bar==1) Open_Sell(); // Bewegung von oben nach unten = die Öffnung Sell //------------------------------------------------------------------------------------------- return; } //------------------------------------------------------------------------------------------- int Peresechenie() { ret=0; // Das ist der Kern der Sache!!:) //------------------------------------------------------------------------------------------- if ((Pred<=Golub && Tek> Golub) || (Pred< Golub && Tek>=Golub) ) ret=1; // Die Kreuzung von unten nach oben //-------------------------------------------------------------------------------------------- if ((Pred>=Golub && Tek< Golub) || (Pred> Golub && Tek<=Golub) ) ret=2; // Die Kreuzung von oben nach unten //------------------------------------------------------------------------------------------- return(ret); // Liefern wir die Richtung der Kreuzung } //------------------------------------------------------------------------------------------- int Open_Buy() { if (total==1) { OrderSelect(0, SELECT_BY_POS); // Wählen wir die Order aus if (OrderType()==0)return; // wenn es buy ist, dann öffnen wir es nicht } OrderSend(Symbol(),0, Lots(), Ask, 0, Ask-SL, Ask+TP, "", 0, 0, Blue);// Öffnen wir es return; } //------------------------------------------------------------------------------------------- int Open_Sell() { if (total==1) { OrderSelect(0, SELECT_BY_POS); // Wählen wir die Order aus if (OrderType()==1)return; // Wenn es sell ist, dann öffnen wir es nicht } OrderSend(Symbol(),1, Lots(), Bid, 0, Bid+SL, Bid-TP, "", 0, 0, Red);// Öffnen wir es return; } //------------------------------------------------------------------------------------------- double Lots() { Lot = NormalizeDouble( AccountEquity()*Prots/100/1000, 1);// Berechnen wir die Anzahl der Lots if (Lot<0.1)Lot = 0.1; // Zum Test auf konstanten minimalen der Lots return(Lot); } //-------------------------------------------------------------------------------------------
Der Test des Expertes unter dem konstanten Preis der Lots :hat ein anderes Ergebnis gezeigt:
![](https://c.mql5.com/2/13/graal_pic_15.gif)
Unser Programmier ist sehr enttäuscht gewesen. So viel Arbeit, und alles umsonst. Die Zeit lief weiter, aber er suchte trotzdem seinen "Graal". In einigen Monaten kam er zurück zum Experten Graal_3.mq4. "Ja, es gab da einen Fehler, er hatte ein gutes Ergebnis gezeigt. Vielleicht sollte es so sein! Möge der Experte Orders da öffnen, wo er will, muss einfach gute Ergebnisse zeigen". Und er hat wieder angefangen, zu testen.
![](https://c.mql5.com/2/13/graal_pic_16.gif)
3.4. Die Nacharbeit der Ergebnisse.
Es stellte sich heraus, dass unser Programmier sich die ganze Zeit nur angelogen hat. Es ist klar geworden, dass es kein Problem gibt, optimale Parameter in einem History-Intervall für einen Experten auszuwählen. Ein dasselbe Experte kann unterschiedliche Ergebnisse in verschiedenen History-Intervallen geben.
Die Frage ist nur, welche optimale Parameter des Experten ausgewählt werden müssen (wenn es möglich ist), bei denen kleine Marktpreisschwankungen auf dem Markt keine Auswirkungen auf die Funktionalität und Leistung des Experten hätten. Man muss sich generell auf die Strategie verlassen, die für jede Änderung auf dem Markt stabil bleibt, und die Einstellung der Parameter muss nur etwas bei der Leistung helfen.
Die Suche der optionalen Experte-Einstellungen für Graal_3.mq4 hat nichts gebracht. Der Test des Experten unter verschiedenen externen Variablen hatte entweder nur einen Verlust gezeigt, oder führte zu wesentlich verschiedenen Einstellungen für verschiedenen History-Intervallen. Aus diesem Grund hat es unserem Programmier nicht geklappt, auf die "Goldader" in Einstellungen zu stoßen, und er kam zum Schluss, dass diese Strategie keine universelle Einstellungen für alle Gelegenheiten hat.
Unser Programmier kam zurück zum Experten Graal_31.mq4 und hat das letzte Mal versucht, die gewünschten Ergebnisse zu erreichen, das beste, was er bekommen hat, sah so aus:
![](https://c.mql5.com/2/13/graal_pic_17.gif)
Aber das, was er gesehen hat, sah gar nicht wie "Graal" aus. Wegen einem tiefen Rückschlag in der Mitte des Charts konnte man mit bloßem Auge sehen, dass der Experte gar nicht in einem realen Konto verwendet werden kann. Aber trotzdem war es ein funktionierender Experte, der keine fantastische Ergebnisse zeigte, aber sowieso profitable Ergebnisse.
4. Abschluss.
Die Illusionen abzubauen ist immer schwer, besonderes, wenn sie so zuversichtlich und süß sind. Aber das Leben bringt alles zu seinem Platz, früher oder später. Das hat auch unseren Programmier geschlagen - er hat die Beziehung mit zwei Dealing-Center ruiniert und hat eine seine Menge Geld verloren. Nach der unschätzbaren Erfahrung bei der Programmierung und dem Handeln im Markt Forex, die er selbst gesammelt hat, unser Programmier war fast sicher, dass er "der Mozart ist..", aber hat sich rechtzeitig gestoppt und beschlossen, dass er nie wieder voreilige Entscheidungen trifft.
Stattdessen nimmt er ein leeres Blatt-Papier und formuliert Schlussfolgerungen, die auf der Grundlage der Lehre erfahren wurden:
-
Progressive Investitionen in realen Handeln - sind normal. Jedoch können hohe Preise der Orders nicht zugelassen werden.
-
Die Anfangsstrategie halten .
Wenn es während der Arbeit über den Experten klar wird, dass die erhebliche Änderungen der regelbaren Parameter zu den erheblichen Änderungen bei Ergebnissen führen, wird die Anfangsstrategie nivelliert. Es ist durchaus möglich, dass die zufällig gefundene Strategie zu besseren Ergebnissen führt. In diesem Fall muss sie etwas später neu betrachten und sie später wieder verwenden, dabei muss man aber aufmerksam die Gründe dieses Erfolgs betrachten. Aber zuerst müssen wir zur Anfangsidee kommen und ihre Verwendbarkeit forschen, dabei lassen wir aber nur die Änderungen innerhalb der angemessenen Grenzen zu. -
Geben Sie Acht auf algorithmische Fehler.
Die Anwesenheit von algorithmischen Fehlern ist ein ganz natürliches Phänomen. Man braucht manchmal viel Erfahrung, um solche Fehler zu entdecken. Gleichzeitig können oder sogar müssen einige von ihnen nach den endgültigen Ergebnissen der Arbeit gefunden werden. Sehr oft geöffnete Orders oder wenn sie "unangebracht" geöffnet werden, zeigt auf algorithmische Fehler. -
Richtig die Experten-Testergebnisse im Strategy Tester interpretieren
Zwischen der Arbeit des Experten auf dem realen Konto und der Modellierung der gleichen Arbeit im Tester, gibt es einen Unterschied, der besteht darin, dass die Ausführungsverweigerungen der Handelns-befehle und des Requotes nicht berücksichtigt werden. Für Experten mit hoher erwarteten Auszahlung spielt es keine große Rolle, aber die Experten-Advisors mit der geringen erwarteten Auszahlung können dadurch ein sehr unterschiedliches Ergebnis bekommen, im Vergleich mit den Test-Ergebnissen. In einigen Fallen wird der Experten-Advisor mit der geringen erwarteten Auszahlung auf dem realen Konto einen Verlust zeigen, aber im Tester wird er immer noch ein fantastisches Gewinn bringen. -
Lassen Sie nicht ein aggressives Reinvestieren zu.
Jede Handelsstrategie muss auf die verlustbringenden Operationen Rücksicht nehmen. Bei dem unbegrenzt hohen Preis der Order kann sogar eine kurze Reihe aus Verlusten zum Totalverlust der Balane führen, und in einigen Fällen zur Pleite des Deposites. Ein unkontrolliertes agressives Reinvestitionen zulassen, bedeutet eine freiwillige Selbstlüge, und ein garantierter vorhersagbarer Bankrott. - Versuchen nicht Geld auf zufälligen Spikes zu verdienen.
Spikes stellen keine normale natürliche Marktkurse dar. Wenn der Trader bei Speakes erfolgreich arbeitet, dann kriegt er als Gewinn das Geld des Dealers. Tatsächlich wird es früher oder später vom Dealer entdeckt, was zu folgenden Maßnahmen bringt: Aufhebung der Geschäften, Deaktivieren des Experten, Sperrung des Kontos. - Die Testergebnisse müssen auf verschiedenen History-Intervallen überprüft werden.
Jeder Experte wird unterschiedliche Ergebnisse auf verschiedenen Perioden zeigen. Für jeden History-Intervall können seine optimale Einstellungen gefunden werden, bei denen die Ergebnisse am besten werden. Man muss sehr aufmerksam testieren, keine Selbstlüge (Die Nacharbeit der Expertenparameter)erlauben, sondern die erhaltende Ergebnisse in maximal möglichen History-Abständen überprüfen.
SK. Dnepropetrovsk. 2006.
Übersetzt aus dem Russischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/ru/articles/1413
![Verwendung der Crashlogs, um eigene dll einzurichten](https://c.mql5.com/2/13/153_6.gif)
![Mehrmalige Neuberechnungen des nullwertigen Bars in einigen Indikatoren](https://c.mql5.com/2/13/139_6.png)
![Wie man ein Handelssignal zum Abonnieren richtig auswählt. Eine Schritt-für-Schritt-Anleitung](https://c.mql5.com/2/18/signals__1.png)
![Genetische Algorithmen in MetaTrader 4. Im Vergleich zur direkten Sortierung des Optimizers](https://c.mql5.com/2/13/135_1.gif)
![MQL5 - Sprache von Handelsstrategien, eingebaut ins Kundenterminal MetaTrader 5](https://c.mql5.com/i/registerlandings/logo-2.png)
- 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.