如何在 MetaTrader 5 中创建并测试自定义 MOEX(莫斯科证券交易所) 品种·综合运用
正文
<span class="functions">CustomSymbolSetDouble</span>(name,<span class="macro">SYMBOL_TRADE_TICK_SIZE</span>,<span class="number">0.01</span>);<span> </span><span class="comment">// 最小价格变化</span> <span class="keyword">while</span>(!<span class="functions">FileIsEnding</span>(handle)) { str =<span class="functions">FileReadString</span>(handle); <span class="comment">//--- 跳过行 -----------------------+ </span> <span class="keyword">if</span>(str==<span class="string">""</span>) <span class="keyword">continue</span>; <span class="keyword">if</span>(<span class="functions">StringFind</span>(str,<span class="string">"//"</span>)<<span class="number">10</span>) <span class="keyword">continue</span>; <span class="comment">//------------------------------------------+ </span> sub =<span class="functions">StringSplit</span>(str,u_sep,split); <span class="keyword">if</span>(sub<<span class="number">2</span>) <span class="keyword">continue</span>; SetProperties(SName,split[<span class="number">0</span>],split[<span class="number">1</span>]); } <span class="keyword">void</span> SetProperties(<span class="keyword">string</span> name,<span class="keyword">string</span> str1,<span class="keyword">string</span> str2)
「把脚本参数搬进可视面板」
做 MT5 工具时,若配置项基本固定、不需要反复改外部输入,就该考虑用界面替代 input 参数。最终形态往往是自建一个输入面板,把原本暴露在 EA 属性里的外参转成面板内的局部变量,交易者点一下 OK 才真正跑逻辑。 面板依赖标准控件库,核心头文件就是 Dialog、Label、Button、ComboBox 这几个。OK 按钮挂上点击事件后,原先散在外部的 yyyymmdd、hhdmmdss 等格式变量全部收进事件处理函数,变成函数体内的局部声明,SkipString 默认跳 1 行、DatePosition 置 1、TimePosition 置 2 这类硬编码可在面板里改成下拉选择。 每个控件都配一个 Create() 函数,执行后把返回值塞回对应变量。比如日期格式下拉框列了 6 种:yyyy.mm.dd、yyyymmdd、yymmdd、ddmmyy、dd/mm/yy、mm/dd/yy,默认选中索引 1 即 yyyymmdd;点确认时再用 StringToInteger 读跳过行数、用 Value() 读下拉索引,switch 分支映射回 indate 枚举。 这套带界面的版本实现量明显更大。若你只是想快速改两行逻辑做验证,保留 input 版反而更顺手;面板版适合给不熟悉代码的人点选使用,外汇与贵金属波动剧烈、高风险,任何格式解析错都可能漏掉行情时间戳。
class="macro">#include <Controls\Dialog.mqh> class="macro">#include <Controls\Label.mqh> class="macro">#include <Controls\Button.mqh> class="macro">#include <Controls\ComboBox.mqh> class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| 事件处理 | class=class="str">"cmt">//+------------------------------------------------------------------+ EVENT_MAP_BEGIN(CFormatPanel) ON_EVENT(ON_CLICK,BOK,OnClickButton) EVENT_MAP_END(CAppDialog) class="type">void CFormatPanel::OnClickButton(class="type">void) { class=class="str">"cmt">// 上述属性 } class="type">long SkipString =class="num">1; class=class="str">"cmt">// 要跳过的字符串数量 DATE indate =yyyymmdd; class=class="str">"cmt">// 源日期格式 TIME intime =hhdmmdss; class=class="str">"cmt">// 源时间格式 class="type">int DatePosition =class="num">1; class=class="str">"cmt">// 日期位置 class="type">int TimePosition =class="num">2; class=class="str">"cmt">// 时间位置 class=class="str">"cmt">// 其它参数 class=class="str">"cmt">//-----------多选框日期格式------------------------------------+ if(!CreateComboBox(CDateFormat,"ComDateFormat",x0,y0+h+class="num">1,x0+w,y0+class="num">2*h+class="num">1)) { class="kw">return false; } CDateFormat.ListViewItems(class="num">6); CDateFormat.AddItem(" yyyy.mm.dd",class="num">0); CDateFormat.AddItem(" yyyymmdd",class="num">1); CDateFormat.AddItem(" yymmdd",class="num">2); CDateFormat.AddItem(" ddmmyy",class="num">3); CDateFormat.AddItem(" dd/mm/yy",class="num">4); CDateFormat.AddItem(" mm/dd/yy",class="num">5); CDateFormat.Select(class="num">1); } class="type">long sw; SkipString =StringToInteger(ESkip.Text()); sw =CDateFormat.Value(); class="kw">switch(class="type">int(sw)) { case class="num">0 :indate =yyyycmmcdd; class="kw">break; case class="num">1 :indate =yyyymmdd; class="kw">break; case class="num">2 :indate =yymmdd; class="kw">break; case class="num">3 :indate =ddmmyy; class="kw">break; case class="num">4 :indate =ddslmmslyy; class="kw">break; case class="num">5 :indate =mmslddslyy; class="kw">break; }
◍ 把外部报价喂进 MT5 建自定义品种
若你的报价是 Finam 这类标准格式、且不想改代码,直接走向导即可;非标准格式才需动第 1 部分的源码。核心前提:报价必须是一分钟帧,本文示例用的是莫斯科交易所 Sberbank 股票的 sb.csv。 先把 csv 丢进 MQL5/Files。MT5 出于安全限制文件目录,最省事的办法是在导航窗右键对应文件夹选“打开文件夹”,顺手把 Specifications.txt 也放同目录,这个文本管品种属性。 面板上要填全文件名(带扩展名),点差这里用固定值,不模拟浮动。点 OK 前把 Specifications.txt 里的规格填好——MetaEditor 里编辑最舒服,属性红、数值绿、被 // 注释的行不会生效,逗号是分隔符,手别抖删格式。 股票常见 SYMBOL_DIGITS=2、点值 0.01 卢布;股票期货小数位 0、点值 1 卢布,具体以 moex.com 规格为准。最小属性集一般在文件开头,至少含价格增量、点值、最小手数。填完 OK,导航窗里新品种会绿色高亮,开图核对后就能丢进策略测试器。 用自带 MA EA 跑自己的数据,一切正常就说明品种建对了。外汇和贵金属自定义品种同样高风险,规格填错回测就是 garbage in garbage out。要补报价或改属性,对已有品种重跑一遍即可;规格没变直接 OK。
把示例文件归到正确目录
这套自定义品种方案给了一组可直接落地的源文件,解压 MQL5.zip(526.52 KB)后,按用途分目录放才不会在 MT5 里编译报错。 脚本 CreateCustomSymbol.mq5(13.49 KB)和面板 EA CreateSymbolPanel.mq5(47.11 KB)分别进 MQL5\Scripts 与 MQL5\Experts;三个头文件 FormatFunctions.mqh(9.14 KB)、PropertiesSet.mqh(35.55 KB)、Specification.mqh(21.21 KB)丢进 MQL5\Include;品种设定的 Specifications.txt(8.04 KB)放到 MQL5\Files 供 EA 读取。 放错路径最常见的现象是 EA 启动后报 cannot open file 或直接不加载自定义品种——遇到这种情况先核对上面四个目录。外汇与贵金属自定义品种测试波动剧烈、点差跳变频繁,属高风险操作,先用模拟环境跑通再谈实盘。 文件rights归原作者所有,部分转载被禁,但个人验证用途复制进自己终端目录通常无碍;装好后开 MT5 调出 CreateSymbolPanel,加载 Specifications.txt 看能否生成新品种,这一步能验证你目录是否真放对了。