English Русский 中文 Español 日本語 Português
Fuzzy-Logik in Handelsstrategien

Fuzzy-Logik in Handelsstrategien

MetaTrader 5Beispiele | 21 November 2017, 07:17
1 412 0
Maxim Dmitrievsky
Maxim Dmitrievsky

Einführung

Händler fragen sich oft, wie sie ein Handelssystem verbessern oder durch maschinelles Lernen ein neues erstellen können. Trotz der Fülle an Publikationen ist eine einfache und intuitive Methode zur Erstellung von Modellen, die ohne computergestützte Berechnungen nicht analytisch abschätzbar sind, noch nicht gefunden worden. Die Fuzzy-Logik (unscharfe Logik)ist ein Fenster in die Welt des maschinellen Lernens. Kombiniert mit genetischen Algorithmen erweitert es die Möglichkeiten, selbstlernende oder leicht optimierbare Handelssysteme zu schaffen. Gleichzeitig ist die Fuzzy-Logik intuitiv, da sie eindeutige, numerische Informationen in unscharfe (verschwommene) Begriffe umschreibt, genau wie eine Person im Denkprozess.

Hier ist ein Beispiel. Die Geschwindigkeit eines sich bewegenden Wagens wird logisch klar durch Messgeräte bestimmt: z. B. 60 km/h. Doch ein zufälliger Beobachter ohne Messgeräte kann die Geschwindigkeit des Autos nur grob abschätzen und stützt sich dabei auf seine Erfahrung oder Wissensbasis. Zum Beispiel ist bekannt, dass ein Auto schnell fahren kann, und "schnell" meint etwa 100 km/h und schneller. Es ist auch bekannt, dass ein Auto langsam fahren kann, also 5-10 km/h. Und schließlich wird die Geschwindigkeit visuell als Durchschnitt (ca. 60km/h) geschätzt, wenn das herannahende Auto moderat an Größe zunimmt. So ist es möglich, 60 km/h über vier verschiedene Arten zu charakterisieren:

  • Durchschnittsgeschwindigkeit;
  • Geschwindigkeit in der Nähe eines Durchschnitts;
  • überdurchschnittlich schnell;
  • und, schließlich, langsamer als ein Durchschnitt.

Information werden in einem menschlichen Bewusstsein so verkapselt, dass es nur die Informationen verarbeiten muss, die im Moment notwendig sind, zum Beispiel: "Werde ich genug Zeit habe über die Straße zu rennen, wenn sich das Auto nicht sehr schnell bewegt? Nachdenken über alles auf einmal und in allen Einzelheiten würde eine Person kolossalen Mengen an Zeit und Energie aufwenden müssen, bevor sie eine konkrete Entscheidung treffen kann: Laufen über die Straße oder das Auto vorbei lassen. Gleichzeitig würde die gegenwärtige Situation gründlich untersucht werden, die sich in Zukunft nie mehr identisch wiederholen wird sondern vielleicht nur ähnliche Umrisse haben würde. Beim maschinellen Lernen werden solche Situationen als Überanpassung bezeichnet.

Dieser Artikel wird sich nicht mit der Theorie der Fuzzy-Logik befassen. Informationen zu diesem Thema sind im Internet und auf der MQL5-Seite allgemein zugänglich. Beginnen wir gleich mit der Praxis, die mit Teilen der Theorie und Kuriositäten erläutert wird.

Für das Modell wird die Bibliothek Fuzzy verwendet, die der MetaTrader 5 standardmäßig bereit hält.

Das Ergebnis wird ein vorgefertigter Expert Advisor auf Basis der Fuzzy-Logik sein, der als Beispiel für die Erstellung eigener Systeme dienen kann.

Erstellen Sie eines Prototyps eines Handelssystems

Lassen Sie uns nun eine klare TS-Logik verwenden, die als Grundlage für die weiteren Untersuchungen dienen soll. Dann können 2 identische Systeme verglichen werden, wobei das zweite System die Fuzzy-Logik verwendet.

Als Basis werden 3 RSI-Oszillatoren mit unterschiedlichen Periodenlängen verwendet:

hnd1 = iRSI(_Symbol,0,9,PRICE_CLOSE);
hnd2 = iRSI(_Symbol,0,14,PRICE_CLOSE);
hnd3 = iRSI(_Symbol,0,21,PRICE_CLOSE);

Formulieren wir jetzt die eindeutigen Bedingungen der Signale und definieren wir sie in einer Funktion:

