使用MQL5经济日历进行交易(第二部分):创建新闻交易面板·综合运用
(3/3)· 前两部分啃完了日历函数,这一篇把检索结果焊进一个能看能点的面板里
「新闻面板逐行绘制与数据装配」
这段逻辑负责把财经日历在 MT5 图表上画出可视图层,并给每一行装配数据。先按影响等级批量造按钮,再限制最多显示 11 条记录——valuesTotal 被硬截断在 11,意味着面板纵向空间只预留了 11 行的容量。 行容器用奇偶交替着色:偶数行是 C'213,227,207'(淡绿),奇数行是 clrWhite。起始 Y 坐标 162,每行占 25 像素并顺推,Print(startY) 会把每次递增加工坐标打到专家日志,方便你核对是否溢出。 数据列循环里用 CalendarEventById 和 CalendarCountryById 反查事件与国家结构。重要性颜色直接映射:低=黄、中=橙、高=红,news_data[3] 塞了一个 0x25CF(● 实心圆)作 impact 符号。注意被注释掉的货币过滤行,放开后就能只留 _Symbol 对应币种的新闻。 外汇与贵金属受新闻冲击跳空概率高,面板仅是信息层,不构成方向判断。复制下面片段到 EA 的 OnCreate 类函数里,改 valuesTotal 上限或 startY 步长即可验证排版。
class=class="str">"cmt">//--- Create button for each impact level createButton(IMPACT_LABEL+class="type">class="kw">string(i),class="num">140+impact_size*i,class="num">105,impact_size,class="num">25,impact_labels[i],label_color,class="num">12,impact_color,clrBlack); } class=class="str">"cmt">//--- Limit the total number of values to display class="type">int valuesTotal = (allValues <= class="num">11) ? allValues : class="num">11; class=class="str">"cmt">//--- Initialize starting y-coordinate for displaying news data class="type">int startY = class="num">162; class=class="str">"cmt">//--- Loop through each calendar value up to the maximum defined total for (class="type">int i = class="num">0; i < valuesTotal; i++){ class=class="str">"cmt">//--- Set alternating colors for each data row holder class="type">class="kw">color holder_color = (i % class="num">2 == class="num">0) ? C&class="macro">#x27;class="num">213,class="num">227,class="num">207&class="macro">#x27; : clrWhite; class=class="str">"cmt">//--- Create rectangle label for each data row holder createRecLabel(DATA_HOLDERS+class="type">class="kw">string(i),class="num">62,startY-class="num">1,class="num">716,class="num">26,holder_color,class="num">1,clrBlack); class=class="str">"cmt">//--- Increment y-coordinate for the next row of data startY += class="num">25; Print(startY); class=class="str">"cmt">//--- Print current y-coordinate for debugging } class="macro">#define DATA_HOLDERS "DATA_HOLDERS" class="macro">#define ARRAY_NEWS "ARRAY_NEWS" class=class="str">"cmt">//--- Initialize starting x-coordinate for each data entry class="type">int startX = class="num">65; class=class="str">"cmt">//--- Loop through calendar data columns for (class="type">int k=class="num">0; k<ArraySize(array_calendar); k++){ MqlCalendarEvent event; class=class="str">"cmt">//--- Declare event structure CalendarEventById(values[i].event_id,event); class=class="str">"cmt">//--- Retrieve event details by ID MqlCalendarCountry country; class=class="str">"cmt">//--- Declare country structure CalendarCountryById(event.country_id,country); class=class="str">"cmt">//--- Retrieve country details by event&class="macro">#x27;s country ID class=class="str">"cmt">//--- Print event details for debugging Print("Name = ",event.name,", IMP = ",EnumToString(event.importance),", COUNTRY = ",country.name,", TIME = ",values[i].time); class=class="str">"cmt">//--- Skip event if currency does not match the selected country code class=class="str">"cmt">// if (StringFind(_Symbol,country.currency) < class="num">0) class="kw">continue; class=class="str">"cmt">//--- Prepare news data array with time, country, and other event details class="type">class="kw">string news_data[ArraySize(array_calendar)]; news_data[class="num">0] = TimeToString(values[i].time,TIME_DATE); class=class="str">"cmt">//--- Event date news_data[class="num">1] = TimeToString(values[i].time,TIME_MINUTES); class=class="str">"cmt">//--- Event time news_data[class="num">2] = country.currency; class=class="str">"cmt">//--- Event country currency class=class="str">"cmt">//--- Determine importance class="type">class="kw">color based on event impact class="type">class="kw">color importance_color = clrBlack; if (event.importance == CALENDAR_IMPORTANCE_LOW){importance_color=clrYellow;} else if (event.importance == CALENDAR_IMPORTANCE_MODERATE){importance_color=clrOrange;} else if (event.importance == CALENDAR_IMPORTANCE_HIGH){importance_color=clrRed;} class=class="str">"cmt">//--- Set importance symbol for the event news_data[class="num">3] = ShortToString(0x25CF); class=class="str">"cmt">//--- Set event name in the data array news_data[class="num">4] = event.name; MqlCalendarValue value; class=class="str">"cmt">//--- Declare calendar value structure
◍ 把财经日历数值塞进面板标签
这段逻辑干的事很直接:先用 CalendarValueById 按事件 id 抓到实际、预测、前值三组数,再统一用 DoubleToString 保留 3 位小数写进 news_data 数组的第 5、6、7 位。实际值那行对应数组下标 5,预测值下标 6,前值下标 7,少一位就会错位。 标签绘制分了两路:当 k 等于 3 时走 createLabel 的特殊分支,字号给到 22、纵向偏移算成 startY-(22-12),颜色用 importance_color 标重要性;其余情况用 12 号字、纯黑、贴着 startY 画。 每画完一列,startX 要加上 buttons[k]+3 的步长,否则下一列会和当前列重叠。在 MT5 里把这段接进你自己的日历面板循环,改 buttons[] 里的列宽参数就能直接看排版效果,外汇与贵金属事件受数据跳空影响大,面板数值仅作盘前参考,实际冲击概率随流动性变化。
CalendarValueById(values[i].id,value); class=class="str">"cmt">//--- Retrieve actual, forecast, and previous values class=class="str">"cmt">//--- Populate actual, forecast, and previous values in the news data array news_data[class="num">5] = DoubleToString(value.GetActualValue(),class="num">3); news_data[class="num">6] = DoubleToString(value.GetForecastValue(),class="num">3); news_data[class="num">7] = DoubleToString(value.GetPreviousValue(),class="num">3); class=class="str">"cmt">//--- Create label for each news data item if (k == class="num">3){ createLabel(ARRAY_NEWS+IntegerToString(i)+" "+array_calendar[k],startX,startY-(class="num">22-class="num">12),news_data[k],importance_color,class="num">22,"Calibri"); } else { createLabel(ARRAY_NEWS+IntegerToString(i)+" "+array_calendar[k],startX,startY,news_data[k],clrBlack,class="num">12,"Calibri"); } class=class="str">"cmt">//--- Increment x-coordinate for the next column startX += buttons[k]+class="num">3; }
把这条线请下神坛
到这一步,交互式经济日历面板已经能跑通基础链路:拉取日历数据、按重要性做视觉分类、用标签区分事件类型。它确实让关键宏观事件从一堆文字里浮出来了,但别把它当成决策终点。 外汇和贵金属受数据跳空与流动性真空影响,宏观事件只是概率变量,面板提示的高影响事件也可能被价格提前消化。 后续可接新闻过滤器与实时刷新,把同策略相关的信息留下、噪音筛掉;这一步做完,面板才从「能看」变成「能用」。 现在就把 MQL5_NEWS_CALENDAR_PART_2.mq5 拖进 MT5 测一遍,看你的品种在哪些数据发布点会异常抖动,比任何总结都实在。