news
Download scriptThis script functions as an automated economic news tracker designed to pull live data from the web and display it directly on your trading charts. Instead of requiring you to manually check websites for upcoming economic events, it handles the data collection, filtering, and visual representation automatically.
Core Functionality
1. Live Data Retrieval The script connects to an external economic calendar via the internet. It downloads a list of global economic events, including their scheduled times, descriptions, and importance levels. Because it interacts with the internet, it includes a check to ensure your platform settings allow for necessary external connections.
2. Smart Filtering and Customization The tool is highly customizable to ensure you only see the information relevant to your trading:
- Currency Specifics: You can choose to monitor specific currencies (like USD, EUR, GBP, etc.). The script even features an "Auto-select" mode that detects which currencies are in your current chart and highlights the news for them automatically.
- Importance Levels: You can filter out minor news to focus only on High, Medium, or Low impact events.
- Language Support: It includes a translation mechanism that can swap specific news terms into Russian using a local file.
3. Visual Chart Integration Once the data is retrieved, the script "draws" the news onto your chart in several ways:
- Vertical Lines: It places vertical dashed lines at the exact moment an economic event occurs.
- On-Chart Labels: It creates text labels on the chart that display the time, the name of the event, and specific details (like interest rate changes or GDP figures).
- Color Coding: Events are automatically color-coded based on their importance (e.g., different colors for High vs. Low impact) so you can identify volatility at a glance.
4. Real-Time Notifications and Alerts To keep you informed without constantly watching the screen, the script provides:
- Visual Comments: A text summary appears in the corner of your chart showing a list of the next upcoming events.
- Audio Alerts: The script can play a sound notification as an event approaches.
- Countdown Warnings: It can alert you a specific number of minutes before a major release, and it repeats these alerts at set intervals (e.g., every 30 seconds) until the news hits.
Technical Workflow Summary
Every 15 minutes (or your chosen interval), the script clears old visual data and fetches a fresh list from the web. It parses the raw data, converts the time zones to match your local or server time, identifies the "next" upcoming event in the queue, and updates the chart labels and alert system accordingly.
//+------------------------------------------------------------------+
//| News.mq4 |
//| * |
//| * |
//+------------------------------------------------------------------+
#property copyright "Áóëàãèí Àíäðåé"
#property link "andre9@ya.ru"
#property indicator_chart_window
#property indicator_buffers 0
//----
#import "wininet.dll"
int InternetAttemptConnect (int x);
int InternetOpenA(string sAgent, int lAccessType,
string sProxyName = "", string sProxyBypass = "",
int lFlags = 0);
int InternetOpenUrlA(int hInternetSession, string sUrl,
string sHeaders = "", int lHeadersLength = 0,
int lFlags = 0, int lContext = 0);
int InternetReadFile(int hFile, int& sBuffer[], int lNumBytesToRead,
int& lNumberOfBytesRead[]);
int InternetCloseHandle(int hInet);
#import
extern bool lines = true; // ïîêàçûâàòü âåðòèêàëüíûå ëèíèè â ìîìåíòû âûõîäà íîâîñòåé
extern bool texts = true; // ïîêàçûâàòü òåêñòîâûå íàäïèñè ñ îïèñàíèÿìè íîâîñòåé
extern bool comments = true; // ïîêàçûâàòü ñïèñîê áëèæàéøèõ áóäóùèõ è ïðîøåäøèõ íîâîñòåé
extern int total_in_list = 10; // êîëè÷åñòâî íîâîñòåé â ñïèñêå
extern bool high = true; // ïîêàçûâàòü âàæíûå íîâîñòè
extern bool medium = true; // ïîêàçûâàòü íîâîñòè ñðåäíåé âàæíîñòè
extern bool low = true; // ïîêàçûâàòü íîâîñòè ìàëîé âàæíîñòè
extern int update = 15; // îáíîâëÿòü ñïèñîê íîâîñòåé êàæäûå 15 ìèíóò
extern bool auto = true; // àâòî-âûáîð íîâîñòåé, ïîäõîäÿùèõ äëÿ âàëþòíîé ïàðû ãðàôèêà
extern bool eur = true; // ïîêàçûâàòü íîâîñòè äëÿ îïðåäåëåííûõ âàëþò
extern bool usd = true;
extern bool jpy = true;
extern bool gbp = true;
extern bool chf = true;
extern bool cad = true;
extern bool aud = true;
extern bool nzd = true;
extern color high_color = Maroon; // öâåò âàæíûõ íîâîñòåé
extern color medium_color = Sienna; // öâåò îáû÷íûõ íîâîñòåé
extern color low_color = DarkSlateGray; // öâåò íåçíà÷èòåëüíûõ íîâîñòåé
extern bool russian = true; // èñïîëüçîâàòü ôàéë ïåðåâîäà äëÿ ðóññèôèêàöèè íîâîñòåé
extern int server_timezone = 2; // ÷àñîâîé ïîÿñ ñåðâåðà (Alpary - GMT+2)
extern int show_timezone = 4; // ïîêàçûâàòü âðåìÿ äëÿ ÷àñîâîãî ïîÿñà (Ìîñêâà - GMT+4)
extern bool alerts = true; // ïðåäóïðåæäàòü î âûõîäå íîâîñòåé çâóêîâûìè ñèãíàëàìè
extern int alert_before = 5; // ïðåäóïðåæäàòü çà 5 ìèíóò äî âûõîäà íîâîñòåé
extern int alert_every = 30; // çâóêîâûå ñèãíàëû êàæäûå 30 ñåêóíä
// -----------------------------------------------------------------------------------------------------------------------------
int TotalNews = 0;
string News[1000][10];
datetime LastUpdate = 0;
int NextNewsLine = 0;
int LastAlert = 0;
string Translate[1000][2];
int TotalTranslate = 0;
// -----------------------------------------------------------------------------------------------------------------------------
int init()
{
if(auto) // àâòî-âûáîð íîâîñòåé, ïîäõîäÿùèõ äëÿ òåêóùåé âàëþòíîé ïàðû
{
string sym = Symbol();
if(StringFind(sym, "EUR") != -1) eur = true; else eur = false;
if(StringFind(sym, "USD") != -1) usd = true; else usd = false;
if(StringFind(sym, "JPY") != -1) jpy = true; else jpy = false;
if(StringFind(sym, "GBP") != -1) gbp = true; else gbp = false;
if(StringFind(sym, "CHF") != -1) chf = true; else chf = false;
if(StringFind(sym, "CAD") != -1) cad = true; else cad = false;
if(StringFind(sym, "AUD") != -1) aud = true; else aud = false;
if(StringFind(sym, "NZD") != -1) nzd = true; else nzd = false;
}
if(russian) // ïîäãîòîâêà øàáëîíîâ ïåðåâîäà íîâîñòåé
{
int fhandle = FileOpen("translate.txt", FILE_READ);
if(fhandle>0)
{
int i = 0;
while(!FileIsEnding(fhandle))
{
string str = FileReadString(fhandle);
if(str == "") break;
Translate[i][0] = str;
Translate[i][1] = FileReadString(fhandle);
if(Translate[i][1] == "") Translate[i][1] = Translate[i][0];
i++;
}
TotalTranslate = i;
FileClose(fhandle);
}
}
return(0);
}
// -----------------------------------------------------------------------------------------------------------------------------
int deinit()
{
for(int i=0; i<TotalNews; i++)
{
ObjectDelete("News Line "+i);
ObjectDelete("News Text "+i);
}
return(0);
}
// -----------------------------------------------------------------------------------------------------------------------------
int start()
{
string Filter1 = "";
if(!eur) Filter1 = Filter1 + "EUR|";
if(!usd) Filter1 = Filter1 + "USD|";
if(!jpy) Filter1 = Filter1 + "JPY|";
if(!gbp) Filter1 = Filter1 + "GBP|";
if(!chf) Filter1 = Filter1 + "CHF|";
if(!cad) Filter1 = Filter1 + "CAD|";
if(!aud) Filter1 = Filter1 + "AUD|";
if(!nzd) Filter1 = Filter1 + "NZD|";
string Filter2 = "";
if(!high) Filter2 = Filter2 + "High|";
if(!medium) Filter2 = Filter2 + "Medium|";
if(!low) Filter2 = Filter2 + "Low|";
datetime time = TimeCurrent();
if(time >= LastUpdate+update*60) // îáíîâëåíèå ñïèñêà íîâîñòåé
{
for(int i=0; i<TotalNews; i++)
{
ObjectDelete("News Line "+i);
ObjectDelete("News Text "+i);
}
LastUpdate = time;
string str = ReadWebPage("http://www.dailyfx.com/calendar/Dailyfx_Global_Economic_Calendar.csv?direction=none&collector=allInFolderDateDesc&view=week&timezone=GMT¤cyFilter="+Filter1+"&importanceFilter="+Filter2+"&time="+time);
if(str == "") return(0);
int pos = StringFind(str,"\r\n\r\n\r\n");
str = StringTrimRight(StringTrimLeft(StringSubstr(str,pos+6)));
string arr[1000];
TotalNews = Explode(str, "\r\n\r\n\r\n", arr);
for( i=0; i<TotalNews; i++)
{
string arr1[10];
Explode(arr[i], ",", arr1);
for( int j=0; j<10; j++ )
News[i][j] = arr1[j];
string tmp[3], tmp1[2];
Explode(News[i][0], " ", tmp);
int mon = 0;
if(tmp[1]=="Jan") mon=1; else
if(tmp[1]=="Feb") mon=2; else
if(tmp[1]=="Mar") mon=3; else
if(tmp[1]=="Apr") mon=4; else
if(tmp[1]=="May") mon=5; else
if(tmp[1]=="Jun") mon=6; else
if(tmp[1]=="Jul") mon=7; else
if(tmp[1]=="Aug") mon=8; else
if(tmp[1]=="Sep") mon=9; else
if(tmp[1]=="Oct") mon=10; else
if(tmp[1]=="Nov") mon=11; else
if(tmp[1]=="Dec") mon=12;
News[i][0] = Year()+"."+mon+"."+tmp[2];
Explode(News[i][1], " ", tmp);
bool pm = tmp[1]=="PM";
Explode(tmp[0], ":", tmp1);
tmp1[0] = StrToInteger(tmp1[0])%12;
if(pm) tmp1[0] = StrToInteger(tmp1[0])+12;
News[i][1] = tmp1[0]+":"+tmp1[1];
datetime dt = StrToTime(News[i][0]+" "+News[i][1]);
News[i][0] = TimeToStr(dt + server_timezone*60*60, TIME_DATE);
News[i][1] = TimeToStr(dt + server_timezone*60*60, TIME_MINUTES);
News[i][9] = TimeToStr(dt + show_timezone*60*60, TIME_MINUTES);
if(russian)
{
for(j=0; j<TotalTranslate; j++)
{
pos = StringFind(News[i][4], Translate[j][0]);
if(pos != -1) News[i][4] = StringSubstr(News[i][4], 0, pos) + Translate[j][1] + StringSubstr(News[i][4], pos+StringLen(Translate[j][0]));
}
}
}
datetime current = 0;
for( i=0; i<TotalNews; i++) // ñîçäàíèå ëèíèé è íàäïèñåé íîâîñòåé íà ãðàôèêå
{
if(StrToTime(News[i][0]+" "+News[i][1]) == current) continue;
current = StrToTime(News[i][0]+" "+News[i][1]);
color clr;
if(News[i][5] == "Low") clr = low_color; else
if(News[i][5] == "Medium") clr = medium_color; else
if(News[i][5] == "High") clr = high_color;
string text = "";
if(News[i][8] != "" || News[i][7] != "") text = "[" + News[i][8] + ", " + News[i][7] + "]";
if(News[i][6] != "") text = text + " " + News[i][6];
if(lines)
{
ObjectCreate("News Line "+i, OBJ_VLINE, 0, current, 0);
ObjectSet("News Line "+i, OBJPROP_COLOR, clr);
ObjectSet("News Line "+i, OBJPROP_STYLE, STYLE_DASHDOTDOT);
ObjectSet("News Line "+i, OBJPROP_BACK, true);
ObjectSetText("News Line "+i, News[i][9] + " " + News[i][4] + " " + text, 8);
}
if (texts)
{
ObjectCreate("News Text "+i, OBJ_TEXT, 0, current, WindowPriceMin()+(WindowPriceMax()-WindowPriceMin())*0.8 );
ObjectSet("News Text "+i, OBJPROP_COLOR, clr);
ObjectSet("News Text "+i, OBJPROP_ANGLE, 90);
ObjectSetText("News Text "+i, News[i][9] + " " + News[i][4] + " " + text, 8);
}
}
for(i=0; i<TotalNews; i++)
if(StrToTime(News[i][0]+" "+News[i][1]) > time) break;
NextNewsLine = i;
LastAlert = 0;
if(comments) // ñîçäàíèå ñïèñêà íîâîñòåé íà ãðàôèêå
{
int start = 0;
if(NextNewsLine >= 5) start = NextNewsLine - 5;
string com = "";
for(i=start; i<start+total_in_list && i<TotalNews; i++)
{
text = "";
if(News[i][8] != "" || News[i][7] != "") text = "[" + News[i][8] + ", " + News[i][7] + "]";
if(News[i][6] != "") text = text + " " + News[i][6];
com = com + News[i][9] + " " + StringSubstr(News[i][5], 0, 1) + " " + News[i][4] + " " + text + "\n";
}
Comment(com);
}
} // êîíåö îáíîâëåíèÿ ñïèñêà íîâîñòåé
datetime next_time = StrToTime(News[NextNewsLine][0]+" "+News[NextNewsLine][1]);
if(time >= next_time) // âûøëà ñëåäóþùàÿ íîâîñòü
{
LastUpdate = time - update*60 + 60; // îáíîâèòü ñïèñîê íîâîñòåé ÷åðåç ìèíóòó ïîñëå âûõîäà î÷åðåäíîé íîâîñòè
for(i=0; i<TotalNews; i++)
if(StrToTime(News[i][0]+" "+News[i][1]) > time) break;
NextNewsLine = i;
LastAlert = 0;
if(comments)
{
start = 0;
if(NextNewsLine >= 5) start = NextNewsLine - 5;
com = "";
for(i=start; i<start+10 && i<TotalNews; i++)
{
text = "";
if(News[i][8] != "" || News[i][7] != "") text = "[" + News[i][8] + ", " + News[i][7] + "]";
if(News[i][6] != "") text = text + " " + News[i][6];
com = com + News[i][9] + " " + StringSubstr(News[i][5], 0, 1) + " " + News[i][4] + " " + text + "\n";
}
Comment(com);
}
}
next_time = StrToTime(News[NextNewsLine][0]+" "+News[NextNewsLine][1]);
if(time >= next_time - alert_before*60) // ñêîðî âûéäåò ñëåäóþùàÿ íîâîñòü
{
if(time >= LastAlert + alert_every)
{
if(alerts) PlaySound("alert.wav");
Print("Ñëåäóþùàÿ íîâîñòü âûéäåò ÷åðåç " + (((next_time-time)-(next_time-time)%60)/60) + " ìèíóò(û) " + ((next_time-time)%60) + " ñåêóíä(û).");
LastAlert = time;
}
}
return(0);
}
// -----------------------------------------------------------------------------------------------------------------------------
int Explode(string str, string delimiter, string& arr[])
{
int i = 0;
int pos = StringFind(str, delimiter);
while(pos != -1)
{
if(pos == 0) arr[i] = ""; else arr[i] = StringSubstr(str, 0, pos);
i++;
str = StringSubstr(str, pos+StringLen(delimiter));
pos = StringFind(str, delimiter);
if(pos == -1 || str == "") break;
}
arr[i] = str;
return(i+1);
}
// -----------------------------------------------------------------------------------------------------------------------------
string ReadWebPage(string url)
{
if(!IsDllsAllowed())
{
Alert("Íåîáõîäèìî â íàñòðîéêàõ ðàçðåøèòü èñïîëüçîâàíèå DLL");
return("");
}
int rv = InternetAttemptConnect(0);
if(rv != 0)
{
Alert("Îøèáêà ïðè âûçîâå InternetAttemptConnect()");
return("");
}
int hInternetSession = InternetOpenA("Microsoft Internet Explorer",
0, "", "", 0);
if(hInternetSession <= 0)
{
Alert("Îøèáêà ïðè âûçîâå InternetOpenA()");
return("");
}
int hURL = InternetOpenUrlA(hInternetSession,
url, "", 0, 0, 0);
if(hURL <= 0)
{
Alert("Îøèáêà ïðè âûçîâå InternetOpenUrlA()");
InternetCloseHandle(hInternetSession);
return(0);
}
int cBuffer[256];
int dwBytesRead[1];
string TXT = "";
while(!IsStopped())
{
for(int i = 0; i<256; i++) cBuffer[i] = 0;
bool bResult = InternetReadFile(hURL, cBuffer, 1024, dwBytesRead);
if(dwBytesRead[0] == 0) break;
string text = "";
for(i = 0; i < 256; i++)
{
text = text + CharToStr(cBuffer[i] & 0x000000FF);
if(StringLen(text) == dwBytesRead[0]) break;
text = text + CharToStr(cBuffer[i] >> 8 & 0x000000FF);
if(StringLen(text) == dwBytesRead[0]) break;
text = text + CharToStr(cBuffer[i] >> 16 & 0x000000FF);
if(StringLen(text) == dwBytesRead[0]) break;
text = text + CharToStr(cBuffer[i] >> 24 & 0x000000FF);
}
TXT = TXT + text;
Sleep(1);
}
if(TXT == "") Alert("Íåò ñ÷èòàííûõ äàííûõ");
InternetCloseHandle(hInternetSession);
return(TXT);
}
// -----------------------------------------------------------------------------------------------------------------------------
Comments