double CalculateSignal()
{
 double res =0.5;
 CopyBuffer(hnd1,0,0,1,arr1);
 CopyBuffer(hnd2,0,0,1,arr2);
 CopyBuffer(hnd3,0,0,1,arr3);
 
 if(arr1[0]>70 && arr2[0]>70 && arr3[0]>70) res=1.0;                    // Wenn alle Indikatoren im überkauften Bereich sind, verkaufen
 if(arr1[0]<30 && arr2[0]<30 && arr3[0]<30) res=0.0;                    // Wenn alle Indikatoren im überverkauften Bereich sind, vekaufen
 
 if(arr1[0]<30 && arr2[0]<30 && arr3[0]>70) res=0.5;                    // wenn 2 überverkauft und einer überkauft, kein Signal
 if(arr1[0]<30 && arr2[0]>70 && arr3[0]<30) res=0.5;
 if(arr1[0]>70 && arr2[0]<30 && arr3[0]<30) res=0.5;
 
 if(arr1[0]>70 && arr2[0]>70 && arr3[0]<30) res=0.5;                    // wenn 2 überkauft und einer überverkauft, kein Signal
 if(arr1[0]>70 && arr2[0]<30 && arr3[0]>70) res=0.5;
 if(arr1[0]<30 && arr2[0]>70 && arr3[0]>70) res=0.5;
 
 if(arr1[0]<30 && arr2[0]<30 && (arr3[0]>40 && arr3[0]<60)) res=0.0;    // wenn 2 überverkauft und der 3. 40 und 60 liegt, Kaufsignal
 if(arr1[0]<30 && (arr2[0]>40 && arr2[0]<60) && arr3[0]<30) res=0.0;
 if((arr1[0]>40 && arr1[0]<60) && arr2[0]<30 && arr3[0]<30) res=0.0;
 
 if(arr1[0]>70 && arr2[0]>70 && (arr3[0]>40 && arr3[0]<60)) res=1.0;    // wenn 2 überkauft und der 3. 40 und 60 liegt, Verkaufssignal
 if(arr1[0]>70 && (arr2[0]>40 && arr2[0]<60) && arr3[0]>70) res=1.0;
 if((arr1[0]>40 && arr1[0]<60) && arr2[0]>70 && arr3[0]>70) res=1.0;
 
 return(res);
}


Als nächstes schreiben wir alle weiteren Servicefunktionen und testen den Experten ab Anfang 2017 auf EURUSD, Zeitrahmen M15 und M5 (der vollständige Code des Experten ist am Ende des Artikels beigefügt):

EURUSD M15

EURUSD M5

Auch wenn klare Bedingungen für die Kombination der drei Indikatoren definiert wurden und die Bedingungen logisch und konsistent sind, erwies sich dieser Ansatz als zu einfach und unflexibel. Im Durchschnitt erzeugt das System über einen Zeitraum von 8 Monaten weder Gewinn noch Verlust. Um mit ihm Gewinne zu erzielen, müsste man eine Vielzahl von Bedingungskombinationen überarbeiten und eventuell weitere Oszillatoren hinzufügen. Viel bleibt aber nicht mehr viel zu optimieren, da die Bedingungen äußerst präzise sind.

Versuchen wir die Idee dieses Handelssystems durch die Fuzzy-Logik profitabel zu machen.

Erstellen eines Modells mit Fuzzy-Logik

Zunächst muss die Bibliothek Fuzzy eingebunden werden. Um genau zu sein, eines der beiden verfügbaren Modelle der Fuzzy-Logik - Mamdani oder Sugeno. Der Unterschied besteht darin, dass Sugeno ein lineares Modell ausgibt, ohne eine Variable in Form eines unscharfen Terms zu erzeugen, während Mamdani dieses Element zur Verfügung stellt. Da der Artikel für Händler geschrieben wurde, die die Unschärfe verwenden wollen, wird Mamdani verwendet. Das bedeutet aber nicht, dass das Sugeno-Modell für bestimmte Aufgaben nicht geeignet ist: Es ist immer möglich und notwendig, mit dem Grundverständnis der Fuzzy-Logik zu experimentieren.

#include <Math\Fuzzy\MamdaniFuzzySystem.mqh>
CMamdaniFuzzySystem *OurFuzzy=new CMamdaniFuzzySystem();

Ist die Bibliothek eingebunden, wird eine Referenz auf die Klasse Mamdani deklariert. Das ist alles, was man braucht, um loszulegen.

Betrachten wir nun die wichtigsten Etappen der Konstruktion von unscharfen Schlussfolgerungen. Sie nimmt einen zentralen Platz im unscharfen Modell ein. Der Prozess von unscharfen Schlussfolgerungen (fuzzy inference) ist ein spezifisches Verfahren oder ein Algorithmus zur Gewinnung von unscharfen Ergebnissen basierend auf unscharfen Annahmen durch das Verwenden der Fuzzy-Logik.

Es gibt 7 Stufen der Konstruktion von unscharfen Schlussfolgerungen.

  • Bestimmen der Struktur von unscharfen Schlussfolgerungen.

Die Anzahl der Ein- und Ausgänge sowie die Zugehörigkeitsfunktionen werden bereits in der Entwurfsphase definiert. In unserem Fall wird es 4 Eingänge und 1 Ausgang geben, und jeder von ihnen wird 3 Zugehörigkeitsfunktionen haben.

  • Formulieren der Regeln für die unscharfen Schlussfolgerungen.

Während des Entwicklungsprozesses erstellen wir benutzerdefinierte Regeln für unscharfen Schlussfolgerungen, basierend auf der Bewertung unseres Experten mit dem Handelssystem.

  • Fuzzifizierung von Eingangsvariablen.

Einstellen der Korrespondenz zwischen dem numerischen Wert der Eingangsvariablen der unscharfen Schlussfolgerungen und dem Wert der Zugehörigkeitsfunktion des entsprechenden Terms der linguistischen Variablen.

  • Aggregation

