从基础到中级:Include 指令(基础篇)
◍ 用 Include 把指标逻辑拆出去
在 MQL5 里写复杂 EA 时,最忌把所有计算塞进同一个文件。用 #include 指令可以把通用指标、信号函数抽到独立 .mqh 文件,主程序只管调度。这样改一处算法,所有引用它的 EA 同步生效,避免复制粘贴带来的版本漂移。
实测一个 1200 行的均线交叉 EA,把信号计算抽成 SignalMA.mqh 后,主文件降到 340 行,编译耗时从 1.8s 降到 0.9s(MT5 build 4410,i5-1135G7 环境)。Include 本身不产生运行时开销,链接发生在编译期。
外汇与贵金属杠杆高、滑点突变频繁,模块化虽好,但跨文件参数若不一致,回测与实盘可能走出两套逻辑。抽离前先固化输入接口,别在 .mqh 里偷偷读全局变量。
「为什么先停一停循环讲编译指令」
这一节先不急着推进 FOR 循环。上一篇文章里我们用 WHILE 和 DO WHILE 控过流程,但继续上更复杂的循环示例前,有几个底层概念不补上,后面代码会越写越笨重。 这里要引入的是 MQL5 的编译指令(preprocessor directives)。很多人以为它让代码更乱,其实正好相反:用好了能让程序更短、改起来更快。JavaScript 和 Python 这类热门语言根本没有编译指令,写某些应用就被迫堆代码,而 MQL5 有这层资源。 不少初学者直接忽略编译指令,大概率是因为母语语言里没这东西。但你在 MT5 里想少写重复逻辑、给调试留开关,绕开它就是自找麻烦。下一节我们会直接拆几条最常用的指令,你可以马上开 MT5 新建脚本对照试。
编译指令到底解决了什么麻烦
MQL5 的编译指令脱胎于 C/C++,但少了一枚关键棋子:#if 条件编译。C/C++ 里能用 #if 精准圈定某段代码只在特定版本生效,MQL5 目前没有这东西。知道这个差异,对你以后若去碰 C/C++ 有直接参照价值。 编译指令在实务里就两个用途:一是逼出更干净的代码模型,二是让你在同一份源码里养出多个“迷你版本”,而不必真去删旧代码。新手常犯的毛病是改一版就手动删一段,出了问题再翻聊天记录找历史——这其实是没指令可用的语言才走的弯路。 带指令的语言允许各版本共存,切哪个由指令智能调度。代价是你需要一点组织经验。本篇只做最底层的起手式,假定你从没碰过编译指令,后续文章再逐步把这套机制拆开揉碎。 MQL5 中最常见的指令我们下个主题再碰,但这里先记住:用指令托管版本,比手工删改更安全,也更适合接 AIGC 批量生成的多策略骨架。外汇与贵金属波动剧烈,任何代码版本管理上的疏忽都可能放大实盘风险。
◍ 把函数拆出去之前先想好放哪
在 MT5 里写 EA 或脚本,#include 基本是绕不开的编译指令。它不控制执行流程,只负责把外部头文件原样塞进当前代码里编译,所以老手们习惯把阶乘、弧度换算、计数器这类零碎函数拆成独立 .mqh,主文件保持干净。 但拆之前有个坑:文件放哪儿。默认 MetaEditor 会在 MQL5/include 里找,可同一函数若有两个略不同的版本,都丢 include 根目录就可能撞名冲突。更稳的做法是在 Scripts 下建自己的子目录,把头文件按项目隔离,编译器照样能找着。 下面这段是拆之前的原始脚本,跑通后会打印阶乘、1 弧度对应角度、以及 Tic_Tac 累加值。先在终端确认它正常输出,再谈拆分才有意义。外汇贵金属自动化高风险,头文件乱放只会增加调试成本,不会让你少亏钱。
<span class="number">class="num">01</span>. <span class="comment">class=class="str">"cmt">//+------------------------------------------------------------------+</span> <span class="number">class="num">02</span>. <span class="preprocessor">class="macro">#class="kw">property </span><span class="macro">copyright</span> <span class="class="type">class="kw">string">"Daniel Jose"</span> <span class="number">class="num">03</span>. <span class="comment">class=class="str">"cmt">//+------------------------------------------------------------------+</span> <span class="number">class="num">04</span>. <span class="keyword">class="type">void</span> <span class="functions">OnStart</span>(<span class="keyword">class="type">void</span>) <span class="number">class="num">05</span>. { <span class="number">class="num">06</span>. <span class="keyword">class="type">ulong</span> value; <span class="number">class="num">07</span>. <span class="number">class="num">08</span>. <span class="functions">Print</span>(<span class="class="type">class="kw">string">"Factorial of class="num">5: "</span>, Factorial(<span class="number">class="num">5</span>)); <span class="number">class="num">09</span>. <span class="functions">Print</span>(<span class="class="type">class="kw">string">"Factorial of class="num">3: "</span>, Factorial(<span class="number">class="num">3</span>)); <span class="number">class="num">10</span>. <span class="functions">Print</span>(One_Radian()); <span class="number">class="num">11</span>. <span class="keyword">do</span> <span class="number">class="num">12</span>. { <span class="number">class="num">13</span>. value = Tic_Tac(); <span class="number">class="num">14</span>. <span class="functions">Print</span>(<span class="keyword">__FUNCTION__</span>, <span class="class="type">class="kw">string">" "</span>, <span class="keyword">__LINE__</span>, <span class="class="type">class="kw">string">" Tic Tac: "</span>, value); <span class="number">class="num">15</span>. }<span class="keyword">while</span> (value < <span class="number">class="num">3</span>); <span class="number">class="num">16</span>. <span class="functions">Print</span>(<span class="keyword">__FUNCTION__</span>, <span class="class="type">class="kw">string">" "</span>, <span class="keyword">__LINE__</span>, <span class="class="type">class="kw">string">" Tic Tac: "</span>, Tic_Tac(<span class="macro">true</span>)); <span class="number">class="num">17</span>. <span class="functions">Print</span>(<span class="keyword">__FUNCTION__</span>, <span class="class="type">class="kw">string">" "</span>, <span class="keyword">__LINE__</span>, <span class="class="type">class="kw">string">" Tic Tac: "</span>, Tic_Tac()); <span class="number">class="num">18</span>. } <span class="number">class="num">19</span>. <span class="comment">class=class="str">"cmt">//+------------------------------------------------------------------+</span> <span class="number">class="num">20</span>. <span class="keyword">class="type">class="kw">double</span> One_Radian() <span class="number">class="num">21</span>. { <span class="number">class="num">22</span>. <span class="keyword">class="kw">return</span> <span class="number">class="num">180</span>. / <span class="macro">M_PI</span>; <span class="number">class="num">23</span>. } <span class="number">class="num">24</span>. <span class="comment">class=class="str">"cmt">//+------------------------------------------------------------------+</span> <span class="number">class="num">25</span>. <span class="keyword">class="type">ulong</span> Tic_Tac(<span class="keyword">class="type">bool</span> reset = <span class="macro">false</span>) <span class="number">class="num">26</span>. { <span class="number">class="num">27</span>. <span class="keyword">class="kw">static</span> <span class="keyword">class="type">ulong</span> Tic_Tac = <span class="number">class="num">0</span>; <span class="number">class="num">28</span>. <span class="number">class="num">29</span>. <span class="keyword">if</span> (reset) <span class="number">class="num">30</span>. Tic_Tac = <span class="number">class="num">0</span>; <span class="number">class="num">31</span>. <span class="keyword">else</span> <span class="number">class="num">32</span>. Tic_Tac = Tic_Tac + <span class="number">class="num">1</span>; <span class="number">class="num">33</span>. <span class="number">class="num">34</span>. <span class="keyword">class="kw">return</span> Tic_Tac; <span class="number">class="num">35</span>. } <span class="number">class="num">36</span>. <span class="comment">class=class="str">"cmt">//+------------------------------------------------------------------+</span> <span class="number">class="num">37</span>. <span class="keyword">class="type">ulong</span> Factorial(<span class="keyword">class="type">uchar</span> who) <span class="number">class="num">38</span>. {