English Русский 中文 Español 日本語 Português 한국어 Français Italiano
preview
Messen der Information von Indikatoren

Messen der Information von Indikatoren

MetaTrader 5Beispiele |
268 10
Francis Dube
Francis Dube

Einführung

Das maschinelle Lernen stützt sich auf Trainingsdaten, um das allgemeine Verhalten des Marktes zu erlernen und letztendlich ziemlich genaue Vorhersagen zu treffen. Der gewählte Lernalgorithmus muss sich durch eine sorgfältig ausgewählte Stichprobe wühlen, um aussagekräftige Informationen zu gewinnen. Der Grund, warum viele diese hochentwickelten Tools nicht erfolgreich anwenden können, ist, dass die meisten aussagekräftigen Informationen in verrauschten Daten verborgen sind. Vielen Strategieentwicklern ist vielleicht nicht klar, dass die von uns verwendeten Datensätze für das Modelltraining nicht geeignet sind.

Indikatoren können als Überbringer von Informationen über die zugrunde liegenden Preisreihen betrachtet werden, auf die sie angewendet werden. Unter dieser Prämisse kann die Entropie dazu verwendet werden, zu messen, wie viel Information ein Indikator übermittelt. Anhand der Schritte und Werkzeuge, die im Buch Testing and Tuning Market Trading Systems (TTMTS) von Timothy Masters dokumentiert sind, werden wir demonstrieren, wie diese zur Bewertung der Struktur von Indikatordaten verwendet werden können.


Warum die Information der Indikatoren messen?

Bei der Verwendung von Tools für maschinelles Lernen zur Strategieentwicklung greifen wir oft darauf zurück, einfach alle möglichen Daten auf die Algorithmen zu werfen, in der Hoffnung, dass etwas dabei herauskommt. Letztlich hängt der Erfolg von der Qualität der im Modell verwendeten Prädiktoren ab, und wirksame Prädiktoren haben in der Regel bestimmte Merkmale. Eine davon ist mit einem hohen Informationsgehalt ausgestattet.

Die Menge an Informationen in den für das Modelltraining verwendeten Variablen ist wichtig, aber nicht die einzige Voraussetzung für ein effektives Modelltraining. Daher kann die Messung des Informationsgehalts dazu verwendet werden, Indikatoren zu überprüfen, die ansonsten während des Ausbildungsprozesses blind verwendet würden.  Hier kommt das Konzept der Entropie zum Tragen.


Entropie

Über die Entropy wurde bereits mehrfach, auch auf MQL5.com, geschrieben. Ich entschuldige mich bei den Lesern, dass sie eine weitere Definition über sich ergehen lassen müssen, aber ich verspreche, dass dies für das Verständnis der Anwendung des Konzepts wesentlich ist. In früheren Artikeln wurden die Geschichte und die Herleitung der Entropieberechnung erläutert, sodass wir der Kürze halber gleich mit der Gleichung beginnen werden.

                                                        

Entropie-Gleichung

H(X) ist die Entropie von X. X ist eine diskrete Variable, die eine beliebige Variable, beispielsweise eine Nachricht, darstellt. Der Inhalt der Nachricht kann nur eine endliche Anzahl von Werten annehmen. Dies wird in der Gleichung als kleines x dargestellt. Kleine x sind die beobachteten Werte der Meldungen, sodass, wenn alle möglichen Werte von x in einer Menge N aufgezählt würden.

Nehmen wir zum Beispiel einen fairen Würfel. Die Würfel, wenn sie gewürfelt werden, können als Informationen wahrgenommen werden, die den Ausgang eines Spiels bestimmen. Der Würfel hat 6 individuelle Seiten, die von 1 bis 6 nummeriert sind. Die Wahrscheinlichkeit, dass eine der Zahlen nach oben zeigt, beträgt 1/6.

In diesem Beispiel wäre das große X der Würfel und das kleine x könnte eine der Zahlen sein, die auf die Seiten des Würfels gemalt sind. Diese werden alle in die Menge N ={ 1,2,3,4,5,6} eingeordnet. Nach dieser Formel beträgt die Entropie dieses Würfels 0,7781.

                                                         

Fairer Würfel


Betrachten wir nun einen anderen Würfel, der einen Fabrikationsfehler hat. Es hat 2 Seiten mit der gleichen Nummer. Für diesen defekten Würfel ist die Menge N der möglichen Werte {1,1,3,4,5,6}. Wenn wir die Formel erneut anwenden, erhalten wir einen durchschnittlichen Entropiewert von 0,6778.

                                                 

Defekter Würfel

Vergleicht man die Werte, so stellt man fest, dass der Informationsgehalt gesunken ist. Analysiert man beide Würfel, so ergibt die Entropiegleichung ihren größtmöglichen Wert, wenn die Wahrscheinlichkeiten für die Beobachtung jedes möglichen Wertes gleich sind. Daher erreicht die Entropie ihren maximalen Mittelwert, wenn die Wahrscheinlichkeiten aller möglichen Werte gleich sind.

