通过有用的技术组合让您的 MQL5 客户惊叹!·进阶篇
📘

通过有用的技术组合让您的 MQL5 客户惊叹!·进阶篇

第 2/2 篇

用网页 GUI 给客户攒新闻 CSV

给 MT5 用户交付新闻监控方案时,与其让他们手填日历,不如直接做一个浏览器端 Web GUI 来生成 CSV。整套前端代码放在 news-watcher-csv.html 里,配合 EA 一起发给客户,他们打开页面选时间、填描述,点一下就能拿到标准格式的文件。 加载层走的是 Google Hosted Libraries 的 CDN:JQuery 1.10.2 和 JQuery UI 1.10.3 直接从谷歌服务器拉,浏览器首个 HTTP 请求就搞定,本地不用存库。但 timepicker 这个第三方时间选择组件谷歌没托管,只能把 jquery.timepicker.css 和 jquery.timepicker.min.js 放本地引用——客户看到多余文件会觉得烦,更优解是传到一个公共服务器再指向它,文件越少越好。 GUI 里实际用到的 JQuery 控件就四个:datepicker 选日期、timepicker 选时间(灵感来自谷歌日历)、sortable 拖拽排新闻顺序、dialog 弹窗显示内容。dialog 易用性纯粹主义者不喜欢,神经运动障碍用户操作费劲,但特定场景仍能用,后续可改成不打扰的呈现方式留作练习。 主程序逻辑极短:先修 YouTube iframe 的 zIndex 验证问题,再初始化上述控件,最后给「添加新闻」按钮和「生成 CSV」链接绑行为。下面这段是头文件加载与核心 jQuery 片段的原文,逐行拆完你就能在本地复现。 头文件里前两行 link 引谷歌的 jquery-ui.css 和本地 timepicker.css;三个 script 分别引谷歌 jquery.min.js、jquery-ui.min.js 和本地 timepicker.min.js。JS 部分 $(function(){}) 是就绪事件;iframe 循环加 ?wmode=transparent 修透明层;#datepicker 格式 yy.m.dd、#timepicker 格式 H:i:s;#sortable 启用排序并禁文本选中;#news-calendar 先隐藏;#add-new 点击后淡入日历并向 #sortable 追加一条 li,拼接基础货币、日期、时间、描述用分号隔开;#get-csv 点击后预设表头 Country;Time;Event\n。外汇与贵金属消息面波动剧烈,此类 CSV 仅辅助复盘,实盘仍属高风险。