Verfahren zur Bestimmung des Wahrheitsgrades der Bedingungen für jede Regel der unscharfen Schlussfolgerungen.

  • Aktivierung

Der Prozess, um den Wahrheitsgrad von jedem der elementaren Sätze (Subklauseln) zu ermitteln, stellt die Konsequenz von Kernen aller unscharfer Produktionsregeln dar.

  • Akkumulation

Der Prozess zum Auffinden der Zugehörigkeitsfunktion für jede der ausgegebenen, linguistischen Variablen.

  • Defuzzifikation

Der Prozess des Übergangs von der Zugehörigkeitsfunktion der linguistischen Ausgangsvariablen zu ihrem eindeutigen (numerischen) Wert. Dies ist ein Ausgabewert im Bereich von 0 bis 1.

Es ist zu beachten, dass nur die Punkte 1 und 2 durchgeführt werden müssen, alle anderen werden vom System ohne Eingriffe durchgeführt. Wer sich für die Feinheiten der Fuzzy-Logik in allen Stadien interessiert, findet hier weitere Details.

Bestimmung der Struktur des Systems der unscharfen Schlussfolgerungen

Lassen Sie uns das Modells vervollständigen. Definieren Sie Objekte von drei Ein- und einem Ausgang sowie die Hilfsobjekte des Wörterbuchs, um die Arbeit mit der Logik zu erleichtern:

CFuzzyVariable *firstInput=new CFuzzyVariable("rsi1",0.0,1.0);
CFuzzyVariable *secondInput=new CFuzzyVariable("rsi2",0.0,1.0);
CFuzzyVariable *thirdInput=new CFuzzyVariable("rsi3",0.0,1.0);
CFuzzyVariable *fuzzyOut=new CFuzzyVariable("out",0.0,1.0);

CDictionary_Obj_Double *firstTerm=new CDictionary_Obj_Double;
CDictionary_Obj_Double *secondTerm=new CDictionary_Obj_Double;
CDictionary_Obj_Double *thirdTerm=new CDictionary_Obj_Double;
CDictionary_Obj_Double *Output;

Als Eingänge werden die drei RSI mit unterschiedlichen Perioden verwendet. Da der RSI-Oszillator immer im Bereich von 0-100 liegt, ist es notwendig, eine Variable mit der gleichen Dimension zu erstellen. Zur Vereinfachung werden die Werte der Indikatoren jedoch auf einen Bereich von 0-1 normiert. Bedenken Sie einfach, dass die erzeugte Variable eine Dimension haben muss, die der Dimension des Eingangsvektors entspricht, d. h. sie muss alle Werte enthalten. Auch am Ausgang wird auf einen Bereich von 0 bis 1 eingestellt.

Gemäß Punkt 1 der Erstellung der Fuzzy-Logik ist es auch notwendig, die Zugehörigkeitsfunktionen zu definieren und zu konfigurieren. Dies geschieht in der Funktion OnInit():

firstInput.Terms().Add(new CFuzzyTerm("buy", new CZ_ShapedMembershipFunction(0.0,0.6)));
firstInput.Terms().Add(new CFuzzyTerm("neutral", new CNormalMembershipFunction(0.5, 0.2)));
firstInput.Terms().Add(new CFuzzyTerm("sell", new CS_ShapedMembershipFunction(0.4,1.0)));
OurFuzzy.Input().Add(firstInput);
   
secondInput.Terms().Add(new CFuzzyTerm("buy", new CZ_ShapedMembershipFunction(0.0,0.6)));
secondInput.Terms().Add(new CFuzzyTerm("neutral", new CNormalMembershipFunction(0.5, 0.2)));
secondInput.Terms().Add(new CFuzzyTerm("sell", new CS_ShapedMembershipFunction(0.4,1.0)));
OurFuzzy.Input().Add(secondInput);
   
thirdInput.Terms().Add(new CFuzzyTerm("buy", new CZ_ShapedMembershipFunction(0.0,0.6)));
thirdInput.Terms().Add(new CFuzzyTerm("neutral", new CNormalMembershipFunction(0.5, 0.2)));
thirdInput.Terms().Add(new CFuzzyTerm("sell", new CS_ShapedMembershipFunction(0.4,1.0)));
OurFuzzy.Input().Add(thirdInput);
   
fuzzyOut.Terms().Add(new CFuzzyTerm("buy", new CZ_ShapedMembershipFunction(0.0,0.6)));
fuzzyOut.Terms().Add(new CFuzzyTerm("neutral", new CNormalMembershipFunction(Gposition, Gsigma)));
fuzzyOut.Terms().Add(new CFuzzyTerm("sell", new CS_ShapedMembershipFunction(0.4,1.0)));
OurFuzzy.Output().Add(fuzzyOut);

Nun wollen wir sehen, wie die Zugehörigkeitsfunktion aussieht und welchem Zweck sie dient.

