FFC
Download scriptThis script is a specialized financial tool designed to integrate an economic news calendar directly onto your trading platform. Instead of requiring you to manually check external websites for upcoming economic events, this tool automatically fetches, processes, and displays that information in a visual panel on your charts.
Core Functionality
The logic follows a streamlined path: from downloading raw data to displaying filtered, real-time notifications.
1. Data Acquisition & Management
- Automated Downloading: The script connects to an external economic calendar (Forex Factory) to download a data file in XML format.
- Smart Updates: It doesn't just download once; it includes logic to check if the data is outdated. Based on your settings, it can automatically refresh this data at specific intervals so you are always looking at current information.
- Local Processing: Once downloaded, the script parses (reads) the raw text code to extract meaningful details like event titles, countries, dates, times, and their economic "impact" levels.
2. Filtering & Customization One of the most robust parts of this logic is its ability to filter out noise. You can tell the script exactly what you want to see:
- Currency Specifics: You can toggle individual currencies (like USD, EUR, GBP) on or off so you only see news relevant to your current trades.
- Impact Levels: You can choose to hide "Low" impact events and only see "Medium" or "High" volatility news.
- Keyword Filtering: It includes a search feature where you can specifically include or exclude certain words (e.g., if you want to ignore all "Speaks" events).
3. Visual Display & User Interface The script translates the raw data into several visual elements on your chart:
- The Info Panel: A dedicated dashboard displays the next few upcoming events, showing the title, the country of origin, the specific time remaining, and the forecast versus previous figures.
- Dynamic Colors: The panel uses a color-coding system—for example, high-impact events are highlighted in different colors than low-impact ones to grab your attention instantly.
- Vertical Lines: It can draw physical lines on your chart at the exact moment an event is scheduled to occur, helping you see where significant price action might happen ahead of time.
- Interactive Tooltips: By hovering your mouse over the items in the panel, you get extra details about the specific event.
4. Alerting System The logic includes a multi-channel notification system to ensure you don't miss critical moments:
- Time-Based Triggers: You can set the script to notify you exactly X minutes before an event begins.
- Multi-Method Alerts: Depending on your preference, these alerts can be delivered as on-screen popups, audio sounds, push notifications to your mobile device, or even direct emails.
5. Extra Market Data Beyond just news, the script also includes a "Symbol Info" logic. This monitors and displays real-time data for the specific asset you are viewing, including current currency strength (relative to the day's move), the current spread, and a countdown of how much time is left in the current candle.
//+-------------------------------------------------------------------------------------------------------+
//| FFC.mq4 |
//| Copyright © 2016, DerkWehler, |
//| traderathome,|
//| deVries, |
//| qFish, |
//| atstrader, |
//| awran5 |
//| Last Modifications, 2016 |
//|-------------------------------------------------------------------------------------------------------+
/*
ACKNOWLEDGEMENTS:
derkwehler and other contributors - the core code of the FFCal indicator,
FFCal_v20 dated 07/07/2009, Copyright @ 2006 derkwehler
http://www.forexfactory.com/showthread.php?t=19293
email: derkwehler@gmail.com
deVries - for his excellent donated work that significantly altered and streamlined the file
handling coding to establish compatibility with the new release of MT4 Build 600+,
and which has resulted in faster code execution.
(Jobs for deVries www.mql5.com/en/job/new?prefered=deVries)
qFish - for his generously given time and help during the effort to improve this indicator.
atstrader - For a neat new option controlling for what pair/pairs(s) news is shown.
- Traderathome, 03-17-2014
email: traderathome@msn.com
-------------------------------------------- MAIN MODIFICATIONS --------------------------------------------
------------------------------------------------------------------------------------------------------------
These modifications were applied to 03-17-2014 release founded here: http://www.forexfactory.com/showthread.php?t=114792
Added: #property strict for compatibility with MT4 Build 600+ and better code quality.
Added: Show event Previous/Forecast. (colored impact)
Added: Option to show events related to active chart only (override other parameters)
Added: Keyword filter. Find or Ignore a specific one word, i.e. "NFP", will filter out all events with/without only that word. (case-sensitive)
Added: Option to show currency strength / bar time left / spread value.
Added: Option to control the time for display of past events (in minutes).
Added: Option to set panel location in 4 chart corners.
Added: Tool-tip on mouse hover that shows event title, impact and event time left.
Added: Panel title. You can use it as a reminder note :)
Modified: Show event in "Date/Time format" instead of minutes left (you can show minutes left through Tool-tip)
Modified: Vertical lines for the upcoming events. (You may need to modify the "time offset" input depending on your broker time).
Modified: Buffers that holds the upcoming event minute and impact (see examples below)
Modified: Revised order of external inputs.
Improved: Replaced DownLoadWebPageToFile() function with native Windows URLDownloadToFileW() function.
Improved: Placed (download/read XML file) and related codes into a functions so we can call them when needed.
Improved: Replaced "GlobalVariables" that used to update XML file with FILE_MODIFY_DATE - OnTimer() set by "AllowUpdates", "UpdateHour" inputs.
Improved: Time GMT offset, now the events will show in your local time automatically.
Improved: Justify the panel/text when set to right/left.
Improved: Alert function, Now it will send beside the Popup Alert: sound alert, Push notification and Emails. (two separate alerts)
Improved: Code quality, now the indicator is lighter and faster than ever.
Fixed: Various bug fixes, some unnecessary/unused codes or variables removed, placed some variables inside their related functions.
-------------------------------------------- HOW TO USE BUFFERS --------------------------------------------
------------------------------------------------------------------------------------------------------------
For use in an EA, the indicator holds 2 buffers:
- Buffer (0) Contains minutes until the most recent event
- Buffer (1) Contains impact value for the most recent event (Low = 1, Medium = 2, High = 3)
*Please note that the indicator will not work on strategy tester
------------------------------------------------- EXAMPLES -------------------------------------------------
------------------------------------------------------------------------------------------------------------
Simple call:
-------------
NOTE: if you use the simple call method, default values will be applied
int EventMinute = (int)iCustom(NULL,0,"FFC",0,0);
if(EventMinute == 30) { .. YOUR CODE .. } 30 minutes before the event
int EventImpact = (int)iCustom(NULL,0,"FFC",1,0);
if(EventImpact == 3) { .. YOUR CODE .. } High impact event
Advanced call:
-------------
iCustom(
string NULL, // symbol
int 0, // timeframe
string "FFC", // path/name of the custom indicator compiled program
bool true, // true/false: Active chart only
bool true, // true/false: Include High impact
bool true, // true/false: Include Medium impact
bool true, // true/false: Include Low impact
bool true, // true/false: Include Speaks
bool false, // true/false: Include Holidays
string "", // Find keyword
string "", // Ignore keyword
bool true, // true/false: Allow Updates
int 4, // Update every (in hours)
int 0, // Buffers: (0) Minutes, (1) Impact
int 0 // shift
);
- Awran5, 08-14-2016
email: awran5@yahoo.com
-------------------------------------------------- HEADER ----------------------------------------------------
--------------------------------------------------------------------------------------------------------------
*/
#property copyright "Copyright © 2009-2016, traderathome, deVries, qFish, atstrader, awran5."
#property link "awran5@yahoo.com"
#property description "Modified version of FF Calendar Indicator with new features"
#property version "1.00"
#property strict
#property indicator_chart_window
#property indicator_buffers 2
//--- to download the xml
#import "urlmon.dll"
int URLDownloadToFileW(int pCaller,string szURL,string szFileName,int dwReserved,int Callback);
#import
//---
#define INAME "FFC"
#define TITLE 0
#define COUNTRY 1
#define DATE 2
#define TIME 3
#define IMPACT 4
#define FORECAST 5
#define PREVIOUS 6
//-------------------------------------------- EXTERNAL VARIABLE ---------------------------------------------
//------------------------------------------------------------------------------------------------------------
extern bool ReportActive = false; // Report for active chart only (override other inputs)
extern bool IncludeHigh = true; // Include high
extern bool IncludeMedium = true; // Include medium
extern bool IncludeLow = true; // Include low
extern bool IncludeSpeaks = true; // Include speaks
extern bool IncludeHolidays = false; // Include holidays
extern string FindKeyword = ""; // Find keyword
extern string IgnoreKeyword = ""; // Ignore keyword
extern bool AllowUpdates = true; // Allow updates
extern int UpdateHour = 4; // Update every (in hours)
input string lb_0 = ""; // ------------------------------------------------------------
input string lb_1 = ""; // ------> PANEL SETTINGS
extern bool ShowPanel = true; // Show panel
extern bool AllowSubwindow = false; // Show Panel in sub window
extern ENUM_BASE_CORNER Corner = 2; // Panel side
extern string PanelTitle="Forex Calendar @ Forex Factory"; // Panel title
extern color TitleColor = C'46,188,46'; // Title color
extern bool ShowPanelBG = true; // Show panel backgroud
extern color Pbgc = C'25,25,25'; // Panel backgroud color
extern color LowImpactColor = C'91,192,222'; // Low impact color
extern color MediumImpactColor = C'255,185,83'; // Medium impact color
extern color HighImpactColor = C'217,83,79'; // High impact color
extern color HolidayColor = clrOrchid; // Holidays color
extern color RemarksColor = clrGray; // Remarks color
extern color PreviousColor = C'170,170,170'; // Forecast color
extern color PositiveColor = C'46,188,46'; // Positive forecast color
extern color NegativeColor = clrTomato; // Negative forecast color
extern bool ShowVerticalNews = true; // Show vertical lines
extern int ChartTimeOffset = 0; // Chart time offset (in hours)
extern int EventDisplay = 10; // Hide event after (in minutes)
input string lb_2 = ""; // ------------------------------------------------------------
input string lb_3 = ""; // ------> SYMBOL SETTINGS
extern bool ReportForUSD = true; // Report for USD
extern bool ReportForEUR = true; // Report for EUR
extern bool ReportForGBP = true; // Report for GBP
extern bool ReportForNZD = true; // Report for NZD
extern bool ReportForJPY = true; // Report for JPY
extern bool ReportForAUD = true; // Report for AUD
extern bool ReportForCHF = true; // Report for CHF
extern bool ReportForCAD = true; // Report for CAD
extern bool ReportForCNY = false; // Report for CNY
input string lb_4 = ""; // ------------------------------------------------------------
input string lb_5 = ""; // ------> INFO SETTINGS
extern bool ShowInfo = true; // Show Symbol info ( Strength / Bar Time / Spread )
extern color InfoColor = C'255,185,83'; // Info color
extern int InfoFontSize = 8; // Info font size
input string lb_6 = ""; // ------------------------------------------------------------
input string lb_7 = ""; // ------> NOTIFICATION
input string lb_8 = ""; // *Note: Set (-1) to disable the Alert
extern int Alert1Minutes = 30; // Minutes before first Alert
extern int Alert2Minutes = -1; // Minutes before second Alert
extern bool PopupAlerts = false; // Popup Alerts
extern bool SoundAlerts = true; // Sound Alerts
extern string AlertSoundFile = "news.wav"; // Sound file name
extern bool EmailAlerts = false; // Send email
extern bool NotificationAlerts= false; // Send push notification
//------------------------------------------------------------------------------------------------------------
//--------------------------------------------- INTERNAL VARIABLE --------------------------------------------
//--- Vars and arrays
string xmlFileName;
string sData;
string Event[200][7];
string eTitle[10],eCountry[10],eImpact[10],eForecast[10],ePrevious[10];
int eMinutes[10];
datetime eTime[10];
int anchor,x0,x1,x2,xf,xp;
int Factor;
//--- Alert
bool FirstAlert;
bool SecondAlert;
datetime AlertTime;
//--- Buffers
double MinuteBuffer[];
double ImpactBuffer[];
//--- time
datetime xmlModifed;
int TimeOfDay;
datetime Midnight;
bool IsEvent;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- check for DLL
if(!TerminalInfoInteger(TERMINAL_DLLS_ALLOWED))
{
Alert(INAME+": Please Allow DLL Imports!");
return(INIT_FAILED);
}
//--- indicator buffers mapping
SetIndexBuffer(0,MinuteBuffer);
SetIndexBuffer(1,ImpactBuffer);
SetIndexStyle(0,DRAW_NONE);
SetIndexStyle(1,DRAW_NONE);
//--- 0 value will not be displayed
SetIndexEmptyValue(0,0.0);
SetIndexEmptyValue(1,0.0);
//--- 4/5 digit brokers
if(Digits%2==1) Factor=10;
else Factor=1;
//--- get today time
TimeOfDay=(int)TimeLocal()%86400;
Midnight=TimeLocal()-TimeOfDay;
//--- set xml file name ffcal_week_this (fixed name)
xmlFileName=INAME+"-ffcal_week_this.xml";
//--- checks the existence of the file.
if(!FileIsExist(xmlFileName))
{
xmlDownload();
xmlRead();
}
//--- else just read it
else xmlRead();
//--- get last modification time
xmlModifed=(datetime)FileGetInteger(xmlFileName,FILE_MODIFY_DATE,false);
//--- check for updates
if(AllowUpdates)
{
if(xmlModifed<TimeLocal()-(UpdateHour*3600))
{
Print(INAME+": xml file is out of date");
xmlUpdate();
}
//--- set timer to update old xml file every x hours
else EventSetTimer(UpdateHour*3600);
}
//--- set panel corner
switch(Corner)
{
case CORNER_LEFT_UPPER: x0=5; x1=165; x2=15; xf=340; xp=390; anchor=0; break;
case CORNER_RIGHT_UPPER: x0=455; x1=265; x2=440; xf=110; xp=60; anchor=0; break;
case CORNER_RIGHT_LOWER: x0=455; x1=265; x2=440; xf=110; xp=60; anchor=2; break;
case CORNER_LEFT_LOWER: x0=5; x1=165; x2=15; xf=340; xp=390; anchor=2; break;
}
//--- indicator name
IndicatorShortName(INAME);
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
//---
//--- BY AUTHORS WITH SOME MODIFICATIONS
//--- define the XML Tags, Vars
string sTags[7]={"<title>","<country>","<date><![CDATA[","<time><![CDATA[","<impact><![CDATA[","<forecast><![CDATA[","<previous><![CDATA["};
string eTags[7]={"</title>","</country>","]]></date>","]]></time>","]]></impact>","]]></forecast>","]]></previous>"};
int index=0;
int next=-1;
int BoEvent=0,begin=0,end=0;
string myEvent="";
//--- Minutes calculation
datetime EventTime=0;
int EventMinute=0;
//--- split the currencies into the two parts
string MainSymbol=StringSubstr(Symbol(),0,3);
string SecondSymbol=StringSubstr(Symbol(),3,3);
//--- loop to get the data from xml tags
while(true)
{
BoEvent=StringFind(sData,"<event>",BoEvent);
if(BoEvent==-1) break;
BoEvent+=7;
next=StringFind(sData,"</event>",BoEvent);
if(next == -1) break;
myEvent = StringSubstr(sData,BoEvent,next-BoEvent);
BoEvent = next;
begin=0;
for(int i=0; i<7; i++)
{
Event[index][i]="";
next=StringFind(myEvent,sTags[i],begin);
//--- Within this event, if tag not found, then it must be missing; skip it
if(next==-1) continue;
else
{
//--- We must have found the sTag okay...
//--- Advance past the start tag
begin=next+StringLen(sTags[i]);
end=StringFind(myEvent,eTags[i],begin);
//---Find start of end tag and Get data between start and end tag
if(end>begin && end!=-1)
Event[index][i]=StringSubstr(myEvent,begin,end-begin);
}
}
//--- filters that define whether we want to skip this particular currencies or events
if(ReportActive && MainSymbol!=Event[index][COUNTRY] && SecondSymbol!=Event[index][COUNTRY])
continue;
if(!IsCurrency(Event[index][COUNTRY]))
continue;
if(!IncludeHigh && Event[index][IMPACT]=="High")
continue;
if(!IncludeMedium && Event[index][IMPACT]=="Medium")
continue;
if(!IncludeLow && Event[index][IMPACT]=="Low")
continue;
if(!IncludeSpeaks && StringFind(Event[index][TITLE],"Speaks")!=-1)
continue;
if(!IncludeHolidays && Event[index][IMPACT]=="Holiday")
continue;
if(Event[index][TIME]=="All Day" ||
Event[index][TIME]=="Tentative" ||
Event[index][TIME]=="")
continue;
if(FindKeyword!="")
{
if(StringFind(Event[index][TITLE],FindKeyword)==-1)
continue;
}
if(IgnoreKeyword!="")
{
if(StringFind(Event[index][TITLE],IgnoreKeyword)!=-1)
continue;
}
//--- sometimes they forget to remove the tags :)
if(StringFind(Event[index][TITLE],"<![CDATA[")!=-1)
StringReplace(Event[index][TITLE],"<![CDATA[","");
if(StringFind(Event[index][TITLE],"]]>")!=-1)
StringReplace(Event[index][TITLE],"]]>","");
if(StringFind(Event[index][TITLE],"]]>")!=-1)
StringReplace(Event[index][TITLE],"]]>","");
//---
if(StringFind(Event[index][FORECAST],"<")!=-1)
StringReplace(Event[index][FORECAST],"<","");
if(StringFind(Event[index][PREVIOUS],"<")!=-1)
StringReplace(Event[index][PREVIOUS],"<","");
//--- set some values (dashes) if empty
if(Event[index][FORECAST]=="") Event[index][FORECAST]="---";
if(Event[index][PREVIOUS]=="") Event[index][PREVIOUS]="---";
//--- Convert Event time to MT4 time
EventTime=datetime(MakeDateTime(Event[index][DATE],Event[index][TIME]));
//--- calculate how many minutes before the event (may be negative)
EventMinute=int(EventTime-TimeGMT())/60;
//--- only Alert once
if(EventMinute==0 && AlertTime!=EventTime)
{
FirstAlert =false;
SecondAlert=false;
AlertTime=EventTime;
}
//--- Remove the event after x minutes
if(EventMinute+EventDisplay<0) continue;
//--- Set buffers
MinuteBuffer[index]=EventMinute;
ImpactBuffer[index]=ImpactToNumber(Event[index][IMPACT]);
index++;
}
//--- loop to set arrays/buffers that uses to draw objects and alert
for(int i=0; i<index; i++)
{
for(int n=i; n<10; n++)
{
eTitle[n] = Event[i][TITLE];
eCountry[n] = Event[i][COUNTRY];
eImpact[n] = Event[i][IMPACT];
eForecast[n] = Event[i][FORECAST];
ePrevious[n] = Event[i][PREVIOUS];
eTime[n] = datetime(MakeDateTime(Event[i][DATE],Event[i][TIME]))-TimeGMTOffset();
eMinutes[n] = (int)MinuteBuffer[i];
//--- Check if there are any events
if(ObjectFind(eTitle[n])!=0) IsEvent=true;
}
}
//--- check then call draw / alert function
if(IsEvent) DrawEvents();
else Draw("no more events","NO MORE EVENTS",14,"Arial Black",RemarksColor,2,10,30,"Get some rest!");
//--- call info function
if(ShowInfo) SymbolInfo();
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+
//| Timer function |
//+------------------------------------------------------------------+
void OnTimer()
{
//---
Print(INAME+": xml file is out of date");
xmlUpdate();
//---
}
//+------------------------------------------------------------------+
//| Deinitialization |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---
for(int i=ObjectsTotal(); i>=0; i--)
{
string name=ObjectName(i);
if(StringFind(name,INAME)==0) ObjectDelete(name);
}
//--- Kill update timer only if removed
if(reason==1) EventKillTimer();
//---
}
//+-------------------------------------------------------------------------------------------+
//| Download XML file from forexfactory |
//| for windows 7 and later file path would be: |
//| C:\Users\xxx\AppData\Roaming\MetaQuotes\Terminal\xxxxxxxxxxxxxxx\MQL4\Files\xmlFileName |
//+-------------------------------------------------------------------------------------------+
void xmlDownload()
{
//---
ResetLastError();
string sUrl="http://www.forexfactory.com/ff_calendar_thisweek.xml";
string FilePath=StringConcatenate(TerminalInfoString(TERMINAL_DATA_PATH),"\\MQL4\\files\\",xmlFileName);
int FileGet=URLDownloadToFileW(NULL,sUrl,FilePath,0,NULL);
if(FileGet==0) PrintFormat(INAME+": %s file downloaded successfully!",xmlFileName);
//--- check for errors
else PrintFormat(INAME+": failed to download %s file, Error code = %d",xmlFileName,GetLastError());
//---
}
//+------------------------------------------------------------------+
//| Read the XML file |
//+------------------------------------------------------------------+
void xmlRead()
{
//---
ResetLastError();
int FileHandle=FileOpen(xmlFileName,FILE_BIN|FILE_READ);
if(FileHandle!=INVALID_HANDLE)
{
//--- receive the file size
ulong size=FileSize(FileHandle);
//--- read data from the file
while(!FileIsEnding(FileHandle))
sData=FileReadString(FileHandle,(int)size);
//--- close
FileClose(FileHandle);
}
//--- check for errors
else PrintFormat(INAME+": failed to open %s file, Error code = %d",xmlFileName,GetLastError());
//---
}
//+------------------------------------------------------------------+
//| Check for update XML |
//+------------------------------------------------------------------+
void xmlUpdate()
{
//--- do not download on saturday
if(TimeDayOfWeek(Midnight)==6) return;
else
{
Print(INAME+": check for updates...");
Print(INAME+": delete old file");
FileDelete(xmlFileName);
xmlDownload();
xmlRead();
xmlModifed=(datetime)FileGetInteger(xmlFileName,FILE_MODIFY_DATE,false);
PrintFormat(INAME+": updated successfully! last modified: %s",(string)xmlModifed);
}
//---
}
//+------------------------------------------------------------------+
//| Draw panel and events on the chart |
//+------------------------------------------------------------------+
void DrawEvents()
{
string FontName = "Arial";
int FontSize = 8;
string eToolTip = "";
//--- draw backbround / date / special note
if(ShowPanel && ShowPanelBG)
{
eToolTip="Hover on the Event!";
Draw("BG","gggg",85,"Webdings",Pbgc,Corner,x0,3,eToolTip);
Draw("Date",DayToStr(Midnight)+", "+MonthToStr()+" "+(string)TimeDay(Midnight),FontSize+1,"Arial Black",TitleColor,Corner,x2,95,"Today");
Draw("Title",PanelTitle,FontSize,FontName,TitleColor,Corner,x1,95,"Panel Title");
Draw("Spreator","------",10,"Arial",RemarksColor,Corner,x2,83,eToolTip);
}
//--- draw objects / alert functions
for(int i=0; i<5; i++)
{
eToolTip=eTitle[i]+"\nCurrency: "+eCountry[i]+"\nTime left: "+(string)eMinutes[i]+" Minutes"+"\nImpact: "+eImpact[i];
//--- impact color
color EventColor=ImpactToColor(eImpact[i]);
//--- previous/forecast color
color ForecastColor=PreviousColor;
if(ePrevious[i]>eForecast[i]) ForecastColor=NegativeColor;
else if(ePrevious[i]<eForecast[i]) ForecastColor=PositiveColor;
//--- past event color
if(eMinutes[i]<0)
EventColor=ForecastColor=PreviousColor=RemarksColor;
//--- panel
if(ShowPanel)
{
//--- date/time / title / currency
Draw("Event "+(string)i,
DayToStr(eTime[i])+" | "+
TimeToStr(eTime[i],TIME_MINUTES)+" | "+
eCountry[i]+" | "+
eTitle[i],FontSize,FontName,EventColor,Corner,x2,70-i*15,eToolTip);
//--- forecast
Draw("Event Forecast "+(string)i,"[ "+eForecast[i]+" ]",FontSize,FontName,ForecastColor,Corner,xf,70-i*15,
"Forecast: "+eForecast[i]);
//--- previous
Draw("Event Previous "+(string)i,"[ "+ePrevious[i]+" ]",FontSize,FontName,PreviousColor,Corner,xp,70-i*15,
"Previous: "+ePrevious[i]);
}
//--- vertical news
if(ShowVerticalNews)
DrawLine("Event Line "+(string)i,eTime[i]+(ChartTimeOffset*3600),EventColor,eToolTip);
//--- Set alert message
string AlertMessage=(string)eMinutes[i]+" Minutes until ["+eTitle[i]+"] Event on "+eCountry[i]+
"\nImpact: "+eImpact[i]+
"\nForecast: "+eForecast[i]+
"\nPrevious: "+ePrevious[i];
//--- first alert
if(Alert1Minutes!=-1 && eMinutes[i]==Alert1Minutes && !FirstAlert)
{
setAlerts("First Alert! "+AlertMessage);
FirstAlert=true;
}
//--- second alert
if(Alert2Minutes!=-1 && eMinutes[i]==Alert2Minutes && !SecondAlert)
{
setAlerts("Second Alert! "+AlertMessage);
SecondAlert=true;
}
//--- break if no more data
if(eTitle[i]==eTitle[i+1])
{
Draw(INAME+" no more events","NO MORE EVENTS",8,"Arial",RemarksColor,Corner,x2,50-i*15,"Get some rest!");
break;
}
}
//---
}
//+-----------------------------------------------------------------------------------------------+
//| Subroutine: to ID currency even if broker has added a prefix to the symbol, and is used to |
//| determine the news to show, based on the users external inputs - by authors (Modified) |
//+-----------------------------------------------------------------------------------------------+
bool IsCurrency(string symbol)
{
//---
if(ReportForUSD && symbol == "USD") return(true);
else if(ReportForGBP && symbol == "GBP") return(true);
else if(ReportForEUR && symbol == "EUR") return(true);
else if(ReportForCAD && symbol == "CAD") return(true);
else if(ReportForAUD && symbol == "AUD") return(true);
else if(ReportForCHF && symbol == "CHF") return(true);
else if(ReportForJPY && symbol == "JPY") return(true);
else if(ReportForNZD && symbol == "NZD") return(true);
else if(ReportForCNY && symbol == "CNY") return(true);
return(false);
//---
}
//+------------------------------------------------------------------+
//| Converts ff time & date into yyyy.mm.dd hh:mm - by deVries |
//+------------------------------------------------------------------+
string MakeDateTime(string strDate,string strTime)
{
//---
int n1stDash=StringFind(strDate, "-");
int n2ndDash=StringFind(strDate, "-", n1stDash+1);
string strMonth=StringSubstr(strDate,0,2);
string strDay=StringSubstr(strDate,3,2);
string strYear=StringSubstr(strDate,6,4);
int nTimeColonPos=StringFind(strTime,":");
string strHour=StringSubstr(strTime,0,nTimeColonPos);
string strMinute=StringSubstr(strTime,nTimeColonPos+1,2);
string strAM_PM=StringSubstr(strTime,StringLen(strTime)-2);
int nHour24=StrToInteger(strHour);
if((strAM_PM=="pm" || strAM_PM=="PM") && nHour24!=12) nHour24+=12;
if((strAM_PM=="am" || strAM_PM=="AM") && nHour24==12) nHour24=0;
string strHourPad="";
if(nHour24<10) strHourPad="0";
return(StringConcatenate(strYear, ".", strMonth, ".", strDay, " ", strHourPad, nHour24, ":", strMinute));
//---
}
//+------------------------------------------------------------------+
//| set impact Color - by authors |
//+------------------------------------------------------------------+
color ImpactToColor(string impact)
{
//---
if(impact == "High") return (HighImpactColor);
else if(impact == "Medium") return (MediumImpactColor);
else if(impact == "Low") return (LowImpactColor);
else if(impact == "Holiday") return (HolidayColor);
else return (RemarksColor);
//---
}
//+------------------------------------------------------------------+
//| Impact to number - by authors |
//+------------------------------------------------------------------+
int ImpactToNumber(string impact)
{
//---
if(impact == "High") return(3);
else if(impact == "Medium") return(2);
else if(impact == "Low") return(1);
else return(0);
//---
}
//+------------------------------------------------------------------+
//| Convert day of the week to text |
//+------------------------------------------------------------------+
string DayToStr(datetime time)
{
int ThisDay=TimeDayOfWeek(time);
string day="";
switch(ThisDay)
{
case 0: day="Sun"; break;
case 1: day="Mon"; break;
case 2: day="Tue"; break;
case 3: day="Wed"; break;
case 4: day="Thu"; break;
case 5: day="Fri"; break;
case 6: day="Sat"; break;
}
return(day);
}
//+------------------------------------------------------------------+
//| Convert months to text |
//+------------------------------------------------------------------+
string MonthToStr()
{
int ThisMonth=Month();
string month="";
switch(ThisMonth)
{
case 1: month="Jan"; break;
case 2: month="Feb"; break;
case 3: month="Mar"; break;
case 4: month="Apr"; break;
case 5: month="May"; break;
case 6: month="Jun"; break;
case 7: month="Jul"; break;
case 8: month="Aug"; break;
case 9: month="Sep"; break;
case 10: month="Oct"; break;
case 11: month="Nov"; break;
case 12: month="Dec"; break;
}
return(month);
}
//+------------------------------------------------------------------+
//| Candle Time Left / Spread |
//+------------------------------------------------------------------+
void SymbolInfo()
{
//---
string TimeLeft=TimeToStr(Time[0]+Period()*60-TimeCurrent(),TIME_MINUTES|TIME_SECONDS);
string Spread=DoubleToStr(MarketInfo(Symbol(),MODE_SPREAD)/Factor,1);
double DayClose=iClose(NULL,PERIOD_D1,1);
if(DayClose!=0)
{
double Strength=((Bid-DayClose)/DayClose)*100;
string Label=DoubleToStr(Strength,2)+"%"+" / "+Spread+" / "+TimeLeft;
ENUM_BASE_CORNER corner=1;
if(Corner==1) corner=3;
string arrow="q";
if(Strength>0) arrow="p";
string tooltip="Strength / Spread / Candle Time";
Draw(INAME+": info",Label,InfoFontSize,"Calibri",InfoColor,corner,120,20,tooltip);
Draw(INAME+": info arrow",arrow,InfoFontSize-2,"Wingdings 3",InfoColor,corner,130,18,tooltip);
}
//---
}
//+------------------------------------------------------------------+
//| draw event text |
//+------------------------------------------------------------------+
void Draw(string name,string label,int size,string font,color clr,ENUM_BASE_CORNER c,int x,int y,string tooltip)
{
//---
name=INAME+": "+name;
int windows=0;
if(AllowSubwindow && WindowsTotal()>1) windows=1;
ObjectDelete(name);
ObjectCreate(name,OBJ_LABEL,windows,0,0);
ObjectSetText(name,label,size,font,clr);
ObjectSet(name,OBJPROP_CORNER,c);
ObjectSet(name,OBJPROP_XDISTANCE,x);
ObjectSet(name,OBJPROP_YDISTANCE,y);
//--- justify text
ObjectSet(name,OBJPROP_ANCHOR,anchor);
ObjectSetString(0,name,OBJPROP_TOOLTIP,tooltip);
ObjectSet(name,OBJPROP_SELECTABLE,0);
//---
}
//+------------------------------------------------------------------+
//| draw vertical lines |
//+------------------------------------------------------------------+
void DrawLine(string name,datetime time,color clr,string tooltip)
{
//---
name=INAME+": "+name;
ObjectDelete(name);
ObjectCreate(name,OBJ_VLINE,0,time,0);
ObjectSet(name,OBJPROP_COLOR,clr);
ObjectSet(name,OBJPROP_STYLE,2);
ObjectSet(name,OBJPROP_WIDTH,0);
ObjectSetString(0,name,OBJPROP_TOOLTIP,tooltip);
//---
}
//+------------------------------------------------------------------+
//| Notifications |
//+------------------------------------------------------------------+
void setAlerts(string message)
{
//---
if(PopupAlerts) Alert(message);
if(SoundAlerts) PlaySound(AlertSoundFile);
if(NotificationAlerts) SendNotification(message);
if(EmailAlerts) SendMail(INAME,message);
//---
}
//+--------------------------- END ----------------------------------+
Comments