English
preview
DiscordとMetaTrader 5の統合:リアルタイム通知機能を備えたトレーディングボットの構築

DiscordとMetaTrader 5の統合:リアルタイム通知機能を備えたトレーディングボットの構築

MetaTrader 5統合 | 22 4月 2025, 10:21
26 0
Javier Santiago Gaston De Iriarte Cabrera
Javier Santiago Gaston De Iriarte Cabrera

はじめに

現在のスピード感ある取引市場においては、取引活動をリモートで監視・管理する能力がますます重要になっています。こうしたリモート監視を実現する手段のひとつとして、MetaTrader 5にDiscord通知を統合する方法があります。Discordアプリに通知を受け取ることで、場所を問わずリアルタイムで取引状況を確認することが可能になります。この記事では、ランダムトレーディングボットの実例を用いて、通知統合の仕組みと実装手順を具体的に説明します。MetaTrader 5とDiscordプラットフォーム間で確実な通信経路を構築し、取引実行や市場の変動、その他のアラートに関する通知をリアルタイムで受け取る方法を解説していきます。

この統合を実現するために、まずはMetaTrader 5側で必要となる設定項目を確認します。特にWebRequestの設定に注目し、これを通じてプラットフォームとDiscordや他のインスタントメッセージングサービスとの接続を可能にします。さらに、MetaTrader 5からの通知を受け取るために必要なDiscordサーバーサイドの設定方法についても紹介します。

なお、この記事の内容を理解し実践するには、MQL5プログラミングに関するある程度の知識と、MetaTrader 5プラットフォームの基本的な操作方法についての理解が前提となります。


DiscordとMetaTrader 5の設定

次の2つの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に変更する必要があります。

MetaTrader 5 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はマークダウン形式に対応しているため、重要な情報を際立たせるようにメッセージを構成できます。私たちは、各取引の詳細を素早くかつ直感的に把握できるよう、取引データのフォーマットに関する徹底した方法を導入しています。

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を返し、メッセージの送信ができなかったことを示します。

メッセージ構築の際には、視覚的なマークを用いて可読性を高めています。エラーメッセージには赤いバツ印の絵文字(❌)、成功メッセージには緑のチェックマーク(✅)を先頭に付加し、トレーダーが通知内容をDiscordチャンネル上で一目で把握できるようにしています。

続いて、メッセージはDiscordのAPIが受け付ける形式であるJSONペイロードとしてラップされます。このときに呼び出されるEscapeJSON関数は、メッセージ内の特殊文字がJSON構造を壊さないようにエスケープ処理をおこなう重要な役割を果たします。具体的には、引用符や改行など、パースエラーの原因となる文字を適切に処理します。

関数は適切なHTTPヘッダーを設定し、送信するデータの内容がJSONであることを明示します。このヘッダー情報は、Discordのサーバーに対して受信データの解釈方法を伝えるために重要です。Content-Typeヘッダーは「application/json」に設定されており、これはREST API通信における標準となる指定です。

より技術的な側面として、文字列ペイロードはchar配列に変換されます。これは、MetaTrader 5のWebRequest関数がプレーンな文字列ではなくバイナリデータを必要とするためです。ArrayResize関数は、UTF-8エンコーディングに基づいて、変換後のメッセージを格納するために配列のサイズを適切に調整します。これにより、特殊文字や絵文字を正しく扱うことが可能になります。

実際の通信は、WebRequest関数の呼び出しによって実行され、POSTリクエストがDiscordのWebhook URLに送信されます。この関数にはいくつかの重要なパラメータが含まれています。

  • Discordのサーバーからの応答が遅れた場合にシステムのハングを防ぐため、タイムアウト値として5000ミリ秒(5秒)を設定
  • 事前に準備されたヘッダーとデータ
  • 応答データとヘッダーを格納する配列

