«

»

Feb 13

Dynamisches zweidimensionales Array zur Speicherung von Ticks in MetaTrader

show all ticks in timeframeIn diesem Blogeintrag möchte ich eine Möglichkeit vorstellen in MetaTrader Ticks zu speichern. Für die Entwicklung und das Trading von Scalping-Strategien aber auch für das Trading von Strategien die sich auf Zeitebenen unter einer Minute abspielen ist das die zwingende Voraussetzung, denn MetaTrader kennt leider keine Zeiteinheiten unter einer Minute.
Außerdem erlaubt MetaTrader nicht das Abfragen von einzelnen Ticks aus der Vergangenheit. MetaTrader kennt immer nur den aktuellen Preis oder Werte zu bestimmten vordefinierten Zeitebenen wie 1min 5min 15min usw.
Der nachfolgend vorgestellte Quellcode speichert alle eingehenden Ticks und die dazugehörige Zeit in einem dynamischen mehrdimensionalen Array. Das Tool bietet also beispielsweise die Möglichkeit alle Ticks der letzten 30 Sekunden zu speichern. Darauf aufbauend lassen sich dann Strategien entwickeln die ohne dieses Art der Datenspeicherung nicht zu entwickeln wären 🙂
Die Einstellung der Dauer der Speicherung kann bei der Aktivierung des Tools vorgenommen werden.

Wie speichert man Daten unbekannter Größe bzw. Anzahl in einem dynamischen Array?

Die Herausforderung bei der Speicherung von Tickdaten liegt in der unbekannten Anzahl von Ticks innerhalb eines gewissen Zeitraumes. Es ist also nicht möglich für zum Beispiel 10Sekunden eine Array der Größe 10 anzulegen. Es kann zwar sein, dass es in 10 Sekunden nur 10 Ticks gibt und die Arraygröße genau ausreicht, es kann aber auch sein, dass es 25 oder 50 Ticks gibt. Da es also unbekannt ist wie viele Ticks in einer bestimmten Zeiteinheit eintreffen werden, muss die Programmierung dynamisch sein, um sich der Anzahl der Marktticks anzupassen.

Die Speicherung einer unbekannten Anzahl von Daten ist nur durch den Aufbau eines dynamischen Arrays möglich.

Das große GodmodeTrader-Handbuch: Die besten Strategien der Toptrader

Wie ordnet man jedem Preis genau eine Zeit zu?

Die reine Speicherung einer Preisabfolge ist für die Erarbeitung von Scalping-Strategien, oder für die Erstellung von kleinsten Zeiteinheiten (zum Beispiel 5 Sekunden Chart) leider nicht ausreichend. Jeder Preis muss auch immer um die Information der dazugehörigen Zeit erweitert werden.
Zu diesem Zweck wäre es denkbar zwei Arrays zu pflegen, je eines für den Preis und eins für die dazugehörige Zeit. Das ist für mich aber nicht sinnvoll, denn Preis und Zeit gehören ohne jeden Zweifel mit einer 1:1 Beziehung zusammen und deshalb in ein einziges zweidimensionales Array.

#define  _tickTime         0
#define  _tickBid          1  
#define  neededArrayPlaces 2

double   myTicks[1][neededArrayPlaces];

Das zweidimensionale myTicks Array speichert also eine beliebige Anzahl Preis – Zeit Kombinationen. Die erste Dimension ist der Counter für die Anzahl der Ticks der beliebig hochgezählt werden kann (also nach jeder Veränderung der Größe des Arrays) und auf dem zweite Array-Platz ist jeweils Platz für eine Zeit und den dazugehörigen Preis. Die Adressierung von Preis und Zeit erfolgt über die Defines

_tickTime

und

_tickBid

Mal angenommen das Array ist später gefüllt und es soll der 15. Preis / Zeit ermittelt werden.
15. Zeit und Preisinformation (liegt auf Platz 14, denn ein Array fängt ja immer bei Platz 0 an)

myTicks[14][_tickBid];
myTicks[14][_tickTime];

Ablauf der Datenverarbeitung mit jedem neuen Tick

1. Mit jedem Tick wird das myTick Array um einen Platz erweitert und der aktuelle Preis und die dazugehörige Zeit auf den neuen Platz gespeichert.
2. Anschließend wird das myTick Array einmal komplett durchgescannt um alle Preis – Zeitkombinationen zu finden, die noch innerhalb des gewünschten Timeframes liegen (also zum Beispiel 30 Sekunden). Diese Ticks werden temporär in ein vorher auf 0 gesetztes Array geschrieben und dort gespeichert. Dieses temporäre Array enthält nach dem Scan des myTick Arrays also genau 100% der noch validen Ticks innerhalb des Zeitfensters.
3. Nachdem die validen Ticks im temporären Array gespeichert wurden wir das myTick Array gelöscht, mit 0 neu initialisiert, auf die Größe des temporären Arrays angepasst und dann wird der Inhalt des temporären Arrays in das myTick Array zurück geschrieben. Am Ende erhält das myTick Array wieder nur noch die validen Ticks im Zeitfenster.

Nachfolgend der Ablauf im Quellcode. In der OnTick Funktion findet man die eben eben erwähnten 3 Funktionen und noch eine Funktion die uns alle interessanten Infos auf den Chart schreibt.

void OnTick()
{
   f_addCurrentTickAtLastPlaceIntoTickArray();
   
   f_saveAllTicksThatBelongToScannedTimeframeInTempArray();
   
   f_refillMasterArrayWithValidTicks();
   
   f_showAllInfosOnScreen();
}