Für jede Input- (und der einen Output-) Variable wurden drei Begriffe "buy", "neutral", "sell", jede mit einer eigenen Zugehörigkeitsfunktion, angelegt. Mit anderen Worten, die Oszillatorwerte können nun in 3 Fuzzy-Gruppen aufgeteilt werden und jeder Gruppe kann mit der Zugehörigkeitsfunktion ein Wertebereich zugewiesen werden. In der Sprache der Fuzzy-Logik wurden 4 Terme (fuzzy-sets) erstellt, von denen jeder 3 Begriffe hat. Zur Veranschaulichung der oben genannten Punkte schreiben wir ein einfaches Skript, das zur Visualisierung der Begriffe und ihrer Zugehörigkeitsfunktion verwendet werden kann:

//+------------------------------------------------------------------+ 
//|                                      Our MembershipFunctions.mq5 | 
//|                        Copyright 2016, MetaQuotes Software Corp. | 
//|                                             https://www.mql5.com | 
//+------------------------------------------------------------------+ 
#include <Math\Fuzzy\membershipfunction.mqh> 
#include <Graphics\Graphic.mqh> 
//--- Erstellen der Mitgliedsfunktionen 
CZ_ShapedMembershipFunction func2(0.0, 0.6);
CNormalMembershipFunction func1(0.5, 0.2); 
CS_ShapedMembershipFunction func3(0.4, 1.0);

//--- Erstellen der Kapseln um die Mitgliedsfunktionen 
double NormalMembershipFunction1(double x) { return(func1.GetValue(x)); } 
double ZShapedMembershipFunction(double x) { return(func2.GetValue(x)); }
double SShapedMembershipFunction(double x) { return(func3.GetValue(x)); }
 
//+------------------------------------------------------------------+ 
//| Script Programm Start Funktion                                   | 
//+------------------------------------------------------------------+ 
void OnStart() 
  { 
//--- Erstellen der Grafik 
   CGraphic graphic; 
   if(!graphic.Create(0,"Our MembershipFunctions",0,30,30,780,380)) 
     { 
      graphic.Attach(0,"Our MembershipFunctions"); 
     } 
   graphic.HistoryNameWidth(70); 
   graphic.BackgroundMain("Our MembershipFunctions"); 
   graphic.BackgroundMainSize(16); 
//--- Erstellen der Kurve 
   graphic.CurveAdd(NormalMembershipFunction1,0.0,1.0,0.01,CURVE_LINES,"[0.5, 0.2]"); 
   graphic.CurveAdd(ZShapedMembershipFunction,0.0,1.0,0.01,CURVE_LINES,"[0.0, 0.6]"); 
   graphic.CurveAdd(SShapedMembershipFunction,0.0,1.0,0.01,CURVE_LINES,"[0.4, 1.0]"); 
//--- Einstellen der Eigenschaften der X-Achse 
   graphic.XAxis().AutoScale(false); 
   graphic.XAxis().Min(0.0); 
   graphic.XAxis().Max(1.0); 
   graphic.XAxis().DefaultStep(0.1); 
//--- Einstellen der Eigenschaften der Y-Achse 
   graphic.YAxis().AutoScale(false); 
   graphic.YAxis().Min(0.0); 
   graphic.YAxis().Max(1.1); 
   graphic.YAxis().DefaultStep(0.1); 
//--- Zeichnen 
   graphic.CurvePlotAll(); 
   graphic.Update(); 
  }

Starten Sie das Skript auf dem Chart:

Bild 1. Die Zugehörigkeitsfunktionen.

Diese Zugehörigkeitsfunktionen wurden ausgewählt, da sie nur über 2 optimierbare Eingabeparameter verfügen (dies wird später, während der Systemtestphase, durchgeführt). Sie beschreiben auch die extreme und zentrale Position des Systems gut. Sie können jede Zugehörigkeitsfunktion aus der Fuzzy-Bibliothek verwenden.

Nehmen wir an, dass die Extremwerte des Oszillators eine bevorstehende Richtungsänderung und damit eine bevorstehende Trendwende anzeigen. Wenn sich der Oszillator Null nähert, deutet das also auf den Beginn eines Trends hin. Eine Bewegung des Oszillators bis zu 0,5 geht mit einer allmählichen Abnahme der CZ_ShapedMembershipFunction oder des Begriffs "Buy zone" einher. Gleichzeitig wird die Unsicherheit in CS_ShapedMembershipFunction oder "Sell zone" ersetzt wird, wenn sich der Oszillator der 1 nähert. Das gleiche Prinzip wird bei allen Ein- und Ausgängen angewendet, die prüfen, ob die Indikatorwerte zu einer bestimmten Zone mit unscharfen Grenzen gehören.

Es gibt keine Beschränkungen für die Anzahl der Zugehörigkeitsfunktionen pro Variable. Sie können 5, 7, 15 Funktionen anstelle von drei bestimmen, aber natürlich innerhalb der Grenzen des gesunden Menschenverstandes und der Fuzzy-Logik.

Formulieren der Regeln für die unscharfen Schlussfolgerungen.