Wenn wir die defekten Würfel für einen Indikator verwerfen, der traditionelle reelle Zahlen als Ausgabe produziert. Dann wird X zum Indikator und die kleinen x sind die Werte des Wertebereichs, die der Indikator annehmen kann. Bevor wir fortfahren, haben wir ein Problem, denn die Entropiegleichung befasst sich ausschließlich mit diskreten Variablen. Eine Umformung der Gleichung, um mit kontinuierlichen Variablen zu arbeiten, ist möglich, aber die Anwendung wäre schwierig, sodass es einfacher ist, im Bereich der diskreten Zahlen zu bleiben.


Berechnung der Entropie eines Indikators

Um die Entropiegleichung auf kontinuierliche Variablen anzuwenden, müssen wir die Werte des Indikators diskretisieren, indem wir den Wertebereich in gleich große Intervalle unterteilen und dann die Anzahl der Werte zählen, die in jedes Intervall fallen. Bei dieser Methode wird die ursprüngliche Menge, die den maximalen Bereich aller Werte des Indikators aufzählt, durch Teilmengen ersetzt, die jeweils die ausgewählten Intervalle darstellen.

Bei kontinuierlichen Variablen ist die Variation der Wahrscheinlichkeiten der möglichen Werte, die die Variable annehmen kann, von Bedeutung, da sie eine wichtige Facette bei der Anwendung der Entropie auf Indikatoren darstellt.

Um auf das erste Beispiel des Würfels zurückzukommen. Wenn wir die endgültigen Entropiewerte jedes einzelnen durch log(N) für das jeweilige n dividieren. Der erste Würfel ergibt 1, während der fehlerhafte Würfel 0,87 ergibt. Dividiert man den Entropiewert durch den Logarithmus der Anzahl der Werte, die die Variable annehmen kann, erhält man ein Maß, das sich auf die theoretische maximale Entropie der Variablen bezieht. Das wird auch als proportionale oder relative Entropie bezeichnet.

Dieser Wert ist für die Indikatorbewertung von Nutzen, da er angibt, wie nahe die Entropie des Indikators an seinem theoretischen Höchstwert liegt. Je näher er an einem Maximalwert liegt, desto besser, und alles, was am anderen Ende liegt, kann auf einen Indikator hindeuten, der für die Verwendung in maschinellen Lernverfahren ungeeignet ist. 

                                  

Relative Entropie-Gleichung

Die endgültige Gleichung, die oben gezeigt wird, und der Code sind unten als mql5-Skript implementiert, das als Anhang am Ende des Artikels zum Download zur Verfügung steht. Mit diesem Skript können wir die meisten Indikatoren analysieren.


Ein Skript zur Berechnung der Entropie eines Indikators

Das Skript wird mit den folgenden vom Nutzer einstellbaren Parametern aufgerufen:

  • TimeFrame - ausgewählter Zeitrahmen für die Analyse der Indikatorwerte.
  • IndicatorType - hier kann der Nutzer einen der integrierten Indikatoren für die Analyse auswählen. Um einen nutzerdefinierten Indikator festzulegen, wählen Sie die Option Custom Indikator und geben Sie den Namen des Indikators in den nächsten Parameterwert ein.
  • CustomIndicatorName - wenn die Option CustomIndicator für den vorherigen Parameter ausgewählt wurde, muss der Nutzer hier den richtigen Namen des Indikators eingeben.
  • UseDefaults - wenn diese Option auf true gesetzt ist, werden die im Indikator fest kodierten Standard-Nutzereingaben verwendet.
  • IndicatorParameterTypes - dies ist eine durch Komma getrennte Zeichenkette, die die Datentypen des Indikators in der richtigen Reihenfolge auflistet, ein Beispiel für eine mögliche Eingabe: Angenommen, der zu analysierende Indikator akzeptiert 4 Eingaben des Typs double, integer, integer bzw. string, dann muss der Nutzer einfach „double, integer, integer, string“ eingeben; die Kurzform „d, i, i, s“ wird ebenfalls unterstützt, wobei d= double, i=integer und s=string. Enum-Werte werden auf den Typ Integer abgebildet.
  • IndicatorParameterValues - wie bei der vorherigen Eingabe handelt es sich auch hier um eine durch Kommata getrennte Liste von Werten, z. B. „0.5,4,5,string_value“, wie im vorherigen Beispiel. Liegt ein Fehler in der Formatierung der Parameter für IndicatorParameterValues oder IndicatorParameterTypes vor, werden die Standardwerte des Indikators für nicht auflösbare oder fehlende Werte verwendet.
    Überprüfen Sie die Registerkarte Experten auf Fehlermeldungen. Beachten Sie, dass der Name des Indikators hier nicht angegeben werden muss. Wenn es sich um einen nutzerdefinierten Indikator handelt, muss dieser durch CustomIndicatorName angegeben werden.
  • IndicatorBuffer - der Nutzer kann festlegen, welcher der Indikatorpuffer analysiert werden soll.
  • HistoryStart - das Startdatum der Stichprobe der Kurshistorie.
  • HistorySize - dies ist die Anzahl der zu analysierenden Balken relativ zu HistoryStart.
  • Intervals - dieser Parameter wird verwendet, um die Anzahl der Intervalle anzugeben, die für den Deskretisierungsprozess erstellt werden. Der Autor von TTMTS gibt 20 Intervalle für einen Stichprobenumfang von mehreren Tausend an, wobei 2 als harter Mindestwert festgelegt wurde.  Ich habe hier einen eigenen Ansatz für einen geeigneten Wert entwickelt, indem ich die Möglichkeit eingebaut habe, die Anzahl der Intervalle in Abhängigkeit vom Stichprobenumfang zu variieren, und zwar 51 für jeweils 1000 Stichproben. Diese Option ist verfügbar, wenn ein Nutzer einen Wert kleiner als 2 eingibt. Wenn Sie also Intervall auf eine beliebige Zahl kleiner als 2 einstellen, ändert sich die Anzahl der verwendeten Intervalle je nach der Anzahl der analysierten Takte.