関数は、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チャンネルにメッセージを投稿できるため、機密情報として取り扱う必要があります。Webhook URLを保護するためには、暗号化技術を使用するか、安全な設定ファイルに格納することをお勧めします。

また、もう1つ重要な要素はネットワークの信頼性です。DiscordのAPIは時折停止したり、レート制限がかかることがありますし、インターネット接続が不安定な場合もあります。これらの状況に適切に対応するためには、強力なエラー処理と再試行機能を実装する必要があります。これには、失敗した試行のためにメッセージキューを保持し、失敗したメッセージに対して指数バックオフ手法を導入することが含まれます。


パフォーマンスに関する考慮事項

特に高頻度取引システムにおいては、パフォーマンスの最適化が非常に重要です。Discordアラートは便利ですが、取引ロジックのパフォーマンスに影響を与えるべきではありません。主な取引活動に支障をきたさずにDiscordとのやり取りを管理するためには、専用のスレッドを設定するか、非同期メッセージキューを導入することを検討してください。

Discord統合の機能を拡張する方法はいくつかあります。たとえば、取引統計や損益計算などのリアルタイムのパフォーマンス指標、特定のエクスポージャーレベルに達したときに通知するリスク管理からのアラートなどの機能を含めることができます。市場分析は、取引計画の指標に従って更新されます。また、エラー率や、パラメータを変更したり取引システムのステータスを確認したりできるDiscordベースのカスタムコマンドの接続など、システムの健全性も監視する必要があります。

これらの機能を実現するためには、情報をどのように整理し、メッセージをどのように構成するかについて慎重に考慮する必要があります。Discordのマークダウン形式を利用することで、通知の種類ごとに視覚的に異なるメッセージを作成でき、重要な情報を素早く識別できるようになります。

いずれにせよ、新しい機能を追加する際には、役立つ情報を提供しつつ、情報過多を防ぐバランスを取ることが重要です。最も重要な通知が何かをよく考え、場合によっては特定の通知を無効にしたり、Webhook URLを通知カテゴリーごとに分けることも検討してください。


実用的な使用例

以下は、このDiscord統合が実際の環境でどのように活用できるかの一例です。

  • ポートフォリオ管理:複数の口座で異なる取引戦略を追跡する
  • リスク管理:設定したレベルを超えた際に即座にアラートを受け取る
  • 戦略パフォーマンスと市場状況の頻繁な更新を受け取る
  • 市場調査や取引シグナルを取引チームと共有する

これまで説明したアプローチは、これらの用途に強固な基盤を提供しつつ、特定の要件に柔軟に対応できる適応性を持っています。統合の技術的な側面を理解し、システムを利用するトレーダーの実際の要件を把握することが、効果的な導入にとって非常に重要です。

Discord統合が安定して機能し続けるためには、定期的なテストと監視が必要です。これには、メッセージ配信の成功率を監視し、失敗した通信を追跡して、すべての重要なアラートが予定通りに送信されているかを確認することが含まれます。また、Discordとの全てのやり取りと発生したエラーをログとして記録するシステムを導入し、問題が発生した場合に迅速に対応できる体制を整えることを検討しましょう。

この接続を拡張し改善する方法は無限にあります。制限となるのは、あなたの創造力と取引の要件だけです。この強力な基盤からスタートし、フィードバックや実際の使用状況に基づいて機能を順次追加することで、取引業務を強化し、世界中どこにいても取引活動を把握できるような、強力なコミュニケーションシステムを構築することができます。


監視とメンテナンス

適切なリソースと知識を活用することは、健全な取引手法を持つことと同じくらい、効果的な取引において重要であることを忘れないでください。このDiscord統合は、自動取引システムと市場の状況に即座に反応できる能力との間に重要な接続を確立するため、現代のトレーダーにとって不可欠なツールとなっています。


結論

