DoEasy 函数库中的其他类(第六十六部分):MQL5.com 信号集合类(基础篇)
📘

DoEasy 函数库中的其他类(第六十六部分):MQL5.com 信号集合类(基础篇)

第 1/3 篇

◍ 给信号对象造一个集合容器

在 DoEasy 函数库里,信号对象原本是零散存在的,要把它们当一组来管理,就得单独做一个集合类。这个类专门收纳 MQL5 信号对象,方便后续统一遍历、查找和释放。 做集合类时,核心是把每个信号对象封装成可索引的节点,外层用动态数组或哈希结构持有指针。这样在 EA 里调用时,不用反复向终端请求信号列表,本地就能直接拿到已缓存的对象引用。 实际落地时,建议先在脚本里打印集合的 Size() 和首个信号名,确认装载逻辑没问题再接进策略。外汇与贵金属信号波动受杠杆和流动性影响,高杠杆品类风险显著,信号历史表现不代表未来概率。

「信号集合与DOM快照的对象化封装」

上一节只解决了单个信号对象的建模,这一节把视角拉到信号数据库整体:用一个集合类把服务里广播的所有信号塞进同一张列表,之后按索引调 SignalBaseSelect() 就能直接取到目标信号。 集合类落地后,筛选逻辑可以完全参数化。比如只拉免费或付费信号、按盈利能力排序,或者一步返回参数等于、大于、小于某阈值的信号索引——搜索和排序都在对象内部完成,外层不用再写循环。 顺带把市场深度(DOM)快照类也补了属性:建对象时直接算好买卖盘总成交量。做贵金属或外汇 DOM 策略时,你不必再临时遍历挂单求和,开 MT5 调 CMarketDepth 构造就能拿到即时买卖量。 外汇与贵金属杠杆高、滑点跳空频繁,DOM 成交量只是概率参考,不能直接当成交保证。

给 DoEasy 库补上快照量与信号检索的底层接口

做图形化操控前,先把库里的消息与对象属性接口铺平。Data.mqh 里新增了 DOM 快照买卖量、快照序列、以及 MQL5 信号服务相关的一批消息索引,这些索引后续由 Message 类统一往日志抛,不再散用 Print()。 Message.mqh 中给 ToLog() 做了重载:新变体多接收一个“来源方法/函数名”参数,日志输出时把这个来源写在消息前面。调试时你能直接看到是哪段逻辑吐的线,不用再手动拼前缀。 MarketBookSnapshot 类的私密区加了总买量、总卖量两个成员变量。参数型构造函数里遍历 DOM 订单时,按订单方向把交易量分别累加进这两个变量——对象建完,总买卖量就已经就绪,不用事后另算。 返回说明的两个新方法会做阈值判断:交易量大于 0 才返回“标题+实数交易量”,否则返回整数型占位。这条规则让日志里的 DOM 简报更干净。 MQLSignal 类补了带连字符标志的 PrintShort(),并新增按描述执行信号订阅的方法;构造函数里订阅状态不再写死 false,而是用信号对象 ID 与“当前已订阅”有效 ID 比对的结果初始化。相等即视为已激活订阅。 Select.mqh 的 CSelect 类声明了操控信号对象集合的搜索/排序方法,逻辑与第三篇文章里其他对象类一致。Defines.mqh 则加了信号集合的自定义 ID,为后面独立集合类铺路。 下面这段是本次新增消息索引的原文片段,直接贴进对应头文件即可编译:

MQL5 / C++
class=class="str">"cmt">//--- CMarketBookSnapshot
  MSG_MBOOK_SNAP_TEXT_SNAPSHOT,                 class=class="str">"cmt">// DOM snapshot
  MSG_MBOOK_SNAP_VOLUME_BUY,                    class=class="str">"cmt">// Buy volume
  MSG_MBOOK_SNAP_VOLUME_SELL,                   class=class="str">"cmt">// Sell volume

class=class="str">"cmt">//--- CMBookSeries
  MSG_MBOOK_SERIES_TEXT_MBOOKSERIES,            class=class="str">"cmt">// DOM snapshot series
  MSG_MBOOK_SERIES_ERR_ADD_TO_LIST,             class=class="str">"cmt">// Error. Failed to add DOM snapshot series to the list
