学习为什么、以及如何设计算法交易系统·进阶篇
(2/3)· 从变量到条件语句,逐一拆解一段可跑的 MQL5 代码如何长成交易纪律的载体
◍ MT5 里变量怎么分作用域和类型
在 MT5 写 EA 或脚本时,变量就是一块带名字的内存,用来存能改的数据。按作用域分两种:在函数里声明的叫局部变量,只能在那个函数内读写;写在全部函数外面的叫全局变量,整个程序都能用,且只在函数首次执行前用常量初始化一次,表达式不行。 类型上,int 存整数;float 占 4 字节,范围约 1.175494351e-38 到 3.402823466e+38,double 占 8 字节,范围约 2.2250738585072014e-308 到 1.7976931348623158e+308,报价和手数计算多用 double;string 管文字,bool 只取 true / false。 下面这段能直接塞进 MT5 脚本跑,编译后无报错就会弹四个 Alert:整数、小数、字符串、布尔各一个。逐行看:myInteger 是 int 并赋 5;myDouble 是 double 赋 10.56;myString 存一段文字;myBoolean 设 true;后面四个 Alert 依次把这四个值弹窗输出。 另一个常见场景是把 A=10、B=10、C=10+5、var1=2.5、var2=4、result=2.5/4、message1="Hello Mohamed"、message2 拼上 A 的值都记下来,执行后警报会带出 C、result、message1、message2 四块内容。外汇和贵金属波动剧烈,用变量存价格相关数值时务必考虑滑点和重算时机,高风险。
class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| Variables.mq5 | class=class="str">"cmt">//| Copyright class="num">2022, MetaQuotes Ltd. | class=class="str">"cmt">//| [MQL5官方文档] | class=class="str">"cmt">//+------------------------------------------------------------------+ class="macro">#class="kw">property copyright "Copyright class="num">2022, MetaQuotes Ltd." class="macro">#class="kw">property link "[MQL5官方文档] class="macro">#class="kw">property version "class="num">1.00" class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| Script program start function | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">void OnStart() { class="type">int myInteger = class="num">5; class="type">class="kw">double myDouble = class="num">10.56; class="type">class="kw">string myString = "My name is Mohamed"; class="type">bool myBoolean = true; Alert(myInteger); Alert(myDouble); Alert(myString); Alert(myBoolean); } class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| Variables class="num">2.mq5 | class=class="str">"cmt">//| Copyright class="num">2022, MetaQuotes Ltd. | class=class="str">"cmt">//| [MQL5官方文档] | class=class="str">"cmt">//+------------------------------------------------------------------+ class="macro">#class="kw">property copyright "Copyright class="num">2022, MetaQuotes Ltd." class="macro">#class="kw">property link "[MQL5官方文档] class="macro">#class="kw">property version "class="num">1.00" class=class="str">"cmt">//+------------------------------------------------------------------+
「用 OnStart 跑通基础变量与弹窗」
在 MT5 脚本里,所有执行逻辑都从 OnStart() 入口开始。上面这段直接声明了整型、双精度、字符串三类变量,并在函数体内完成一次除法与字符串拼接,最后用 Alert 把结果推到终端弹窗。 具体看:A=10、B=5 为整数,C 先声明后赋值 C=A+B 得到 15;var1=2.5 除以 var2=4 得到双精度结果 0.625,这类隐式浮点运算在风控计算里很容易因精度被误读。 字符串部分把 "Hello"、空格、"Mohamed" 拼成 message1,又把 "Value of A is: " 接上 string(A) 转出的字符得 message2。四句 Alert 依次弹出问候语、整数 15、0.625、带标签的文本,验证时你开 MT5 新建脚本粘入即可看到四次弹窗。 外汇与贵金属行情受杠杆与跳空影响,这类基础变量练习虽无直接交易风险,但真接实时报价时须警惕浮点误差放大导致的信号偏移。
class="type">void OnStart() { class="type">int A = class="num">10; class="type">int B = class="num">5; class="type">int C; class="type">class="kw">double var1 = class="num">2.5; class="type">class="kw">double var2 = class="num">4; class="type">class="kw">double result = var1 / var2; class="type">class="kw">string greeting = "Hello"; class="type">class="kw">string space = " "; class="type">class="kw">string name = "Mohamed"; class="type">class="kw">string message1; class="type">class="kw">string message2; C = A + B; message1 = greeting + space + name; message2 = "Value of A is: " + class="type">class="kw">string(A); Alert(message1); Alert(C); Alert(result); Alert(message2); }
MT5里的真假判断怎么写
布尔类型只干一件事:做逻辑比较,结果不是 true 就是 false。MQL5 里常用的关系符号有 ==(等于)、!=(不等于)、<(小于)、<=(小于等于)、>(大于)、>=(大于等于),它们直接决定条件分支走哪边。 拿最直观的例子看,表达式 4<5 在数学上成立,所以在脚本里赋值给 bool 变量后,Alert 弹出的内容会是 true。这类判断是 EA 过滤信号、开关仓位的前提,写错一个符号整个逻辑就反了。 下面这段演示代码可以在 MT5 新建脚本直接跑,验证布尔赋值和弹窗行为: //+------------------------------------------------------------------+
| // | Boolean Operations.mq5 |
|---|---|
| // | Copyright 2022, MetaQuotes Ltd. |
| // | [MQL5官方文档] |
//+------------------------------------------------------------------+ #property copyright "Copyright 2022, MetaQuotes Ltd." #property link "[MQL5官方文档] #property version "1.00" //+------------------------------------------------------------------+
| // | Script program start function |
|---|
//+------------------------------------------------------------------+ void OnStart() { bool result = 4 < 5; Alert (result); //true } //+------------------------------------------------------------------+ 逐行拆一下:#property 三行是脚本元数据,不影响逻辑;OnStart() 是脚本入口;bool result = 4 < 5; 把比较结果存进 result;Alert(result); 把 true 打到终端警报窗。外汇与贵金属交易杠杆高、风险大,用布尔条件触发下单前务必在策略测试器跑历史数据确认逻辑。
class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| Boolean Operations.mq5 | class=class="str">"cmt">//| Copyright class="num">2022, MetaQuotes Ltd. | class=class="str">"cmt">//| [MQL5官方文档] | class=class="str">"cmt">//+------------------------------------------------------------------+ class="macro">#class="kw">property copyright "Copyright class="num">2022, MetaQuotes Ltd." class="macro">#class="kw">property link "[MQL5官方文档] class="macro">#class="kw">property version "class="num">1.00" class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| Script program start function | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">void OnStart() { class="type">bool result = class="num">4 < class="num">5; Alert(result); class=class="str">"cmt">//true } class=class="str">"cmt">//+------------------------------------------------------------------+
◍ 用 while 把重复动作交给计数器
while 循环由一个判断表达式和一段执行体构成:只要表达式为真,执行体就反复运行,直到表达式转为假才退出。它适合把『条件满足前一直做某件事』这类逻辑写得很干净,不用手动堆叠代码。 下面这段脚本把计数器从 1 起步,只要 counter < 3 就弹出当前值并加 1。跑完循环再弹一次收尾提示,最终警报顺序会是:脚本开始、1、2、循环已完成——共 4 条消息,循环体只进了 2 次。 在 MT5 里新建脚本粘入代码,拖到图表运行就能看到弹窗。若把判断里的 3 改成 10,警报会多输出到 9,这种改一个数就拉长行为的特性,正是循环比复制粘贴更有用的地方。外汇与贵金属波动剧烈,任何自动逻辑上线前都应在模拟盘验证。
class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| While Loop.mq5 | class=class="str">"cmt">//| Copyright class="num">2022, MetaQuotes Ltd. | class=class="str">"cmt">//| [MQL5官方文档] | class=class="str">"cmt">//+------------------------------------------------------------------+ class="macro">#class="kw">property copyright "Copyright class="num">2022, MetaQuotes Ltd." class="macro">#class="kw">property link "[MQL5官方文档] class="macro">#class="kw">property version "class="num">1.00" class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| Script program start function | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">void OnStart() { class=class="str">"cmt">//While(Loop) Alert("Start of script"); class="type">int counter = class="num">1; while(counter < class="num">3) class=class="str">"cmt">//true? { Alert(counter); counter = counter + class="num">1; } Alert("Loop has finished"); }
「for 循环的三段式与一次实跑」
MQL5 里的 for 循环由三个表达式加一个循环体构成:第一段做初始化,第二段每次判断终止条件,为真就继续跑循环体,为假就把控制权交出去;第三段在每轮迭代末尾做增量或计算。 拿上面这段代码来说,初始化把 i 置 0,条件卡在 i<5,每轮结束 i 自加 1。循环体只干一件事:弹一条 Alert("Hello")。 按这个逻辑,i 会依次取 0、1、2、3、4,共触发 5 次 Hello 弹窗;等到 i 累加到 5,条件 i<5 不成立,循环停下。你在 MT5 里新建脚本粘进去跑,终端会确切地报 5 次提醒,不会多也不会少。 外层 OnStart 是脚本入口,for 写在它里面就能直接验证。想改次数就把 i<5 里的 5 换成别的整数,比如 20 就会弹 20 条,外汇或贵金属 EA 里拿它扫 K 线序号时也是同一套机制,注意这类自动循环在实盘高频调用时存在执行延迟与滑点风险。
class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| For Loop.mq5 | class=class="str">"cmt">//| Copyright class="num">2022, MetaQuotes Ltd. | class=class="str">"cmt">//| [MQL5官方文档] | class=class="str">"cmt">//+------------------------------------------------------------------+ class="macro">#class="kw">property copyright "Copyright class="num">2022, MetaQuotes Ltd." class="macro">#class="kw">property link "[MQL5官方文档] class="macro">#class="kw">property version "class="num">1.00" class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| Script program start function | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">void OnStart() { for(class="type">int i=class="num">0; i<class="num">5 ; i++) { Alert("Hello"); } } class=class="str">"cmt">//+------------------------------------------------------------------+
用 if-else 给报价分叉报警
条件分支在 EA 或脚本里就是做二选一。语法骨架是 if (条件) 操作1 else 操作2:条件为真只跑操作1,为假只跑操作2,两者不会同时执行。 下面这段脚本把阈值钉在 1.146600,先弹出现价,再判断 Bid 与阈值的上下关系给出方向提示。外汇与贵金属波动剧烈,这类报警只作参考,实际下单需结合风控,杠杆品种高风险。 代码逐行拆: // 版权与版本元信息,仅标识脚本属性 #property copyright "Copyright 2022, MetaQuotes Ltd." #property link "[MQL5官方文档] #property version "1.00" // 脚本入口函数 void OnStart() // 设定判断阈值 1.146600 double level = 1.146600; // 取当前品种买价并按规定小数位规范化 double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits); // 弹出当前买价报警 Alert("Bid Price = " + string(Bid)); // 若买价大于阈值 if(Bid > level) // 弹窗提示价格高于阈值倾向 BUY { Alert ("The price is above " + string(level) + " -> BUY"); } // 否则(买价不高于阈值) else // 弹窗提示价格低于阈值倾向 SELL { Alert ("The price is below " + string(level) + " -> SELL"); } } 把 level 改成你盯的黄金或欧美关键位,挂到 MT5 脚本里跑一次,就能在终端看到分叉报警的实际效果。
class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| If-else statement.mq5 | class=class="str">"cmt">//| Copyright class="num">2022, MetaQuotes Ltd. | class=class="str">"cmt">//| [MQL5官方文档] | class=class="str">"cmt">//+------------------------------------------------------------------+ class="macro">#class="kw">property copyright "Copyright class="num">2022, MetaQuotes Ltd." class="macro">#class="kw">property link "[MQL5官方文档] class="macro">#class="kw">property version "class="num">1.00" class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| Script program start function | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">void OnStart() { class="type">class="kw">double level = class="num">1.146600; class="type">class="kw">double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits); Alert("Bid Price = " + class="type">class="kw">string(Bid)); if(Bid > level) { Alert("The price is above " + class="type">class="kw">string(level) + " -> BUY"); } class=class="str">"cmt">// What if the condition is false and we need to take an action also here we can use else function instead of writing another if code else { Alert("The price is below " + class="type">class="kw">string(level) + " -> SELL"); } } class=class="str">"cmt">//+------------------------------------------------------------------+