//--- input parameters
input ENUM_TIMEFRAMES Timeframe=0;
input ENUM_INDICATOR  IndicatorType=IND_BEARS;
input string   CustomIndicatorName="";
input bool     UseDefaults=true;
input string   IndicatorParameterTypes="";
input string   IndicatorParameterValues="";
input int      IndicatorBuffer=0;
input datetime HistoryStart=D'2023.02.01 04:00';
input int HistorySize=50000;
input int      Intervals=0;

int handle=INVALID_HANDLE;
double buffer[];
MqlParam b_params[];
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   if(!processParameters(UseDefaults,b_params))
      return;

   int y=10;
   while(handle==INVALID_HANDLE && y>=0)
     {
      y--;
      handle=IndicatorCreate(Symbol(),Timeframe,IndicatorType,ArraySize(b_params),b_params);
     }
//---
   if(handle==INVALID_HANDLE)
     {
      Print("Invalid indicator handle, error code: ",GetLastError());
      return;
     }

   ResetLastError();
//---
   if(CopyBuffer(handle,IndicatorBuffer,HistoryStart,HistorySize,buffer)<0)
     {
      Print("error copying to buffer, returned error is ",GetLastError());
      IndicatorRelease(handle);
      return;
     }
//---
   Print("Entropy of ",(IndicatorType==IND_CUSTOM)?CustomIndicatorName:EnumToString(IndicatorType)," is ",relativeEntroy(Intervals,buffer));
//---
   IndicatorRelease(handle);
  }
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool processParameters(bool use_defaults,MqlParam &params[])
  {

   bool custom=(IndicatorType==IND_CUSTOM);

   string ind_v[],ind_t[];

   int types,values;

   if(use_defaults)
      types=values=0;
   else
     {
      types=StringSplit(IndicatorParameterTypes,StringGetCharacter(",",0),ind_t);
      values=StringSplit(IndicatorParameterValues,StringGetCharacter(",",0),ind_v);
     }

   int p_size=MathMin(types,values);

   int values_to_input=ArrayResize(params,(custom)?p_size+1:p_size);

   if(custom)
     {
      params[0].type=TYPE_STRING;
      params[0].string_value=CustomIndicatorName;
     }

//if(!p_size)
//  return true;

   if(use_defaults)
      return true;

   int i,z;
   int max=(custom)?values_to_input-1:values_to_input;

   for(i=0,z=(custom)?i+1:i; i<max; i++,z++)
     {
      if(ind_t[i]=="" || ind_v[i]=="")
        {
         Print("Warning: Encountered empty string value, avoid adding comma at end of string parameters");
         break;
        }

      params[z].type=EnumType(ind_t[i]);

      switch(params[z].type)
        {
         case TYPE_INT:
            params[z].integer_value=StringToInteger(ind_v[i]);
            break;
         case TYPE_DOUBLE:
            params[z].double_value=StringToDouble(ind_v[i]);
            break;
         case TYPE_STRING:
            params[z].string_value=ind_v[i];
            break;
         default:
            Print("Error: Unknown specified parameter type");
            break;
        }
     }

   return true;

  }


//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
ENUM_DATATYPE EnumType(string type)
  {
   StringToLower(type);
   const ushort firstletter=StringGetCharacter(type,0);

   switch(firstletter)
     {
      case 105:
         return TYPE_INT;
      case 100:
         return TYPE_DOUBLE;
      case 115:
         return TYPE_STRING;
      default:
         Print("Error: could not parse string to match data type");
         return ENUM_DATATYPE(-1);
     }

   return ENUM_DATATYPE(-1);
  }
//+------------------------------------------------------------------+

Noch ein Hinweis zu dem für Intervalle gewählten Wert: Wenn Sie die Anzahl der in der Berechnung verwendeten Intervalle ändern, ändert sich der endgültige Entropiewert. Bei der Durchführung von Analysen wäre es ratsam, eine gewisse Konsistenz zu wahren, um die Auswirkungen des verwendeten unabhängigen Inputs zu minimieren. Im Skript ist die Berechnung der relativen Entropie in einer Funktion gekapselt, die in der Datei Entropy.mqh definiert ist.


Das Skript gibt einfach den resultierenden Entropiewert in der Registerkarte „Experten“ aus. Wenn Sie das Skript für verschiedene integrierte und nutzerdefinierte Indikatoren ausführen, erhalten Sie die unten aufgeführten Ergebnisse. Es ist interessant festzustellen, dass William's Percent Range eine relative Entropie nahe der Perfektion aufweist. Vergleichen Sie dies mit dem Market Facilitation Index, der ein enttäuschendes Ergebnis zeigt.

Ergebnisse