結論として、DiscordとMetaTrader 5の統合は、トレーダーに市場の状況を追跡し、素早く反応する手段を提供する便利なソリューションです。リアルタイム通知、チーム内コミュニケーション、リモート監視機能の利点により、非常に便利で効果的です。しかし、この統合を実装するには、ある程度の時間と知識が必要です。また、セキュリティ、ネットワークの信頼性、パフォーマンス最適化には慎重に対処する必要があります。音声チャネル通知、インタラクティブな指示、機械学習を用いたアラートフィルタリングなど、今後の機能改善によって、取引効率をさらに向上させる機会が増えるでしょう。自動取引システムとリアルタイム通信の間にこの重要な接続を構築することで、トレーダーは場所を問わず取引活動をより細かく管理し、重要な市場の動きや取引シグナルを見逃すことなく、より高いコントロールを実現できます。


ファイル 保存パス
Discord_examples.mq5 MQL5/Experts/フォルダ

では。Javier S. Gastón de Iriarte Cabrera

MetaQuotes Ltdにより英語から翻訳されました。
元の記事: https://www.mql5.com/en/articles/16682

添付されたファイル |
Discord_example.mq5 (20.38 KB)
知っておくべきMQL5ウィザードのテクニック(第51回):SACによる強化学習 知っておくべきMQL5ウィザードのテクニック(第51回):SACによる強化学習
Soft Actor Criticは、Actorネットワーク1つとCriticネットワーク2つ、合計3つのニューラルネットワークを用いる強化学習アルゴリズムです。これらのモデルは、CriticがActorネットワークの予測精度を高めるように設計された、いわばマスタースレーブの関係で連携します。本連載では、ONNXの導入も兼ねて、こうした概念を、ウィザード形式で構築されたエキスパートアドバイザー(EA)内のカスタムシグナルとしてどのように実装・活用できるかを探っていきます。
MQL5取引ツールキット(第5回):ポジション関数による履歴管理EX5ライブラリの拡張 MQL5取引ツールキット(第5回):ポジション関数による履歴管理EX5ライブラリの拡張
エクスポート可能なEX5関数を作成して、過去のポジションデータを効率的にクエリおよび保存する方法を解説します。このステップバイステップのガイドでは、直近にクローズされたポジションの主要なプロパティを取得するモジュールを開発し、HistoryManagement EX5ライブラリを拡張していきます。対象となるプロパティには、純利益、取引時間、ピップ単位でのストップロスやテイクプロフィット、利益値、その他多くの重要な情報が含まれます。
MQL5の分類タスクを強化するアンサンブル法 MQL5の分類タスクを強化するアンサンブル法
本記事では、MQL5における複数のアンサンブル分類器の実装を紹介し、それらがさまざまな状況下でどれほど効果的に機能するかについて論じます。
Candlestick Trend Constraintモデルの構築(第10回):戦略的ゴールデンクロスとデスクロス(EA) Candlestick Trend Constraintモデルの構築(第10回):戦略的ゴールデンクロスとデスクロス(EA)
移動平均線のクロスオーバーに基づくゴールデンクロスおよびデッドクロス戦略は、長期的な市場トレンドを見極める上で最も信頼性の高い指標の一つであることをご存知でしょうか。ゴールデンクロスは、短期移動平均線が長期移動平均線を上回るときに強気トレンドの到来を示します。一方、デッドクロスは、短期移動平均線が長期線を下回ることで弱気トレンドの兆候を示します。これらの戦略は非常にシンプルでありながら効果的ですが、手動で運用すると機会の逸失やエントリーの遅れが発生しやすいという課題があります。しかし、MQL5を活用してTrend Constraintエキスパートアドバイザー(EA)内で自動化することで、これらの戦略は独立して機能し、市場の反転に迅速かつ効率的に対応できるようになります。また、制約付きの戦略と組み合わせることで、広範なトレンドと整合性を保つことができます。このアプローチにより、反転戦略とトレンドフォロー戦略のシームレスな統合が実現され、精密なエントリーと一貫したパフォーマンス向上をもたらします。