MQL5 / C++
<span class="tag">&lt;<span class="keyword">link</span><span class="attribute"> rel=<span class="value">"stylesheet"</span></span><span class="attribute"> href=<span class="value">"http:class=class="str">"cmt">//ajax.googleapis.com/ajax/libs/jqueryui/class="num">1.10.class="num">3/themes/smoothness/jquery-ui.css"</span></span> /&gt;</span>
<span class="tag">&lt;<span class="keyword">link</span><span class="attribute"> rel=<span class="value">"stylesheet"</span></span><span class="attribute"> href=<span class="value">"jquery.timepicker.css"</span></span> /&gt;</span>
<span class="tag">&lt;<span class="keyword">script</span><span class="attribute"> src=<span class="value">"http:class=class="str">"cmt">//ajax.googleapis.com/ajax/libs/jquery/class="num">1.10.class="num">2/jquery.min.js"</span></span>&gt;</span><span></span><span class="tag">&lt;/<span class="keyword">script</span>&gt;</span>
<span class="tag">&lt;<span class="keyword">script</span><span class="attribute"> src=<span class="value">"http:class=class="str">"cmt">//ajax.googleapis.com/ajax/libs/jqueryui/class="num">1.10.class="num">3/jquery-ui.min.js"</span></span>&gt;</span><span></span><span class="tag">&lt;/<span class="keyword">script</span>&gt;</span>
<span class="tag">&lt;<span class="keyword">script</span><span class="attribute"> src=<span class="value">"jquery.timepicker.min.js"</span></span>&gt;</span><span></span><span class="tag">&lt;/<span class="keyword">script</span>&gt;</span>
$(function() {
    class=class="str">"cmt">// fix YouTube&class="macro">#x27;s zIndex iframes issue
    $(<span class="class="type">class="kw">string">&class="macro">#x27;iframe&class="macro">#x27;</span>).each(function(){
        var url = $(<span class="keyword">this</span>).attr(<span class="class="type">class="kw">string">"src"</span>);
        $(<span class="keyword">this</span>).attr(<span class="class="type">class="kw">string">"src"</span>,url+<span class="class="type">class="kw">string">"?wmode=transparent"</span>);
    });
    class=class="str">"cmt">// Init GUI elements
    $(<span class="class="type">class="kw">string">"class="macro">#datepicker"</span>).datepicker({ <span class="class="type">class="kw">string">&class="macro">#x27;dateFormat&class="macro">#x27;</span>: <span class="class="type">class="kw">string">&class="macro">#x27;yy.m.dd&class="macro">#x27;</span> });
    $(<span class="class="type">class="kw">string">"class="macro">#timepicker"</span>).timepicker({ <span class="class="type">class="kw">string">&class="macro">#x27;timeFormat&class="macro">#x27;</span>: <span class="class="type">class="kw">string">&class="macro">#x27;H:i:s&class="macro">#x27;</span> });
    $(<span class="class="type">class="kw">string">"class="macro">#sortable"</span>).sortable().disableSelection();
    $(<span class="class="type">class="kw">string">"class="macro">#news-calendar"</span>).hide();
    class=class="str">"cmt">// Buttons behavior
    $(<span class="class="type">class="kw">string">"class="macro">#add-new"</span>).click(function() {
        $(<span class="class="type">class="kw">string">"class="macro">#news-calendar"</span>).fadeIn(<span class="class="type">class="kw">string">"class="num">500"</span>);
        $(<span class="class="type">class="kw">string">"class="macro">#sortable"</span>).append(<span class="class="type">class="kw">string">&class="macro">#x27;&lt;li class="ui-state-class="kw">default"&gt;&lt;span class="ui-icon ui-icon-arrowthick-class="num">2-n-s"&gt;&lt;/span&gt;&class="macro">#x27;</span> +
            $(<span class="class="type">class="kw">string">&class="macro">#x27;class="macro">#base-currency&class="macro">#x27;</span>).val() + <span class="class="type">class="kw">string">&class="macro">#x27; ;&class="macro">#x27;</span> +
            $(<span class="class="type">class="kw">string">&class="macro">#x27;class="macro">#datepicker&class="macro">#x27;</span>).val() + <span class="class="type">class="kw">string">&class="macro">#x27; ;&class="macro">#x27;</span> +
            $(<span class="class="type">class="kw">string">&class="macro">#x27;class="macro">#timepicker&class="macro">#x27;</span>).val() + <span class="class="type">class="kw">string">&class="macro">#x27; ;&class="macro">#x27;</span> +
            $(<span class="class="type">class="kw">string">&class="macro">#x27;class="macro">#description&class="macro">#x27;</span>).val() + <span class="class="type">class="kw">string">&class="macro">#x27;&lt;/li&gt;&class="macro">#x27;</span>);
    });
    $(<span class="class="type">class="kw">string">"class="macro">#get-csv"</span>).click(function() {
        var csv = <span class="class="type">class="kw">string">"Country;Time;Event\n"</span>;

◍ 把新闻列表导出成 CSV 的弹窗逻辑

这段 jQuery 脚本干的事很直接:遍历页面里 #sortable li 的每个列表项,把文字拼进 csv 变量并用换行符隔开,最终形成一份纯文本日历。 随后清空 #dialog 并弹出一个模态框,宽度锁死在 650 像素,出现用 blind 特效、关闭用 explode 特效,两者时长都是 400 毫秒——这种设定在 MT5 配套的网页小工具里很常见,目的是让交易者点一下就能看到整理好的新闻清单。 弹窗内容会把 csv 里的 全部替换成 <br/> 再追加显示,只留一个 Ok 按钮关闭对话框。整套交互不涉及任何行情判断,纯粹是给 NewsWatcher EA 喂数据的预处理环节,外汇与贵金属新闻驱动行情波动大,用这类工具降低手动抄写出错概率比较务实。

MQL5 / C++
$("class="macro">#sortable li").each(function(){
      csv += $(this).text() + "\n";
    });
    $("class="macro">#dialog").empty().dialog({
      modal: true,
      width: class="num">650,
      show: {
        effect: "blind",
        duration: class="num">400
      },
      hide: {
        effect: "explode",
        duration: class="num">400
      },
      buttons: {
        Ok: function() {
          $( this ).dialog( "close" );
        }
      }
    }).append(csv.replace(/\n/g, &class="macro">#x27;<br/>&class="macro">#x27;));
    class="kw">return false;
  });
});

「新闻事件录入界面的 DOM 结构」

给 MT5 用的新闻监控工具,前端其实就一个静态 HTML 片段:用 select 下拉框限定品种(原文示例含 NZD、USD 两个 option),再配 datepicker、timepicker、description 三个文本输入,最后靠 id="add-new" 的按钮把一条事件塞进列表。 这堆标签最终被包在 id="csv-generator" 的 div 里;点完「+ Add new」之后,新闻条目会写进 id="sortable" 的 ul 里,页面右侧 id="news-calendar" 区域提供「Get CSV」链接导出。 导出路径被硬编码在 dialog 的 title 里:data_folder\MQL5\FILES\news_watcher.csv。也就是说你本地 MT5 的 MQL5\Files 目录下必须存在这个 csv,EA 或脚本才可能读得到——外汇和贵金属事件驱动策略本身高风险,文件路径不对 EA 就会静默失效。 CSS 部分只做了极简 reset(* 选择器 margin/padding 归零)和 body 的 Arial 字体声明,没有参与任何逻辑,纯为渲染干净。

MQL5 / C++
<div id="csv-generator">
  <div class="form-field">
    <label>Symbol:</label>
    <select id="symbol">
      <option>NZD</option>
      <option>USD</option>
    </select>
  </div>
  <div class="form-field">
    <label>Date:</label>
    <input type="text" id="datepicker"/>
  </div>
  <div class="form-field">
    <label>Time:</label>
    <input type="text" id="timepicker"/>
  </div>
  <div class="form-field">
    <label>Description:</label>
    <input id="description" type="text"/>
  </div>
  <div id="add-new-button" class="form-field">
    <label></label>
    <button id="add-new">+ Add new</button>
  </div>
</div>
<div id="news-calendar">
  <p><a id="get-csv" href="#">Get CSV</a></p>
  <ul id="sortable"></ul>
</div>
<div id="dialog" title="Please, copy and paste in data_folder\MQL5\FILES\news_watcher.csv"></div>

新闻日历面板的样式骨架

这段 CSS 决定了 MT5 网页端新闻日历组件的外观与布局逻辑,直接抄进自定义 HTML 面板就能复用。 整体容器 #csv-generator 占满 100% 宽度并做了跨浏览器渐变(#ffffff 到 #fafafa),#news-calendar 则留出上边距 2em、内边距 0 2em 2em 1em,用 1px 实线收边,视觉上把日历区和表单区切开。 表单区 #form 固定 65% 宽并右浮动,视频块 #video 占 30% 宽左浮动且带 3px 模糊的阴影;两者中间靠 1em 间距缓冲。标签 label 统一 150px 宽、右对齐,输入框按用途限宽:日期/时间框 100px,描述框 300px。 可排序列表 #sortable 去掉了默认项目符号,单行 li 留 0.4em 内边距与 1.5em 左缩进,拖动句柄靠绝对定位的 span 实现 -1.3em 偏移。想验证效果,把这段样式挂到本地 HTML 再用 jQuery UI 初始化 sortable 即可看到拖拽排版。

MQL5 / C++
padding: 0em 2em
}
header { border-bottom: 1px solid class="macro">#cccccc }
footer { border-top: 1px solid class="macro">#cccccc; margin-top: 2em; padding-top: 1em }
h1, h2, h3, h4, h5, p { padding: 1em 0em }
label {
    width: 150px;
    display: class="kw">inline-block;
    margin: 5px;
    text-align: right
}
input { border: 1px solid class="macro">#cccccc }
button, option, input { padding: 4px }
select { padding: 3px }
class=class="str">"cmt">/* Custom ids */
class="macro">#csv-generator {
    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=&class="macro">#x27;class="macro">#ffffff&class="macro">#x27;, endColorstr=&class="macro">#x27;class="macro">#fafafa&class="macro">#x27;);
    background: -webkit-gradient(linear, left top, left bottom, from(class="macro">#ffffff), to(class="macro">#fafafa));
    background: -moz-linear-gradient(top, class="macro">#ffffff, class="macro">#fafafa);
    width: class="num">100%;
    clear: both;
    overflow: hidden
}
class="macro">#video {
    width: class="num">30%;
    class="type">float: left;
    margin-right: 1em;
    -moz-box-shadow: 0px 3px 5px #class="num">888;
    -webkit-box-shadow: 0px 3px 5px #class="num">888;
    box-shadow: 0px 3px 5px #class="num">888;
    border:class="num">0
}
class="macro">#dialog { font-size: 12px }
class=class="str">"cmt">/* Form for adding the news */
class="macro">#form { width: class="num">65%; class="type">float: right }
inputclass="macro">#datepicker, inputclass="macro">#timepicker { width: 100px }
inputclass="macro">#description { width: 300px }
class="macro">#add-new-button { class="type">float: left; margin-right: 1em }
class=class="str">"cmt">/* Sortable */
class="macro">#news-calendar { clear: both; margin-top: 2em; padding: 0em 2em 2em 1em; background: class="macro">#fafafa; border: 1px solid class="macro">#cccccc }
class="macro">#sortable { list-style-type: none; margin: class="num">0; padding: 0em; width: auto; clear: both }
class="macro">#sortable li { margin: 3px; padding: class="num">0.4em; padding-left: class="num">1.5em; }
class="macro">#sortable li span { position: absolute; margin-left: -class="num">1.3em; }
aclass="macro">#get-csv {
    background: url(&class="macro">#x27;http:class=class="str">"cmt">//icons.iconarchive.com/icons/deleket/soft-scraps/class="num">24/File-New-icon.png&class="macro">#x27;) no-repeat 0px 8px;
    padding: 10px 58px 20px 30px;
}
class=class="str">"cmt">/* Custom classes */
.form-field { margin-bottom: class="num">0.5em }
class=class="str">"cmt">/* Overwrites */
.ui-dialog-title { font-size: 12px }

◍ 把工具请下神坛

这套基于 HTML5、CSS 和 JQuery 的 Web 前端,本质只是给自动新闻 EA 喂 CSV 日历的壳:三个文件以 txt 发出,需手动重命名为 .html / .css / .js 才能跑,jQuery 2.0 已明确不支持 IE 6、7、8,老浏览器直接弃用。 代码经 W3C 标记验证、在 Chrome 与 Firefox 最新版测过,但别把它当跨平台银弹——ActiveX 一类微软交互技术能补 Windows 端能力,也可能成恶意程序入口,信任边界得自己划。 外汇和贵金属本身高风险,新闻波动常让技术位失效;工具再花哨也改不了杠杆和滑点的概率游戏,开 MT5 把重命名后的文件挂上 EA 验证一遍,比信任何「整合方案」都实在。

常见问题

在新闻日历面板里填好事件和时间,点导出按钮即可生成 CSV 文件,直接用表格软件打开转发就行。
先搭一个固定宽高的面板骨架,里面用表单行放事件名、时间和影响等级,再套一层浅色边框样式即可。
可以,小布能按你给的时间窗口和品种把新闻事件汇总成清单,省去手动录入和导出的重复劳动。
用容器 div 包住 label 和 input 成对出现,提交区单独放底部,别把按钮写进循环里就不会错乱。
把多余装饰去掉,只留录入、预览和导出三件事,工具越轻客户越愿意天天打开用。