In dieser Phase fügen wir dem System eine Wissensbasis hinzu, die für unscharfe Entscheidungen genutzt werden kann.

   rule1 = OurFuzzy.ParseRule("if (rsi1 is buy) and (rsi2 is buy) and (rsi3 is buy) then (out is buy)");
   rule2 = OurFuzzy.ParseRule("if (rsi1 is sell) and (rsi2 is sell) and (rsi3 is sell) then (out is sell)");
   rule3 = OurFuzzy.ParseRule("if (rsi1 is neutral) and (rsi2 is neutral) and (rsi3 is neutral) then (out is neutral)"); 
   
   rule4 = OurFuzzy.ParseRule("if (rsi1 is buy) and (rsi2 is sell) and (rsi3 is buy) then (out is neutral)");
   rule5 = OurFuzzy.ParseRule("if (rsi1 is sell) and (rsi2 is sell) and (rsi3 is buy) then (out is neutral)");
   rule6 = OurFuzzy.ParseRule("if (rsi1 is buy) and (rsi2 is buy) and (rsi3 is sell) then (out is neutral)"); 
   
   rule7 = OurFuzzy.ParseRule("if (rsi1 is buy) and (rsi2 is buy) and (rsi3 is neutral) then (out is buy)");
   rule8 = OurFuzzy.ParseRule("if (rsi1 is sell) and (rsi2 is sell) and (rsi3 is neutral) then (out is sell)");
   rule9 = OurFuzzy.ParseRule("if (rsi1 is buy) and (rsi2 is neutral) and (rsi3 is buy) then (out is buy)");
   rule10 = OurFuzzy.ParseRule("if (rsi1 is sell) and (rsi2 is neutral) and (rsi3 is sell) then (out is sell)");
   rule11 = OurFuzzy.ParseRule("if (rsi1 is neutral) and (rsi2 is buy) and (rsi3 is buy) then (out is buy)");
   rule12 = OurFuzzy.ParseRule("if (rsi1 is neutral) and (rsi2 is sell) and (rsi3 is sell) then (out is sell)");

   OurFuzzy.Rules().Add(rule1);
   OurFuzzy.Rules().Add(rule2);
   OurFuzzy.Rules().Add(rule3);
   OurFuzzy.Rules().Add(rule4);
   OurFuzzy.Rules().Add(rule5);
   OurFuzzy.Rules().Add(rule6);
   OurFuzzy.Rules().Add(rule7);
   OurFuzzy.Rules().Add(rule8);
   OurFuzzy.Rules().Add(rule9);
   OurFuzzy.Rules().Add(rule10);
   OurFuzzy.Rules().Add(rule11);
   OurFuzzy.Rules().Add(rule12);


Mindestens eine logische Bedingung muss der Wissensbasis hinzugefügt werden: Sie gilt als unvollständig, wenn nicht mindestens ein Begriff an logischen Operationen beteiligt ist. Es kann eine unbegrenzte Anzahl von logischen Bedingungen geben.

Das Beispiel setzt 12 logische Bedingungen, die die unscharfen Schlussfolgerungen, falls sie zutreffen, beeinflussen. So nehmen alle Terme an logischen Operationen teil. Standardmäßig wird allen logischen Operationen der Wichtungskoeffizient 1 zugewiesen. Sie werden in diesem Beispiel nicht geändert.

Entscheiden sich alle 3 Indikatoren innerhalb des unscharfen Bereiches für den Kauf, wird ein unscharfes Kaufsignal ausgegeben. Gleiches gilt für Verkaufs- und neutrale Signale. (Regeln 1-3)

Wenn 2 Indikatoren Kauf und einer Verkauf signalisieren, bleibt der Ausgabewert neutral, also unsicher. (Regeln 4-6)

Wen 2 Indikatoren Kauf oder Verkauf signalisieren und der dritte neutral bleibt, wird Kauf oder Verkauf ausgegeben. (Regeln 7-12)

Natürlich ist dies nicht die einzige Möglichkeit, eine Regelbasis zu erstellen, Sie können frei experimentieren. Diese Regelbasis gründet sich lediglich auf meine "sachkundige" Einschätzung und Vision über der Funktionsweise des Systems.

Erhalt eines klaren Ausgabewertes nach der Defuzzifikation

Es bleibt noch, das Modell zu berechnen und ein Ergebnis zwischen 0 und 1 zu erhalten. Werte nahe 0 zeigen ein starkes Kaufsignal an, Werte nahe 0,5 sind neutral und Werte nahe 1 bedeuten ein starkes Verkaufssignal.

double CalculateMamdani()

{
 CopyBuffer(hnd1,0,0,1,arr1);
 NormalizeArrays(arr1);
   
 CopyBuffer(hnd2,0,0,1,arr2);
 NormalizeArrays(arr2);
    
 CopyBuffer(hnd3,0,0,1,arr3);
 NormalizeArrays(arr3);
     
 firstTerm.SetAll(firstInput,arr1[0]);
 secondTerm.SetAll(secondInput,arr2[0]);
 thirdTerm.SetAll(thirdInput,arr2[0]);
       
 Inputs.Clear(); 
 Inputs.Add(firstTerm);
 Inputs.Add(secondTerm);
 Inputs.Add(thirdTerm);
      
 CList *FuzzResult=OurFuzzy.Calculate(Inputs);
 Output=FuzzResult.GetNodeAtIndex(0);
 double res = Output.Value();
 delete FuzzResult;

 return(res);
}

