显示新日历
简介
- 指标应该独立的(没有用户的帮助下)下载当前周的必要的事件日历文件。
- 指标应该从该文件以带新闻标题的竖行形式显示所有的事件(过去的和未来的)。
- 指标应从外部资源追踪事件的更新状态。
技术部分
编写指标
在已经解决了一些问题后,我们可以开始编写指标。
extern string HtmlAdress = "http://www.dailyfx.com/calendar/Dailyfx_Global_Economic_Calendar.csv"; extern string GetrightAdress = "c:\progra~1\getright\getright.exe"; #include <Time.mqh> #import "kernel32.dll" int WinExec(string NameEx, int dwFlags);
只有两个外部变量:外部资源的地址(实际上,你不必更改这个参数)和 GetRight 程序的地址(如果你已经将程序下载在另一个目录,我建议更改指标内的初始值,以免每次启动指标时要更改变量的值)。要启动 GetRight.exe 文件,我们必须使用 WinExec 函数,可以从 Kernel32.dll 库导入。Time.mqh 库包含用于 GMT 的函数。
void DownloadCalendar() { Print("Downloading "+HtmlAdress+" to experts\files\html\Calendar.csv"); WinExec(GetrightAdress+" /URL:"+HtmlAdress+" /FILE:Calendar.csv /W /O",0); }
可见,由于使用了 GetRight 程序,从外部资源下载文件的函数看起来非常简单。/W 参数表示:除非文件下载结束,否则过程不会返回到程序。/O 参数表示:如果有同名的文件,将会被覆盖。记住:如果你已经正确更改了 GetRight 的设置,日历将下载到 \files\html\。下面是两个额外的函数:
datetime PerviousMonday(datetime d) { datetime res = d - (TimeDayOfWeek(d)-1)*24*60*60; return(res); } datetime ToDate(string stDate,string stTime) { string WeekDay = StringSubstr(stDate,0,3); int WeekPlus = 0; if (WeekDay=="Mon") WeekPlus=0; if (WeekDay=="Tue") WeekPlus=1; if (WeekDay=="Wed") WeekPlus=2; if (WeekDay=="Thu") WeekPlus=3; if (WeekDay=="Fri") WeekPlus=4; if (WeekDay=="Sat") WeekPlus=5; if (WeekDay=="Sun") WeekPlus=-1; datetime Res = PerviousMonday(GetTimeGMT())+WeekPlus*24*60*60; datetime Tm = StrToTime(stTime); Res=Res+TimeHour(Tm )*60*60+TimeMinute(Tm )*60+TimeSeconds(Tm ) -TimeHour(Res)*60*60-TimeMinute(Res)*60-TimeSeconds(Res); if (StringFind(stTime,"PM")>=0) Res+=12*60*60; Res=Res-GetShiftGMT(); return (Res); }
PerviousMonday() 函数返回当前周的起始日期。ToDate() 函数将日期和时间从日历格式转换为数据时间。
void GrabNews() { int file = FileOpen("\Html\Calendar.csv",FILE_READ|FILE_CSV,','); if (file==-1||FileSize(file)==0) return; int i=0; while (!FileIsEnding(file)) { string stDate=""; while (!FileIsEnding(file)&&stDate=="") stDate = FileReadString(file); string stTime = FileReadString(file); string stTimeZone = FileReadString(file); string stCurrency = FileReadString(file); string stDescription = FileReadString(file); string stImportance = FileReadString(file); string stActual = FileReadString(file); string stForecast = FileReadString(file); string stPrevious = FileReadString(file); datetime Date = ToDate(stDate,stTime); color c=Green; if (stImportance=="Low") c = Yellow; if (stImportance=="Medium") c = Orange; if (stImportance=="High") c = Red; ObjectCreate("CalendarText"+i, OBJ_TEXT, 0, Date, Close[0]); ObjectSet("CalendarText"+i, OBJPROP_COLOR, c); ObjectSetText("CalendarText"+i, stDate + " : "+ stDescription, 8); ObjectSet("CalendarText"+i, OBJPROP_ANGLE, 90); ObjectCreate("CalendarLine"+i, OBJ_VLINE, 0, Date, Close[0]); ObjectSet("CalendarLine"+i, OBJPROP_COLOR, c); ObjectSet("CalendarLine"+i, OBJPROP_STYLE, STYLE_DOT); ObjectSet("CalendarLine"+i, OBJPROP_BACK, true); ObjectSetText("CalendarLine"+i, stDescription, 8); i++; } Max = i; if (file!=-1) FileClose(file); }
GrabNews() 的主要程序打开下载的 \Html\Calendar. csv 文件、读取所有的事件参数并为每个新闻创建两个对象:竖行和文本。事件日历每隔 15 分钟更新一次:
int start() { int counted_bars=IndicatorCounted(); //---- if (TimeCurrent()>LastTimeDownloading+15*60) { DeleteObjects(); DownloadCalendar(); LastTimeDownloading = TimeCurrent(); int file=-1; while (file==-1) file = FileOpen("\Html\Calendar.csv",FILE_READ|FILE_CSV,','); FileClose(file); GrabNews(); } //---- return(0); }
总结
附言:我要指出日历运行中的一个错误 http://www.dailyfx.com/calendar/。请注意:来自 http://www.dailyfx.com/calendar/Dailyfx_Global_Economic_Calendar.csv 的 .csv 文件中的事件有时跟 http://www.dailyfx.com/calendar/ 页面不一致。这可能出现于 00:00 到 01:00 (GMT) 发布的新闻。在 .csv 文件中,这种新闻在 12 个小时以后显示。
另需注意的是,指标使用外部 dll (kernell32.dll),所以不要忘记在指标设置中启用相应的参数。
CalendarArticle.mq4 文件应该存放在 \experts\indicators 文件夹中。Time.mq4 应存放在 expers\library, Time.mqh - in experts\include。
本文由MetaQuotes Ltd译自俄文
原文地址: https://www.mql5.com/ru/articles/1502