Hier sieht man, wie das myTick Array nach der Vergrößerung um einen Platz mit den aktuellen Zeit (TimeCurrent();) und Preis (Bid) Werten gefüllt wird.

void f_addCurrentTickAtLastPlaceIntoTickArray()
{
   string fName = StringConcatenate("void f_addCurrentTickAtLastPlaceIntoTickArray");
   // ------------------------------------------------------------------------------------------------
   
   if (f_resizeTickArrayToSaveCurrentTick() > 0)
   {
      uint currentUnusedLastPlaceInArray;
      
      currentUnusedLastPlaceInArray = ArraySize(myTicks)/neededArrayPlaces-2;
   
      myTicks[currentUnusedLastPlaceInArray][_tickTime] = TimeCurrent();
      myTicks[currentUnusedLastPlaceInArray][_tickBid] = Bid;
   }
}

Anschließend wird in einer Schleife durch alle vorhandenen Zeiten (also Array-Plätze mit _tickTime) geloopt und Werte die noch innerhalb des scannedTimeframe liegen werden in das temporäre Array (copyOfMyTicks) gespeichert.

void f_saveAllTicksThatBelongToScannedTimeframeInTempArray(bool forceLoggingInThisFunction = false)
{
   string fName = StringConcatenate("void f_saveAllTicksThatBelongToScannedTimeframeInTempArray");
   // ------------------------------------------------------------------------------------------------
   
   ArrayResize(copyOfMyTicks, 1);
   
   for (int thisPlace = 0; thisPlace <= ArraySize(myTicks)/neededArrayPlaces-1; thisPlace ++)
   {
      if (myTicks[thisPlace][_tickTime] >= TimeCurrent() - scannedTimeframe)
      {
         copyOfMyTicks[ArraySize(copyOfMyTicks)/neededArrayPlaces - 1][_tickTime] = myTicks[thisPlace][_tickTime];
         copyOfMyTicks[ArraySize(copyOfMyTicks)/neededArrayPlaces - 1][_tickBid] = myTicks[thisPlace][_tickBid];
         
         ArrayResize(copyOfMyTicks, ArraySize(copyOfMyTicks)/neededArrayPlaces + 1);
      }
   }
}

Und zu guter letzt wird das myTicks Array auf die Größe des temporären Arrays adjustiert, mit 0 neu initialisiert und anschließend aus dem temporären Array mit den validen Werten neu befüllt.

void f_refillMasterArrayWithValidTicks()
{
   string fName = StringConcatenate("void f_refillMasterArrayWithValidTicks");
   // ------------------------------------------------------------------------------------------------
   
   int myResizedArray = ArrayResize(myTicks, ArraySize(copyOfMyTicks)/2);
   
   if (myResizedArray > 0)
   {
      ArrayInitialize(myTicks, 0);
      ArrayCopy(myTicks, copyOfMyTicks,0,0,WHOLE_ARRAY);
   }
   else
      f_PrintMeTheErrorThatHasOccured(GetLastError(), fName);
}

Nachfolgend noch zwei Bücher, die Ihnen helfen werden wenn Sie sich mit der Programmierung oder dem Trading noch intensiver beschäftigen möchten.

Wer sich mit Arrays noch nicht so gut auskennt und gerne etwas tiefer in die Materie einsteigen will, dem sei ein sehr gutes Buch von Joachim Goll und Manfred Dausmann empfohlen. Mit diesem Buch kann man die Programmierung in C lernen, was der Art und Weise der MQL-Programmierung sehr nahe kommt. Auch wenn man nicht jede Technik aus C verwenden kann in MQL, so hilft es doch sehr sich mit wesentlichen Elementen der Programmierung vertraut zu machen.

Wer mit der Programmierung schon vertraut ist, aber noch mehr über die Grundlagen des Funktionierens der Märkte lernen möchte, dem sei die Plfichtlektüre für jeden angehenden Trader und Systementwickler ans Herz gelegt. Michael Voigt mit seiner wirklich ausgezeichneten Abhandlung über die Märke und deren klassichen Verhaltensweisen.

Da aufaubend auf den realen Ticks die Möglichkeit der Entwicklung ausgefallener Strategien sehr mächtig ist und viele ungeahnte Möglichkeiten bietet, die sich mit herkömmlichen Strategien in den bekannten Zeiteinheiten nicht darstellen lassen, werde ich in späteren Blog-Einträgen auf einige praktische Ansätze des Tradings eingehen.

Zum Schluss der gesamte MQL-Quellcode und auch die sofort verwendbare ex4-Datei hier kostenlos zum Download für alle registrierten Nutzer und natürlich wie immer für jegliche private Nutzung frei verfügbar. Wer noch keinen User hat, einfach einen eigenen USER-Registrieren, valide Mail-Adresse eingeben, Mail-Adresse nach Antwort vom Server bestätigen und schon steht sämtlicher Quellcode aller Blog-Einträge zum Download zur Verfügung.

Wir übernehmen wie immer keine Garantie für die korrekte Funktionsweise dieses Tools bei allen MetaTrader Brokern die es auf der Welt gibt. Bitte auch dieses MetaTrader Tool wie immer bei Ihrem Broker testen und bei Fragen gerne melden.

Quellcode zum Tool zur Speicherung von Ticks in einem mehrdimensionalen dynamischen Array

Viel Erfolg beim selber ausprobieren
Thomas @ ForexInnovation

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*