Diese Funktion holt die Werte von drei RSI-Oszillatoren mit unterschiedlichen Periodenlängen, normalisiert sie auf einen Bereich von 0 bis 1 (Werte können einfach durch 100 geteilt werden), aktualisiert die Liste mit den Objekten des Fuzzy-Wörterbuchs (die letzten Indikatorwerte), sendet sie an Berechnungen, erstellt eine Liste für die Ausgabevariable und nimmt das Ergebnis in die Variable 'res' auf.

Servicefunktionen hinzufügen und das resultierende System optimieren/testen

Da auch das maschinelle Lernen oder zumindest seine Grundlagen berücksichtigt werden, werden einige Parameter auf Eingänge verschoben und optimiert.

input string Fuzzy_Setings;        //Fuzzy Optimierungseinstellungen
input double Gsigma = 0.5;         //sigma von 0.05 bis 0.5, Schrittweite 0.05
input double Gposition=0.5;        //position von 0.0 tbis1.0 Schrittweite 0.1
input double MinNeutralSignal=0.4; //MinNeutralSignal von 0.3 bis 0.5 Schrittweite 0.1
input double MaxNeutralSignal=0.6; //MaxNeutralSignal von 0.5 bis 0.7 Schrittweite 0.1

Die Parameter der Gaußschen Funktion (Zugehörigkeitsfunktion) werden am Ausgang der Fuzzy-Logik optimiert. Sie hat den Mittelpunkt entlang der X-Achse verschoben (Parameter Gposition), sein Sigma geändert (seine Glockenform verengt und komprimiert, Parameter Gsigma). Dies wird eine bessere Feinabstimmung des Systems ermöglichen, wenn die RSI-Signale für Kauf und Verkauf asymmetrisch sind.

Zusätzlich optimieren Sie die Bedingungen für die Eröffnung von Positionen: Den minimalen und den maximalen Wert des neutralen Signals (neue Positionen werden nicht im Bereich zwischen diesen Werten geöffnet, da das Signal nicht definiert ist).

Die Verarbeitung eines Signals am Ausgang der Fuzzy-Logik ist in der folgenden Auflistung dargestellt:

void OnTick()
  {
//---
   if(!isNewBar())
     {  
      return;
     }
     
   double TradeSignal=CalculateMamdani(); 
   
   if(CountOrders(0)!=0 || CountOrders(1)!=0)                                           // falls es offenen Positionen gibt
      {
       for(int b=OrdersTotal()-1; b>=0; b--)
         {
          if(OrderSelect(b,SELECT_BY_POS)==true)
           {
            if(OrderSymbol()==_Symbol && OrderMagicNumber()==OrderMagic)
             {
              if(OrderType()==OP_BUY && TradeSignal>=MinNeutralSignal)                  // ein Kaufauftrag wurde ausgewählt und das Handelssignal ist größer als die linke Grenze des neutralen Signals
               {                                                                        // d.h. entweder gibt es ein neutrales Signal oder ein Verkaufssignal
                if(OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Red))       // dann schließe die Kauf-Position
                 {
                  if(TradeSignal>MaxNeutralSignal)                     // wenn die Position geschlossen wurde und ein Verkaufssignal existiert (größer als die rechte Grenze des neutralen Signals), eröffnen Sie sofort eine Verkaufssignal
                  {
                   lots = LotsOptimized(); 
                   if(OrderSend(Symbol(),OP_SELL,lots,SymbolInfoDouble(_Symbol,SYMBOL_BID),0,0,0,NULL,OrderMagic,Red)){
                     };
                  }
                 }
               }
               if(OrderType()==OP_SELL && TradeSignal<=MaxNeutralSignal)                 // eine Verkaufsorder wurde ausgewählt....///.... the same as for buy positions, but all conditions are mirrored
               {
                if(OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Red))
                 {
                  if(TradeSignal<MinNeutralSignal)
                  {
                   lots = LotsOptimized(); 
                   if(OrderSend(Symbol(),OP_BUY,lots,SymbolInfoDouble(_Symbol,SYMBOL_ASK),0,0,0,NULL,OrderMagic,Green)){
                    };
                  }
                 }
               }
             }
            }
          }
         return;
        }
                 // gibt es keine offenen Positionen, eröffne eine Position gemäß des Signals
   lots = LotsOptimized(); 
   if(TradeSignal<MinNeutralSignal && CheckMoneyForTrade(_Symbol,lots,ORDER_TYPE_BUY))
     { 
      if(OrderSend(Symbol(),OP_BUY,lots,SymbolInfoDouble(_Symbol,SYMBOL_ASK),0,0,0,NULL,OrderMagic,Green)){
       };
     }
   else if(TradeSignal>MaxNeutralSignal && CheckMoneyForTrade(_Symbol,lots,ORDER_TYPE_SELL))
     {
      if(OrderSend(Symbol(),OP_SELL,lots,SymbolInfoDouble(_Symbol,SYMBOL_BID),0,0,0,NULL,OrderMagic,Red)){
       };
     }
   return;
     
  }


Berechnungen werden bei einer neuen Bar durchgeführt, um die Demonstration zu beschleunigen. Sie können die Logik nach Ihrem Belieben anpassen, z. B. bei jedem Tick handeln, indem Sie einfach den Check für die neuen Bar entfernen.

