MT4正版下载 - MT4平仓邮件通知设置及EA代码编写全流程

先弄明白MT4邮件功能的基础配置
动手写代码之前,得先把MT4自带的邮件服务设置好,否则EA里调用发送邮件的函数时,平台根本不知道往哪儿发、怎么发。打开MT4的“工具”菜单,找到“选项”,切到“电子邮件”标签页,这里需要填SMTP服务器地址、端口、登录账号和密码。不同邮箱服务商的SMTP参数不太一样,以常见的QQ邮箱为例,SMTP服务器是smtp.
qq.com,端口选465或者587,账号填你的完整邮箱地址,密码不是邮箱登录密码,而是开启SMTP服务后生成的那个授权码。填完别急着关窗口,点一下“测试”按钮,如果收到一封标题为“MetaTrader测试消息”的邮件,说明配置没问题,后面EA调用发送函数就能正常工作了。
这里有个容易踩的坑,很多人把邮箱密码直接填进去,结果发送失败。因为现在主流邮箱都强制要求使用授权码或专用密码连接第三方客户端,你必须在邮箱网页端的设置里找到“SMTP服务”或“客户端授权”选项,单独开启并生成一串随机码。另外,如果你用的是企业邮箱,端口和加密方式可能跟普通个人邮箱不同,最好先查一下服务商提供的官方文档,把SSL/TLS加密方式选对,不然连接会被拒绝。
配置好之后,MT4自带的邮件通知功能其实就能用了,在“工具”菜单的“选项”里,勾选“启用电子邮件通知”,再勾选“当账户余额变化时发送邮件”,平台会在每次余额变动时发一封简单邮件。但说句实话,这个内置通知太粗糙了,邮件里只有余额数字和几个预设字段,根本看不到订单号、手数、开平仓价格这些关键信息。所以为了拿到完整数据,还是得靠下面要讲的EA代码方案。
EA里监听平仓事件的核心逻辑
MT4的EA(Expert Advisor)本质上是挂在图表上的一个程序,它通过事件处理函数来响应市场变化和交易行为。平仓事件没有专门的回调函数,但我们可以用两种方式来捕获它。第一种是用OnTradeTransaction函数,这个函数在每次交易事务发生时都会被调用,包括开仓、平仓、修改订单等,在函数内部检查交易记录,就能识别出刚平掉的单子。第二种更简单粗暴,用OnTick函数配合历史订单对比,每次价格跳动时都把历史订单列表拉出来,跟上一根K线时记录的列表做对比,发现新出现的已平仓订单就触发邮件发送。
实际写代码时,我建议优先用OnTradeTransaction,因为它的触发时机更精准,不会像OnTick那样在行情剧烈波动时反复执行导致性能浪费。OnTradeTransaction函数的参数里有一个交易类型变量,比如TRADE_TRANSACTION_DEAL_ADD表示新成交,DEAL_ENTRY_OUT表示平仓出场,我们只需要在判断到DEAL_ENTRY_OUT类型时,再去获取对应的订单详细信息即可。这里有个细节,平仓可能产生多条成交记录,比如分批平仓或者部分平仓,每条记录都需要分别处理,不能只取最后一条。
还有一个需要注意的地方,EA在MT4里默认只处理当前图表对应品种的订单,如果你想让它监控所有品种的平仓事件,就得在代码里遍历整个账户历史。遍历历史订单用HistorySelect和HistoryDealGet系列函数,先按时间范围筛选出最近一段时间的成交记录,再逐条判断是否属于平仓类型。时间范围可以设成从上次记录的时间戳到当前时间,这样能减少不必要的遍历次数,提升运行效率。
邮件内容的构造与发送代码实战
现在到了最核心的部分,直接上代码示例。下面这段代码展示了如何在OnTradeTransaction里捕获平仓事件并发送邮件,先创建一个处理函数,在OnTradeTransaction中调用它。
void OnTradeTransaction(const MqlTradeTransaction& trans, const MqlTradeRequest& request, const MqlTradeResult& result) { if(trans.type == TRADE_TRANSACTION_DEAL_ADD && trans.entry == DEAL_ENTRY_OUT) { ProcessClosedDeal(trans.
deal); } } 接下来是ProcessClosedDeal函数,它的任务是提取订单信息并调用SendMail发送邮件。先通过HistoryDealGetInteger获取订单号、类型、手数,再用HistoryDealGetDouble拿价格和盈亏,用HistoryDealGetString拿品种名称。把这些字段拼成一个字符串,注意加上换行符和分隔线,让邮件内容一眼能看清。邮件标题可以带上订单号和品种,方便在收件箱里快速识别。
关于发送邮件的函数,MT4提供了SendMail(Subject, Body)这个内置函数,它直接用前面配置好的SMTP设置发送。但有个限制,这个函数只能发送纯文本内容,不支持HTML格式,所以排版上别指望用表格或加粗,老老实实用纯文本的换行和缩进。如果嫌默认函数不够用,也可以调用ShellExecute启动外部程序来发邮件,但那样做太复杂了,而且容易被杀毒软件拦截,不推荐新手尝试。
代码写完以后,记得在MT4的“导航器”窗口里编译一下EA,确认没有语法错误。编译通过后,把EA拖到图表上,勾选“允许实时自动交易”,再在“工具”菜单的“选项”里勾选“启用算法交易”。这里提醒一句,如果图表上挂载了多个EA,它们会同时监听交易事件,可能导致重复发送邮件,所以最好只在一个图表上挂载这个平仓通知EA,其他图表保持干净。
实际使用中的注意事项与细节调优
用了一段时间你会发现,有些细节没处理好会让人抓狂。比如EA把邮件发出去之后,如果同一秒内有多笔平仓,邮件会按顺序逐封发出,收件箱里可能一下子堆好几封,看着乱糟糟的。解决办法是在代码里加一个简单的缓存机制,把最近30秒内的交易记录去重,只发送第一笔通知,或者把多笔交易合并到一封邮件里。后者实现起来稍麻烦,但效果更好,邮件标题可以写成“15:23:45 平仓3笔订单”,正文里列出每笔明细。
另一个常见问题是,EA发送邮件时如果SMTP服务器响应慢,会阻塞主线程,导致图表卡顿。MT4的SendMail函数是同步执行的,遇到网络延迟时确实会卡一下。解决思路是不要在OnTradeTransaction里直接发邮件,而是把待发送的信息写入一个全局变量或文件队列,然后在OnTimer函数里异步处理。虽然代码量会增加不少,但换来的流畅体验是值得的,尤其对那种交易频率高的用户来说。
最后说说测试的重要性。编译通过不等于跑起来没问题,一定要在模拟账户上先跑几天,故意做几笔平仓操作,检查邮件是否准时到达、内容是否准确。我遇到过一种情况,ECOIN交易品种的小数位跟默认的两位不一样,导致邮件里的价格显示成乱码,后来在获取价格时加了NormalizeDouble函数,按品种的Digits参数处理才解决。这种细节坑很多,建议你把EA日志打开,在邮件发送前后打印一段调试信息,方便定位问题。
邮件通知本质上是个工具,它能帮你节省盯盘时间,但别指望它替你决策。真正下单前还是得自己看行情判断,邮件只是事后留个记录。如果你想把邮件内容进一步丰富,比如加上当前账户净值、持仓总数、最近几笔交易的盈亏曲线,那就要额外调用AccountInfoDouble和HistorySelect这些函数,逻辑并不复杂,就是拼字符串时多写几行的事。反正代码是死的,需求是活的,照着这个思路去扩展,你很快就能做出一个完全贴合自己习惯的平仓邮件通知系统。