class=class="str">"cmt">//--- CMQLSignal
  MSG_SIGNAL_MQL5_TEXT_SIGNAL,                  class=class="str">"cmt">// Signal
  MSG_SIGNAL_MQL5_TEXT_SIGNAL_MQL5,             class=class="str">"cmt">// MQL5.com Signals service signal
  MSG_SIGNAL_MQL5_TRADE_MODE,                   class=class="str">"cmt">// Account type
  MSG_SIGNAL_MQL5_DATE_PUBLISHED,               class=class="str">"cmt">// Publication date
  MSG_SIGNAL_MQL5_DATE_STARTED,                 class=class="str">"cmt">// Monitoring start date
  MSG_SIGNAL_MQL5_DATE_UPDATED,                 class=class="str">"cmt">// Date of the latest update of the trading statistics
  MSG_SIGNAL_MQL5_ID,                           class=class="str">"cmt">// ID
  MSG_SIGNAL_MQL5_LEVERAGE,                     class=class="str">"cmt">// Trading account leverage
  MSG_SIGNAL_MQL5_PIPS,                         class=class="str">"cmt">// Trading result in pips
  MSG_SIGNAL_MQL5_RATING,                       class=class="str">"cmt">// Position in the signal rating

◍ 信号元数据枚举里藏着的订阅参数

在 MQL5 的信号接口里,一组 MSG_SIGNAL_MQL5_* 枚举直接对应信号展示与订阅时的核心字段。从订阅人数、交易笔数到账户权益、最大回撤、ROI 百分比,这些常量决定了你在终端里能看到哪些信号指标。 下面这段枚举清单是直接从标准头文件截出的,逐行看就能明白每个 ID 管什么: MSG_SIGNAL_MQL5_SUBSCRIBERS, // 订阅者数量 MSG_SIGNAL_MQL5_TRADES, // 交易笔数 MSG_SIGNAL_MQL5_SUBSCRIPTION_STATUS, // 账户对该信号的订阅状态 MSG_SIGNAL_MQL5_EQUITY, // 账户权益 MSG_SIGNAL_MQL5_GAIN, // 账户增长百分比 MSG_SIGNAL_MQL5_MAX_DRAWDOWN, // 最大回撤 MSG_SIGNAL_MQL5_PRICE, // 信号订阅价格 MSG_SIGNAL_MQL5_ROI, // 信号投资回报率百分比 MSG_SIGNAL_MQL5_AUTHOR_LOGIN, // 作者登录名 MSG_SIGNAL_MQL5_BROKER, // 经纪商公司名 MSG_SIGNAL_MQL5_BROKER_SERVER, // 经纪商服务器 MSG_SIGNAL_MQL5_NAME, // 名称 MSG_SIGNAL_MQL5_CURRENCY, // 账户货币 MSG_SIGNAL_MQL5_TEXT_GAIN, // 增长文本 MSG_SIGNAL_MQL5_TEXT_DRAWDOWN, // 回撤文本 MSG_SIGNAL_MQL5_TEXT_SUBSCRIBERS, // 订阅者文本 CMQLSignalsCollection 这组则管信号集合本身:付费/免费信号分类、新信号入列、拉取失败报错都在里面。 MSG_MQLSIG_COLLECTION_TEXT_MQL5_SIGNAL_COLLECTION, // MQL5信号服务信号集合 MSG_MQLSIG_COLLECTION_TEXT_SIGNALS_PAID, // 付费信号 MSG_MQLSIG_COLLECTION_TEXT_SIGNALS_FREE, // 免费信号 MSG_MQLSIG_COLLECTION_TEXT_SIGNALS_NEW, // 新加入集合的信号 MSG_MQLSIG_COLLECTION_ERR_FAILED_GET_SIGNAL, // 从集合接收信号失败 订阅复制端的参数也暴露了风控点:MSG_SIGNAL_INFO_EQUITY_LIMIT 是仓位体积转换的百分比,MSG_SIGNAL_INFO_SLIPPAGE 是同步持仓时的市价单滑点,MSG_SIGNAL_INFO_VOLUME_PERCENT 限制信号权益。外汇和贵金属信号订阅自带高杠杆风险,复制前建议先在 MT5 策略测试器里用历史数据核验最大回撤与 ROI 是否匹配你的账户权益上限。

