English Русский Deutsch 日本語
preview
将 Discord 与 MetaTrader 5 集成:构建具有实时通知功能的交易机器人

将 Discord 与 MetaTrader 5 集成:构建具有实时通知功能的交易机器人

MetaTrader 5积分 |
96 0
Javier Santiago Gaston De Iriarte Cabrera
Javier Santiago Gaston De Iriarte Cabrera

引言

在当今快节奏的交易市场中,远程监控和控制交易活动的能力变得愈发重要。实现这种远程监控功能的一种可能方案,就是将 Discord 通知与 MetaTrader 5 进行集成。通过在您的 Discord 应用中接收通知,您可以从任何位置实时监控您的交易活动。在本文中,我们将使用一个随机交易机器人的实际示例,来说明相关理念和实现步骤。因此,我们将建立 MetaTrader 5 与 Discord 平台之间的可靠通信,通过该通信渠道,您可以获取交易执行、市场变化及其他警报的实时通知。

在本文中,我们将介绍需要在平台端进行哪些设置才能启用此类集成。特别是,我们将探讨 WebRequest 设置,这些设置允许平台与 Discord 等其他即时通讯工具建立连接。我们还将介绍如何配置您的 Discord 服务器,以便能够接收来自 MetaTrader 5 的通知。

本文内容要求读者具备一定的 MQL5 编程基础,并对平台的运行方式有较好的了解。


Discord 与 MetaTrader 5 的配置

您需要添加以下两个 https 地址,并确保指定的 URL 允许发送 Web 请求:

允许 WebRequests


除了创建并复制 webhook 外,您还需要设置一个服务器(或使用您在 Discord 中已有的服务器)。


EA 代码示例

在EA中,别忘了粘贴 WebHook 链接。

#include <Trade/Trade.mqh>

CTrade trade;
// Discord webhook URL - Replace with your webhook URL
string discord_webhook = "https://discord.com/api/webhooks/XXXXXXXXXXXXXXXXXXXXXXXXX";

// Strategy Parameters

我不知道为什么,但 webhook 需要从 discordapp.com 更改为 discord.com。

以下是我们设置EA基本 Discord 参数的方法:

string discord_webhook = "https://discord.com/api/webhooks/your-webhook-url";

input group "Discord Settings"
input string DiscordBotName = "MT5 Trading Bot";    
input color MessageColor = clrBlue;                 
input bool SendPriceUpdates = true;

Discord 与您的 MetaTrader 5 EA之间最重要的连接是 webhook URL。此外,我们还包含了一些可供用户自定义的输入参数,用于更改机器人的外观和行为这些选项为集成提供了灵活性,使交易者能够根据自身需求调整系统。

确保 MetaTrader 5 与 Discord 之间可靠连接的关键步骤在于激活流程。在此阶段,我们必须确认 Discord webhook 正常工作,并且EA具有发送 Web 请求的必要权限。此验证过程包含几项关键测试:

int OnInit() {
    Print("Initialization step 1: Checking WebRequest permissions...");
    
    if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED)) {
        Print("Error: WebRequest is not allowed. Please allow in Tool -> Options -> Expert Advisors");
        return INIT_FAILED;
    }
    
    string test_message = "{\"content\":\"Test message from MT5\"}";
    string headers = "Content-Type: application/json\r\n";
    char data[], result[];
    ArrayResize(data, StringToCharArray(test_message, data, 0, WHOLE_ARRAY, CP_UTF8) - 1);
    
    int res = WebRequest(
        "POST",
        discord_webhook,
        headers,
        5000,
        data,
        result,
        headers
    );
    
    if(res == -1) {
        Print("Make sure these URLs are allowed: https://discord.com/*, https://discordapp.com/*");
        return INIT_FAILED;
    }
    
    return(INIT_SUCCEEDED);
}

为了使 Discord 警报既具有教学意义又美观,消息的格式化至关重要。由于 Discord 支持 Markdown 格式,我们可以通过组织消息来突出关键信息。我们实施了一套全面的方法来格式化交易数据,使用户能够快速轻松地理解每笔交易的细节:

string FormatTradeMessage(TradeInfo& tradeInfo) {
    string message = "**New " + tradeInfo.type + " Signal Alert!**\n";
    message += "Symbol: " + tradeInfo.symbol + "\n";
    message += "Type: " + tradeInfo.type + "\n";
    message += "Price: " + DoubleToString(tradeInfo.price, _Digits) + "\n";
    message += "Lots: " + DoubleToString(tradeInfo.lots, 2) + "\n";
    message += "Stop Loss: " + DoubleToString(tradeInfo.sl, _Digits) + "\n";
    message += "Take Profit: " + DoubleToString(tradeInfo.tp, _Digits) + "\n";
    message += "Time: " + TimeToString(TimeCurrent());
    return message;
}