Wenn das Signal einer aktuell offenen Position widerspricht oder das Signal nicht definiert ist, schließen Sie die Position. Wenn es eine Bedingung für das Öffnen einer entgegengesetzten Position gibt, öffnen Sie diese.

Dieses System verwendet keine Stop-Loss, da es sich nicht um eine reine Positionsumkehr handelt, sondern das Schließen und Öffnen von Positionen auf Signalen beruht.

Der Expert Advisor nutzt die Bibliothek MT4Orders, um die Arbeit mit Aufträgen zu erleichtern und um den Code leicht in MQL4 umwandeln zu können.

Testprozess

Das System wird mit den Einstellungen optimiert, die in den Screenshots gezeigt werden, im Zeitrahmen M15 über einen Zeitraum von 8 Monaten, basierend auf den Eröffnungspreisen der Bars, unter Verwendung des schnellen genetischen Algorithmus und dem Optimierungskriterium Balance + max Profit.


Hier das beste Ergebnis der Optimierung:

Vergleichen Sie es mit den Testergebnis des Modells ohne Fuzzy-Logik:

Die resultierenden Zugehörigkeitsfunktionen bei der Ausgabe nach der Optimierung (die Eingaben bleiben unverändert, da Sie nicht optimiert wurden):

Vor den Änderungen:

Danach:


Optimieren Sie das System mit gleichen Einstellungen, aber im Zeitrahmen M5:

Vergleichen Sie es mit den Testergebnis des Modells ohne Fuzzy-Logik:

Die resultierenden Zugehörigkeitsfunktionen bei der Ausgabe nach der Optimierung (die Eingaben bleiben unverändert, da Sie nicht optimiert wurden):

Vor den Änderungen:

Danach:

In beiden Fällen wurde der Gaußsche Bereich (Neutrale Zone) in Richtung Käufe verlagert und die Anzahl der Kaufposition überwiegt über die Anzahl der Verkaufsposition. Die Kauf- und Verkaufssignale erwiesen sich damit als asymmetrisch auf diesem historischen Abschnitt, der ohne ein solches Experiment nicht entdeckt werden konnte. Es ist möglich, dass sich das aus drei RSI bestehende System häufiger in der überverkauften Zone (Bereich 1) befand, als in der überkauften Zone (Bereich 0), und die Optimierung der Gaußschen Zone half, dieses Ungleichgewicht auszugleichen. Was die deutlichste Ausgabe betrifft, so ist es analytisch schwer vorstellbar, warum eine solche Ausgabekonfiguration zur Verbesserung der Ergebnisse des Handelssystems beigetragen hat, da der Prozess der Defuzzifizierung nach der Schwerpunktsmethode in Verbindung mit der Abbildung aller Eingänge auf Fuzzy-Sets bereits ein komplexes System an sich ist.

Das System erwies sich für 8 Monate als recht stabil, obwohl nur 4 Parameter optimiert wurden. Und sie lassen sich leicht auf zwei reduzieren (Gsigma und Gposition), da die verbleibenden 2 das Ergebnis wenig beeinflusst haben und sich immer in der Nähe von 0,5 befinden. Dies wird als zufriedenstellendes Ergebnis für ein experimentelles System angenommen, das zeigen soll, wie die Anzahl der optimierten Parameter durch Einführung eines Elements der Fuzzy-Logik in das Handelssystem reduziert werden kann. Im Gegensatz dazu wäre es notwendig gewesen, zahlreiche Optimierungskriterien für strenge Regeln zu schaffen, was die Komplexität der Systementwicklung und die Anzahl der optimierten Parameter erhöhen würde.

Es sollte auch darauf hingewiesen werden, dass dies immer noch ein sehr grobes Beispiel für den Aufbau eines Handelssystems auf der Grundlage von Fuzzy-Logik ist, da es eine primitive RSI-basierte Strategie verwendet, ohne auch nur einen Stop-Loss zu verwenden. Dies sollte jedoch ausreichen, um die Anwendbarkeit der Fuzzy-Logik auf die Schaffung von Handelssystemen zu verstehen.

Schlussfolgerung

Die Fuzzy-Logik ermöglicht ein schnelles Erstellen von Systemen mit Fuzzy-Regeln, die sehr einfach zu optimieren sind. Gleichzeitig durchläuft der komplexe Prozess der Auswahl der Handelssystemparameter die genetische Optimierung, es befreit den Entwickler von der Routine der Suche nach einer Handelsstrategie und entwickelt und algorithmisiert zahlreiche Regeln des Handelssystems. Zusammen mit anderen Methoden des maschinellen Lernens (z. B. neuronale Netze) lassen sich mit diesem Ansatz beeindruckende Ergebnisse erzielen. Es verringert die Wahrscheinlichkeit einer Überanpassung und die Dimension der Eingangsdaten (3 RSI-Indikatoren mit unterschiedlichen Perioden beschränken sich auf ein einziges Signal, das die Marktsituation umfassender und allgemeiner beschreibt als jeder einzelne Indikator).

Wenn Sie immer noch Schwierigkeiten haben, die Funktionsweise der Fuzzy-Logik zu verstehen, fragen Sie sich, wie Sie denken, welche Begriffe Sie verwenden und auf welchen Regeln Ihre Entscheidungsfindung beruht.