MQL5 / C++
MSG_SIGNAL_MQL5_SUBSCRIBERS,                    class=class="str">"cmt">// Number of subscribers
MSG_SIGNAL_MQL5_TRADES,                        class=class="str">"cmt">// Number of trades
MSG_SIGNAL_MQL5_SUBSCRIPTION_STATUS,           class=class="str">"cmt">// Status of account subscription to a signal
MSG_SIGNAL_MQL5_EQUITY,                        class=class="str">"cmt">// Account equity
MSG_SIGNAL_MQL5_GAIN,                          class=class="str">"cmt">// Account growth in %
MSG_SIGNAL_MQL5_MAX_DRAWDOWN,                  class=class="str">"cmt">// Maximum drawdown
MSG_SIGNAL_MQL5_PRICE,                         class=class="str">"cmt">// Signal subscription price
MSG_SIGNAL_MQL5_ROI,                           class=class="str">"cmt">// Signal ROI(Return on Investment) in %
MSG_SIGNAL_MQL5_AUTHOR_LOGIN,                  class=class="str">"cmt">// Author login
MSG_SIGNAL_MQL5_BROKER,                        class=class="str">"cmt">// Broker(company) name
MSG_SIGNAL_MQL5_BROKER_SERVER,                 class=class="str">"cmt">// Broker server
MSG_SIGNAL_MQL5_NAME,                          class=class="str">"cmt">// Name
MSG_SIGNAL_MQL5_CURRENCY,                      class=class="str">"cmt">// Account currency
MSG_SIGNAL_MQL5_TEXT_GAIN,                     class=class="str">"cmt">// Growth
MSG_SIGNAL_MQL5_TEXT_DRAWDOWN,                 class=class="str">"cmt">// Drawdown
MSG_SIGNAL_MQL5_TEXT_SUBSCRIBERS,              class=class="str">"cmt">// Subscribers

class=class="str">"cmt">//--- CMQLSignalsCollection
MSG_MQLSIG_COLLECTION_TEXT_MQL5_SIGNAL_COLLECTION, class=class="str">"cmt">// Collection of MQL5.com Signals service signals
MSG_MQLSIG_COLLECTION_TEXT_SIGNALS_PAID,           class=class="str">"cmt">// Paid signals
MSG_MQLSIG_COLLECTION_TEXT_SIGNALS_FREE,           class=class="str">"cmt">// Free signals
MSG_MQLSIG_COLLECTION_TEXT_SIGNALS_NEW,            class=class="str">"cmt">// New signal added to collection
MSG_MQLSIG_COLLECTION_ERR_FAILED_GET_SIGNAL,       class=class="str">"cmt">// Failed to receive signal from collection
MSG_SIGNAL_INFO_PARAMETERS,                        class=class="str">"cmt">// Signal copying parameters
MSG_SIGNAL_INFO_EQUITY_LIMIT,                      class=class="str">"cmt">// Percentage for converting deal volume
MSG_SIGNAL_INFO_SLIPPAGE,                          class=class="str">"cmt">// Market order slippage when synchronizing positions and copying deals
MSG_SIGNAL_INFO_VOLUME_PERCENT,                    class=class="str">"cmt">// Limitation on signal equity
MSG_SIGNAL_INFO_CONFIRMATIONS_DISABLED            class=class="str">"cmt">// Enable synchronization without confirmation dialog

「信号订阅与行情快照的本地化字段映射」

在 MT5 的 EA 或指标源码里,信号服务与深度行情快照的类对象通常带一套俄英双语文案常量,编译后用于界面提示和多语言切换。上面这段枚举/结构体初始化列出了 MSG_SIGNAL_INFO_* 系列,覆盖复制止损止盈、按保证金限制、信号 ID、订阅开关、服务条款同意等 12 个关键状态位。 其中 MSG_SIGNAL_INFO_ERR_SIGNAL_NOT_ALLOWED 对应的提示是「Signal service disabled for program」,意味着在程序属性 Common 页没勾选 Allow modification of Signals settings 时,EA 内部调用信号接口会直接返回该错误,而不是静默失败。 紧跟着的 CMarketBookSnapshot、CMBookSeries 等类把「Снимок стакана цен」映射为 Depth of Market Snapshot,「Объём на покупку / продажу」分别映射为 Buy Volume / Sell Volume,这是本地化 DOM 面板数据的底层键值。CMQLSignal 类则暴露了信号账号杠杆、盈利点数、订阅人数、最大回撤、ROI(%) 等 20 余个可读属性——接信号前先读 Number of subscribers 和 Account maximum drawdown,外汇与贵金属信号自带高杠杆风险,订阅复制可能放大本金亏损。 开 MT5 按 F4 进 MetaEditor,搜 MSG_SIGNAL_INFO_TEXT_CHECK_SETTINGS 就能定位到这段映射,改双语常量即可做私有化提示,不必动逻辑层。

