Mein erster Gral

Сергей Ковалев | 18 Januar, 2016


".. 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.

   Wenn man einfach nur die Kursbewegung als Richtungskriterium wählt, hat dies keine Auswirkungen, da die schwarzen und weißen  Kerzen einander sehr schnell abwechseln und die Reichweite dieser kleinen Änderungen sich innerhalb des Spread-Wertes bzw. sehr nahe daran befindet. Außerdem wäre es besser, auf der Höhe der Welle in den Markt einzutreten, nicht während ihres An- oder Abstiegs. Und Wellen sind leider auch unterschiedlich groß. Nachdem er ein bisschen nachgedacht hat, bestimmt unser Programmierer also die folgenden Kriterien:
  • •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.



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.

    Lassen Sie uns den Code in einer lesbaren Form präsentieren und versuchen zu verstehen, wie es funktioniert. Nach einer Korrektur kann dieser Experte so aussehen:

//-------------------------------------------------------------------------------------------
// 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.


 

in Abb. 2. Ein klassischer "Graal". Das Ergebnis wurde erzielt, als der Experte namens Graal_1.mq4 (Grail 1) laut der History von März 2005 bis Juni 2006 für M1 EURUSD unter den Trading-Bedingungen des MetaQuotes Software Corp Demoservers getestet wurde.

    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!"

    Nicht jede formale Strategie resultiert notwendigerweise in der Schaffung eines “Grals”, aber in unserem Beispiel ist es so. Lasst uns mal näher untersuchen, wie der Programmierer zu diesem Ergebnis gekommen ist.
 

1.2. Fortgeschrittene Investitionen.

    Unser Programmierer ist nicht auf halber Strecke stehengeblieben, sondern hat beschlossen zu versuchen, die Werte seiner Orders zu maximieren. Er hat den Wert der Orders bis zu 70% (der Wert der extern-variablen Prots=70) von der Gesamtmenge der verfügbaren Mittels erreicht, aber das Ergebnis hat gezeigt, dass diese Methode nicht effektiv ist:

 

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.

    Untersuchen wir mal, wodurch dieses Ergebnis zustande kam.
 

1.2.1. Geometrische Progression.

   Werfen wir einmal einen Blick auf die Technik der Wertekalkulation der Orders. Nach dem obigen Code wächst der Orderwert proportional zum Betrag der liquiden Mittel.
   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.

    Die Progression selbst ist kein Attribut des “Grals”. Jeder andere normale Experte kann mit dieser Technik geschaffen werden. Jedoch  muss eine geometrische Progression vollständig ausgeschlossen werden, um den “Gral” besser untersuchen zu können, und man sollte sich nur auf die bei einem konstanten Minimum der Orderwerte (wenn möglich, 0.1 Lot entsprechend) erzielten Testwerte konzentrieren. In diesem Fall können wir die Höhe der gewonnenen Punkt leicht schätzen.

    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:
 
 

               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.

    Zum Beispiel kann das Verhältnis 3:1 zwischen Profit und Verlust als ganz akzeptabel gelten. Das bedeutet, dass bei 100 aufeinanderfolgenden eröffneten und geschlossenen Orders 75 Trades profitabel und 25 nicht profitabel sein müssen. Wir können aber  nie vorhersagen, wie die nicht profitablen unter den profitablen Orders verteilt sind. Diese Verteilung ist überwiegend zufällig.

    A. Eine ideale Verteilung von Profit und Verlust wäre es, wenn diese während der ganzen Trading-History gleichbleibend wäre:

P P P L P P P L P P P L P P P L P P P L P P P L P P P L ...

    Es gibt aber keine Garantie dafür, dass die Verteilung immer so ideal ist. Ganz im Gegenteil, es ist sehr wahrscheinlich, dass früher oder später eine lange Serie von aufeinanderfolgenden Verlusten auftritt.


    B.
Unten steht ein Beispiel für die sehr wahrscheinlichen Situationen mit nicht gleichbleibenden Trades während des realen Tradings:

P P P P P P P P P P P P P P P  LLLL P P P L P P P L ...


    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.

    Im Falle von aggressiven Reinvestments wird sich die History  des Trading-Kontos unkalkulierbar entwickeln. Eine seltene “Glückssträhne” kann wahrscheinlich Rettung bringen. Doch in zahlreichen Fällen steht wirklich ein negatives Ergebnis bevor. Um zu illustrieren, wie der Experte  Graal_1.mq4  in mögliche Szenarien arbeitet, analysieren wir mal zwei Investment-Fälle, bei denen alle anderen Bedingungen gleich sind (die gleiche Phase der Entwickung, gleiche Inputs).
  • • 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.

    Er ist zu einem Schluss gekommen: Traden mit aggressiven Reinvestments  ist  eine Selbsttäuschung und wird früher oder später in den Ruin führen. Jeder Trader muss selbst entscheiden, wo er das Limit setzt. Die Ergebnisse sind dann entsprechend.
 

    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,
 
 
 
in Abb. 5.  keine Fehler bei der Kompilation.

    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?

    Es gibt keine klar definierbare Grenze zwischen Schwarz und Weiß. Alle Zwischenstadien kann man nur an ihrem Grad der Weiße oder Schwärze beschreiben. Doch man kann normalerweise erkennen, ob eine Farbe eher schwarz als weiß ist oder umgekehrt. In unserem Fall wurde die ursprüngliche Vorstellung von “rein weiß” so sehr “geschwärzt” dass sie tiefschwarz wurde und all ihre Kraft verlor. Wir können dies als den Grund dafür ansehen, dass der “Gral” schließlich so geworden ist.
 
