Kann Heiken-Ashi in Kombination mit gleitenden Durchschnitten gute Signale liefern?

Javier Santiago Gaston De Iriarte Cabrera | 7 August, 2023

Einführung

Kombinationen von Strategien können bessere Chancen bieten. Wir können Indikatoren oder Muster miteinander kombinieren, oder noch besser, Indikatoren mit Mustern, sodass wir einen zusätzlichen Bestätigungsfaktor erhalten. In diesem Artikel werden wir sehen, wie man den Heiken-Ashi-Indikator zusammen mit gleitenden Durchschnitten als Trendbestätigungstechnik verwenden kann. Und am Ende können wir uns Optimierungsmöglichkeiten ansehen.

Chart



Die Methode der Kerzen Heiken-Ashi

Kerzen sind eine schnelle Methode, um OHLC-Daten zu verstehen und Muster zu erkennen. Sie ist sehr übersichtlich und leicht zu interpretieren. Eine Aufwärtskerze (in der Regel ist sie grün) tritt auf, wenn der Markt über ihrem Eröffnungskurs schließt. Eine Abwärtskerze (in der Regel ist sie rot) tritt auf, wenn der Markt unter ihrem Eröffnungskurs schließt.


Kerze ohlc


Handelsmuster


Sehen wir uns ein vollständiges Kerzen-Chart an, um besser zu verstehen, wie es dargestellt wird. Der Trend zeigt eindeutig nach oben, wobei um die roten Kerzen herum einige Korrekturen zu beobachten sind. Beachten Sie die kleinen Kerzen, bei denen der Eröffnungskurs fast gleich dem Schlusskurs ist. Dies wird als Doji bezeichnet und deutet auf Unentschlossenheit und eine mögliche Umkehr oder Konsolidierung hin.

Kerzen


Die Heiken-Ashi-Kerzen (auch Heikin-Ashi) versuchen, das Bild zu bereinigen und einen klareren Trend zu zeigen, indem sie die OHLC-Daten glätten. Hier erfahren Sie, wie Sie die Heiken-Ashi-Kerzen berechnen können:

(Eröffnungskurs + Hoch + Tief + Schlusskurs) ÷ 4


Heikin-Ashi Hoch = Maximum von (Hoch-0, Eröffnungskurs-0 und Schlusskurs-0) 

Heikin-Ashi Tief = Minimum von (Tief-0, Eröffnungskurs-0, und Schlusskurs-0)


Heikin-Ashi ist ein japanischer Handelsindikator und ein Finanzchart, das „durchschnittliches Tempo“ bedeutet. Heikin-Ashi-Chart ähneln Kerzen-Charts, haben aber ein glatteres Erscheinungsbild, da sie eine Reihe von Kursbewegungen verfolgen und nicht jede Kursbewegung wie bei Kerzen. Der Heikin-Ashi wurde in den 1700er Jahren von Munehisa Homma entwickelt, der auch das Kerzen-Chart schuf. Diese Charts werden von Händlern und Anlegern verwendet, um Kursbewegungen zu ermitteln und vorherzusagen.

Eine Heikin-Ashi-Kerze hat wie ein herkömmlicher Kerzen einen Körper und einen Docht, allerdings haben sie nicht denselben Zweck wie ein Kerzen-Chart. Der letzte Kurs einer Heikin-Ashi-Kerze wird anhand des Durchschnittskurses des aktuellen Balkens oder Zeitrahmens berechnet (z. B. würde bei einem täglichen Zeitrahmen jeder Balken die Kursbewegungen des jeweiligen Tages darstellen). Die Formel für den letzten Preis der Heikin-Ashi-Kerze oder der Balken wird wie folgt berechnet: (Open + High + Low + Close) ÷ 4. Der Eröffnungskurs eines Heikin-Ashi beginnt in der Mitte der vorhergehenden Kerze; er wird berechnet durch: (die Eröffnungskurs des vorherigen Balkens + der Schlusskurs des vorherigen Balkens) ÷ 2. Die Höchst- und Tiefstkurse werden ähnlich wie bei den Kerzen durch Dochte dargestellt.

Die obigen Formeln glätten die Kerzen, um einen klareren und eindeutigeren Trend zu ermitteln.


Heiken Ashi (1) Kerzen(2)


