//+------------------------------------------------------------------+
//| CustomTicksAdd.mq5 |
//| Copyright 2024, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, MetaQuotes Ltd."
#property link "https://www.mql5.com"
#property version "1.00"
#define CUSTOM_SYMBOL_NAME Symbol()+".C" // Name des nutzerdefinierten Symbols
#define CUSTOM_SYMBOL_PATH "Forex" // Name der Gruppe, in der das Symbol erstellt werden soll
#define CUSTOM_SYMBOL_ORIGIN Symbol() // Name des Symbols, das als Basis des nutzerdefinierten Symbols dienen soll
#define DATATICKS_TO_COPY UINT_MAX // Anzahl der kopierten Ticks
#defineDATATICKS_TO_PRINT 20 // Anzahl der an das Log gesendeten Ticks
//+------------------------------------------------------------------+
//| Skript Programm Start Funktion |
//+------------------------------------------------------------------+
void OnStart()
{
//--- Abrufen des Fehlercodes beim Erstellen eines nutzerdefinierten Symbols
int create=CreateCustomSymbol(CUSTOM_SYMBOL_NAME, CUSTOM_SYMBOL_PATH, CUSTOM_SYMBOL_ORIGIN);
//--- wenn der Fehlercode nicht 0 (erfolgreiche Symbolerstellung) und nicht 5304 (Symbol wurde bereits erstellt) ist - verlasse das Skript
if(create!=0 && create!=5304)
return;
//--- Abrufen der Tick-Daten des Standardsymbols in einem MqlTick-Array
MqlTick array[]={};
if(!GetTicksToArray(CUSTOM_SYMBOL_ORIGIN, DATATICKS_TO_COPY, array))
return;
//--- Ausdruck der Zeit des ersten und des letzten empfangenen Ticks des Standardsymbols
int total=(int)array.Size();
PrintFormat("First tick time: %s.%03u, Last tick time: %s.%03u",
TimeToString(array[0].time, TIME_DATE|TIME_MINUTES|TIME_SECONDS), array[0].time_msc%1000,
TimeToString(array[total-1].time, TIME_DATE|TIME_MINUTES|TIME_SECONDS), array[total-1].time_msc%1000);
//--- Ausdruck von DATATICKS_TO_PRINT letzten Ticks des Standardsymbols in das Log
PrintFormat("\nThe last %d ticks for the standard symbol '%s':", DATATICKS_TO_PRINT, CUSTOM_SYMBOL_ORIGIN);
for(int i=total-DATATICKS_TO_PRINT; i<total; i++)
{
if(i<0)
continue;
PrintFormat(" %dth Tick: %s", i, GetTickDescription(array[i]));
}
//--- ein nutzerdefiniertes Symbol zum Fenster der Marktübersicht hinzufügen
ResetLastError();
if(!SymbolSelect(CUSTOM_SYMBOL_NAME, true))
{
Print("SymbolSelect() failed. Error ", GetLastError());
return;
}
//--- Hinzufügen der Daten des Tick-Arrays zur Preishistorie des nutzerdefinierten Symbols
Print("...");
uint start=GetTickCount();
PrintFormat("Start of adding %u ticks to the history of the custom symbol '%s'", array.Size(), CUSTOM_SYMBOL_NAME);
int added=CustomTicksAdd(CUSTOM_SYMBOL_NAME, array);
PrintFormat("Added %u ticks to the history of the custom symbol '%s' in %u ms", added, CUSTOM_SYMBOL_NAME, GetTickCount()-start);
//--- Abrufen der Tick-Daten des nutzerdefinierten Symbols mit dem MqlTick-Array
Print("...");
if(!GetTicksToArray(CUSTOM_SYMBOL_NAME, array.Size(), array))
return;
//--- Ausdruck der Zeit des ersten und letzten empfangenen Ticks des nutzerdefinierten Symbols
total=(int)array.Size();
PrintFormat("First tick time: %s.%03u, Last tick time: %s.%03u",
TimeToString(array[0].time, TIME_DATE|TIME_MINUTES|TIME_SECONDS), array[0].time_msc%1000,
TimeToString(array[total-1].time, TIME_DATE|TIME_MINUTES|TIME_SECONDS), array[total-1].time_msc%1000);
//--- Ausdruck von DATATICKS_TO_PRINT letzten Ticks des nutzerdefinierten Symbols in das Log
PrintFormat("\nThe last %d ticks for the custom symbol '%s':", DATATICKS_TO_PRINT, CUSTOM_SYMBOL_NAME);
for(int i=total-DATATICKS_TO_PRINT; i<total; i++)
{
if(i<0)
continue;
PrintFormat(" %dth Tick: %s", i, GetTickDescription(array[i]));
}
//--- einen Hinweis zu den Tasten zur Beendigung des Skripts im Kommentar des Charts anzeigen
Comment(StringFormat("Press 'Esc' to exit or 'Del' to delete the '%s' symbol and exit", CUSTOM_SYMBOL_NAME));
//--- warten, bis die Tasten „Esc“ oder „Entf“ gedrückt werden, um die Endlosschleife zu verlassen
while(!IsStopped() && TerminalInfoInteger(TERMINAL_KEYSTATE_ESCAPE)==0)
{
Sleep(16);
//--- beim Drücken von Entf das erstellte nutzerdefinierte Symbol und seine Daten löschen
if(TerminalInfoInteger(TERMINAL_KEYSTATE_DELETE)<0)
{
//--- Balkendaten löschen
int deleted=CustomRatesDelete(CUSTOM_SYMBOL_NAME, 0, LONG_MAX);
if(deleted>0)
PrintFormat("%d history bars of the custom symbol '%s' were successfully deleted", deleted, CUSTOM_SYMBOL_NAME);
//--- Tickdaten löschen
deleted=CustomTicksDelete(CUSTOM_SYMBOL_NAME, 0, LONG_MAX);
if(deleted>0)
PrintFormat("%d history ticks of the custom symbol '%s' were successfully deleted", deleted, CUSTOM_SYMBOL_NAME);
//--- Symbol löschen
if(DeleteCustomSymbol(CUSTOM_SYMBOL_NAME))
PrintFormat("Custom symbol '%s' deleted successfully", CUSTOM_SYMBOL_NAME);
break;
}
}
//--- Chart vor dem Ende löschen
Comment("");
/*
Ergebnis:
Requested 4294967295 ticks to download tick history for the symbol 'EURUSD'
The tick history for the 'EURUSD' symbol is received in the amount of 351183943 ticks in 56454 ms
First tick time: 2011.12.19 00:00:08.000, Last tick time: 2024.06.20 21:18:12.010
The last 20 ticks for the standard symbol 'EURUSD':
351183923th Tick: 2024.06.20 21:17:46.380 Bid=1.07124 (Info tick)
351183924th Tick: 2024.06.20 21:17:47.779 Ask=1.07125 Bid=1.07125 (Info tick)
351183925th Tick: 2024.06.20 21:17:48.584 Ask=1.07124 Bid=1.07124 (Info tick)
351183926th Tick: 2024.06.20 21:17:49.481 Ask=1.07125 (Info tick)
351183927th Tick: 2024.06.20 21:17:49.985 Ask=1.07122 Bid=1.07122 (Info tick)
351183928th Tick: 2024.06.20 21:17:50.482 Ask=1.07124 Bid=1.07124 (Info tick)
351183929th Tick: 2024.06.20 21:17:51.584 Ask=1.07123 Bid=1.07123 (Info tick)
351183930th Tick: 2024.06.20 21:17:52.786 Ask=1.07124 Bid=1.07124 (Info tick)
351183931th Tick: 2024.06.20 21:17:53.487 Ask=1.07125 Bid=1.07125 (Info tick)
351183932th Tick: 2024.06.20 21:17:53.989 Ask=1.07126 Bid=1.07126 (Info tick)
351183933th Tick: 2024.06.20 21:17:55.789 Ask=1.07125 Bid=1.07125 (Info tick)
351183934th Tick: 2024.06.20 21:17:58.495 Ask=1.07126 Bid=1.07126 (Info tick)
351183935th Tick: 2024.06.20 21:18:00.102 Bid=1.07126 (Info tick)
351183936th Tick: 2024.06.20 21:18:00.698 Ask=1.07129 Bid=1.07129 (Info tick)
351183937th Tick: 2024.06.20 21:18:03.699 Bid=1.07129 (Info tick)
351183938th Tick: 2024.06.20 21:18:04.699 Ask=1.07128 Bid=1.07128 (Info tick)
351183939th Tick: 2024.06.20 21:18:05.901 Ask=1.07129 Bid=1.07129 (Info tick)
351183940th Tick: 2024.06.20 21:18:07.606 Ask=1.07128 Bid=1.07128 (Info tick)
351183941th Tick: 2024.06.20 21:18:11.512 Ask=1.07127 Bid=1.07127 (Info tick)
351183942th Tick: 2024.06.20 21:18:12.010 Ask=1.07126 Bid=1.07126 (Info tick)
...
Start of adding 351183943 ticks to the history of the custom symbol 'EURUSD.C'
Added 351183943 ticks to the history of the custom symbol 'EURUSD.C' in 269890 ms
...
Requested 351183943 ticks to download tick history for the symbol 'EURUSD.C'
The tick history for the 'EURUSD.C' symbol is received in the amount of 351183943 ticks in 116407 ms
First tick time: 2011.12.19 00:00:08.000, Last tick time: 2024.06.20 21:18:12.010
The last 20 ticks for the custom symbol 'EURUSD.C':
351183923th Tick: 2024.06.20 21:17:46.380 Ask=1.07124 Bid=1.07124 (Info tick)
351183924th Tick: 2024.06.20 21:17:47.779 Ask=1.07125 Bid=1.07125 (Info tick)
351183925th Tick: 2024.06.20 21:17:48.584 Ask=1.07124 Bid=1.07124 (Info tick)
351183926th Tick: 2024.06.20 21:17:49.481 Ask=1.07125 Bid=1.07125 (Info tick)
351183927th Tick: 2024.06.20 21:17:49.985 Ask=1.07122 Bid=1.07122 (Info tick)
351183928th Tick: 2024.06.20 21:17:50.482 Ask=1.07124 Bid=1.07124 (Info tick)
351183929th Tick: 2024.06.20 21:17:51.584 Ask=1.07123 Bid=1.07123 (Info tick)
351183930th Tick: 2024.06.20 21:17:52.786 Ask=1.07124 Bid=1.07124 (Info tick)
351183931th Tick: 2024.06.20 21:17:53.487 Ask=1.07125 Bid=1.07125 (Info tick)
351183932th Tick: 2024.06.20 21:17:53.989 Ask=1.07126 Bid=1.07126 (Info tick)
351183933th Tick: 2024.06.20 21:17:55.789 Ask=1.07125 Bid=1.07125 (Info tick)
351183934th Tick: 2024.06.20 21:17:58.495 Ask=1.07126 Bid=1.07126 (Info tick)
351183935th Tick: 2024.06.20 21:18:00.102 Ask=1.07126 Bid=1.07126 (Info tick)
351183936th Tick: 2024.06.20 21:18:00.698 Ask=1.07129 Bid=1.07129 (Info tick)
351183937th Tick: 2024.06.20 21:18:03.699 Ask=1.07129 Bid=1.07129 (Info tick)
351183938th Tick: 2024.06.20 21:18:04.699 Ask=1.07128 Bid=1.07128 (Info tick)
351183939th Tick: 2024.06.20 21:18:05.901 Ask=1.07129 Bid=1.07129 (Info tick)
351183940th Tick: 2024.06.20 21:18:07.606 Ask=1.07128 Bid=1.07128 (Info tick)
351183941th Tick: 2024.06.20 21:18:11.512 Ask=1.07127 Bid=1.07127 (Info tick)
351183942th Tick: 2024.06.20 21:18:12.010 Ask=1.07126 Bid=1.07126 (Info tick)
*/
}
//+------------------------------------------------------------------+
//| Nutzerdefiniertes Symbol erstellen, Fehlercode zurückgeben |
//+------------------------------------------------------------------+
int CreateCustomSymbol(const string symbol_name, const string symbol_path, const string symbol_origin=NULL)
{
//--- Definition des Namens eines Symbols, auf dem ein nutzerdefiniertes Symbol basieren soll.
string origin=(symbol_origin==NULL ? Symbol() : symbol_origin);
//--- Wenn das Erstellen eines nutzerdefinierten Symbols fehlgeschlagen ist und nicht der Fehler 5304 aufgetreten ist, wird es im Log gemeldet.
ResetLastError();
int error=0;
if(!CustomSymbolCreate(symbol_name, symbol_path, origin))
{
error=GetLastError();
if(error!=5304)
PrintFormat("CustomSymbolCreate(%s, %s, %s) failed. Error %d", symbol_name, symbol_path, origin, error);
}
//--- Erfolg
return(error);
}
//+------------------------------------------------------------------+
//| Nutzerdefiniertes Symbol entfernen |
//+------------------------------------------------------------------+
bool DeleteCustomSymbol(const string symbol_name)
{
//--- das Symbol aus dem Fenster der Marktübersicht ausblenden
ResetLastError();
if(!SymbolSelect(symbol_name, false))
{
PrintFormat("SymbolSelect(%s, false) failed. Error %d", GetLastError());
return(false);
}
//--- Wenn das Löschen eines nutzerdefinierten Symbols fehlgeschlagen ist, wird das im Log gemeldet und „false“ zurückgegeben.
ResetLastError();
if(!CustomSymbolDelete(symbol_name))
{
PrintFormat("CustomSymbolDelete(%s) failed. Error %d", symbol_name, GetLastError());
return(false);
}
//--- Erfolg
return(true);
}
//+------------------------------------------------------------------+
//| Abrufen der angegebenen Anzahl von Ticks im Array |
//+------------------------------------------------------------------+
bool GetTicksToArray(const string symbol, const uint count, MqlTick &array[])
{
//--- Benachrichtigung über den Beginn des Ladens historischer Daten
PrintFormat("Requested %u ticks to get tick history for the symbol '%s'", count, symbol);
//--- 3 Versuche, Ticks abzurufen
int attempts=0;
while(attempts<3)
{
//--- Startzeit vor Empfang der Ticks messen
uint start=GetTickCount();
//--- Anforderung der Tick-Historie seit 1970.01.01 00:00.001 (Parameter von=1 ms)
int received=CopyTicks(symbol, array, COPY_TICKS_ALL, 1, count);
if(received!=-1)
{
//--- Informationen über die Anzahl der Ticks und die verwendete Zeit anzeigen
PrintFormat("The tick history for the '%s' symbol is received in the amount of %u ticks in %d ms", symbol, received, GetTickCount()-start);
//--- Wenn die Tick-Historie synchronisiert ist, ist der Fehlercode gleich Null - return 'true'
if(GetLastError()==0)
return(true);
PrintFormat("%s: Ticks are not synchronized yet, %d ticks received for %d ms. Error=%d",
symbol, received, GetTickCount()-start, GetLastError());
}
//--- Versuche zählen
attempts++;
//--- eine Pause von einer Sekunde, um auf das Ende der Synchronisierung der Tick-Datenbank zu warten
Sleep(1000);
}
//--- Konnten die Ticks nach 3 Versuchen nicht kopiert werden:
return(false);
}
//+------------------------------------------------------------------+
//| gibt die String-Beschreibung eines Ticks zurück |
//+------------------------------------------------------------------+
string GetTickDescription(MqlTick &tick)
{
string desc=StringFormat("%s.%03u ", TimeToString(tick.time, TIME_DATE|TIME_MINUTES|TIME_SECONDS),tick.time_msc%1000);
//--- Prüfen der Flags
bool buy_tick = ((tick.flags &TICK_FLAG_BUY) == TICK_FLAG_BUY);
bool sell_tick = ((tick.flags &TICK_FLAG_SELL) == TICK_FLAG_SELL);
bool ask_tick = ((tick.flags &TICK_FLAG_ASK) == TICK_FLAG_ASK);
bool bid_tick = ((tick.flags &TICK_FLAG_BID) == TICK_FLAG_BID);
bool last_tick = ((tick.flags &TICK_FLAG_LAST) == TICK_FLAG_LAST);
bool volume_tick= ((tick.flags &TICK_FLAG_VOLUME)== TICK_FLAG_VOLUME);
//--- zuerst den Tick auf die Handelsflags prüfen (es gibt keine für CustomTicksAdd())
if(buy_tick || sell_tick)
{
//--- eine Ausgabe für einen Handelstick bilden
desc += (buy_tick ? StringFormat("Buy Tick: Last=%G Volume=%d ", tick.last, tick.volume) : "");
desc += (sell_tick? StringFormat("Sell Tick: Last=%G Volume=%d ",tick.last, tick.volume) : "");
desc += (ask_tick ? StringFormat("Ask=%G ", tick.ask) : "");
desc += (bid_tick ? StringFormat("Bid=%G ", tick.ask) : "");
desc += "(Trade tick)";
}
else
{
//--- die Ausgabe für einen Info-Tick etwas anders gestalten
desc += (ask_tick ? StringFormat("Ask=%G ", tick.ask) : "");
desc += (bid_tick ? StringFormat("Bid=%G ", tick.ask) : "");
desc += (last_tick ? StringFormat("Last=%G ", tick.last) : "");
desc += (volume_tick? StringFormat("Volume=%d ",tick.volume): "");
desc += "(Info tick)";
}
//--- Tick-Beschreibung zurückgeben
return(desc);
}
|