Messmethoden zur Preisgeschwindigkeit

Alexander Fedosov | 17 Juli, 2019

Inhalt

Einführung

Es gibt mehrere, unterschiedliche Ansätze zur Marktanalyse und -forschung. Die wichtigsten sind technische und fundamentale Analysen. In der technischen Analyse sammeln, verarbeiten und analysieren Händler numerische Daten und marktrelevante Parameter, einschließlich Preise, Volumina usw. In der Fundamentalanalyse analysieren Händler Ereignisse und Nachrichten, die die Märkte direkt oder indirekt betreffen. Bei der Analyse von Fundamentaldaten geht es vor allem um die Interpretation eines Ereignisses hinsichtlich seiner Auswirkungen auf den Markt. Eine solche Interpretation kann durch die Meinungen und Erwartungen des Händlers beeinflusst werden. Im Gegensatz dazu geben technische Daten in der Regel keinen Anlass zu unterschiedlichen Interpretationen. Der menschliche Faktor ist jedoch auch bei der Auswertung von Ergebnissen der technischen Analyse vorhanden.


Wahrnehmungsproblem

Wenn wir über die technische Analyse von Märkten sprechen, meinen wir den Einsatz von Bewertungssystemen aus verschiedenen, wissenschaftlichen Bereichen, sei es Mathematik oder Physik. Die Notwendigkeit der Mathematik in der technischen Analyse ist ziemlich klar, während die Anwendung verschiedener physikalischer Phänomene auf die Märkte interessanter ist. Daher werden wir in diesem Artikel ein so bekanntes physikalisches Phänomen wie die Geschwindigkeit betrachten, die ein Maß für die Bewegung pro Zeiteinheit ist. Wenn wir uns Forex und andere Charts ansehen, können wir nicht nur die aktuelle Kursrichtung, sondern auch deren Geschwindigkeit deutlich erkennen, insbesondere in Zeiten hoher Volatilität. Jeder ist in der Lage, das Chart visuell zu analysieren und festzustellen, ob die aktuellen Preisänderungen schnell oder langsam sind. Solche visuellen Einschätzungen bleiben jedoch aufgrund der unterschiedlichen Wahrnehmungen der Menschen sehr subjektiv.

Ein einfaches Beispiel aus der Praxis ist ein visueller Trick, bei dem sich ein kleines Fahrzeug scheinbar mit einer langsameren Geschwindigkeit bewegt, während ein großer Lkw mit einer höheren Geschwindigkeit zu fahren scheint. Dieses Problem wird durch Geschwindigkeitsmesser gelöst, die alles in Zahlen anzeigen, die für jede Person absolut gleich sind.

Messmethoden zur Preisgeschwindigkeit

Vor der Besprechung der verschiedenen Methoden, die Preisgeschwindigkeit zu messen, erinnern wir uns, was Geschwindigkeit eigentlich ist.

Nach Wikipedia:

Die Geschwindigkeit beschreibt, wie schnell und in welcher Richtung ein Körper oder ein Phänomen (beispielsweise ein Wellenberg) im Lauf der Zeit seinen Ort verändert. Eine Geschwindigkeit wird durch ihren Betrag und die Bewegungsrichtung angegeben; es handelt sich also um eine vektorielle Größe. 

Wie können wir diese Definition auf den Devisenhandel anwenden? Der einfachste Weg ist, ein Objekt durch einen Preis zu ersetzen und die Zeit, innerhalb derer ein Balken oder eine Kerze entsteht, als Bezugsrahmen einzustellen. Aus der Sicht des Preischarts sieht dies wie folgt aus:


Abb. 1. Darstellung von Preisen als japanischer Kerzen im H1-Zeitrahmen

In diesem Fall sieht eine einfache Geschwindigkeitsmessung wie folgt aus:

Durchschnittsgeschwindigkeit = (Schlusskurs - Eröffnungskurs) / Stunde