Die beiden Charts vergleichen einen regulären Kerzen-Chart mit einem Heiken-Ashi-Chart. Wir können die Ähnlichkeit erkennen, aber wir können auch sehen, dass das erste Bild glatter ist. Da es sich bei der Heiken-Ashi-Methode jedoch lediglich um einen Durchschnittswert handelt, entspricht der angezeigte Preis möglicherweise nicht dem tatsächlichen Marktpreis.


Das Konzept der gleitenden Durchschnitte

Gleitende Durchschnitte helfen uns, den Trend zu bestätigen und zu verfolgen. Sie sind die bekanntesten technischen Indikatoren, und das liegt an ihrer Einfachheit und ihrer erwiesenen Fähigkeit, einen Mehrwert für Analysen zu schaffen. Wir können sie nutzen, um Unterstützungs- und Widerstandsniveaus, Stopps und Ziele sowie den zugrunde liegenden Trend zu finden. Diese Vielseitigkeit macht sie zu einem unverzichtbaren Instrument in unserem Handelsarsenal.

In der Statistik ist ein gleitender Durchschnitt (gleitender Durchschnitt oder laufender Durchschnitt) eine Berechnung zur Analyse von Datenpunkten, bei der eine Reihe von Durchschnittswerten aus verschiedenen Auswahlen des gesamten Datensatzes gebildet wird. Er wird auch als gleitender Mittelwert (moving mean, MM) oder rollierender Mittelwert bezeichnet und ist eine Art Filter mit endlicher Impulsantwort. Es gibt verschiedene Varianten: einfache, kumulative oder gewichtete Formen (siehe unten).

Ein Filter für den gleitenden Durchschnitt wird manchmal auch als Boxcar-Filter bezeichnet, insbesondere wenn er mit einer Dezimierung verbunden ist.

Bei einer Zahlenreihe und einer festen Teilmenge erhält man das erste Element des gleitenden Durchschnitts, indem man den Durchschnitt der ersten festen Teilmenge der Zahlenreihe bildet. Dann wird die Teilmenge durch „Vorwärtsschieben“ geändert, d. h. die erste Zahl der Reihe wird ausgeschlossen und der nächste Wert in die Teilmenge aufgenommen.

Ein gleitender Durchschnitt wird üblicherweise bei Zeitreihendaten verwendet, um kurzfristige Schwankungen zu glätten und längerfristige Trends oder Zyklen hervorzuheben. Die Grenze zwischen kurz- und langfristig hängt von der Anwendung ab, und die Parameter des gleitenden Durchschnitts werden entsprechend eingestellt. Sie wird auch in der Wirtschaft verwendet, um das Bruttoinlandsprodukt, die Beschäftigung oder andere makroökonomische Zeitreihen zu untersuchen. Mathematisch gesehen ist ein gleitender Durchschnitt eine Art Faltung und kann daher als Beispiel für einen Tiefpassfilter in der Signalverarbeitung betrachtet werden. Bei der Verwendung mit Daten, die keine Zeitreihen sind, filtert ein gleitender Durchschnitt Komponenten mit höherer Frequenz, ohne dass ein spezifischer Zusammenhang mit der Zeit besteht, obwohl in der Regel eine Art von Ordnung impliziert ist. Vereinfacht betrachtet, kann man dies als Glättung der Daten betrachten.


MA


Wie der Name schon sagt, handelt es sich hierbei um ein einfaches Mittel, das überall in der Statistik und in jedem anderen Bereich unseres Lebens verwendet wird. Sie ist einfach die Summe der Werte der Beobachtungen geteilt durch die Anzahl der Beobachtungen. Mathematisch gesehen lässt sich dies wie folgt ausdrücken:

MA-Formel


Wir können sehen, dass der gleitende Durchschnitt gute dynamische Unterstützungs- und Widerstandsniveaus bietet, von denen aus wir unsere Aufträge platzieren können, falls der Markt nach unten geht.



Plan

kaufen


Wie bei jeder angemessenen Forschungsmethode besteht das Ziel darin, die Strategie zu testen und mit eigenen Augen zu sehen, ob sie es wert ist, als Ergänzung zu unserem bereits bestehenden Handelsrahmen eingesetzt zu werden oder nicht.

Der erste Schritt ist die Erstellung der Handelsregeln. Wann kauft das System und wann geht es leer aus? Mit anderen Worten: Wann wird das Signal gegeben, das dem System sagt, dass der aktuelle Markt steigen oder fallen wird?