Mit diesen Ergebnissen können wir weitere Schritte unternehmen, um die Daten so zu verarbeiten, dass sie für maschinelle Lernalgorithmen geeignet sind. Dazu ist eine strenge Analyse der statistischen Eigenschaften des Indikators erforderlich. Durch die Untersuchung der Verteilung der Indikatorwerte lassen sich Probleme mit Schieflage und Ausreißern erkennen. All dies kann die Modellbildung beeinträchtigen.

Als Beispiel untersuchen wir einige statistische Eigenschaften von zwei oben analysierten Indikatoren.

William‘s Percent Range

Die Verteilung der prozentualen Spanne von Williams zeigt, dass fast alle Werte über die gesamte Spanne verteilt sind; abgesehen davon, dass die Verteilung multimodal ist, ist sie ziemlich gleichmäßig. Eine solche Verteilung ist ideal und spiegelt sich im Entropiewert wider.

Market Facilitation Index
Dies steht im Gegensatz zur Verteilung des Market Facilitation Index, der einen langen „Rattenschwanz“ von Werten aufweist. Ein solcher Indikator wäre für die meisten Lernalgorithmen problematisch und erfordert eine Transformation der Werte. Die Umwandlung der Werte sollte zu einer Verbesserung der relativen Entropie des Indikators führen.


Verbesserung des Informationsgehalts eines Indikators

Es sollte darauf hingewiesen werden, dass Änderungen, die die Entropie des Indikators erhöhen, nicht als eine Möglichkeit zur Verbesserung der Genauigkeit der vom Indikator gelieferten Signale angesehen werden sollten. Durch die Erhöhung der Entropie wird ein nutzloser Indikator nicht zum heiligen Gral. Bei der Verbesserung der Entropie geht es um die Verarbeitung der Indikatordaten für eine effektive Nutzung in Vorhersagemodellen.

Diese Option sollte in Betracht gezogen werden, wenn der Entropiewert hoffnungslos schlecht ist, d. h. weit unter 0,5 und näher an Null liegt. Obere Schwellenwerte sind rein willkürlich. Es ist Sache des Entwicklers, einen akzeptierten Mindestwert zu wählen. Das Ziel ist es, eine möglichst gleichmäßige Verteilung der Indikatorwerte zu erreichen. Die Entscheidung, eine Transformation anzuwenden, sollte auf einer Analyse beruhen, die an einer umfangreichen und repräsentativen Stichprobe von Indikatorwerten durchgeführt wurde.

Die angewandte Transformation sollte das eigentliche Verhalten des Indikators nicht verändern. Der transformierte Indikator sollte eine ähnliche Form wie der Rohindikator haben, d. h. die Lage der Tiefpunkte und Spitzenwerte sollte in beiden Reihen ähnlich sein. Wenn dies nicht der Fall ist, besteht die Gefahr, dass potenziell nützliche Informationen verloren gehen.

Es gibt zahlreiche Transformationsmethoden, die auf verschiedene Aspekte der Unzulänglichkeiten von Testdaten abzielen. Wir werden nur einige einfache Transformationen betrachten, die darauf abzielen, offensichtliche Mängel zu beheben, die durch grundlegende statistische Analysen aufgedeckt werden. Die Vorverarbeitung ist ein weites Feld des maschinellen Lernens. Jeder, der die Anwendung von Methoden des maschinellen Lernens beherrschen möchte, sollte sich mehr Wissen auf diesem Gebiet aneignen.