Die genauen Beobachtungen und Schlussfolgerungen zur Preisentwicklung im Zeitablauf stellen sich wie folgt dar:

Schließlich ist der Hauptpunkt bei der so einfachen Geschwindigkeitsmessung, dass sie keine detaillierten Daten über die Preisdynamik innerhalb der Kerze liefert, sondern nur das endgültige Durchschnittsergebnis anzeigt. Wenn wir zum Beispiel eine Durchschnittsgeschwindigkeit einer H1-Kerze kennen, können wir nicht definieren, dass der Preis zunächst hoch war und bis zum Ende der Stunde deutlich fiel.

Aus Gründen der Klarheit möchte ich ein Beispiel anführen, das die oben genannten Schlussfolgerungen perfekt veranschaulicht. Abb. 2 zeigt die H1-Kerze mit ihrer durchschnittlichen Geschwindigkeit pro Minute, berechnet mit dem Indikator Average Speed. Hier sind es 2,53 Punkten pro Minute.

Abb. 2. Berechnung der Durchschnittsgeschwindigkeit für EURUSD H1

Werfen wir nun einen Blick auf die gleiche Kerze auf M15.


Abb. 3. Berechnung der Durchschnittsgeschwindigkeit für EURUSD H15

Abb. 3 zeigt, dass die Bewegung in den ersten 15 Minuten der gewählten Stunde (Average speed war 6,93) sehr ausgeprägt war und sich danach deutlich verringerte. Wenn wir natürlich alle vier Werte der Durchschnittsgeschwindigkeit zusammenfassen, erhalten wir die gleichen 2,53 Punkte pro Minute. Die Zerlegung einer Kerze in Komponenten ermöglicht es uns also, viele Daten über ihre Dynamik aufzudecken.

Das Aufteilen einer H1-Kerze in M1-Intervalle liefert noch mehr Daten.

Abb. 4. Berechnung der Durchschnittsgeschwindigkeit für EURUSD M1

Es gibt noch eine weitere Messmethode, wenn es um Möglichkeiten zur Berechnung der Bewegungsgeschwindigkeit in Punkten für den Zeitrahmen M1 geht.

Es handelt sich um die momentane (aktuelle) Preisgeschwindigkeit. Einerseits sind seine Werte immer so relevant wie möglich. Andererseits sieht ein Beispielindikator, der mit Tick-Preisänderungen arbeitet, so aus:

Abb. 5. Indikator der augenblicklichen Preisgeschwindigkeit

Anscheinend ist die Auswertung solch chaotischer (wenn auch relevanter) Daten für die spätere Verwendung im Devisenhandel eine ziemlich anspruchsvolle Aufgabe.

Wie wir wissen, ist die überwiegende Mehrheit der Indikatoren Ableitungen des Preises oder seiner Analysatoren. Dies gibt einige bekannte Indikatoren, die mit der Preisgeschwindigkeit arbeiten:


Entwickeln von Handelsstrategien auf Basis von Messmethoden

Daher sind die Ziele der Prüfung verschiedener Preisgeschwindigkeitsmessungen in drei Hauptgruppen einzuteilen:

Handelsstrategie 1

Um die erste Methode, die auf der Messung der Geschwindigkeit als eine Anzahl von durchlaufenen Punkten pro Zeiteinheit unter Verwendung des Indikators Average Speed basiert, zu testen, sollte der Filter, der eine Trendrichtung anzeigt, der getesteten Strategie hinzugefügt werden, da der Indikator die Anzahl der Punkte pro Zeiteinheit unabhängig von der Trendrichtung anzeigt.

Ich habe mich entschieden, den Indikator Coordinated ADX und MACD (CAM) als Filter dafür zu verwenden. Die Handelsstrategie wird so aussehen:

Parameter Beschreibung
Verwendeter Indikator Average Speed
Verwendeter Indikator Coordinated ADX and MACD (CAM) 
Zeitrahmen Jeder 
Kaufbedingungen Eine Kerze ist grün gefärbt, wenn der Wert der Durchschnittsgeschwindigkeit über dem Schwellenwert liegt (voreingestellt in den Parametern).
Verkaufsbedingungen Eine Kerze ist rot gefärbt, wenn der Wert der Durchschnittsgeschwindigkeit über dem Schwellenwert liegt (voreingestellt in den Parametern).
Ausstiegsbedingungen   Take-Profit/Stop-Loss

Abb. 6 zeigt die Eröffnung von Kauf- und Verkaufspositionen

Abb. 6. Die Einstiegsbedingungen der Handelsstrategie

Die Strategie wird wie folgt umgesetzt:

//+------------------------------------------------------------------+
//| EA Eingabeparameter                                              |
//+------------------------------------------------------------------+
input string               InpEaComment         =  "Strategy #1"; // EA Comment
input int                  InpMagicNum          =  1111;          // Magic number
input double               InpLot               =  0.1;           // Lots
input uint                 InpStopLoss          =  400;           // StopLoss in points
input uint                 InpTakeProfit        =  500;           // TakeProfit in points
input uint                 InpSlippage          =  0;             // Slippage in points
input ENUM_TIMEFRAMES      InpInd_Timeframe     =  PERIOD_H1;     // Timeframe for the calculation
//--- Average Speed Indikatorparameter
input int                  InpBars              =  1;             // Days
input ENUM_APPLIED_PRICE   InpPrice             =  PRICE_CLOSE;   // Applied price
input double               InpTrendLev          =  2;             // Trend Level
//--- CAM indicator parameters
input uint                 InpPeriodADX         =  10;            // ADX period
input uint                 InpPeriodFast        =  12;            // MACD Fast EMA period
input uint                 InpPeriodSlow        =  26;            // MACD Slow EMA period
//---
CEngine        engine;
CTrade         trade;
//--- Declare the indicator variables and handles
double         lot;
ulong          magic_number;
uint           stoploss;
uint           takeprofit;
uint           slippage;
int            InpInd_Handle1,InpInd_Handle2;
double         avr_speed[],cam_up[],cam_dn[];
//+------------------------------------------------------------------+
//| Initialisierungsfunktion des Experten                            |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- Initial checks
   if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
     {
      Print(InpEaComment,": Trade is not allowed!");
      return(INIT_FAILED);
     }
   if(!TerminalInfoInteger(TERMINAL_CONNECTED))
     {
      Print(InpEaComment,": No Connection!");
      return(INIT_FAILED);
     }
//--- Get the Average Speed indicator handle
   InpInd_Handle1=iCustom(Symbol(),InpInd_Timeframe,"Speed Price\\average_speed",
                          InpBars,
                          InpPrice
                          );
   if(InpInd_Handle1==INVALID_HANDLE)
     {
      Print(InpEaComment,": Failed to get average_speed handle");
      Print("Handle = ",InpInd_Handle1,"  error = ",GetLastError());
      return(INIT_FAILED);
     }
//--- Get the CAM indicator handle
   InpInd_Handle2=iCustom(Symbol(),InpInd_Timeframe,"Speed Price\\CAM",
                          InpPeriodADX,
                          InpPeriodFast,
                          InpPeriodSlow
                          );
   if(InpInd_Handle2==INVALID_HANDLE)
     {
      Print(InpEaComment,": Failed to get average_speed handle");
      Print("Handle = ",InpInd_Handle2,"  error = ",GetLastError());
      return(INIT_FAILED);
     }
//---
   ArrayInitialize(avr_speed,0.0);
   ArrayInitialize(cam_up,0.0);
   ArrayInitialize(cam_dn,0.0);
   ArraySetAsSeries(avr_speed,true);
   ArraySetAsSeries(cam_up,true);
   ArraySetAsSeries(cam_dn,true);
//--- Setzen der Handelsparameter
   lot=NormalizeLot(Symbol(),fmax(InpLot,MinimumLots(Symbol())));
   magic_number=InpMagicNum;
   stoploss=InpStopLoss;
   takeprofit=InpTakeProfit;
   slippage=InpSlippage;