Folgende Handelsbedingungen stehen zur Auswahl:

Wenn wir einen Handelsalgorithmus entwickeln, müssen wir die Häufigkeit der Signale berücksichtigen. Die Signalfunktion, die verwendet wird, um die Auslöser auf der Grundlage der genannten Bedingungen zu erzeugen.



Ergebnisse

Dies sind die Ergebnisse für das Symbol EURUSD vom 1. Januar 2022 bis zum 5. Juli 2023 für einen Zeitraum von 30 Minuten. Bessere Ergebnisse sollten mit der Optimierung und anderen Zeiträumen erzielt werden. Um es mit allen Symbolen verwenden zu können, sollten Optimierungen und Tests durchgeführt werden.

Chart

Bericht der Strategietester



Code

int OnInit()
  {
//---
   handle_iCustomMA=iCustom(_Symbol,my_timeframe,"\\folder/s where you have the indicator\\sma",MAPeriod,MAShift);
   handle_iCustomHeiken=iCustom(_Symbol,my_timeframe_Heiken,"\\folder/s where you have the indicator\\Heiken_Ashi_copy");
//---
   if(handle_iCustomMA==INVALID_HANDLE)
     {
      //--- tell about the failure and output the error code
      PrintFormat("Failed to create handle of the iCustom indicator for the symbol %s/%s, error code %d",
                  _Symbol,
                  EnumToString(my_timeframe),
                  GetLastError());
      //--- the indicator is stopped early
      return(INIT_FAILED);
     }
   if(handle_iCustomHeiken==INVALID_HANDLE)
     {
      //--- tell about the failure and output the error code
      PrintFormat("Failed to create handle of the iCustom indicator for the symbol %s/%s, error code %d",
                  _Symbol,
                  EnumToString(my_timeframe_Heiken),
                  GetLastError());
      //--- the indicator is stopped early
      return(INIT_FAILED);
     }
   return(INIT_SUCCEEDED);
  }

Dieser Code wird zur Initialisierung von zwei nutzerdefinierten Indikatoren in der Sprache MQL5 verwendet. Der erste Indikator ist ein Einfacher Gleitender Durchschnitt (Simple Moving Average, SMA) mit den Parametern MAPeriod und MAShift. Der zweite Indikator ist eine Kopie des Heiken Ashi. Der Code erstellt Handles für jeden Indikator und prüft auf Fehler. Wenn ein Fehler gefunden wird, gibt der Code den Fehlercode aus und liefert den Wert INIT_FAILED. Wenn keine Fehler gefunden werden, gibt der Code den Wert INIT_SUCCEEDED zurück.

void OnTick()
  {
   double heikenAshiOpen[], heikenAshiHigh[], heikenAshiLow[], heikenAshiClose[];
   CopyBuffer(handle_iCustomHeiken,0,0,2,heikenAshiOpen);
   CopyBuffer(handle_iCustomHeiken,1,0,2,heikenAshiHigh);
   CopyBuffer(handle_iCustomHeiken,2,0,2,heikenAshiLow);
   CopyBuffer(handle_iCustomHeiken,3,0,2,heikenAshiClose);
   Comment("heikenAshiOpen ",DoubleToString(heikenAshiOpen[0],_Digits),
           "\n heikenAshiHigh ",DoubleToString(heikenAshiHigh[0],_Digits),
           "\n heikenAshiLow ",DoubleToString(heikenAshiLow[0],_Digits),
           "\n heikenAshiClose ",DoubleToString(heikenAshiClose[0],_Digits));
//---
   MqlTick tick;
   double last_price = tick.ask;
   SymbolInfoTick(_Symbol,tick);
   int total = PositionsTotal();
//---
// Retrieve the current value
   MqlTradeResult  result;
   MqlRates rates[];
//---
   double array_ma[];
   ArraySetAsSeries(array_ma,true);
   int start_pos2=0,count2=5;
   if(!iGetArray2(handle_iCustomMA,0,start_pos2,count2,array_ma))
      return;
//------------------------------------------------------------------------------
     {
      if(DoubleToString(heikenAshiClose[0],_Digits) < DoubleToString(heikenAshiOpen[0],_Digits) && (DoubleToString(heikenAshiClose[1],_Digits) > DoubleToString(heikenAshiOpen[1],_Digits)))
        {
         Print("Open Order Buy");
         Alert(" Buying");
         Orden="Buy";
         sl=NormalizeDouble(tick.ask - ptsl*_Point,_Digits);
         tp=NormalizeDouble(tick.bid + pttp*_Point,_Digits);
         trade.PositionOpen(_Symbol,ORDER_TYPE_BUY,get_lot(tick.bid),tick.bid,sl,tp,"Buy");
         return;
        }
     }
     {
      if(DoubleToString(heikenAshiClose[0],_Digits) > DoubleToString(heikenAshiOpen[0],_Digits) && (DoubleToString(heikenAshiClose[1],_Digits) < DoubleToString(heikenAshiOpen[1],_Digits)))
        {
         Print("Open Order Sell");
         Alert(" Selling");
         Orden="Sell";
         sl=NormalizeDouble(tick.bid + ptsl*_Point,_Digits);
         tp=NormalizeDouble(tick.ask - pttp*_Point,_Digits);
         trade.PositionOpen(_Symbol,ORDER_TYPE_SELL,get_lot(tick.ask),tick.ask,sl,tp,"Sell");
         return;
        }
     }
   if(total>0)
     {
      if(Orden=="Sell" &&(DoubleToString(heikenAshiClose[0],_Digits) < DoubleToString(heikenAshiOpen[0],_Digits) ))
        {
         trade.PositionClose(_Symbol,5);
         Print("cerró sell");
         return;
        }
      if(Orden=="Buy" &&(DoubleToString(heikenAshiClose[0],_Digits) > DoubleToString(heikenAshiOpen[0],_Digits) ))
        {
         trade.PositionClose(_Symbol,5);
         Print("cerró buy");
         return;
        }
     }
  }