在 MetaTrader 5 中处理 JSON 数据时,正确处理特殊字符至关重要,以避免生成错误的 JSON 字符串,从而导致消息发送失败。我们的实现中包含了一个强大的 JSON 转义方法,可以处理所有常见的特殊字符:

string EscapeJSON(string text) {
    string escaped = text;
    StringReplace(escaped, "\\", "\\\\");
    StringReplace(escaped, "\"", "\\\"");
    StringReplace(escaped, "\n", "\\n");
    StringReplace(escaped, "\r", "\\r");
    StringReplace(escaped, "\t", "\\t");
    return escaped;
}

SendDiscordMessage 函数负责通过 Discord 的 Webhook API,将消息从 MetaTrader 5 可靠地发送到 Discord。该函数的核心是接收一个消息字符串和一个可选的错误标志作为参数,并将它们转换为 Discord 服务器能够理解和处理的格式正确的 HTTP 请求。

该函数首先通过检查 isWebRequestEnabled 标志来进行安全验证,以确认是否启用了 Web 请求。这一验证步骤可防止在 MetaTrader 5 平台缺少必要权限时尝试通信,从而避免潜在的系统挂起或崩溃。如果未启用 Web 请求,函数会立即返回 false,表示消息无法发送。

在构建消息时,该函数使用视觉标记来提升可读性。它会在错误消息前添加一个红色的 X 表情符号(❌),在成功操作前添加一个绿色的勾号表情符号(✅)。这些视觉提示使交易者能够快速了解 Discord 频道中通知的性质。

随后,消息被封装为 JSON 负载(payload),这是 Discord API 所期望的格式。EscapeJSON 函数(在构建负载时调用)在此起到了关键作用,确保消息中的特殊字符不会破坏 JSON 结构。这包括处理引号、换行符和其他可能导致解析错误的特殊字符。

该函数设置正确的 HTTP 头部,特别指明内容类型为 JSON。该头部信息至关重要,因为它告诉 Discord 服务器如何解释传入的数据。Content-Type 头部被设置为 “application/json”,这是 REST API 通信的标准格式。

技术性较强的一个方面是将字符串负载转换为字符数组。这种转换是必要的,因为 MetaTrader 5 的 WebRequest 函数需要的是二进制数据,而不是纯字符串。ArrayResize 函数确保字符数组的大小适合容纳转换后的消息,并考虑 UTF-8 编码,这对于正确处理特殊字符和表情符号至关重要。

实际通信通过调用 WebRequest 函数完成,该函数向 Discord Webhook URL 发送一个 POST 请求。该函数包含几个重要参数:

  • 超时值设置为 5000 毫秒(5 秒),以防止在 Discord 服务器响应缓慢时系统挂起。
  • 先前准备好的头部和数据。
  • 用于存储响应数据和头部的数组。

该函数通过 HTTP 响应代码监控消息发送的成功情况。响应代码 200 或 204 表示发送成功(200 表示成功并返回内容,204 表示成功但无内容)。当检测到成功时,函数会更新 lastMessageTime 时间戳,该时间戳可用于限流控制,并返回 true 表示发送成功。

在消息发送失败的情况下(由非 200 或 204 的任何响应代码表示),函数返回 false,使调用代码能够适当处理失败。这种错误处理机制使得在 Discord 通信失败时可以实现重试逻辑或备用通知方式。

这一实现创建了 MetaTrader 5 与 Discord 之间稳健可靠的通信渠道,处理了跨平台通信的所有复杂性,同时为调用代码提供了清晰的成功/失败反馈。对正确错误处理、字符编码和 API 合规性的关注,使该函数成为 Discord 集成系统中一个可靠的核心组件。

bool SendDiscordMessage(string message, bool isError = false) {
    if(!isWebRequestEnabled) return false;
    
    message = (isError ? "❌ " : "✅ ") + message;
    string payload = "{\"content\":\"" + EscapeJSON(message) + "\"}";
    string headers = "Content-Type: application/json\r\n";
    
    char post[], result[];
    ArrayResize(post, StringToCharArray(payload, post, 0, WHOLE_ARRAY, CP_UTF8) - 1);
    
    int res = WebRequest(
        "POST",
        discord_webhook,
        headers,
        5000,
        post,
        result,
        headers
    );
    
    if(res == 200 || res == 204) {
        lastMessageTime = TimeCurrent();
        return true;
    }
    
    return false;
}