1.3.2. Fehlerhafte Programmierung

    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.

    Wenn wir den Verlauf eines Balkens in einem längeren Zeitrahmen präzisieren wollen, können wir den Balkenverlauf eines kürzeren Zeitrahmens benutzen. Doch für M1 gibt es keinen kürzeren Zeitrahmen, da der Tick-Verlauf im MetaTrader 4 nicht gespeichert oder verwendet wird. (siehe Strategy Tester: Die Modes der Modelierung beim Test).

   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.


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?

 

Abb.7.  Der Bericht über den Test des Experten Graal_1.


    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.


 

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.

Gemäß normaler Logik reicht es, Pending-Orders vom Limit-Typ etwas oberhalb und etwas unterhalb des Mainstream zu platzieren und einige von ihnen werden höchstwahrscheinlich mit Erfolg eröffnet werden. Damit Pending-Orders angemessen auf Änderungen im Mainstream reagieren, müssen sie an einer Art Mittellinie “entlanggezogen” und ständig in einem bestimmten Abstand nahe der MA (Moving Average- gleitender Durchschnitt)-Linie gehalten werden. Unser Programmierer hat einen Experten geschrieben, um seine Idee zu realisieren:
//-------------------------------------------------------------------------------------------
// 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. 
    Während des Programmschreibens hat unser Programmier bemerkt, dass er sie unendlich entwickeln kann, und hat entschieden, dass das Programm nicht "beendet" werden kann, er muss einfach damit "aufhören".! Der Test des Experten in EURCHF hat die folgenden Ergebnisse gegeben: (betrachten wir nur die Variante, wobei wir sowas auch für EURGBP bekommen können).
 
 

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.

    In diesem, auch wie in den vorherigen Experten, wurde die Technologie des progressiven Investitions verwendet. Unter dem konstanten Wert der Orders sieht das Balance-Chart so aus:
 
  

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.
 
 
      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.

    Unser Programmier hat noch mal seinen Experten geguckt, hat keinen Fehler gefunden ("Einfach und schön!") und hat ihn zum Test eingestellt. Nach der Optimierung der Variablen hat er ein herrliches Ergebnis bekommen:
 
 

in Abb. 12. Das Test-Ergebnis des Experten Graal_3.mq4 in der History von März 2005 bis Juli 2005 in H1 des Währungswerkzeuges EURUSD hat unter Handelsbedigungen des Demo-Servers MetaQuotes Software Corp gezeigt.

    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:


 

in Abb. 13. Das Test-Ergebnis des Experten Graal_3.mq4 in der History von März 2005 bis Juli 2005 in H1 des Währungswerkzeuges EURUSD hat unter Handelsbedigungen des Demo-Servers MetaQuotes Software Corp. unter dem konstanten Preis der Lots.
 

    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..

    Dann hat er entschieden, Timeframes mit Zeichens über die Eröffnung und Schließung der Orders aufmerksamer zu gucken, hat erstaunlicherweise gefunden, dass der Experte die Orders nicht nur bei der Kreuzung der MA öffnet, sondern auch ohne Grund bei anderen Orten!
 
 

in Abb. 14. Die Orderseröffnung vom Experten Graal_3.mq4 in der Situationen, die in der Anfangsstrategie nicht vorgesehen sind.
 

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.

    Geben Sie Acht auf die einfache Funktion:

//-------------------------------------------------------------------------------------------
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
   }
//-------------------------------------------------------------------------------------------
    Es sieht alles klar aus, was könnte man hier noch finden? Aber es gibt einen Fehler. Der besteht darin, dass bei der Verwendung der globalen Variable ret, wird ihr Wert gleich dem letzten berechneten Wert gespeichert, das heißt , wird 1 oder 2 sein. Aus diesem Grund wird die Funktion Peresechenie() unabhängig von der Situation den letzten berechneten Wert zurückliefern, deshalb  wird in der Funktion start() ständig der Befehl für die Eröffnung gegeben:
   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
    Um 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:
 
  

in Abb. 15. Das Test-Ergebnis des Experten Graal_31.mq4 von März 2005 bis Juli 2005 in H1 des Währungswerkzeuges  EURUSD ist unter Handelsbedigungen des Demo-Servers MetaQuotes Software Corp. unter dem konstanten Preis der Lots.


    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.

    Wie überrascht war er, als er gesehen hat, dass der Experte ohne Code-Änderung und unter der gleichen Handelsbedigungen begonnen hat, das Deposit monoton zu verlieren!
 
 

in Abb. 16. Das Test-Ergebnis des Experten Graal_3.mq4 in der History von März 2005 bis Juli 2006 in H1 des Währungswerkzeuges  EURUSD ist unter Handelsbedigungen des Demo-Servers MetaQuotes Software Corp. unter dem konstanten Preis der Lots.
 

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:


 

in Abb. 17. Das Test-Ergebnis des Experten Graal_31.mq4 in der History von März 2005 bis Juli 2006 in H1 des Währungswerkzeuges  EURUSD ist unter Handelsbedigungen des Demo-Servers MetaQuotes Software Corp. unter dem konstanten Preis der Lots.


    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.

    Das gab unserem Programmier die Hoffnung zum Erfolg.
 

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.