Dieser Code ist ein MQL5-Skript, das zum Öffnen und Schließen von Positionen auf dem Devisenmarkt verwendet wird. Zunächst werden vier Doppel-Arrays deklariert (heikenAshiOpen, heikenAshiHigh, heikenAshiLow und heikenAshiClose) und die Werte aus dem nutzerdefinierten Indikator „iCustomHeiken“ kopiert. Anschließend werden die aktuellen Tickdaten aus dem Symbol abgerufen und die Arrays MqlTradeResult und MqlRates deklariert. Dann wird ein Array für den gleitenden Durchschnitt (array_ma) deklariert und das Array als Serie festgelegt. Anschließend werden die Werte aus dem nutzerdefinierten Indikator „iCustomMA“ abgerufen und im array_ma-Array gespeichert. Schließlich wird geprüft, ob der aktuelle Heiken-Ashi-Schlusskurs niedriger als der Eröffnungswert und der vorherige Heiken-Ashi-Schlusskurs höher als der Eröffnungswert ist, und wenn dies der Fall ist, wird ein Kaufauftrag mit dem angegebenen Stop-Loss und Take-Profit eröffnet. Außerdem wird geprüft, ob der aktuelle Heiken-Ashi-Schlusskurs über dem Eröffnungskurs und der vorherige Heiken-Ashi-Schlusskurs unter dem Eröffnungskurs liegt. Ist dies der Fall, wird ein Verkaufsauftrag mit dem angegebenen Stop-Loss und Take-Profit eröffnet. Wenn es offene Positionen gibt, wird geprüft, ob der Heiken-Ashi-Schluss bei einem Verkaufsauftrag niedriger als der Eröffnungswert und bei einem Kaufauftrag höher als der Eröffnungswert ist, und wenn ja, wird die Position geschlossen.

Nur um zu verdeutlichen, die dritte Ganzzahl von CopyBuffer ist der Wert, von wo aus wir zu zählen beginnen, und die vierte ist der Wert der Anzahl der abgerufenen Werte. Ich habe zwei statt einer Kerze verwendet, um die 1-n zu berücksichtigen (in diesem Fall die unmittelbar vorangehende Heiken Ashi-Kerze). Dies wurde am Anfang verwendet, um die Farbänderung in einer Wenn-Bedingung zu sehen, um den Auftrag zu erteilen oder nicht zu erteilen.

Die beiden Wenn-Bedingungen zum Erteilen oder Schließen von Positionen sollten Sie im Code ändern. Sie könnten z. B. mehrere Kerzen mit derselben Farbe verwenden, bevor Sie den Auftrag öffnen, oder die zweite Kerze einer anderen Farbe überspringen, um die Aufträge zu schließen.