我们通过实施一个基础的随机交易策略,将我们的 Discord 集成投入了实际应用。尽管该策略的主要目的是教学性的,但它展示了如何成功地将交易逻辑与 Discord 警报结合起来:

void PlaceRandomTrade() {
    bool isBuy = (MathRand() % 2) == 1;
    
    double price = isBuy ? SymbolInfoDouble(_Symbol, SYMBOL_ASK) 
                        : SymbolInfoDouble(_Symbol, SYMBOL_BID);
    
    int slPoints = 50 + (MathRand() % 100);
    int tpPoints = 50 + (MathRand() % 100);
    
    double sl = isBuy ? price - slPoints * _Point : price + slPoints * _Point;
    double tp = isBuy ? price + tpPoints * _Point : price - tpPoints * _Point;
    
    TradeInfo tradeInfo;
    tradeInfo.symbol = _Symbol;
    tradeInfo.type = isBuy ? "BUY" : "SELL";
    tradeInfo.price = price;
    tradeInfo.lots = LotSize;
    tradeInfo.sl = sl;
    tradeInfo.tp = tp;
    
    string message = FormatTradeMessage(tradeInfo);
    if(SendDiscordMessage(message)) {
        trade.SetExpertMagicNumber(magicNumber);
        
        bool success = isBuy ? 
            trade.PositionOpen(_Symbol, ORDER_TYPE_BUY, LotSize, price, sl, tp, "Random Strategy Trade") :
            trade.PositionOpen(_Symbol, ORDER_TYPE_SELL, LotSize, price, sl, tp, "Random Strategy Trade");
            
        if(success) {
            SendDiscordMessage("✅ Trade executed successfully! Ticket: " + IntegerToString(trade.ResultOrder()));
        }
    }
}

对于那些希望关注价格变动而无需持续监控交易平台的交易者来说,定期的市场更新可能非常有帮助。我们实现了一个价格更新功能,可以定期向 Discord 推送最新价格信息:

void SendPriceUpdate() {
    if(!SendPriceUpdates) return;
    if(TimeCurrent() - lastMessageTime < 300) return;
    
    string message = "```\n";
    message += "Price Update for " + _Symbol + "\n";
    message += "Bid: " + DoubleToString(SymbolInfoDouble(_Symbol, SYMBOL_BID), _Digits) + "\n";
    message += "Ask: " + DoubleToString(SymbolInfoDouble(_Symbol, SYMBOL_ASK), _Digits) + "\n";
    message += "Spread: " + DoubleToString(SymbolInfoInteger(_Symbol, SYMBOL_SPREAD), 0) + " points\n";
    message += "```";
    
    SendDiscordMessage(message);
}

当EA被终止时,需实现包含以下适当的清理步骤:

void OnDeinit(const int reason) {
    SendDiscordMessage("```\nEA stopped. Reason code: " + 
                      IntegerToString(reason) + "```");
}


示例结果

通过此集成示例,您应关注以下内容:


安全与 Webhook 管理

在生产环境中集成 Discord 时,需要考虑多个关键因素。安全是首要问题。由于任何拥有 Webhook URL 的人都可以向您的 Discord 频道发送消息,因此该 URL 应被视为敏感数据。为了保护 Webhook URL,建议使用加密技术或将其存放在安全的配置文件中。

另一个需要考虑的重要因素是网络可靠性。Discord 的 API 偶尔可能出现服务中断或速率限制,互联网连接也可能不稳定。为了妥善应对这些情况,您的解决方案应包含健壮的错误处理和重试机制。这可能包括为重试失败的消息建立消息队列,并实施指数退避策略。


性能考虑

性能优化也至关重要,尤其对于高频交易系统。Discord 警报固然有用,但不应影响交易逻辑的执行效率。为实现 Discord 交互而不干扰主要交易活动,可以考虑使用独立线程或采用异步消息队列机制。

有多种方法可以扩展 Discord 集成的功能。例如,您可能希望加入以下特性:实时绩效指标,如交易统计和盈亏计算;风险管理警报,当达到特定风险敞口水平时发出通知;根据您的交易策略指标更新市场分析。您还应监控系统健康状况,包括错误率、连接状态,以及基于 Discord 的自定义命令,这些命令可让您修改参数或检查交易系统状态。

要实现这些扩展功能,您需要仔细思考如何合理安排不同类型的信息以及如何构建消息。可以使用 Discord 的 Markdown 样式为不同类型的通知生成视觉上独特的消息,从而便于快速识别关键信息。

