用于交易事件和信号的语音通知系统(基础篇)
给 MT5 接一套事件语音播报
MT5 原生支持通过 MQL5 调用系统语音接口,把交易事件、信号触发、报错信息直接念出来,省掉盯盘时反复扫面板的动作。这套思路在 2020-11-17 发布的示例里被实测过,原文页面累计浏览 3 554 次、收藏 5 次,说明刚需不小。 落地形态主要有三类:指标里播报信号状态、EA 里播报开平仓与止损触发、快捷交易脚本里播报一键下单结果。每一类都依赖同一个底层函数族,区别只在调用时机。 外汇与贵金属波动快、滑点随机,语音播报只是降低漏看概率的辅助手段,不替代风控。读者可直接开 MT5 新建脚本,先跑通一次系统发声,再决定接哪类事件。
「给 MT5 事件挂上人声播报」
MT5 自带的声音警报只覆盖 11 个固定事件,且都是短音效,没法告诉你「欧元兑美元空单已平仓」这种具体事。想在 EA 触发、持仓变动或价格越过关键位时听到人话,就得自己接一套语音通知。 现在手机导航、语音翻译大家都用惯了,交易终端也能这么玩。思路不复杂:把终端里的交易事件、市场状态或信号输出,转成文本再丢给系统语音引擎念出来,比蜂鸣声直观得多。 这套做法对外汇、贵金属这类高波动品种尤其有用——行情跳一两根点就可能扫掉止损,声音提醒能让你离开屏幕时也知道发生了什么。但语音只是辅助,信号误触发或延迟都可能发生,实盘前务必在策略测试器里跑通。
◍ 把语音警报塞进 MT5 的包含文件
做语音通知不必动既有的指标或 EA,核心思路是写成一个可复用的类,扔进 MQL5/Include/SoundsLib/SoundsLib.mqh。原文演示用的 CSoundsLib 就长这样,后续想接什么系统,include 一下就能调。 类里先放两个枚举:LANGUAGE 管语种(演示只接了俄语和英语),MESSAGE 管事件。演示集里塞了 24 个事件,多数围绕持仓和挂单的增删与状态,剩下几个给交易环境变化和买卖信号用。 文件落地有个硬规矩:音频必须放 MQL5/Files/SoundsLib,且 PlaySound() 只认 *.WAV。每个 MESSAGE 事件按语种后缀拆成两个文件,比如 SIGNAL_BUY 对应 SIGNAL_BUY_RU 和 SIGNAL_BUY_EN,所以 24 个事件实际要备 48 个 wav。俄语和英语各一份,少一个语种就少一类提示。 自己加事件就两步:先在 mqh 里给 MESSAGE 枚举补一个有意义的名字;再去文本转语音服务生成 wav,按「事件名_语种.wav」存进上述文件夹。只要命名对上,新警报立刻生效,不用改调用逻辑。外汇和贵金属波动剧烈,语音提醒只是辅助,别当成下单依据。
class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| Enumeration for switching the notification language | class=class="str">"cmt">//+------------------------------------------------------------------+ enum LANGUAGE { RUSSIAN, class=class="str">"cmt">// Russian ENGLISH class=class="str">"cmt">// English }; class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| List of voice alerts | class=class="str">"cmt">//+------------------------------------------------------------------+ enum MESSAGE { STATUS_ON, class=class="str">"cmt">// Status of enabled voice alerts SIGNAL_BUY, class=class="str">"cmt">// A Buy signal SIGNAL_SELL, class=class="str">"cmt">// A Sell signal BUY_ORDER_SET, class=class="str">"cmt">// A Buy order has been placed SELL_ORDER_SET, class=class="str">"cmt">// A Sell order has been placed BUYLIMIT_ORDER_SET, class=class="str">"cmt">// A Limit Buy order has been placed BUYSTOP_ORDER_SET, class=class="str">"cmt">// A Stop Buy order has been placed SELLLIMIT_ORDER_SET, class=class="str">"cmt">// A Limit Sell order has been placed SELLSTOP_ORDER_SET, class=class="str">"cmt">// A Stop Sell order has been placed BUYLIMIT_ORDER_DELETE, class=class="str">"cmt">// A Limit Buy order has been deleted BUYSTOP_ORDER_DELETE, class=class="str">"cmt">// A Stop Buy order has been deleted SELLLIMIT_ORDER_DELETE, class=class="str">"cmt">// A Limit Sell order has been deleted SELLSTOP_ORDER_DELETE, class=class="str">"cmt">// A Stop Sell order has been deleted BUY_ORDER_CLOSE_PROFIT, class=class="str">"cmt">// A Buy order has closed with a profit
订单结局与语音提醒类的枚举对接
这段声明把交易终端里最常见的几类事件做成了枚举值,方便后续用统一接口播报。买单亏损平仓、卖单获利平仓、卖单亏损平仓,以及被 TP 或 SL 触发的买卖单关闭,都各自占一个常量;外加市场休市、自动交易开/禁三种环境状态。 CSoundsLib 类封装了语言与激活状态两个私有成员,对外只暴露 Language() 设语种、IsActive() 取/设开关、Message() 触发指定事件语音。这样把『什么事件』和『怎么叫你』解耦,换语种不用改事件逻辑。 下面两个方法给出了最小实现:Language() 仅把入参写进 m_language;IsActive(void) 直接返回 m_activity_status。在 MT5 里新建 EA 引用该类,把 MARKET_CLOSE 接进 OnTick 判断,就能在休市前 0 根 Bar 收到静音或语音提示,避免外汇/贵金属隔夜跳空的高风险暴露。
BUY_ORDER_CLOSE_LOSS, class=class="str">"cmt">// A Buy order has closed with a loss SELL_ORDER_CLOSE_PROFIT, class=class="str">"cmt">// A Sell order has closed with a profit SELL_ORDER_CLOSE_LOSS, class=class="str">"cmt">// A Sell order has closed with a loss BUY_ORDER_CLOSE_TP, class=class="str">"cmt">// A Buy order has been closed by Take Profit BUY_ORDER_CLOSE_SL, class=class="str">"cmt">// A Buy order has been closed by Stop Loss SELL_ORDER_CLOSE_TP, class=class="str">"cmt">// A Sell order has been closed by Take Profit SELL_ORDER_CLOSE_SL, class=class="str">"cmt">// A Sell order has been closed by Stop Loss MARKET_CLOSE, class=class="str">"cmt">// Market is closed AUTO_TRADING_ON, class=class="str">"cmt">// Automated trading is allowed AUTO_TRADING_OFF, class=class="str">"cmt">// Automated trading is prohibited }; class CSoundsLib { class="kw">private: LANGUAGE m_language; class="type">bool m_activity_status; class="kw">public: CSoundsLib(class="type">void); ~CSoundsLib(class="type">void); class="type">void Language(LANGUAGE lang); class="type">void IsActive(class="type">bool flag); class="type">bool IsActive(class="type">void); class="type">bool Message(MESSAGE msg); }; class="type">void CSoundsLib::Language(LANGUAGE lang) { m_language=lang; } class="type">bool CSoundsLib::IsActive(class="type">void) { class="kw">return(m_activity_status); }
「声音反馈里的双语文件寻址逻辑」
在 MT5 里做交易提醒音效,很多人直接写死英文文件名,结果俄文环境用户一听全是哑炮。上面这段把语言切换做进了播放函数,值得照着改。
核心就一行:用枚举转字符串拼出 _RU 或 _EN 后缀,再去 \Files\SoundsLib\ 目录下找对应 wav。若 PlaySound 返回假,就按终端语言打印“Файл не найден”或“File not found”,方便排错。
实测中若 m_language 没跟随 TerminalInfoString(TERMINAL_LANGUAGE) 同步,会出现菜单俄文、提示音英文的割裂。建议把语言判定统一收口到终端属性读取,别在类内部另存一份标志。
外汇与贵金属行情跳动快,音效丢失可能让你漏掉关键信号,这类底层库的高风险在于静默失败——返回 false 但界面无感知。开 MT5 把这段塞进自己的 CSoundsLib,断网删掉 wav 试一次,看打印是不是对的。
class="type">bool CSoundsLib::Message(MESSAGE msg) { if(!m_activity_status) class="kw">return(class="kw">false); class="type">class="kw">string name=(m_language==RUSSIAN ? EnumToString(msg)+"_RU" : EnumToString(msg)+"_EN"); if(PlaySound("\\Files\\SoundsLib\\"+name+".wav")) class="kw">return(true); else { if(TerminalInfoString(TERMINAL_LANGUAGE)=="Russian") Print("Файл не найден"); else Print("File not found"); class="kw">return(class="kw">false); } }
◍ 给复合信号指标接上语音播报
把 ADXCloud 与 ColorZerolagRVI 叠成一套复合信号后,图表上只画箭头还不够——盯盘时眼睛不在屏前就会漏单。原文方案是在箭头指标里挂 SoundsLib.mqh,用语音把买/卖信号念出来。 初始化阶段先建语音通知类实例,并在 OnInit() 里指定语言。英语是默认项,不写也能跑,演示里显式设一遍只是让人看清接口位置。 信号搜索循环必须改:只判零号柱(当前形成中 K 线)的信号,不在历史柱上重播警报,否则一加载指标就炸出一串旧语音。零号柱出现 ADXCloud 绿云 + RVI 红转绿就触发买入播报,红云 + 绿转红则播卖出。 外汇与贵金属波动大、滑点突兀,这类语音提醒只降低漏看概率,不替代风控,信号错过或假突破都可能发生。 下面这段是复合指标头部参数与绘图声明,ADXPeriod=8、Smoothing=15 等数值可直接抄进 MT5 编译验证。
class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| Example.mq5 | class=class="str">"cmt">//| Alex2356 | class=class="str">"cmt">//| [MQL5官方文档] | class=class="str">"cmt">//+------------------------------------------------------------------+ class="macro">#class="kw">property copyright "Alex2356" class="macro">#class="kw">property link "[MQL5官方文档] class="macro">#class="kw">property version "class="num">1.00" class="macro">#class="kw">property indicator_chart_window class=class="str">"cmt">//--- two buffers are used for calculating and drawing the indicator class="macro">#class="kw">property indicator_buffers class="num">2 class=class="str">"cmt">//--- used graphic constructions class="macro">#class="kw">property indicator_plots class="num">2 class="macro">#class="kw">property indicator_label1 "Buy Signal" class="macro">#class="kw">property indicator_type1 DRAW_ARROW class=class="str">"cmt">//--- class="macro">#class="kw">property indicator_label2 "Sell Signal" class="macro">#class="kw">property indicator_type2 DRAW_ARROW class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| | class=class="str">"cmt">//+------------------------------------------------------------------+ input group "ADX Cloud Parameters" input class="type">int ADXPeriod = class="num">8; input class="type">class="kw">double Alpha1 = class="num">0.25; input class="type">class="kw">double Alpha2 = class="num">0.25; input group "RVI Color Parameters" input class="type">uint Smoothing = class="num">15; class=class="str">"cmt">//---- input class="type">class="kw">double Weight1 = class="num">0.05; input class="type">int RVI_period1 = class="num">8; class=class="str">"cmt">//----