Eine weitere gute Lösung zum Schließen von Positionen wäre ein anderer SMA mit einer anderen Periode, und verwenden Sie die Kreuzsignale zum Schließen von Positionen. Wie in dem Beispiel auf dem Bild:

Heiken Ashi 2 MA


//+------------------------------------------------------------------+
double get_lot(double price)
  {
   if(inp_lot_type==LOT_TYPE_FIX)
      return(normalize_lot(inp_lot_fix));
   double one_lot_margin;
   if(!OrderCalcMargin(ORDER_TYPE_BUY,_Symbol,1.0,price,one_lot_margin))
      return(inp_lot_fix);
   return(normalize_lot((AccountInfoDouble(ACCOUNT_BALANCE)*(inp_lot_risk/100))/ one_lot_margin));
  }
double normalize_lot(double lt)
  {
   double lot_step = SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP);
   lt = MathFloor(lt / lot_step) * lot_step;
   double lot_minimum = SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN);
   lt = MathMax(lt, lot_minimum);
   return(lt);
  }
bool iGetArray2(const int handle2,const int buffer2,const int start_pos2,
                const int count2,double &arr_buffer2[])
  {
   bool result2=true;
   if(!ArrayIsDynamic(arr_buffer2))
     {
      //if(InpPrintLog)
      PrintFormat("ERROR! EA: %s, FUNCTION: %s, this a no dynamic array!",__FILE__,__FUNCTION__);
      return(false);
     }
   ArrayFree(arr_buffer2);
//--- reset error code
   ResetLastError();
//--- fill a part of the iBands array with values from the indicator buffer
   int copied2=CopyBuffer(handle2,buffer2,start_pos2,count2,arr_buffer2);
   if(copied2!=count2)
     {
      //--- if the copying fails, tell the error code
      //if(InpPrintLog)
      PrintFormat("ERROR! EA: %s, FUNCTION: %s, amount to copy: %d, copied: %d, error code %d",
                  __FILE__,__FUNCTION__,count2,copied2,GetLastError());
      //--- quit with zero result - it means that the indicator is considered as not calculated
      return(false);
     }
   return(result2);
  }

Dieser Code ist eine Funktion in MQL5, die die Losgröße für einen Handel berechnet. Die Funktion nimmt eine Double-Variable namens price auf und verwendet sie zur Berechnung der Losgröße. 

Die Funktion prüft zunächst, ob es sich um eine feste Losgröße handelt, und gibt in diesem Fall die normalisierte Losgröße zurück. Ist dies nicht der Fall, wird die Marge für ein Lot berechnet und dann die Lotgröße auf der Grundlage des Kontostands und des Risikoprozentsatzes ermittelt. Sie gibt dann die normalisierte Losgröße zurück. 

Die Funktion normalize_lot wird dann verwendet, um die Losgröße auf die nächste Schrittgröße zu runden und um sicherzustellen, dass die Losgröße nicht unter der Mindestlosgröße liegt. 

Die Funktion iGetArray2 wird dann verwendet, um Werte aus dem Indikatorpuffer zu kopieren und auf Fehler zu prüfen. Wenn ein Fehler gefunden wird, gibt die Funktion false zurück.



Schlussfolgerung

Wir haben gesehen, wie Sie den Heiken Ashi mit einem anderen Indikator verwenden können.

Offensichtlich kann hier viel optimiert werden, um die Frequenz der Signale zu regulieren und ihre Qualität zu verbessern:

Wir haben gelernt, wie man diese Strategie umsetzt, und wir haben auch gelernt, wie man nutzerdefinierte Indikatoren implementiert. Wir haben gelernt, ein festes Los oder ein Los mit einem Prozentsatz des Risikos zu verwenden. Wir haben gelernt, wie man Aufträge öffnet und schließt und wie man Bedingungen für die Aufträge verwendet. Wir haben Copybuffer für den Heiken Ashi Indikator und den MA Indikator verwendet. Wir haben einen gewinnbringenden Test durchgeführt und Ergebnisse vorgelegt. Wir haben gelernt, wie man Punkte für Stop-Loss und Take-Profit addiert und mit der Anzahl der Ziffern des Symbols normalisiert. Wir haben das Symbol, Volumenschrittweite (step) und das Mindestvolumen de Symbols verwendet, um Losgröße zu normalisieren.

Ich hoffe, dieser Artikel hat Ihnen gefallen.