不过,在添加新功能时,始终要平衡提供有用信息与避免信息过载之间的关系。请优先考虑最重要的通知。您可能希望禁用某些通知类型,或为不同类别的消息使用不同的 Webhook URL。


实际用例

以下是该 Discord 集成的一些实际应用场景:

  • 组合管理:跨多个账户跟踪多种交易策略;
  • 风险管理:在预设水平被突破时立即收到警报;
  • 定期获取策略绩效与市场状况更新;
  • 与交易团队共享市场分析与交易信号。

我们所讨论的方法为这些应用提供了坚实的基础,同时也足够灵活,可以满足特定需求。成功部署的关键在于理解集成的技术层面,以及使用系统的交易者的实际需求。

保持 Discord 集成的可靠运行,需要定期测试与监控。这包括监控消息传递率、追踪失败的消息,并确保所有重要警报都能及时发送。考虑实现日志系统,记录所有 Discord 交互及发生的错误,以便您能快速发现并解决可能出现的问题。

扩展和改进此集成的可能性仅受您的想象力和交易需求的限制。通过从这个坚实的基础出发,根据反馈和实际使用逐步添加功能,您可以构建一个强大的通信系统,提升您的交易操作,并让您随时随地了解交易动态。


监控与维护

请记住,有效的交易不仅需要良好的策略,还需要掌握适当的工具和知识。此 Discord 集成是现代交易者的重要工具,它在您的自动化交易系统与您监控和响应市场状况的能力之间建立了关键联系。


结论

总之,Discord 与 MetaTrader 5 的集成是另一种有用的解决方案,为交易者提供了一种跟踪和响应市场情况的方式。实时通知、团队沟通和远程监控功能使其非常实用和便捷。然而,实施它需要一定的时间和知识。此外,您必须非常谨慎,并关注安全性、网络可靠性和性能优化。随着两个平台的进一步发展,语音频道通知、交互式命令和基于机器学习的警报过滤等增强功能的可能性,为交易效率提供了更多机会。通过在自动化交易系统与实时通信之间建立这一关键连接,交易者无论身在何处,都能更好地控制其交易活动,并确保不会错过重要的市场变动或交易信号。


文件 保存路径
Discord_examples.mq5 将它保存在 MQL5/Experts/ 文件夹下

此致,哈维尔·S·加斯顿·德·伊里亚特·卡布雷拉(Javier S. Gastón de Iriarte Cabrera)

本文由MetaQuotes Ltd译自英文
原文地址: https://www.mql5.com/en/articles/16682

附加的文件 |
Discord_example.mq5 (20.38 KB)
开发先进的 ICT 交易系统:在指标中实现订单区块 开发先进的 ICT 交易系统:在指标中实现订单区块
在本文中,我们将学习如何创建一个指标来检测、绘制订单区块并提醒订单块的缓解。我们还将详细研究如何在图表上识别这些区块,设置准确的提醒,并使用矩形可视化它们的位置,以更好地了解价格行为。该指标将成为遵循聪明钱概念和内圈交易者(ICT,Inner Circle Trader)方法的交易者的关键工具。
精通 MQL5 文件操作:从基础 I/O 到构建自定义 CSV 读取器 精通 MQL5 文件操作:从基础 I/O 到构建自定义 CSV 读取器
本文聚焦于 MQL5 文件处理的核心技术,涵盖交易日志、CSV 处理以及外部数据集成。它既提供概念性理解,也包含实用的编程指导。读者将逐步学习如何构建一个自定义的 CSV 导入器类,从而掌握适用于实际应用的实用技能。
构建K线趋势约束模型(第十部分):战略均线金叉与死叉(智能交易系统EA) 构建K线趋势约束模型(第十部分):战略均线金叉与死叉(智能交易系统EA)
您是否知道,基于移动平均线交叉的金叉和死叉策略,是识别长期市场趋势最为可靠的指标之一?当短期移动平均线上穿长期移动平均线时,金叉发出看涨趋势信号;而当短期移动平均线下穿长期移动平均线时,死叉则表明看跌趋势。尽管这些策略简单且有效,但手动运用时往往会导致错失机会或延迟交易。
MQL5自动化交易策略(第二部分):基于一目均衡表与动量震荡器的云突破交易系统 MQL5自动化交易策略(第二部分):基于一目均衡表与动量震荡器的云突破交易系统
在本文中,我们将创建一个智能交易系统(EA),利用一目均衡表指标与动量震荡器,实现云图突破策略的自动化交易。我们将逐步解析以下核心流程:指标句柄初始化、突破条件检测和自动化交易执行。此外,我们还实现追踪止损机制与动态仓位管理,以提升EA的盈利能力及对市场波动的适应性。