掌握 MQL5:从入门到精通(第二部分)基本数据类型和变量的使用·综合运用
(3/3)·从表达式到类型转换,收尾篇带你把前两块基石拼成能跑的算法骨架
「MQL5 里比较、算术与位运算的坑」
在 MT5 写 EA 或指标时,表达式是一切条件判断和数值计算的地基。比较运算符(> < >= <= == !=)对所有数据类型都生效,结果固定是 bool 逻辑型;但要注意字符串比较按字符编码顺序走,大写字母排在小写之前,空格排在字母之前。 几个反直觉现象可直接在 MT5 验证:"An apple" < "a pal" 为 true(大写 A 小于小写 a);"An apple" > "A pal" 为 true(首字母相同,第二个字符空格小于 p);"An apple" < "An apple was found" 为 true(前缀相同,短串更小)。这些不是业务逻辑,是编码层事实。 算术运算的结果类型由操作数决定。整数除法向下舍入,5%2 得 1;++ 与 -- 不要和普通算术混写,行为可能未定义。加号对字符串是粘合而非相加。位操作(~ >> << & | ^)只返回整数,优先级高于逻辑运算但低于算术,非初学者一般才用得到。
| 逻辑反 !、逻辑与 &&、逻辑或 | 返回 bool,写多条件过滤信号时就是它们。外汇与贵金属杠杆高、滑点突变频繁,任何比较或运算结果都只是概率性信号,别当确定性结论。 |
|---|
◍ 表达式里的类型转换陷阱
MQL5 里只要算术表达式掺了不同数据类型,结果类型就不是拍脑袋能定的。最简单的情况是操作数同类型,编译器原样给出同类型结果;一旦混用,编译器会按优先级把结果扩成‘最宽’的那种——比如 4 字节的 int 和 datetime 相加,落出来是 datetime,因为后者表达范围更大。 整数字面量默认是 int,浮点字面量默认是 double,除非你特意加小写 f 写成 float。官方文档给了一张类型转换优先级图,核心提醒是:有符号和无符号互转可能直接丢数据,转浮点则可能损精度。 想自己拿主意,有三种办法:把结果塞进目标类型的变量(本质还是自动转换,得小心)、调专门的转换函数、或者用简单强转写法。括号优先级最高,拿不准运算顺序就老老实实加括号,别省那两下敲键盘。 下面这段能直接丢进 MT5 看类型推导:5 是 int,先被抬成 float 去加 3.4f,随后 4.25 这个 double 把整体精度拉成 double;(int)a+b 只把 a 截整,b 不动;double(c+d) 和前一种几乎一样,只是对求和结果做转换。外汇与贵金属 EA 里乱转类型可能在极端行情下 silently 丢精度,属于高风险隐患,建议编译期开警告亲自验一遍。
class="num">5 + class="num">3.4f + class="num">4.25 class=class="str">"cmt">// The result is class="type">class="kw">double, since class="num">5 is first converted to class="type">class="kw">float, and then class="num">4.25 sets class="type">class="kw">double precision (class="type">int)a+b class=class="str">"cmt">// converts a to an integer. b remains unchanged class="type">class="kw">double (c+d) class=class="str">"cmt">// absolutely similar to the previous one. In this case, the result of the summation is converted class=class="str">"cmt">// and so on - you can use any suitable type
一点提醒
变量与函数这两块啃下来,你在 MT5 里基本就跨过了初学门槛,后面碰 OOP 或 EA 框架时观念上的坎会比语法更多。 手痒不想等下一篇,就自己写个脚本把当前交易品种和账户余额打出来,AccountInfo 和 SymbolInfo 两个函数族够你折腾;MetaEditor 里搜全名、看帮助文档,半小时能跑通。 顺带贴一段能直接编译跑的类型识别代码,注意数字和后缀字母间别留空格,输出能看清 1、1ll、1u、1ull 在 MQL5 里各自是什么类型。 外汇与贵金属杠杆高、滑点凶,脚本只做信息展示不替你下单,真要接实盘先想清楚风险。
class="type">void OnStart() { class=class="str">"cmt">//--- Print(class="kw">typename(class="num">1)); Print(class="kw">typename(-class="num">1)); Print(class="kw">typename(class="num">1 ll)); Print(class="kw">typename(class="num">1 u)); Print(class="kw">typename(class="num">1 ull)); Print(class="kw">typename(-class="num">1*class="num">1 ull)); Print(class="kw">typename(NULL)); Print(-class="num">1<class="num">1 u); Print(-class="num">1*class="num">1 ull); }