Um die Auswirkungen einiger Transformationen zu veranschaulichen, stellen wir ein Skript vor, das die Möglichkeit bietet, verschiedene Transformationen anzuwenden und auch die Verteilung der analysierten Daten anzuzeigen. Das Skript implementiert 6 Beispiele für Transformationsfunktionen:

  • Die Transformation mit der Quadratwurzel ist geeignet, um gelegentlich auftretende Indikatorwerte, die erheblich von der Mehrheit abweichen, zu unterdrücken.
  • Die Transformation mit der Kubikwurzel ist eine weitere Funktion zur Quadratur, die am besten für Indikatoren mit negativen Werten geeignet ist.
  • Die Transformation mit der Log-Funktion komprimiert die Werte hingegen in größerem Umfang als die zuvor genannten komprimierenden Transformationen.
  • Die hyperbolischen Tangens und die logistischen Transformationen sollten auf Datenwerte einer geeigneten Skala angewendet werden, um Probleme mit der Erzeugung ungültiger Zahlen (Nan-Fehler) zu vermeiden.
  • Die extreme Transformation führt zu extremer Gleichförmigkeit in einem Datensatz. Sie sollte nur auf Indikatoren angewandt werden, die überwiegend eindeutige Werte mit sehr wenigen ähnlichen Zahlen liefern.

    Ein Skript zum Vergleich transformierter Indikatorwerte

    Im Vergleich zum früheren Skript enthält es die gleichen Nutzereingaben zur Angabe des zu analysierenden Indikators. Die neuen Eingaben werden im Folgenden beschrieben:

    • DisplayTime - das Skript zeigt eine Grafik der Verteilung des Indikators an. DisplayTime ist ein ganzzahliger Wert in Sekunden, der die Zeit angibt, die die Grafik sichtbar ist, bevor sie entfernt wird.
    • ApplyTransfrom - ist ein boolescher Wert, der den Modus für das Skript festlegt. Bei false zeichnet das Skript die Verteilung und zeigt grundlegende Statistiken der Stichprobe zusammen mit der relativen Entropie an. Wenn true gesetzt ist, wird eine Transformation auf die rohen Indikatorwerte angewendet und die relativen Entropiewerte vor und nach der Transformation angezeigt. Die Verteilung der veränderten Proben kann auch als Kurve in Rot eingezeichnet werden.
    • Select_transform - ist eine Aufzählung mit den zuvor beschriebenen Transformationen, die angewendet werden können, um die Entropie des Indikators zu erhöhen.
    //+------------------------------------------------------------------+
    //|                                            IndicatorAnalysis.mq5 |
    //|                        Copyright 2023, MetaQuotes Software Corp. |
    //|                                             https://www.mql5.com |
    //+------------------------------------------------------------------+
    #property copyright "Copyright 2023, MetaQuotes Software Corp."
    #property link      "https://www.mql5.com"
    #property version   "1.00"
    #property script_show_inputs
    #include<Entropy.mqh>
    //--- input parameters
    input ENUM_TIMEFRAMES Timeframe=0;
    input ENUM_INDICATOR  IndicatorType=IND_CUSTOM;
    input string   CustomIndicatorName="";
    input bool     UseDefaults=false;
    input string   IndicatorParameterTypes="";
    input string   IndicatorParameterValues="";
    input int      IndicatorBuffer=0;
    input datetime HistoryStart=D'2023.02.01 04:00';;
    input int HistorySize=50000;
    input int DisplayTime=30;//secs to keep graphic visible
    input bool ApplyTransform=true;
    input ENUM_TRANSFORM Select_transform=TRANSFORM_LOG;//Select function transform
    
    int handle=INVALID_HANDLE;
    double buffer[];
    MqlParam b_params[];
    //+------------------------------------------------------------------+
    //| Script program start function                                    |
    //+------------------------------------------------------------------+
    void OnStart()
      {
    //---
       if(!processParameters(UseDefaults,b_params))
          return;
    
       int y=10;
       while(handle==INVALID_HANDLE && y>=0)
         {
          y--;
          handle=IndicatorCreate(_Symbol,Timeframe,IndicatorType,ArraySize(b_params),b_params);
         }
    //---
       if(handle==INVALID_HANDLE)
         {
          Print("Invalid indicator handle, error code: ",GetLastError());
          return;
         }
    
       ResetLastError();
    //---
       if(CopyBuffer(handle,IndicatorBuffer,HistoryStart,HistorySize,buffer)<0)
         {
          Print("error copying to buffer, returned error is ",GetLastError());
          IndicatorRelease(handle);
          return;
         }
    //---
       DrawIndicatorDistribution(DisplayTime,ApplyTransform,Select_transform,IndicatorType==IND_CUSTOM?CustomIndicatorName:EnumToString(IndicatorType),buffer);
    //---
       IndicatorRelease(handle);
      }
    //+------------------------------------------------------------------+
    bool processParameters(bool use_defaults,MqlParam &params[])
      {
    
       bool custom=(IndicatorType==IND_CUSTOM);
    
       string ind_v[],ind_t[];
    
       int types,values;
    
       if(use_defaults)
          types=values=0;
       else
         {
          types=StringSplit(IndicatorParameterTypes,StringGetCharacter(",",0),ind_t);
          values=StringSplit(IndicatorParameterValues,StringGetCharacter(",",0),ind_v);
         }
    
       int p_size=MathMin(types,values);
    
       int values_to_input=ArrayResize(params,(custom)?p_size+1:p_size);
    
       if(custom)
         {
          params[0].type=TYPE_STRING;
          params[0].string_value=CustomIndicatorName;
         }
    
       if(use_defaults)
          return true;
    
       int i,z;
       int max=(custom)?values_to_input-1:values_to_input;
    
       for(i=0,z=(custom)?i+1:i; i<max; i++,z++)
         {
          if(ind_t[i]=="" || ind_v[i]=="")
            {
             Print("Warning: Encountered empty string value, avoid adding comma at end of string parameters");
             break;
            }
    
          params[z].type=EnumType(ind_t[i]);
    
          switch(params[z].type)
            {
             case TYPE_INT:
                params[z].integer_value=StringToInteger(ind_v[i]);
                break;
             case TYPE_DOUBLE:
                params[z].double_value=StringToDouble(ind_v[i]);
                break;
             case TYPE_STRING:
                params[z].string_value=ind_v[i];
                break;
             default:
                Print("Error: Unknown specified parameter type");
                break;
            }
         }
    
       return true;
    
      }
    
    
    //+------------------------------------------------------------------+
    //|                                                                  |
    //+------------------------------------------------------------------+
    ENUM_DATATYPE EnumType(string type)
      {
       StringToLower(type);
       const ushort firstletter=StringGetCharacter(type,0);
    
       switch(firstletter)
         {
          case 105:
             return TYPE_INT;
          case 100:
             return TYPE_DOUBLE;
          case 115:
             return TYPE_STRING;
          default:
             Print("Error: could not parse string to match data type");
             return ENUM_DATATYPE(-1);
         }
    
       return ENUM_DATATYPE(-1);
      }
    //+------------------------------------------------------------------+
    


    Wir fahren mit den Beispielen fort und vergleichen die Anwendung von Quadratwurzel- und Kubikwurzeltransformationen.

    MFI-Quadratwurzeltransformation


    MFI Kubikwurzeltransformation


    Beide bieten eine Verbesserung der Entropie, aber die restlichen Werte auf der rechten Seite könnten problematisch sein, da die beiden bisher angewandten Transformationen nicht in der Lage waren, ihn effektiv zu bewältigen.

    MFI logarithmische Transformation


    Die Log-Transformation ergibt einen noch besseren Entropiewert. Dennoch sind die Reste ziemlich signifikant. Als letzten Ausweg können wir die Extremtransformation anwenden.


    Schlussfolgerung

    Wir haben das Konzept der Entropie untersucht, um die Notwendigkeit einer Transformation der Indikatorwerte vor der Verwendung beim Training des Vorhersagemodells zu bewerten.

    Das Konzept wurde in zwei Skripten umgesetzt. EntropyIndicatorAnalyis gibt die relative Entropie einer Probe auf der Registerkarte Experten aus. Das andere Skript IndicatorAnalysis geht noch einen Schritt weiter, indem es die Verteilung der rohen und transformierten Indikatorwerte zeichnet und die relativen Entropiewerte davor und danach anzeigt.

    Die Tools können zwar nützlich sein, sind aber nicht auf alle Arten von Indikatoren anwendbar: Pfeilbasierte Indikatoren, die leere Werte enthalten, sind für die hier beschriebenen Skripte nicht geeignet.  In solchen Fällen wären andere Kodierungstechniken erforderlich.

    Das Thema Datentransformation ist nur eine Teilmenge der möglichen Vorverarbeitungsschritte, die bei der Erstellung jeglicher Art von Vorhersagemodellen berücksichtigt werden sollten. Der Einsatz solcher Techniken wird dazu beitragen, wirklich einzigartige Beziehungen zu finden, die den nötigen Vorsprung bieten, um die Märkte zu schlagen.

    Dateiname
     Beschreibung
    Mql5/Include/Entropie.mqh
    Include-Datei, die verschiedene Definitionen für Funktionen zur Berechnung der Entropie und für Hilfsfunktionen enthält, die von den beigefügten Skripten verwendet werden.
    Mql5/Skripte/IndikatorAnalyse.mq5
    ein Skript, das eine Grafik anzeigt, die die Verteilung der Indikatorwerte zusammen mit ihrer Entropie darstellt.
     Mql5/Scripts/EntropyIndicatorAnalysis  ein Skript, das zur Berechnung der Entropie eines Indikators verwendet werden kann.


    Übersetzt aus dem Englischen von MetaQuotes Ltd.
    Originalartikel: https://www.mql5.com/en/articles/12129

    Beigefügte Dateien |
    Mql5.zip (5.26 KB)
    Letzte Kommentare | Zur Diskussion im Händlerforum (10)
    niouininon
    niouininon | 18 Juli 2025 in 09:21
    Aleksey Vyazmikin Wertebereich in gleich große Intervalle ein und zählen dann die Anzahl der Werte, die in jedem Intervall enthalten sind. Mit dieser Methode wird die ursprüngliche Menge, die den maximalen Bereich aller Indikatorwerte auflistet, durch Teilmengen ersetzt, die jedes der ausgewählten Intervalle repräsentieren.

    ...

    Intervalle - die Anzahl der zu beprobenden Intervalle. Der Autor von TTMTS gibt 20 Intervalle für eine Stichprobe von mehreren tausend Personen an, wobei 2 ein absoluter Minimalwert ist. Ich habe meinen eigenen Ansatz für einen angemessenen Wert hinzugefügt, indem ich die Möglichkeit implementiert habe, die Anzahl der Intervalle in Bezug auf die Stichprobengröße zu variieren, insbesondere 51 für 1000 Stichproben. Diese Option ist verfügbar, wenn der Benutzer einen Wert kleiner als 2 eingibt. Wenn Sie also Intervall auf eine Zahl kleiner als 2 setzen, wird die Anzahl der verwendeten Intervalle in Abhängigkeit von der Anzahl der analysierten Balken variieren.

    "

    Frage: Handelt es sich um das Gleiche? Wenn ja, warum hängt die Anzahl der Separatoren im Wertebereich des Indikators von der Anzahl der Balken ab? Welche Logik steckt dahinter? Bisher kann ich davon ausgehen, dass dies nur bei Indikatoren sinnvoll ist, die eine akkumulierende Komponente haben.

    Wenn nicht, worauf bezieht sich dann die Anzahl der Teiler des Bereichs?


    Dem Artikel fehlt eine Tabelle, die den Vorteil der Transformation der Indikatorwerte klar aufzeigt.

    Um die Entropie einer kontinuierlichen Variable zu schätzen, schneidet man ihren Wertebereich in gleiche Intervalle und zählt die Beobachtungen in jedem Intervall. Das Skript lässt Sie diese Anzahl von Intervallen(Intervals) wählen. Wenn Sie < 2 eingeben (oder den Standardwert belassen), löst das Skript seine eigene Heuristik aus: 51 Intervalle pro 1000 Beobachtungen, d. h. eine Anzahl, die proportional zur Stichprobengröße ist. Wenn Sie einen Wert > 2 eingeben, verwendet es ihn so, wie er ist. Es handelt sich also nicht um zwei konkurrierende Methoden. Die eine beschreibt das Konzept, die andere erklärt, wie der Code den Parameter auswählt, wenn man ihn nicht selbst festlegt.


    Wenn man zu wenige Intervalle hat, werden die Werte künstlich aneinandergeklebt. Die Entropie wird unterschätzt (Bias). Wenn man zu viele Intervalle für eine kleine Stichprobe hat, gibt es viele leere Behälter oder nur eine Beobachtung. Die Entropie ist stark verrauscht (Varianz). Es gibt mehrere automatische Regeln für Histogramme: Sturges, Quadratwurzel, Freedman-Diaconis, Scott, usw.). Sie haben alle die gleiche Idee: die Auflösung zu erhöhen, wenn man mehr Daten hat, weil man dann feinere Wahrscheinlichkeiten schätzen kann, ohne die Varianz zu sprengen.


    Auf 1 000 Balken kommen 51 Intervalle => 20 Punkte pro Wanne, wenn die Verteilung gleichmäßig wäre. Dieses Verhältnis (zwischen 15 und 30 Obs / Klasse) ist ein klassischer Kompromiss, den der Autor aus der Literatur übernommen hat. Er hält also die durchschnittliche Anzahl der Beobachtungen pro Klasse in etwa konstant. Dies hat nichts damit zu tun, ob ein Indikator akkumulierend ist oder nicht. Die Logik ist rein statistisch. Man passt die Feinheit des Rasters an die Menge der verfügbaren Informationen an.


    Je höher die Anzahl der vertikalen Balken im Histogramm :
    • desto deutlicher wird die Feinverteilung des Indikators sichtbar,

    • desto mehr Details (Spitzen / Täler) kann die Entropieberechnung einfangen,

    • aber desto mehr Daten werden benötigt, um diese Häufigkeiten stabil zu halten.


    Es stimmt, dass der Artikel davon profitiert hätte, wenn er beispielsweise die Entropie desselben Indikators vor und nach den Transformationen gezeigt hätte. Aber die Demonstration ist immer noch leicht selbst zu machen. Markieren Sie einfach ApplyTransform=true im Skript und lesen Sie die doppelte Ausgabe: before / after. Der Code hat diesen Teil absichtlich interaktiv gelassen, damit jeder seine eigenen Assets und Horizonte ausprobieren kann.

    Aleksey Vyazmikin
    Aleksey Vyazmikin | 18 Juli 2025 in 09:48
    niouininon #:
    Je mehr vertikale Balken im Histogramm:
    • Je mehr vertikale Balken das Histogramm enthält, desto deutlicher wird die Feinverteilung des Indexes,

    • desto mehr Details (Spitzen und Täler) kann die Entropieberechnung erfassen,

    • aber desto mehr Daten werden benötigt, um diese Häufigkeiten zu stabilisieren.

    So wie ich es verstehe, hat die Visualisierung von Indikatorwerten in einer Stichprobe durch ein Histogramm nichts mit den Datenumwandlungsmethoden des Autors zu tun. Liege ich da richtig?

    Mich interessiert eher die Frage nach dem Trainingseffekt dieser Transformationen. Bei neuronalen Netzen kann ich das annehmen, aber nicht bei Baummethoden.

    niouininon
    niouininon | 18 Juli 2025 in 13:31
    Aleksey Vyazmikin #:

    Wenn ich Sie richtig verstehe, hat die Visualisierung der Indikatorwerte in einer Stichprobe mithilfe eines Histogramms nichts mit den Datenumwandlungsmethoden des Autors zu tun. Habe ich Recht?

    Mich interessiert vielmehr die Frage nach dem Spillover-Effekt dieser Transformationen. Bei neuronalen Netzen kann ich das vermuten, bei baumartigen Methoden jedoch nicht.

    Das Histogramm, das das Skript zeichnet, ist lediglich ein visuelles Diagnoseinstrument. Es zeigt, wie sich die Werte eines Indikators vor oder nach der Transformation über die Stichprobe verteilen. Die Funktionen sqrt, log, tanh usw. wirken auf die Daten ein. Das Histogramm zeigt lediglich das Ergebnis an. Die beiden Schritte sind also unabhängig voneinander. Zuerst wird die Reihe transformiert (oder nicht), dann zeichnet man ihr Histogramm, um zu sehen, ob sich die Entropie verändert hat.

    Einen Indikator umzuwandeln, der eher monoton geworden ist (log, sqrt), ändert oft nichts am Ergebnis. Die Reihenfolge bleibt gleich, auch wenn sich nur die Schwellenwerte verschieben. Dagegen ändern nicht-monotone Transformationen (tanh, der sättigt) die Reihenfolge einiger Punkte. Das bedeutet, dass bestimmte Transformationen den Boden für die Schaffung nichtlinearer Wechselwirkungen besser vorbereiten.

    Aleksey Vyazmikin
    Aleksey Vyazmikin | 18 Juli 2025 in 14:11
    niouininon #:

    Das vom Skript erstellte Histogramm ist lediglich ein visuelles Diagnoseinstrument. Es zeigt, wie die Indikatorwerte in der Stichprobe vor oder nach der Transformation verteilt sind. Die Funktionen sqrt, log, tanh, etc. beeinflussen die Daten. Das Histogramm zeigt lediglich das Ergebnis an. Die beiden Schritte sind also unabhängig voneinander. Zuerst wird die Reihe transformiert (oder nicht), dann wird ihr Histogramm aufgezeichnet, um zu sehen, ob sich die Entropie verändert hat.

    Ok, jetzt habe ich den Punkt verstanden. Ich hatte ursprünglich an etwas anderes gedacht.

    niouininon #:

    Die Umwandlung eines Exponenten, der ziemlich monoton geworden ist (log, sqrt), ändert das Ergebnis oft nicht. Andererseits ändern nicht-monotone Transformationen (tanh, saturiert) die Reihenfolge bestimmter Punkte. Das bedeutet, dass bestimmte Transformationen besser geeignet sind, nichtlineare Wechselwirkungen zu erzeugen.

    Wie ändert sich dadurch die Reihenfolge der Punkte? Können Sie ein Beispiel für eine solche Transformation nennen? Bisher habe ich die Aussage so verstanden, dass es ABC-Punkte mit Eigenwerten in aufsteigender Reihenfolge gab, und nach der Transformation wurde die Reihenfolge in aufsteigender Reihenfolge alternativ zu BAC.

    niouininon
    niouininon | 18 Juli 2025 in 21:12
    Aleksey Vyazmikin #:

    Okay, ich habe den Gedanken jetzt verstanden. Ursprünglich hatte ich etwas anderes im Sinn.

    Wie ändert sich dadurch die Reihenfolge der Punkte? Können Sie ein Beispiel für eine solche Transformation geben? Bisher habe ich verstanden, dass es Punkte ABC mit Eigenwerten in aufsteigender Reihenfolge gibt, und dass nach der Transformation die aufsteigende Reihenfolge alternativ zu BAC wurde.

    Die Funktionen des Skripts (Wurzel, log, tanh usw.) sind alle monoton steigend. Sie behalten alle die Reihenfolge der Punkte bei. Mein vorheriger Satz war zweideutig. Die Reihenfolge wechselt nur dann von ABC nach BAC, wenn eine nicht-monotone Transformation verwendet wird. Wenn ich mich nicht irre, ist zum Beispiel die Funktion f(x)=∣x-50∣ nicht monoton, weil sie die Achse um x= 50 faltet. Die Reihenfolge wird also zu BAC. In seiner Einleitung weist der Autor des Artikels auf das Buch"Testing and Tuning Market Trading Systems (TTMTS) von Timothy Masters" hin. Was mich betrifft, so plane ich, mir das Buch zu besorgen, denn wie Sie habe ich noch einige Fragen. Außerdem kenne ich mich weder mit Lernmodellen noch mit neuronalen Netzen gut aus. Anscheinend ist es in Online-Shops recht leicht zu finden. Der Artikel, so interessant er auch sein mag, ist wahrscheinlich unvollständig und/oder in jedem Fall recht synthetisch.

    Testen und Optimieren von Strategien für binäre Optionen in MetaTrader 5 Testen und Optimieren von Strategien für binäre Optionen in MetaTrader 5
    In diesem Artikel werde ich Strategien für binäre Optionen in MetaTrader 5 überprüfen und optimieren.
    Wie man einen Expert Advisor auswählt: Zwanzig starke Kriterien für die Ablehnung eines Handelsroboter Wie man einen Expert Advisor auswählt: Zwanzig starke Kriterien für die Ablehnung eines Handelsroboter
    Dieser Artikel versucht, die Frage zu beantworten: Wie kann man die richtigen Expert Advisor auswählen? Welche sind die besten für unser Portfolio, und wie können wir die große Liste der auf dem Markt erhältlichen Handelsroboter filtern? In diesem Artikel werden zwanzig klare und starke Kriterien für die Ablehnung eines Expert Advisors vorgestellt. Jedes Kriterium wird vorgestellt und gut erklärt, um Ihnen zu helfen, eine nachhaltigere Entscheidung zu treffen und eine profitablere Expert Advisor-Sammlung für Ihre Gewinne aufzubauen.
    MQL5 Kochbuch — Datenbank für makroökonomische Ereignisse MQL5 Kochbuch — Datenbank für makroökonomische Ereignisse
    Der Artikel behandelt die Möglichkeiten des Umgangs mit Datenbanken, die auf der SQLite-Engine basieren. Die Klasse CDatabase wurde aus Gründen der Bequemlichkeit und der effizienten Nutzung von OOP-Prinzipien entwickelt. Anschließend ist sie an der Erstellung und Verwaltung der Datenbank für makroökonomische Ereignisse beteiligt. Der Artikel enthält Beispiele für die Verwendung mehrerer Methoden der CDatabase-Klasse.
    Erstellen eines EA, der automatisch funktioniert (Teil 07): Kontoarten (II) Erstellen eines EA, der automatisch funktioniert (Teil 07): Kontoarten (II)
    Heute werden wir sehen, wie man einen Expert Advisor erstellt, der einfach und sicher im automatischen Modus arbeitet. Der Händler sollte sich immer darüber im Klaren sein, was der automatische EA tut, sodass er ihn im Falle einer „Entgleisung“ so schnell wie möglich aus dem Chart entfernen und die Kontrolle über die Situation übernehmen kann.