s-Downloader
Download scriptThis script is designed to automate the process of downloading historical price data for every financial instrument listed in your trading platform's "Market Watch" window. Instead of requiring you to manually open and scroll through every chart, the script performs these actions automatically.
Core Logic Overview
The script functions by simulating human interactions with the trading platform. It treats the software as if a user were physically clicking through menus, pressing keys on a keyboard, and waiting for data to load.
1. Data Preparation Before starting the download process, the script scans your platform's internal files to identify every available symbol (currency pair, stock, etc.). it creates a temporary list of these symbols so it knows exactly which ones need to be processed.
2. Automated Navigation The script systematically navigates the "Market Watch" window. It performs the following steps for each instrument:
- Selection: It moves through the list of symbols one by one.
- Chart Opening: It automatically opens a new chart window for the current symbol.
- Timeframe Rotation: For every symbol, it cycles through several predefined timeframes (such as H1, M15, etc.) to ensure that historical data is downloaded across various intervals.
3. The "Home Key" Downloading Mechanism To actually trigger the download of historical bars, the script simulates pressing the HOME key on a keyboard.
- When the platform receives this simulated keypress, it attempts to pull the oldest available data into the current view.
- The script repeats this action rapidly until the "time" at the beginning of the chart stops changing. This indicates that the platform has successfully reached the earliest available history.
4. Smart Monitoring and Cleanup The logic includes several "quality of life" features to ensure it runs smoothly without manual intervention:
- Progress Check: It monitors whether the data is actually loading. If the "time" doesn't change after several attempts, it assumes the history is fully downloaded and moves to the next step.
- Refreshing: It periodically refreshes the charts during the process to ensure the history stays up-to-date.
- Automatic Closing: Once the historical data for a specific symbol and timeframe is secured, the script closes that specific chart window automatically and moves on to the next symbol in the list.
Summary of Behavior
For the user, this means you can run the script and leave the terminal active. The script will take over the "manual labor" of opening charts, cycling through timeframes, and scrolling back to the beginning of history for every single instrument available in your account, ultimately populating your terminal with a complete historical database.
//+------------------------------------------------------------------+
//| s-Downloader.mq4 |
//| Copyright © 2009, Talex |
//| talex.kaliningrad@gmail.com |
//+------------------------------------------------------------------+
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Äàííûé ñêðèïò çàêà÷èâàåò èñòîðèþ ïî âñåì ñèìâîëàì, êîòîðûå íàõîäÿòñÿ
â "Îáçîðå ðûíêà" è òàéìôðåéìàì. Ïîäêà÷êà îñóùåñòâëÿåòñÿ ýìóëÿöèåé
íàæàòèÿ êíîïêè HOME, îñóùåñòâëÿÿ ïðè ýòîì êîíòðîëü çàêà÷êè, ò.å.
åñëè çàêà÷êà ïî êëàâèøå îñòàíîâèëàñü íà âðåìÿ îêîëî 5 ñåêóíä, òî
ñ÷èòàåòñÿ, ÷òî âñå ïî äàííîìó ñèìâîëó è òàéìôðåéìó çàêà÷àëîñü è
íà÷èíàåòñÿ ñëåäóþùàÿ èòòåðàöèÿ. Òàêæå ñêðèïò îáíîâëÿåò ãðàôèê, äîêà-
÷èâàÿ, òàêèì îáðàçîì, "ñâåæóþ" èñòîðèþ.
ÂÎ ÂÐÅÌß ÐÀÁÎÒÛ ÑÊÐÈÏÒÀ ÍÅ ÏÐÎÈÇÂÎÄÈÒÜ ÍÈÊÀÊÈÕ ÄÅÉÑÒÂÈÉ Ñ ÒÅÐÌÈÍÀËÎÌ
ÇÀÊÀ×ÊÀ ÏÐÎÄÎËÆÀÅÒÑß ÄÎÂÎËÜÍÎ ÏÐÎÄÎËÆÈÒÅËÜÍÎÅ ÂÐÅÌß, ÏÎÝÒÎÌÓ ËÓרÅ
ÎÑÒÀÂËßÒÜ ÑÊÐÈÏÒ ÐÀÁÎÒÀÒÜ ÍÀ ÍÎ×Ü.
Õî÷ó ïîáëàãîäàðèòü Ilnur, getch, Zhunko, YuraZ è äðóãèõ ó÷àñòíèêîâ
ôîðóìà http://forum.mql4.com/ru/ çà èíòåðåñíûå èäåè ïî WINAPI, áåç
íèõ ÿ âðÿä ëè áû ñäåëàë ýòîò ñêðèïò.
*///++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#property copyright "Copyright © 2009, Talex"
#property link "talex.kaliningrad@gmail.com"
#import "kernel32.dll"
int _lopen (string path, int of);
int _llseek (int handle, int offset, int origin);
int _lread (int handle, string buffer, int bytes);
int _lclose (int handle);
#import
#import "user32.dll"
int GetAncestor (int hWnd, int gaFlags);
int GetParent (int hWnd);
int GetDlgItem (int hDlg, int nIDDlgItem);
int SendMessageA (int hWnd, int Msg, int wParam, int lParam);
int PostMessageA (int hWnd, int Msg, int wParam, int lParam);
#import
#define LVM_GETITEMCOUNT 0x1004
#define WM_COMMAND 0x0111
#define WM_SCROLL 0x80F9
#define WM_KEYDOWN 0x0100
#define WM_CLOSE 0x0010
#define VK_HOME 0x24
#define VK_END 0x23
#define VK_DOWN 0x28
int nsymb,Pause=500;
string Symbols[]; // ìàññèâ â êîòîðîì áóäóò õðàíèòñÿ ñèìâîëû
//+------------------------------------------------------------------+
//| script program start function |
//+------------------------------------------------------------------+
void start() {
int i;
//--------------------------------------------------------------------
if(GlobalVariableCheck("glSymbolHandle")) { // Åñëè çàïóñêàåì íå ïåðâûé ðàç.
GlobalVariableSet("glSymbolHandle",WindowHandle(Symbol(),Period())); // óñòàíîâèì íîâîå çíà÷åíèå ãëîá. ïåðåìåííîé
for(i=0;i<nsymb;i++) { // â öèêëå íàéäåì ïîçèöèþ ñèìâîëà ãðàôèêà
if(Symbols[i]==Symbol()) { // â ìàññèâå Symbols[i] è çíà÷åíèå
GlobalVariableSet("glSymbol",i); // ïðèñâîèì ãëîá.ïåðåìåííîé
return;
}
}
return;
}
MarketInfoToSymbols(); // çàïèñûâàåì íàáîð ñèìâîëîâ ïðåäñòàâëÿåìûõ ÄÖ â ìàññèâ Symbols[]
DownloadHomeKey(); // ïîî÷åðåäè îòêðûâàåì ãðàôèêè èç "Îáçîðà ðûíêà"
return; // è íàæèìàåì êëàâèøó HOME, ïðîâåðÿÿ îêîí÷àíèå çàãðóçêè
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| MarketInfoToSymbols() |
//| Íàçíà÷åíèå: |
//| Çàïèñûâàåò íàáîð ñèìâîëîâ ïðåäñòàâëÿåìûõ ÄÖ â ãëîáàë. ìàññèâ |
//| Symbols[], ïðèøëîñü ñäåëàòü ÷åðåç ïðîìåæóòî÷íûé ôàéë, èíà÷å |
//| âîçíèêàëà ïðîáëåìà http://forum.mql4.com/ru/23603 |
//+------------------------------------------------------------------+
void MarketInfoToSymbols() {
int i,handle,handleset,size;
string symb="symbols ",path;
//--------------------------------------
size=1936;
path=StringConcatenate(TerminalPath(),"\\history\\",AccountServer(),"\\symbols.raw");
handle=_lopen(path,0); // îòêðûâàåì symbols.raw
if(handle<0) {
Print("Îøèáêà îòêðûòèÿ ôàéëà symbols.raw : ",GetLastError());
return;
}
handleset=FileOpen("quoting.set",FILE_READ | FILE_WRITE); // îòêðûâàåì ïðîìåæóòî÷íûé ôàéë
if(handleset<0) {
Print("Îøèáêà îòêðûòèÿ ôàéëà quoting.set : ",GetLastError());
return;
}
nsymb=_llseek(handle,0,2)/size; // íàõîäèì êîëè÷åñòâî ñèìâîëîâ
for(i=0;i<nsymb;i++){ // â öèêëå çàïèñûâàåì âñå
_llseek(handle,i*size,0); // ñèìâîëû â ïðîìåæóòî÷íûé
_lread(handle,symb,12); // ôàéë
FileWrite(handleset,symb);
}
_lclose(handle); // çàêðûâàåì symbols.raw
if(!FileSeek(handleset,0,SEEK_SET)) {
Print("Êóðñîð íå ñìåñòèëñÿ â íà÷àëî ôàéëà quoting.set èç-çà îøèáêè: ",GetLastError());
}
ArrayResize(Symbols,nsymb); // ðåñàéçèì ìàññèâ ñèìâîëîâ
for(i=0;i<nsymb;i++){ // â öèêëå çàãîíÿåì èç ïðî-
Symbols[i]=FileReadString(handleset); // ìåæóòî÷íîãî ôàéëà â ìàññèâ
} // âñå ñèìâîëû
FileClose(handleset); // çàêðûâàåì ïðîìåæóòî÷íûé ôàéë
FileDelete("quoting.set"); // óäàëÿåì ïðîìåæóòî÷íûé ôàéë
return;
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| DownloadHomeKey() |
//| Íàçíà÷åíèå: |
//| Ïîäêà÷êà èñòîðèè â òåðìèíàë ïî âñåì ñèìâîëàì è ÒÔ ñ ýìóëÿöèåé|
//| íàæàòèÿ êëàâèøè HOME |
//+------------------------------------------------------------------+
void DownloadHomeKey() {
int i,j,k,hmain,handle,handlechart,count,num,
TF[8]={33136,33134,33141,33334,33137,33138,33139,33140},
tf[9]={60,240,1440,10080,43200,1,5,15,30};
datetime ebt,prebt;
//------------------------------------
GlobalVariableSet("glSymbolHandle",WindowHandle(Symbol(),Period()));
hmain=GetAncestor(WindowHandle(Symbol(),Period()),2); // íàéäåì ãëàâíîå îêíî òåðìèíàëà.
if (hmain!=0) {
handle=GetDlgItem(hmain,0xE81C);
handle=GetDlgItem(handle,0x50);
handle=GetDlgItem(handle,0x8A71); // íàõîäèì ñïèñîê ñèìâîëîâ.
count=SendMessageA(handle,LVM_GETITEMCOUNT,0,0); // ïîëó÷àåì êîëè÷åñòâî ýëåìåíòîâ ñïèñêà.
}
else Print("Îøèáêà : ",GetLastError());
for(i=1;i<=count&&!IsStopped();i++) { // â öèêëå îòêðûâàåì îêíà ñ ãðàôèêàìè.
OpenChart(i,hmain); // îòêðûâàåì ãðàôèê î÷åðåäíîãî ñèìâîëà èç îêíà "Îáçîð ðûíêà"
Sleep(Pause);
PostMessageA(hmain,WM_COMMAND,33042,0); // çàïóñêàåì íà òîëüêî, ÷òî îòêðûòîì ãðàôèêå ýòîò ñêðèïò.
Sleep (Pause);
handlechart=GlobalVariableGet ("glSymbolHandle"); // îïðåäåëÿåì äåñêðèïòîð òîëüêî, ÷òî îòêðûòîãî îêíà.
for (j=0;j<9&&!IsStopped();j++) { // ïåðåêëþ÷åíèå ÒÔ è ýìóëÿöèÿ
if (j!=0) { // ïåðâóþ èòåðàöèþ ïðîïóñêàåì. Ïî óìîë÷àíèþ ïåðâûé ÒÔ H1.
PostMessageA(handlechart,WM_COMMAND,TF[j-1],0);// óñòàíàâëèâàåì ÒÔ.
}
k=0;
PostMessageA(handlechart,WM_COMMAND,WM_SCROLL,0); // îòêëþ÷àåì ñêðîëëèíã
while(!IsStopped()) {
PostMessageA(handlechart,WM_KEYDOWN,VK_HOME,0);// íàæèìàåì êëàâèøó "HOME"
Sleep(200);
PostMessageA(handlechart,WM_KEYDOWN,VK_HOME,0);// íàæèìàåì êëàâèøó "HOME"
Sleep(200);
PostMessageA(handlechart,WM_KEYDOWN,VK_HOME,0);// íàæèìàåì êëàâèøó "HOME"
Sleep(200);
PostMessageA(handlechart,WM_KEYDOWN,VK_HOME,0);// íàæèìàåì êëàâèøó "HOME"
Sleep(200);
PostMessageA(handlechart,WM_KEYDOWN,VK_HOME,0);// íàæèìàåì êëàâèøó "HOME"
Sleep(200);
num=GlobalVariableGet("glSymbol"); // ïîëó÷àåì èíäåêñ ñèìâîëà
ebt=iTime(Symbols[num],tf[j],(iBars(Symbols[num],tf[j])-1));// ïîëó÷àåì âðåìÿ ïîñëåäíåãî áàðà
if(ebt!=prebt) { // åñëè âðåìÿ èçìåíÿåòñÿ, òî ïîäêà÷èâàåì äàëüøå
prebt=ebt;
k=0;
}
else k++; // èíà÷å óâåëè÷èâàåì çíà÷åíèå ïåðåìåííîé íà 1
if(k>4) break; // è åñëè îíî áîëüøå 4, ïðåêðàùàåì "æàòü" íà HOME
}
PostMessageA(handlechart,WM_KEYDOWN,VK_END,0); // óñòàíàâëèâàåò ãðàôèê â êîíåö (èëè íà÷àëî?) :)
PostMessageA(handlechart,WM_COMMAND,WM_SCROLL,0); // âêëþ÷àåì ñêðîëëèíã
PostMessageA(handlechart,WM_COMMAND,33324,0); // îáíîâëÿåì îêíî äëÿ ïîäêà÷êè "ñâåæåé èñòîðèè"
Sleep(Pause);
}
PostMessageA(GetParent(handlechart),WM_CLOSE,0,0); // çàêðûâàåì îêíî ãðàôèêà.
Sleep(Pause);
}
GlobalVariableDel ("glSymbolHandle"); // óäàëÿåì ãëîáàëüíûå ïåðåìåííûå
GlobalVariableDel ("glSymbol");
return;
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| OpenChart() |
//| Íàçíà÷åíèå: |
//| Îòêðûâàåò îêíî ãðàôèêà ñèìâîëà èç îêíà "Îáçîð ðûíêà". |
//+------------------------------------------------------------------+
void OpenChart (int Num, int handle) {
int hwnd;
//-------------------------------------
hwnd=GetDlgItem(handle,0xE81C);
hwnd=GetDlgItem(hwnd,0x50);
hwnd=GetDlgItem(hwnd,0x8A71); // Íàøëè "Îáçîð ðûíêà".
PostMessageA(hwnd,WM_KEYDOWN,VK_HOME,0); // Âåðõíÿÿ ñòðî÷êà îêíà "Îáçîð ðûíêà".
while (Num>1) {
PostMessageA(hwnd,WM_KEYDOWN,VK_DOWN,0); // Ñìåñòèëèñü íà íóæíóþ ñòðî÷êó.
Num--;
}
PostMessageA(handle,WM_COMMAND,33160,0); // Îòêðûëè ãðàôèê.
return;
}
//+------------------------------------------------------------------+
Comments