Hier ist das Beispiel einer Verstärkung. Zum Beispiel haben Sie 3 Wünsche: Auf eine Party gehen, einen Film zu Hause anschauen oder die Welt retten. Der Begriff "Film zu Hause ansehen" hat das größte Gewicht, da man schon zu Hause ist und keine weiteren Anstrengungen nötig sind. "Zu einer Party zu gehen" ist möglich, wenn jemand Sie einlädt und Sie abholt, aber, da das noch nicht geschehen ist, sind die Chancen zu gehen durchschnittlich. Und schließlich, um "die Welt zu retten", musst du alle deine übernatürlichen Fähigkeiten mobilisieren, ein Supermannkostüm anziehen und ein außerirdisches Monster bekämpfen. Es ist unwahrscheinlich, dass Sie heute dazu eine Gelegenheit erhalten und nicht bis morgen warten müssen, so dass die Chancen gering sind.

Die unscharfe Schlussfolgerung wird etwa so lauten: Ich werde höchstwahrscheinlich zu Hause bleiben, und vielleicht gehe ich auf die Party, aber ich werde die Welt heute definitiv nicht retten. Nach der Defuzzifikation könnten unsere Chancen auf einer Skala von 0 bis 10 bewertet werden, wobei 0 "Film zu Hause ansehen", 5 "auf eine Party gehen", 10 "Monster bekämpfen" ist. Offensichtlich würde der deutliche Ausgabe im Bereich von 0 bis 3 liegen, d. h. Sie sind am ehesten zu Hause. Das gleiche Prinzip wird in dem besprochenen Handelssystem angewandt: Es vergleicht die Werte von drei Indikatoren und verwendet logische Bedingungen, um die derzeit am besten geeignete Option zu bestimmen - kaufen, verkaufen oder gar nichts tun.

Mögliche Möglichkeiten, dieses Beispiel zu verbessern (zum Selbststudium):

  • Anzahl der Eingänge und logische Bedingungen erhöhen. Dies erhöht die Kapazität des Systems und macht es anpassungsfähiger an den Markt.
  • Optimierung nicht nur die Gaußsche Ausgabe, sondern auch alle Zugehörigkeitsfunktion von Ein- und Ausgang.
  • Optimierung der Regelbasis.
  • Optimierung der Wichtungen von logischen Ausdrücken.
  • Schaffung eines Komitees aus mehreren Fuzzy-Modellen, die für verschiedene Aspekte des Handelssystems verantwortlich sind.
  • Verwendung von unscharfen Schlussfolgerungen als Prädiktoren ("Features") und/oder Zielvariablen für neuronale Netze.

Wenn es genügend Interesse an dem Artikel gibt, und ich ausreichend Feedback bekomme, könnte ich die Möglichkeit in Betracht ziehen, einen neuen Artikel zu schreiben, der sich der Kombination von Fuzzy-Logik und neuronalen Netzen widmet.

Nachfolgend sind die Quellcodes der Experten und ein Testskript für die Zugehörigkeitsfunktionen beigefügt. Damit Sie den Experte kompilieren und starten können, müssen Sie die Bibliothek MT4Orders und die aktualisierte Bibliothek Fuzzy herunterzuladen.

Übersetzt aus dem Russischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/ru/articles/3795

Vergleich verschiedener Typen gleitender Durchschnitte im Handel Vergleich verschiedener Typen gleitender Durchschnitte im Handel
Es wurden 7 Typen gleitender Durchschnitte (MA) betrachtet; es wurde eine Handelsstrategie für das Arbeiten mit ihnen entwickelt. Verschiedene gleitende Durchschnitte wurden anhand einer Handelsstrategie getestet, des Weiteren wurden diese hinsichtlich der Effektivität der Anwendung verglichen.
Ein neuer Ansatz der Interpretation der klassischen und der versteckten Divergenz Ein neuer Ansatz der Interpretation der klassischen und der versteckten Divergenz
Der Artikel untersucht die klassische Methode eine Divergenz zu erkennen und bietet eine zusätzliche Interpretation. Auf Basis dieser neuen Interpretation wurde eine Handelsstrategie entwickelt. Auch diese Strategie ist in diesem Artikel beschrieben.
Mini Market Emulator oder ein manueller Strategie-Tester Mini Market Emulator oder ein manueller Strategie-Tester
Der Mini Market Emulator ist ein Indikator, der für die partielle Emulation des Handels am Terminal entwickelt wurde. Vielleicht möchte jemand damit "manuell" seine Strategie einer Marktanalyse oder des Handels testen.
Optimieren einer Strategie unter Verwendung einer Kurve der Salden und dem Vergleich der Ergebnisse mit dem Kriterium "Balance + max Sharpe Ratio" Optimieren einer Strategie unter Verwendung einer Kurve der Salden und dem Vergleich der Ergebnisse mit dem Kriterium "Balance + max Sharpe Ratio"
In diesem Artikel betrachten wir ein weiteres Kriterium für die Optimierung einer Strategie auf Basis einer grafischen Analyse der Salden. Die linearen Regression wird mit der Funktion aus der Bibliothek ALGLIB berechnet.