![Schutz vor Falschauslöser bei Handelsroboter](https://c.mql5.com/i/articles/overlay.png)
Schutz vor Falschauslöser bei Handelsroboter
Einführung
In diesem Artikel beschreiben wir Wege der Verbesserung der Stabilität eines Handelsroboters durch die Beseitigung von möglichen Mehrfachauslösungen (Geknatter) auf unterschiedliche Weise: beide verwenden die Ein- und Ausstiegsalgorithmen sowohl separat wie in Verbindung.
Die Natur des Problems
Das Problem von Falschauslösungen entsteht häufig bei Kurseinbrüchen oder heftigen Kursanstiegen des Marktes, wenn eine Kerze sehr lang wird und es keine Vorkehrung gegen Mehrfachauslösungen im Algorithmus des Handelsroboters gibt. Das verursacht sich wiederholende Positions-Eröffnungen und -Schließungen während der aktuellen Kerze.
Die finanziellen Auswirkungen können unterschiedlich sein und hängen von der speziellen Behandlung der Marktparameter durch den Handelsroboter ab. In jedem Fall steigen die Ausgaben für die Spreads proportional mit der Zahl Auslöser durch die Mehrfachauslösungen.
In diesem Artikel werde ich mich nicht mit der Analyse der finanziellen Instrumente (sein es technische oder fundamentale) beschäftigen, die die Stabilität der Arbeitsweise des Expert Advisors beeinflussen und die Mehrfachauslösungen vermeiden könnten (das ist ein anderes Thema — ich bin der Autor der Theorie von Impuls und Gleichgewicht und eines Systems auf dessen Basis). Hier konzentrieren wir uns auf das Messen der Software, die nicht direkt von den Methoden der Marktanalyse abhängt.
Schreiten wir zur Lösung des Problems. Als Beispiel verwende ich den Expert Adviser "MACD Sample" aus der Grundausstattung des Nutzerterminal des МetaТrader 4.
So schaut das Problem der Mehrfachauslösung aus, am Beispiel des EURUSD, der am 2. Okt. 2015 (М15 Zeitrahmen, "MACD Sample" EA mit seiner Standardeinstellung):
Das Bild zeigt deutlich 8 Auslöser, nacheinander (Kaufaufträge), während einer einzigen Kerze. Aber nur einer wäre richtig gewesen (bezogen auf die Handelslogik), die anderen 7 sind "Geknatter"
Die Gründe für die falschen Auslöser in diesem speziellen Fall sind:
- Der kleine Wert des Take-Profit ist in der Standardeinstellung (Schließalgorithmus) und daher wird jede Position sofort wieder geschlossen;
- ebenso löst der Eröffnungsalgorithmus des "MACD Sample"-EA nach dem Schließen der vorherigen Position aus und das führt zur nächsten Positionseröffnung unabhängig von der Anzahl der Positionen während derselben Kerze.
Wir haben uns darauf festgelegt, die Schwankungen des Marktes selbst nicht zu filtern (jeder Händler hat ja seine eigenen Ein- und Ausstiegsalgorithmen), wir müssen uns daher für die Lösung des Problems auf folgende Faktoren beschränken:
- Zeit (Dauer der Kerze),
- Anzahl der Auslösungen (Zähler),
- die Amplitude der Bewegung (Höhe der Kerze).
Der Eröffnungsalgorithmus
Die einfachste und zugleich die zuverlässigste Methode zur Behebung des Eröffnungsproblems ist der Faktor Zeit, aus folgenden Gründen:
- Ein Zähler der Auslöser bedingt eine Schleife im Programm, die nicht nur den Algorithmus verkompliziert, sondern auch die Ausführungsgeschwindigkeit des Expert Advisor reduziert.
- Die Amplitudenhöhe und das damit verbundene Preisniveau kann sich während der Kerzendauer drehen und führt so zu keinem eindeutigen Kriterium.
- Die Zeit ist unumkehrbar, sie bewegt sich nur in eine Richtung (Zeitwert steigt), und ist damit das genaueste und ein eindeutiges Kriterium für die Lösung unseres Problems durch einen Einmal-Auslöser oder dem Entfernen des "Geknatters".
So ist der Hauptfaktor nur die Positionseröffnung (OrderSend) und nicht der Auslöser des Algorithmus, da er abweichen kann, falls z.B. eine Wartezeit existiert.
Wir speichern daher den Zeitpunkt (Serverzeit) der Positionseröffnung. Aber wie verwenden wir jetzt diesen Wert, um eine zweite Positionseröffnung während dieser Kerze zu verhindern? Wir wissen diesen Wert nicht im Vorhinein (seinen Absolutwert), er kann daher nicht Teil des Eröffnungsalgorithmus sein. Der Algorithmus sollte bestimmte, allgemeine Bedingungen beachten (beinhalten), die die erste Position der Kerze betreffen, aber alle weiteren verhindert ohne die Auslöser zu berechnen (die Möglichkeit eines Zähler hatten wir ja bereits verworfen).
Die Lösung ist ziemlich einfach. Schreiben wir zuerst den Code mit Kommentaren und erläutern ihn dann im Detail. Die ist ein Hilfscode (gelb hervorgehoben), der in den Algorithmus des Expert Advisor kopiert werden muss (siehe MACD_Sample_plus1.mq4):
//+------------------------------------------------------------------+ //| MACD Sample.mq4 | //| Copyright 2005-2014, MetaQuotes Software Corp. | //| https://www.mql4.com | //+------------------------------------------------------------------+ #property copyright "2005-2014, MetaQuotes Software Corp." #property link "https://www.mql4.com" input double TakeProfit =50; input double Lots =0.1; input double TrailingStop =30; input double MACDOpenLevel =3; input double MACDCloseLevel=2; input int MATrendPeriod =26; //--- Einfügen einer neuen Variablen (Wert in Sekunden für eine Kerze dieses Zeitrahmens, für М15 wäre es 60 sec. * 15 = 900 sec) datetime Time_open=900; //--- Einfügen einer neuen Variablen (Eröffnungszeitpunkt der Kerze des 1. Position) datetime Time_bar = 0; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void OnTick(void) { double MacdCurrent,MacdPrevious; double SignalCurrent,SignalPrevious; double MaCurrent,MaPrevious; int cnt,ticket,total; //--- // initial data checks // it is important to make sure that the expert works with a normal // chart and the user did not make any mistakes setting external // variables (Lots, StopLoss, TakeProfit, // TrailingStop) in our case, we check TakeProfit // on a chart of less than 100 bars //--- if(Bars<100) { Print("bars less than 100"); return; } if(TakeProfit<10) { Print("TakeProfit less than 10"); return; } //--- to simplify the coding and speed up access data are put into internal variables MacdCurrent=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,0); MacdPrevious=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,1); SignalCurrent=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,0); SignalPrevious=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,1); MaCurrent=iMA(NULL,0,MATrendPeriod,0,MODE_EMA,PRICE_CLOSE,0); MaPrevious=iMA(NULL,0,MATrendPeriod,0,MODE_EMA,PRICE_CLOSE,1); total=OrdersTotal(); if(total<1) { //--- no opened orders identified if(AccountFreeMargin()<(1000*Lots)) { Print("We have no money. Free Margin = ",AccountFreeMargin()); return; } //--- check for long position (BUY) possibility //--- Einfügen einer neuen Zeile (entfernt das Verbot des Wiedereröffnung, wenn eine neue Kerze erscheint) if( (TimeCurrent() - Time_bar) > 900 ) Time_open = 900; if(MacdCurrent<0 && MacdCurrent>SignalCurrent && MacdPrevious<SignalPrevious && MathAbs(MacdCurrent)>(MACDOpenLevel*Point) && MaCurrent>MaPrevious && (TimeCurrent()-Time[0])<Time_open) //einfügen einer neuen Zeile in den Algorithmus (wird nur einmal ausgeführt, diese Bedingung kann nach dieser Zeile nicht mehr erfüllt werden) { ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,3,0,Ask+TakeProfit*Point,"macd sample",16384,0,Green); if(ticket>0) { if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) { Print("BUY order opened : ",OrderOpenPrice()); Time_open = TimeCurrent()-Time[0]; //neue Zeile (speichert das Zeitintervall zwischen Kerzeneröffnung und Positionseröffnung) Time_bar = Time[0]; //neue Zeile (speichert den Eröffnungszeitpunkt der Kerze der ersten Position) } } else Print("Error opening BUY order : ",GetLastError()); return; }
Mehr dazu:
Statt dem Zeitpunkt (der Eröffnung) verwenden wir den Zeitabstand zwischen Eröffnung der Kerze und der Position. Diesen Wert vergleichen wir mit dem vorher gespeicherten Dauer einer Kerze und das erlaubt uns die erste Position als solche zu erkennen. Im Moment der Eröffnung einer Position ändern (verringern) wir den Wert der Variablen Time_open durch das Überschreiben mit dem Zeitintervall zwischen der Eröffnung der Kerzen und der Eröffnung. Ab jetzt würde jeder Wert von (TimeCurrent() - Time[0]) größer sein als der, den wir gespeichert haben und die Bedingung (TimeCurrent() - Time[0]) < Time_open kann nicht mehr erfüllt werden und blockiert so die Eröffnung weiterer Positionen.
So konnten wir ohne Zähler und ohne Analyse der Kerzengröße das Problem der Mehrfachauslösung lösen.
Unten ist das Ergebnis dieser einfachen Verbesserung des Algorithmus des EAs ("MACD Sample_plus1"):
Wir sehen nur eine Position während der Kerze, keine falschen Auslöser und kein "Geknatter". Die Standardeinstellung wurden nicht geändert, damit ist klar, das Problem wurde ohne Änderungen der Einstellungen des EAs erreicht.
Jetzt, da wir das Problem des "Geknatters" gelöst haben, verbessern wir den Algorithmus der Positionseröffnung, um ein mögliches "Geknatter" durch ein zu schnelles Schließen der Position auszuschließen und in diesem Fall auch noch den Gewinn zu erhöhen (gute Dynamik, aber vorzeitiges Positionsende).
Lösung des Exit-Algorithmus'
Da das ursprüngliche Problem die Beseitigung eines möglichen "Geknatters" ist und nicht der Erhöhung des Gewinns, werde ich nicht die Dynamik des Marktes berücksichtigen, sondern mich auf eine Verbesserung der Parameter beschränken.
Bisher haben wir einen zuverlässigen Parameter, den Faktor Zeit, verwendet, und den werden wir wieder verwenden für die Bestimmung des Zeitpunktes die Position zu schließen, um genau zu sein, zum Zeitpunkt der Eröffnung der neuen Kerze (nach der Positionseröffnung). Dieser Moment des Algorithmus für das Schließen sieht so aus:
if(!OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES)) continue; if(OrderType()<=OP_SELL && // check for opened position OrderSymbol()==Symbol()) // check for symbol { //--- long position is opened if(OrderType()==OP_BUY) { //--- should it be closed? if(/* MacdCurrent>0 && MacdCurrent<SignalCurrent && MacdPrevious>SignalPrevious && // entfernter Code, der das Schließen durch den MACD auslöst, um die neuen Bedingungen nicht zu beeinflussen (siehe unten) MacdCurrent>(MACDCloseLevel*Point) && */ Bid > OrderOpenPrice() && // neue Zeile - optional (Position ist im Gewinn) TimeCurrent() == Time[0] ) // neue Zeile (simple Verbesserung des Algorithmus: Schließen nur beim Erscheinen der neuen Kerze) { //--- close order and exit if(!OrderClose(OrderTicket(),OrderLots(),Bid,3,Violet)) Print("OrderClose error ",GetLastError()); return; }
Mit diese keinen Änderungen funktioniert der Algorithmus für die Eröffnung (Positionseröffnung, kein Bedingungen für das Schließen), die Position bleibt bis TimeCurrent() == Time[0] und schließt zugleich mit dem Beginn der neuen Kerze nach dem Impuls. Gelegentlich macht auch der Schutz vor dem "Geknatter" einen schönen Gewinn (siehe Bild "MACD Sample_plus2"):
Dafür mussten wir den Auslöser, die Position durch den MACD zu schließen, entfernen, da sonst die notwendigen Bedingungen nicht gegriffen hätten.
Daher konnte das Problem des "Geknatters" durch die Algorithmen jeweils für Eröffnung und Schließen gelöst werden. Diskutieren wir nun die gegenseitige Abstimmung dieser beiden Algorithmen.
Verknüpfung der Algorithmen für das Eröffnen und Schließen von Positionen
Ein Verbinden impliziert bestimmte vorbereitende Schritte des Gesamtprozesses: Positionseröffnung — Kontrolle — Positionsschließung. Das spiegelt sich auch im Versatz der Indikatoren und der Funktionen, die im Algorithmus für das Eröffnen und Schließen verwendet werden.
Zum Beispiel, wenn Sie die Bedingung TimeCurrent() == Time[0] zum Schließen verwenden, ist das Ende der Position strikt an den Beginn einer neuen Kerze gebunden, aber dann sollte die Eröffnung während der vorherigen Kerze ausgeführt werde, damit die Bedingung wahr werden kann. Daher, um eine Position unter der Bedingung TimeCurrent() == Time[0] ohne zusätzliche Bedingungen zu schließen, muss der gesamte Vergleichsalgorithmus (beim Schließen) während der vorherigen Kerze durchgeführt (beendet) werden. Es sollten daher alle für den Vergleich relevanten Indikatoren um 1 (offset) versetzt werden. In diesem Fall ist der Vergleich der Werte korrekt und der Beginn einer neuen Kerze wird zum logischen Ende einer Position.
Auf diese Weise verbindet sich die Eröffnung und das Schließen einer Position mit dem Zeitfaktor.
Schlussfolgerung
Das Problem falscher Auslöser eines Expert Advisors wurde elegant gelöst durch einen Zeitfaktor im Algorithmus für die Positionseröffnung. Zusätzliche operative Stabilität eines EA kann durch eine Bestimmung des Momentes des Schließens einer Position (zum Beispiel, zeitlich) und durch eine Verbindung der beiden Algorithmen durch vorbereitende Bearbeitung der Hauptlogik der Auslösung und des Versatzes (offset) erreicht werden (die Kerze der Berechnung der Indikator- oder Funktionsberechnung).
Nachfolgend finden Sie die Codes der EAs: der ursprüngliche (MACD_Sample.mq4), mit verbesserter Positionseröffnung (MACD_Sample_plus1.mq4) und mit verbessertem Ausstieg (MACD_Sample_plus2.mq4). Nur Kauforders wurden verbessert, Verkauforders wurden bewusst nicht verändert, um einen Vergleich der beiden zu ermöglichen.
Und, natürlich gilt, alle angebenden EAs sind nur zu Demonstrationszwecken und sind nicht gedacht für den Einsatz auf realen Konten in den Finanzmärkten.
Übersetzt aus dem Russischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/ru/articles/2110
![Kennenlernen der CCanvas Klasse. Kantenglättung (Antialiasing) und Schatten](https://c.mql5.com/2/21/CCanvas_class_Standard_library_MetaTrader5.png)
![Universal Expert Advisor: Das Event-Modell und der Trading-Strategie Prototyp (Part 2)](https://c.mql5.com/2/21/smyf67hqftm_kaz2.png)
![Thomas DeMarks Beitrag zur technischen Analyse](https://c.mql5.com/2/19/50mlq5_4.png)
![Fuzzy-Logik für eine manuelle Handelsstrategie](https://c.mql5.com/2/22/2195.png)
![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.
Die Natur des Problems
Das Problem von Falschauslösungen entsteht häufig bei Kurseinbrüchen oder heftigen Kursanstiegen des Marktes, wenn eine Kerze sehr lang wird und es keine Vorkehrung gegen Mehrfachauslösungen im Algorithmus des Handelsroboters gibt. Das verursacht sich wiederholende Positions-Eröffnungen und -Schließungen während der aktuellen Kerze.
Die finanziellen Auswirkungen können unterschiedlich sein und hängen von der speziellen Behandlung der Marktparameter durch den Handelsroboter ab. In jedem Fall steigen die Ausgaben für die Spreads proportional mit der Zahl Auslöser durch die Mehrfachauslösungen.
In diesem Artikel werde ich mich nicht mit der Analyse der finanziellen Instrumente (sein es technische oder fundamentale) beschäftigen, die die Stabilität der Arbeitsweise des Expert Advisors beeinflussen und die Mehrfachauslösungen vermeiden könnten (das ist ein anderes Thema — ich bin der Autor der Theorie von Impuls und Gleichgewicht und eines Systems auf dessen Basis). Hier konzentrieren wir uns auf das Messen der Software, die nicht direkt von den Methoden der Marktanalyse abhängt.
****************************************************************************
1,) Wer soll das verstehen ?
2.) Wer progt seine EA schon so, aber
3.) ich habe verstanden.
Dieser Artikel richtet sich an blutige Anfänger. Doch die werden nix damit anzufangen wissen, und quälen uns im Forum.
@MetaQuotes: Bitte bringt doch endlich ein vernünftiges Tutorial heraus.