//--- 
   trade.SetDeviationInPoints(slippage);
   trade.SetExpertMagicNumber(magic_number);
   trade.SetTypeFillingBySymbol(Symbol());
   trade.SetMarginMode();
   trade.LogLevel(LOG_LEVEL_NO);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Timer Funktion                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
   if(!MQLInfoInteger(MQL_TESTER))
      engine.OnTimer();
  }
//+------------------------------------------------------------------+
//| Experten Funktion OnTick                                         |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- If working in the tester
   if(MQLInfoInteger(MQL_TESTER))
      engine.OnTimer();

   if(!IsOpenedByMagic(InpMagicNum))
     {
      //--- Datenabfrage für die Berechnung
      if(!GetIndValue())
         return;
      //---
      if(BuySignal())
        {
         //--- Abrufen der korrekten Preise von StopLoss und TakeProfit relativ zu StopLevel
         double sl=CorrectStopLoss(Symbol(),ORDER_TYPE_BUY,0,stoploss);
         double tp=CorrectTakeProfit(Symbol(),ORDER_TYPE_BUY,0,takeprofit);
         //--- Eröffnen einer Kaufposition
         trade.Buy(lot,Symbol(),0,sl,tp);
        }
      else if(SellSignal())
        {
         //--- Abrufen der korrekten Preise von StopLoss und TakeProfit relativ zu StopLevel
         double sl=CorrectStopLoss(Symbol(),ORDER_TYPE_SELL,0,stoploss);
         double tp=CorrectTakeProfit(Symbol(),ORDER_TYPE_SELL,0,takeprofit);
         //--- Eröffnen einer Verkaufsposition
         trade.Sell(lot,Symbol(),0,sl,tp);
        }
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool BuySignal()
  {
   return(avr_speed[0]>=InpTrendLev && cam_up[0]!=EMPTY_VALUE)?true:false;
  }
//+------------------------------------------------------------------+
bool SellSignal()
  {
   return(avr_speed[0]>=InpTrendLev && cam_dn[0]!=EMPTY_VALUE)?true:false;
  }
//+------------------------------------------------------------------+
//| Abrufen des aktuellen Indikatorwertes                            |
//+------------------------------------------------------------------+
bool GetIndValue()
  {
   return(CopyBuffer(InpInd_Handle2,0,0,1,cam_up)<1 ||
          CopyBuffer(InpInd_Handle2,1,0,1,cam_dn)<1 || 
          CopyBuffer(InpInd_Handle1,0,0,1,avr_speed)<1
          )?false:true;
  }
//+------------------------------------------------------------------+
//| Check for open positions with a magic number                     |
//+------------------------------------------------------------------+
bool IsOpenedByMagic(int MagicNumber)
  {
   int pos=0;
   uint total=PositionsTotal();
//---
   for(uint i=0; i<total; i++)
     {
      if(SelectByIndex(i))
         if(PositionGetInteger(POSITION_MAGIC)==MagicNumber)
            pos++;
     }
   return((pos>0)?true:false);
  }
//+------------------------------------------------------------------+
//| Select a position on the index                                   |
//+------------------------------------------------------------------+
bool SelectByIndex(const int index)
  {
   ENUM_ACCOUNT_MARGIN_MODE margin_mode=(ENUM_ACCOUNT_MARGIN_MODE)AccountInfoInteger(ACCOUNT_MARGIN_MODE);
//---
   if(margin_mode==ACCOUNT_MARGIN_MODE_RETAIL_HEDGING)
     {
      ulong ticket=PositionGetTicket(index);
      if(ticket==0)
         return(false);
     }
   else
     {
      string name=PositionGetSymbol(index);
      if(name=="")
         return(false);
     }
//---
   return(true);
  }
//+------------------------------------------------------------------+

Handelsstrategie 2

Die Idee des EAs Price Impulse wird verwendet, um eine Handelsstrategie zu implementieren, die auf der zweiten Möglichkeit der Messung der Preisgeschwindigkeit basiert. Der wichtigste Punkt ist die Eröffnung von Handelspositionen, wenn sich der Preis für eine bestimmte Anzahl von Punkten bewegt, unter Berücksichtigung der Anzahl der dafür aufgewendeten Ticks. 

Parameter Beschreibung
Zeitrahmen Jeder 
Kaufbedingungen Anzahl der Preispunkte, die für eine bestimmte Anzahl von Ticks durchlaufen wurden.
Verkaufsbedingungen Anzahl der Preispunkte, die für eine bestimmte Anzahl von Ticks durchlaufen wurden.
Ausstiegsbedingungen   Take-Profit/Stop-Loss

Die Umsetzung der Strategie ist wie folgt codiert. Wie wir sehen können, gibt es zwei Eingabeparameter, die für die Schätzung der Preisgeschwindigkeit verantwortlich sind:

//+------------------------------------------------------------------+
//| EA Eingabeparameter                                              |
//+------------------------------------------------------------------+
input string               InpEaComment         =  "Strategy #2"; // EA Comment
input int                  InpMagicNum          =  1111;          // Magic number
input double               InpLots              =  0.1;           // Lots
input uint                 InpStopLoss          =  400;           // StopLoss in points
input uint                 InpTakeProfit        =  500;           // TakeProfit in points
input ENUM_COPY_TICKS      tick_flags           =  TICKS_INFO;    // Ticks resulting from Bid and/or Ask changes
input int                  InpPoints            =  15;            // The price should move NNN points
input uchar                InpTicks             =  15;            // For XXX ticks

//--- arrays for accepting ticks
MqlTick        tick_array_curr[];            // ticks array obtained on the current tick
MqlTick        tick_array_prev[];            // ticks array obtained on the previous tick
ulong          tick_from=0;                  // if tick_from=0, the last tick_count ticks are given
uint           tick_count=15;                // number of ticks that should be obtained 
//---
double         ExtStopLoss=0.0;
double         ExtTakeProfit=0.0;
double         ExtPoints=0.0;
bool           first_start=false;
long           last_trade_time=0;
//+------------------------------------------------------------------+
//| Initialisierungsfunktion des Experten                            |
//+------------------------------------------------------------------+
int OnInit()
  {
   if(!m_symbol.Name(Symbol()))              // sets symbol name
      return(INIT_FAILED);

   tick_count+=InpTicks;                     // request "tick_count" + "for XXX ticks"
   ExtStopLoss=InpStopLoss*Point();
   ExtTakeProfit=InpTakeProfit*Point();
   ExtPoints=InpPoints*Point();
   first_start=false;
//--- request ticks (first filling)
   int copied=CopyTicks(Symbol(),tick_array_curr,tick_flags,tick_from,tick_count);
   if(copied!=tick_count)
      first_start=false;
   else
     {
      first_start=true;
      ArrayCopy(tick_array_prev,tick_array_curr);
     }
   m_trade.SetExpertMagicNumber(InpMagicNum);
   m_trade.SetTypeFillingBySymbol(Symbol());
   m_trade.SetMarginMode();
   m_trade.LogLevel(LOG_LEVEL_NO);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Experten Funktion OnTick                                         |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- check for the first start
   int copied=-1;
   if(!first_start)
     {
      copied=CopyTicks(Symbol(),tick_array_curr,tick_flags,tick_from,tick_count);
      if(copied!=tick_count)
         first_start=false;
      else
        {
         first_start=true;
         ArrayCopy(tick_array_prev,tick_array_curr);
        }
     }
//--- request ticks
   copied=CopyTicks(Symbol(),tick_array_curr,tick_flags,tick_from,tick_count);
   if(copied!=tick_count)
      return;
   int index_new=-1;
   long last_time_msc=tick_array_prev[tick_count-1].time_msc;
   for(int i=(int)tick_count-1;i>=0;i--)
     {
      if(last_time_msc==tick_array_curr[i].time_msc)
        {
         index_new=i;
         break;
        }
     }
//---
   if(index_new!=-1 && !IsOpenedByMagic(InpMagicNum))
     {
      int shift=(int)tick_count-1-index_new-InpTicks;   // shift in the current ticks array
      shift=(shift<0)?0:shift;
      if(tick_array_curr[tick_count-1].ask-tick_array_curr[shift].ask>ExtPoints)
        {
         //--- open BUY
         double sl=(InpStopLoss==0)?0.0:tick_array_curr[tick_count-1].ask-ExtStopLoss;
         double tp=(InpTakeProfit==0)?0.0:tick_array_curr[tick_count-1].ask+ExtTakeProfit;
         m_trade.Buy(InpLots,m_symbol.Name(),tick_array_curr[tick_count-1].ask,
                     m_symbol.NormalizePrice(sl),
                     m_symbol.NormalizePrice(tp));
         last_trade_time=tick_array_curr[tick_count-1].time_msc;
        }
      else if(tick_array_curr[shift].bid-tick_array_curr[tick_count-1].bid>ExtPoints)
        {
         //--- open SELL
         double sl=(InpStopLoss==0)?0.0:tick_array_curr[tick_count-1].bid-ExtStopLoss;
         double tp=(InpTakeProfit==0)?0.0:tick_array_curr[tick_count-1].bid+ExtTakeProfit;
         m_trade.Sell(InpLots,m_symbol.Name(),tick_array_curr[tick_count-1].bid,
                      m_symbol.NormalizePrice(sl),
                      m_symbol.NormalizePrice(tp));
         last_trade_time=tick_array_curr[tick_count-1].time_msc;
        }
     }
   ArrayCopy(tick_array_prev,tick_array_curr);
//---
  }
//+------------------------------------------------------------------+
//| Check for open positions with the magic number                   |
//+------------------------------------------------------------------+
bool IsOpenedByMagic(int MagicNumber)
  {
   int pos=0;
   uint total=PositionsTotal();
//---
   for(uint i=0; i<total; i++)
     {
      if(SelectByIndex(i))
         if(PositionGetInteger(POSITION_MAGIC)==MagicNumber)
            pos++;
     }
   return((pos>0)?true:false);
  }
//+------------------------------------------------------------------+
//| Select a position on the index                                   |
//+------------------------------------------------------------------+
bool SelectByIndex(const int index)
  {
   ENUM_ACCOUNT_MARGIN_MODE margin_mode=(ENUM_ACCOUNT_MARGIN_MODE)AccountInfoInteger(ACCOUNT_MARGIN_MODE);
//---
   if(margin_mode==ACCOUNT_MARGIN_MODE_RETAIL_HEDGING)
     {
      ulong ticket=PositionGetTicket(index);
      if(ticket==0)
         return(false);
     }
   else
     {
      string name=PositionGetSymbol(index);
      if(name=="")
         return(false);
     }
//---
   return(true);
  }
//+------------------------------------------------------------------+

Handelsstrategie 3

Um eine Handelsstrategie zu erstellen, die indirekt die Preisgeschwindigkeit misst, sollten wir einen Trendindikator und einen Filter auswählen, der seine möglichen Signale bestätigt. In Anbetracht der Ziele habe ich als Trendindikator Trend direction and force und HMA Color als Filter gewählt. Abb. 7 zeigt Kauf- und Verkaufseintrittssignale.

Abb. 7. Die Einstiegsbedingungen der Handelsstrategie

Parameter Beschreibung
Verwendeter Indikator Trend direction and force
Verwendeter Indikator HMA Color
Zeitrahmen M30 und höher
Kaufbedingungen Der Wert von 'Trend direction and fast' ist höher als der Schwellenwert eins (die Linie ist blau), während HMA nach oben geht und blau wird.
Verkaufsbedingungen Der Wert von 'Trend direction and fast' ist kleiner als der Schwellenwert eins (die Linie ist rot), während HMA nach unten geht und rot wird.
Ausstiegsbedingungen   Take-Profit/Stop-Loss


Prüfen der Messmethoden zur Preisgeschwindigkeit

Um die ausgewählten drei Strategien zu testen, müssen wir die Bedingungen definieren, unter denen sie getestet werden sollen. 

  • Intervall: Letztes Jahr. (Zum Zeitpunkt dieses Schreibens ist dies 01.01.2019 - 26.05.2019).
  • Symbol: EURUSD.
  • Handelsmodus: Keine Verzögerung (Dies sind keine hochfrequenten Handelsstrategien, daher wäre der Effekt von Verzögerungen sehr gering). 
  • Test: М1 OHLC (Vorabtests an realen Ticks zeigt fast die gleichen Ergebnisse). 
  • Einlage: 1000 USD.
  • Test: 1 Minute OHLC. Vortests mit realen Ticks zeigen fast die gleichen Ergebnisse.
  • Server: MetaQuotes-Demo.
  • Kurse: 5 Dezimalstellen.

Anstatt die Strategie auf die Historie abzustimmen, besteht das Ziel des Tests darin, den allgemeinen Trend und die Effizienz der verschiedenen Ansätze zur Berechnung und Behandlung der Preisgeschwindigkeit zu klären. Daher werden für jede der Handelsstrategien die besten Optimierungsergebnisse und deren Schätzung anhand der Berichtsparameter bereitgestellt. 

Handelsstrategie 1

Nachdem ich die erste Strategie getestet habe, die auf der Standardpreisgeschwindigkeitsänderung basiert, habe ich eine Reihe von Ergebnissen erhalten. Die 20 besten von ihnen sind unten aufgeführt:

Abb. 8. Handelsstrategie 1, die zwanzig beste Optimierungsergebnisse

Aus diesen Ergebnissen können wir schließen, dass die Handelsstrategie unter diesen Testbedingungen die besten Ergebnisse bei niedrigen Zeitrahmen mit engen Take-Profit- und Stop-Loss zeigt. Mit anderen Worten, das Bewegungspotenzial eines erfassten Signals ist gering. Gleichzeitig ist das Sharpe Ratio (mehr darüber und andere Parameter finden Sie im Artikel Mathematik im Trading: Wie man Handelsergebnisse einschätzt) klein, was kein vielversprechendes Zeichen ist. Als Nächstes folgt der Bericht das beste Ergebnis im Tester:


Abb. 9. Das beste Optimierungsergebnis des Tests der Handelsstrategie 1

Bei Verwendung einer konstanten Losgröße von 0,1 können wir sehen, dass das Wachstum fast 100% beträgt, aber das Sharpe-Ratio ist nur 0,33, während der Z-Score -0,16 ist, was auf die mangelnde Konsistenz im Handel und den Einfluss des Zufallsfaktors hinweist. 

Handelsstrategie 2

Um die folgende Strategie zu testen, müssen wir eine Testbedingung aufgrund der Strategiemerkmale ändern:

  • Testen: Ersetzen Sie M1 OHLC (die Voruntersuchung an echten Ticks zeigt fast die gleichen Ergebnisse) durch "Jeder Tick anhand realer Ticks".

Die 20 besten Optimierungsoptionen der Strategie sehen wie folgt aus:

Abb. 10. Handelsstrategie 2, die zwanzig beste Optimierungsergebnisse

Im Durchschnitt ist das Sharpe-Ratio hier höher als bei der ersten Strategie, und die besten Ergebnisse werden mit einer moderaten Anzahl von Punkten innerhalb der minimalen Anzahl von Ticks erzielt. Das System erwies sich auch als sehr selektiv, wie die sehr geringe Anzahl von Positionen zeigt. Lassen Sie uns das beste Optimierungsergebnis testen und den Bericht sehen.


Abb. 11. Das beste Optimierungsergebnis des Tests der Handelsstrategie 2

Das Sharpe-Ratio sieht hier besser aus, da der Gewinn von über 30% nur innerhalb von 10 Positionen erreicht wurde. 

Handelsstrategie 3 

In dieser Strategie kommen wir auf die anfänglichen Testbedingungen zurück. Hier werden wir den Handel anhand von Indikatoren überprüfen, die indirekt die Preisbewegung und deren Geschwindigkeit bestimmen.

Sehen Sie auch die besten Optimierungsergebnisse der aktuellen Strategie:

Abb. 12. Handelsstrategie 3, die zwanzig beste Optimierungsergebnisse

Die meisten Ergebnisse sind sehr ähnlich. Dies deutet darauf hin, dass die letzten beiden Optimierungsparameter keinen großen Einfluss auf das Endergebnis haben. Gleichzeitig liegt das durchschnittliche Sharpe Ratio bei etwa 0,2, was nicht allzu beeindruckend ist. Das beste Optimierungsergebnis liegt natürlich außerhalb der allgemeinen Ordnung, aber wir werden einen Backtest durchführen, wie bei früheren Handelsstrategien.


Abb. 13. Das beste Optimierungsergebnis des Tests der Handelsstrategie 3

Trotz des fast 100%igen Wachstums der Einlage und des hervorragenden Sharpe-Ratio (was dadurch auffällt, dass 52 Positionen benötigt wurden, um das aktuelle Gewinnniveau zu erreichen, während die nächsten Ergebnisse fast zwei Mal geringer sind), zeigt der Z-Score eine negative Korrelation zwischen den Positionen. Das bedeutet, dass auf eine profitable Position höchstwahrscheinlich ein verlustbringende folgt und umgekehrt. 

Zusammenfassung

Nach dem Testen der drei Ansätze zur Messung der Preisgeschwindigkeit und der Untersuchung der Ergebnisse der besten Backtests und anderer Optimierungen wurde festgestellt, dass das beste Optimierungsergebnis der ersten Methode keine Konsistenz aufweist. Die restlichen beiden Methoden zeigten bessere Ergebnisse mit höherem Sharpe-Ratio und einer negativen Korrelation zwischen den Positionen. Natürlich decken die Teststrategien nicht die ganze Vielfalt der Preisgeschwindigkeitsmessmethoden ab, aber dieser Artikel hat einige der offensichtlichsten und am einfachsten zu verstehenden Handelsmethoden beschrieben.

Schlussfolgerung

Das unten angehängte Archiv enthält alle beschriebenen Dateien in den jeweiligen Ordnern. Für ein korrektes Funktionieren sollten Sie den Ordner MQL5 im Stammverzeichnis des Terminals speichern. Um das Stammverzeichnis des Terminals zu öffnen, in dem sich der Ordner MQL5 befindet, drücken Sie die Tastenkombination Ctrl+Shift+D im MetaTrader 5 Terminal oder verwenden Sie das Kontextmenü wie in Abbildung 14 unten gezeigt.


Abb. 14. Öffnen des Ordners MQL5 im Stammordner von MetaTrader 5

Die Programme dieses Artikels:

#
 Name
Typ
Beschreibung
1
Strategy_1.mq5 EA  Der EA mit der Handelsstrategie 1
2 Strategy_2.mq5 EA  Der EA mit der Handelsstrategie 2
3 Strategy_3.mq5 EA   Der EA mit der Handelsstrategie 3
4 Engine.mqh Bibliothek  Die Bibliothek der Handelsfunktionen
 5 Average Speed  Indikator   Verwendet von der Handelsstrategie 1
 6 CAM  Indikator    Verwendet von der Handelsstrategie 1
 7 Trend direction and force  Indikator    Verwendet von der Handelsstrategie 3
 8 HMA_color  Indikator   Verwendet von der Handelsstrategie 3