通过应用程序了解MQL5中的函数(基础篇)
从 MT5 自带程序看清函数长相
打开 MT5 终端,进到「文件 → 打开数据文件夹 → MQL5 → Experts」,里面自带的 MACD Sample 这类 EA 就是现成的函数教科书。跑过一次回测的人会看到:同一段信号判断逻辑,被拆成 CheckForTrade() 这类独立函数反复调用,而不是堆在主过程里。
MQL5 里函数的基本骨架是「返回类型 函数名(参数类型 参数名)」,例如 double GetMA(int period) 表示传入周期、吐出双精度均线值。把常用计算封进函数,EA 在 1 分钟图上每秒重算也不会把主循环写成长毛怪物。
一个可验证现象:新建一个空 EA,只写 OnTick(){ Print(__FUNCTION__); },在 EURUSD 的 M1 上挂 10 分钟,专家日志里会刷出上百次 OnTick 字样——说明这个函数被报价驱动反复触发,外汇与贵金属杠杆高、跳空频繁,这种高频调用下函数若写得臃肿,实盘滑点风险会明显放大。
◍ 先把函数这件事拆开看
MQL5 里函数不是装饰品,而是把重复逻辑收口成单一入口的基本单元。一篇讲透函数用法的技术文,通常会按定义、结构、带参/不带参、默认值、参数传递、return、void、重载这条线走,最后落到几个可直接搬进 EA 的小工具上。 对交易者而言,函数最大的现实意义是:把「新闻提醒」「手数计算」「一键平掉所有单」这类动作封装好,主循环里一行调用就完事,不用每次都把逻辑重写一遍。 原文列出的落点包括新闻提醒程序、手数计算程序、关闭所有持仓程序,以及对应的函数重载与 void 类型用法。外汇与贵金属杠杆高、滑点突发,任何自动逻辑上线前都应在 MT5 策略测试器里用历史数据跑过,并清楚自己承担实盘风险。
「把重复逻辑收进一个函数里」
在 MT5 的 MQL5 编程里,函数就是一块带名字的代码,专门干一件明确的事,哪里要用就直接调用,不用把同一段逻辑抄得到处都是。语言自带的是内置函数,自己按需求写的是用户定义函数,实盘脚本里后者用得最多。 举个具体场景:当账户净值触及最大回撤阈值时,需要一键平掉所有未结订单。如果这个动作在 EA 的多个分支里都要触发,正确做法是把平仓逻辑封成一个函数,在需要的地方调一次就行;要是每处都重写一遍,代码很快就没法看了。 用户定义函数带来的直接好处有这几条可验证的点:落实 DRY(不要重复自己),同样的逻辑只写一次;随时可重用,改一处全生效;分而治之,复杂策略拆成小函数逐个击破;代码可读性上升,调试时定位错误更快。外汇与贵金属杠杆高、回撤失控风险大,用函数管平仓逻辑至少能让风控代码不混乱。 抽象和封装也算附赠价值:不用函数可能要多写几倍行数,而函数把数据和操作收在内部,比散代码更安全、好管。
MQL5 里函数怎么搭起来
写 EA 或指标时,先把函数拆成两步看:先声明或定义,再在需要的地方调用。定义时确定返回类型、函数名、参数列表和函数体;调用时只写函数名并填参数,MT5 就会在对应位置执行那段逻辑。 拿最直白的加法函数举例,返回 int、收两个 int 参数 val1 和 val2,函数体算完和之后用 Print 在「专家」标签页输出,并 return 结果。实盘或回测里调用 add(5,15),专家页会打出 20,这就是函数跑通的最小证据。 参数形态有三种常见写法。带参函数如 sayHello(string greeting, string name),参数类型随任务走;无参函数留空括号,像 sayHello() 内部写死 "Hello, " 和 "World!",调用后输出相同;带默认值函数 sayHello(string greeting="Hello, ", string name="World!") 允许调用时不传参用默认、传参则覆盖。连续调用 sayHello() 与 sayHello("Hi, ","Developer!") 能直接看出差异。 传参分值传递和引用传递。值传递时原始变量不变;引用传递在参数前加 &,如 updateNums(int &val1, int &val2),函数内 val1*=2 会直接改写外部变量。新建两个变量赋 10 和 20,调用前打印一次、调用后打印一次,第二次会看到被乘 2 后的更新值。外汇与贵金属杠杆高,任何代码先在策略测试器用历史数据验证再上真仓。 有返回值的函数必须带 return,且返回类型不能是数组,但可返回数组元素,或改用引用传数组间接改内容。不返回就用 void,例如 void updateNums(...) 不需要 return。同名不同参叫函数重载:两个 add 一个收两数、一个收三数,输入函数名时 MT5 编辑器会列出候选,按参数个数或类型选。这套结构摸清后,你开 MT5 新建 mq5 把上面代码贴进去编译,基本就能确认自己写的函数是否被识别。
returnedDataType functionName(param1, param2) { bodyOfFunction } class=class="str">"cmt">//addition function class=class="str">"cmt">// returned data type is an integer - the name of the function is add - parameters or arguments are two class="type">int variables val1 and val2 class="type">int add(class="type">int val1, class="type">int val2) { class=class="str">"cmt">//body of function that we need the function to perform when calling it class=class="str">"cmt">//create a result new variable to be assigned by the result of val1 and val2 addition class="type">int result = val1+val2; class=class="str">"cmt">//Print result in the experts tab Print(result); class=class="str">"cmt">//returning value class="kw">return result; } class=class="str">"cmt">//calling our defined function by its name and specifying arguments add(class="num">5,class="num">15); class=class="str">"cmt">//sayHello function class=class="str">"cmt">// returned data type is class="type">class="kw">string - name of function is sayHello - parameters or arguments are two class="type">class="kw">string variables greeting and name class="type">class="kw">string sayHello(class="type">class="kw">string greeting, class="type">class="kw">string name) { class=class="str">"cmt">//body of function that we need the function to perform when calling it class=class="str">"cmt">//create a result new variable to be assigned by the result of greeting and name addition class="type">class="kw">string result = greeting+name; class=class="str">"cmt">//Print result in the experts tab Print(result); class=class="str">"cmt">//returning value class="kw">return result; } class=class="str">"cmt">//sayHello function class=class="str">"cmt">// returned data type is a class="type">class="kw">string - the name of the function is sayHello - no parameters class="type">class="kw">string sayHello() { class=class="str">"cmt">//body of the function that we need the function to perform when calling it class=class="str">"cmt">//create a result new variable to be assigned by the result of greeting and name addition class="type">class="kw">string greeting= "Hello, "; class="type">class="kw">string name= "World!"; class="type">class="kw">string result = greeting+name; class=class="str">"cmt">//Print the result in the experts&class="macro">#x27; tab Print(result); class=class="str">"cmt">//returning value class="kw">return result; } sayHello(); class=class="str">"cmt">//defining function with class="kw">default values class="type">class="kw">string sayHello(class="type">class="kw">string greeting= "Hello, ", class="type">class="kw">string name="World!") { class="type">class="kw">string result = greeting+name; Print(result); class="kw">return result; } sayHello(); sayHello("Hi, ", "Developer!"); class=class="str">"cmt">//passing by reference class="type">void updateNums(class="type">int &val1, class="type">int &val2) { val1*=class="num">2;