MQL5 / C++
  MSG_SIGNAL_INFO_COPY_SLTP,                                                                     class=class="str">"cmt">// Copy Stop Loss and Take Profit
  MSG_SIGNAL_INFO_DEPOSIT_PERCENT,                                                                 class=class="str">"cmt">// Limit by deposit
  MSG_SIGNAL_INFO_ID,                                                                              class=class="str">"cmt">// Signal ID
  MSG_SIGNAL_INFO_SUBSCRIPTION_ENABLED,                                                            class=class="str">"cmt">// Enable copying deals by subscription
  MSG_SIGNAL_INFO_TERMS_AGREE,                                                                     class=class="str">"cmt">// Agree to the terms of use of the Signals service
  MSG_SIGNAL_INFO_NAME,                                                                            class=class="str">"cmt">// Signal name
  MSG_SIGNAL_INFO_SIGNALS_PERMISSION,                                                              class=class="str">"cmt">// Allow using signals for program
  MSG_SIGNAL_INFO_TEXT_SIGNAL_SUBSCRIBED,                                                          class=class="str">"cmt">// Subscribed to signal
  MSG_SIGNAL_INFO_TEXT_SIGNAL_UNSUBSCRIBED,                                                        class=class="str">"cmt">// Unsubscribed from signal
  MSG_SIGNAL_INFO_ERR_SIGNAL_NOT_ALLOWED,                                                          class=class="str">"cmt">// Signal service disabled for program
  MSG_SIGNAL_INFO_TEXT_CHECK_SETTINGS,                                                             class=class="str">"cmt">// Please check program settings(Common-->Allow modification of Signals settings)
  };
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//--- CMarketBookSnapshot
  {"Снимок стакана цен","Depth of Market Snapshot"},
  {"Объём на покупку","Buy Volume"},
  {"Объём на продажу","Sell Volume"},
class=class="str">"cmt">//--- CMBookSeries
  {"Серия снимков стакана цен","Series of shots of the Depth of Market"},
  {"Ошибка. Не удалось добавить серию снимков стакана цен в список","Error. Failed to add a shots series of the Depth of Market to the list"},
class=class="str">"cmt">//--- CMBookSeriesCollection
  {"Коллекция серий снимков стакана цен","Collection of series of the Depth of Market shot"},
class=class="str">"cmt">//--- CMQLSignal
  {"Сигнал","Signal"},
  {"Сигнал сервиса сигналов mql5.com","Signal from mql5.com signal service"},
  {"Тип счета","Account type"},
  {"Дата публикации","Publication date"},
  {"Дата начала мониторинга","Monitoring starting date"},
  {"Дата последнего обновления торговой статистики","The date of the last update of the signal&class="macro">#x27;s trading statistics"},
  {"ID","ID"},
  {"Плечо торгового счета","Account leverage"},
  {"Результат торговли в пипсах","Profit in pips"},
  {"Позиция в рейтинге сигналов","Position in rating"},
  {"Количество подписчиков","Number of subscribers"},
  {"Количество трейдов","Number of trades"},
  {"Состояние подписки счёта на этот сигнал","Account subscription status for this signal"},
  {"Средства на счете","Account equity"},
  {"Прирост счета в процентах","Account gain"},
  {"Максимальная просадка","Account maximum drawdown"},
  {"Цена подписки на сигнал","Signal subscription price"},
  {"Значение ROI(Return on Investment) сигнала в %","Return on Investment(%)"},
  {"Логин автора","Author login"}

信号服务多语言映射与日志投递接口

这段结构体初始化把信号服务里的中文/俄文字段逐个映射到英文字符串,覆盖券商名、服务器、账户币种、增益、回撤、订阅人数等基础项,也包含 CMQLSignalsCollection 下的信号集合、付费/免费信号数、复制参数(如 Equity limit 对应成交量转换百分比、Slippage 用于同步持仓与跟单时的滑点容差)。 跟单权限相关字段值得在 MT5 里实测:'Allow synchronization without confirmation dialog' 控制是否跳过确认框直接同步,'Maximum percent of deposit used' 限制信号占用保证金比例,'Copy Stop Loss and Take Profit' 决定止损止盈是否跟随。外汇与贵金属杠杆高,跟单前应先在策略测试器用极小资金验证这些参数实际行为。 日志类静态方法提供了三种出口:ToLog 按 msg_id 往专家日志打消息,重载版可带 source 前缀;ToMail 发邮件,Push 推送到移动端。下面这段声明直接可见接口形态。 调用 ToLog 时若传入 code=true,日志会附带错误码,便于在小布盯盘后台按 ID 过滤信号异常。实际跟单中断多半能在 journal 里用 Signal ID 反查是哪条订阅出了界。

MQL5 / C++
  {"Наименование брокера (компании)","Broker name(company)"},
  {"Сервер брокера","Broker server"},
  {"Имя","Name"},
  {"Валюта счета","Base currency"},
  {"Прирост","Gain"},
  {"Просадка","Drawdown"},
  {"Подписчиков","Subscribers"},

class=class="str">"cmt">//--- CMQLSignalsCollection
  {"Коллекция сигналов сервиса сигналов mql5.com","Collection of signals from the mql5.com signal service"},
  {"Платных сигналов","Paid signals"},
  {"Бесплатных сигналов","Free signals"},
  {"Новый сигнал добавлен в коллекцию","New signal added to collection"},
  {"Не удалось получить сигнал из коллекции","Failed to get signal from collection"},
  {"Параметры копирования сигнала","Signal copying parameters"},
  {"Процент для конвертации объема сделки","Equity limit"},
  {"Проскальзывание, с которым выставляются рыночные ордера при синхронизации позиций и копировании сделок","Slippage(used when placing market orders in synchronization of positions and copying of trades)"},
  {"Ограничение по средствам для сигнала","Maximum percent of deposit used"},
  {"Разрешение синхронизации без показа диалога подтверждения","Allow synchronization without confirmation dialog"},
  {"Копирование Stop Loss и Take Profit","Copy Stop Loss and Take Profit"},
  {"Ограничение по депозиту","Deposit percent"},
  {"Идентификатор сигнала","Signal ID"},
  {"Разрешение на копирование сделок по подписке","Permission to copy trades by subscription"},
  {"Согласие с условиями использования сервиса \"Сигналы\"","Agree to the terms of use of the \"Signals\" service"},
  {"Имя сигнала","Signal name"},
  {"Разрешение на работу с сигналами для программы","Permission to work with signals for the program"},
  {"Осуществлена подписка на сигнал","Signal subscribed"},
  {"Осуществлена отписка от сигнала","Signal unsubscribed"},
  {"Работа с сервисом сигналов для программы не разрешена","Work with the \"Signals\" service is not allowed for the program"},
  {
    "Пожалуйста, проверьте настройки программы (Общие --> Разрешить изменение настроек Сигналов)",
    "Please check the program settings(Common --> Allow modification of Signals settings)"
  },

  };
class=class="str">"cmt">//+---------------------------------------------------------------------+
class=class="str">"cmt">//--- (class="num">1,class="num">2) display a message in the journal by ID, (class="num">3) to e-mail, (class="num">4) to a mobile device
  class="kw">static class="type">void        ToLog(const class="type">int msg_id,const class="type">bool code=false);
  class="kw">static class="type">void        ToLog(const class="type">class="kw">string source,const class="type">int msg_id,const class="type">bool code=false);
  class="kw">static class="type">bool        ToMail(const class="type">class="kw">string message,const class="type">class="kw">string subject=NULL);
  class="kw">static class="type">bool        Push(const class="type">class="kw">string message);
class=class="str">"cmt">//--- (class="num">1) send a file to FTP, (class="num">2) class="kw">return an error code

常见问题

建一个信号集合类,用动态数组或列表容器装信号对象,提供按ID检索和遍历接口即可本地管理。
在信号元数据枚举里加订阅参数和快照量字段,把行情快照的本地化数值直接赋给对象对应属性。
可以,小布能读取你本地的信号集合数据,直接列出各信号订阅字段与DOM快照量的对比结论。
做多语言映射表,写日志前统一转成本地编码再调用日志接口,避免原始语种混排。
订阅参数类字段如到期日、费率层级需订阅后填充,基础描述字段在快照阶段就有值。