English Русский 中文 Español Deutsch Português
preview
Candlestick Trend Constraintモデルの構築(第5回):通知システム(パート1)

Candlestick Trend Constraintモデルの構築(第5回):通知システム(パート1)

MetaTrader 5トレーディングシステム | 13 8月 2024, 10:55
112 0
Clemence Benjamin
Clemence Benjamin

内容


はじめに

MetaTrader 5は、端末、Eメール、プッシュ通知など、取引イベントをユーザーに通知するためのさまざまな通知オプションを提供しています。TelegramやWhatsAppのようなソーシャルプラットフォームと統合してシグナルを共有することは、非常に有益です。MetaTrader 5で通知を設定すると、場所に関係なく取引活動について常に情報を得ることができます。前述の通知アクセス方法を利用することで、要件に最も適したオプションを選択することができます。このガイドでは、Telegramや他のソーシャルメディアプラットフォームとの統合を含む、MetaTrader 5通知の設定とカスタマイズについて説明します。本連載では、構成の詳細と統合のための初期ステップに焦点を当て、本連載の第II回でより深く掘り下げるための道を開きます。


端末通知

端末通知は、MetaTrader 5プラットフォームの内部アラートです。これらは、MetaTrader 5内でトリガーされるすべてのアラートイベントをカバーしています。MetaTrader 5では、特定の条件が満たされたときに作動するアラートを手動で設定できます。アラート設定は通常、デフォルトのMetaTrader 5ウィンドウの下部にある[ツール]タブにあります。

  • 銘柄:アラートを設定したい取引商品を選択します。
  • 条件:アラートをトリガーする条件を選択します(例:Bid >、 Ask <、 Time =など)。
  • 値:条件が比較される値を指定します(特定の価格レベルなど)。
  • ソース:アラートの種類(サウンド、ファイル、Eメールなど)を選択します。端末の通知には、サウンドを選択できます。
  • アクション:アラートがトリガーされたときに実行するアクションを選択します(サウンドの再生、通知の送信など)。
  • サウンド:アラートがトリガーされたときに再生されるサウンドファイルを選択します。
  • タイムアウト:アラートが再度チェックされるまでの時間間隔を設定します。
  • 最大反復:アラートをトリガーする回数を指定します。

以下は、ステップインデックス合成を使用したアラートの設定例です。表に示した値は、ニーズに応じて調整できます。設定を構成した後、[OK]をクリックしてアラートを作成すると、アクティベーションの準備が整います。表の下にあるアニメーションデモ画像で簡単な概要をご覧ください。開始するには、ツールウィンドウの[アラート]タブを右クリックし、表示されるメニューから[作成]を選択します。表に概説されている設定のダイアログボックスが開きます。


設定
銘柄 Step Index
条件 Bid>
9666
ソース サウンド
アクション サウンドファイルを選択( alert2.wav)
タイムアウト 60秒に設定
最大反復回数 5に設定

 

MetaTrader 5で端末アラートを設定する方法



プッシュ通知

これはMetaTrader 5の機能で、内部で生成されたものであれ、指標やエキスパートアドバイザーによって生成されたものであれ、プラットフォーム上で生成された通知を、モバイルデバイスのMetaQuotes IDを介して携帯電話のMetaTrader 5プラットフォームに送信することができます。プッシュ通知を受信するためには、Androidの場合はplayストア、iOSの場合はApple StoreからMetaTrader 5をインストールする必要があります。携帯電話でアラートを受信するには、デスクトップでMetaTrader 5のプッシュ通知を有効にする必要があります。モバイルMetaTrader 5のインストール後すぐに、携帯電話に固有のMetaQuotes IDが作成されます。 

左側に、MetaQuotes IDの見つけ方を説明する画像があります。右側には、デスクトップのMetaTrader 5プラットフォームでプッシュ通知を有効にする方法を示す画像と、MetaQuotes IDを入力する欄があります。ボックスにチェックを入れ、モバイルプラットフォームからIDを入力すると、MetaTrader 5モバイルプラットフォームのメッセージセクションで即座に通知を受信できるようになります。様々なモバイルデバイスから多くのMetaQuotes IDを分離して追加することができます。

Androidでmetaquotes IDを探す MetaTrader 5端末プッシュ通知の設定


Eメール通知

Eメールは、その利便性、効率性、幅広い機能性により、依然として強力で汎用性の高いコミュニケーションツールです。個人的な使用であれ、ビジネス上のやりとりであれ、仕事上のネットワーク作りであれ、Eメールは信頼できる効果的な連絡手段であり、情報交換の手段です。MetaTrader 5でEメール通知を設定すると、価格の動き、注文の約定、カスタムイベントなど、さまざまな取引活動に関するアラートをEメールで受け取ることができます。

Eメールの利点は、ほぼ瞬時に配信されることで、迅速な情報交換や大人数への効率的な情報発信が可能になります。Eメールサービスは、多くの場合、コンテンツを保護するために暗号化を提供し、機密情報を保護します。受信者の受信トレイに直接配信されるため、他の通信形態に比べて傍受リスクを最小限に抑えることができます。

ここでは、Eメール通知を設定するためのステップごとのガイドを示します。

  • コンピュータでMetaTrader 5プラットフォームを起動します。
  • [ツール] > [オプション] > [Eメール]に移動します。
  • [メール設定を有効にする]にチェックを入れます。
  • SMTPサーバーの詳細を入力します。
設定 詳細を記入
SMTPサーバー EメールプロバイダーのSMTPサーバーアドレス(例:Gmailの場合はsmtp.gmail.com)
SMTPログイン Eメールアドレス(例:your-email@gmail.com)
SMTPパスワード Gmailの場合は、Eメールのパスワードまたはアプリ固有のパスワード
差出人 Eメールアドレス(例:your-email@gmail.com)
宛先 通知を受信するEメールアドレス(Fromアドレスと同じでも異なっていてもかまいません)

mt5でEメール通知を設定する

SMTPサーバーとは?

私の調査によると、SMTP (Simple Mail Transfer Protocol)サーバーとは、SMTPプロトコルを利用してEメールの送受信と中継をおこなうEメールサーバーのことです。Eメール転送エージェント(Mail Transfer Agent: MTA)と並んで機能し、送信者のEメールクライアントから受信者のEメールサーバーにEメールを転送します。SMTPサーバーを持つEメールプロバイダーのリストです。

  • gmail
  • yahoo mail
  • hotmail
  • zohomail
  • icloud mail


Trend Constraint V1.04のデバッグ

Draw_Lineスタイルをシステムのトレンドに組み込むことに成功しました。しかし、この新機能のせいで、各バーの後に多数のアラートがトリガーされていることを発見しました。例えば、チャートが分単位の時間枠に設定されている場合、アラートはローソク足の終値が1分経過するごとに生成されていました。

バーごとにアラート通知問題


私たちの目的は、厳選された数少ないものだけに焦点を当て、最適なシグナルを得ることです。この問題に取り組むため、5番目と6番目のバッファからmyalert()を削除することで問題を解決しようと考えました。本記事で説明するように、TelegramとWhatsAppのシームレスな統合のためには、このコードを修正することが不可欠です。以下は改訂版のコードです。

バッファー5を変更します。

// --- Buffer5 (Buy Trend)
      if(MA5[i] > MA6[i])
        {
         Buffer5[i] = Low[i] - 15 * myPoint;
         // Disabled myAlert from Buffer 5
         // myAlert("indicator", "BUY TREND | MA Fast: " + DoubleToString(MA5[i], 2) + " | MA Slow: " + DoubleToString(MA6[i], 2));
        }

バッファー6を変更します。

// --- Buffer6 (Sell Trend)
      if(MA5[i] < MA6[i])
        {
         Buffer6[i] = High[i] + 15 * myPoint;
         // Disabled myAlert from Buffer 6
         // myAlert("indicator", "SELL TREND | MA Fast: " + DoubleToString(MA5[i], 2) + " | MA Slow: " + DoubleToString(MA6[i], 2));
        }

Trend Constraint V1.044を修正します。

///Indicator Name: Trend Constraint
#property copyright "Clemence Benjamin"
#property link      "https://mql5.com"
#property version   "1.04"
#property description "A model that seek to produce sell signal when D1 candle is Bearish only and  buy signal when it is Bullish"
//--- indicator settings
#property indicator_chart_window
#property indicator_buffers 6
#property indicator_plots 6

#property indicator_type1 DRAW_ARROW
#property indicator_width1 5
#property indicator_color1 0xFF3C00
#property indicator_label1 "Buy"

#property indicator_type2 DRAW_ARROW
#property indicator_width2 5
#property indicator_color2 0x0000FF
#property indicator_label2 "Sell"

#property indicator_type3 DRAW_ARROW
#property indicator_width3 2
#property indicator_color3 0xE8351A
#property indicator_label3 "Buy Reversal"

#property indicator_type4 DRAW_ARROW
#property indicator_width4 2
#property indicator_color4 0x1A1AE8
#property indicator_label4 "Sell Reversal"

#property indicator_type5 DRAW_LINE
#property indicator_style5 STYLE_SOLID
#property indicator_width5 2
#property indicator_color5 0xFFAA00
#property indicator_label5 "Buy Trend"

#property indicator_type6 DRAW_LINE
#property indicator_style6 STYLE_SOLID
#property indicator_width6 2
#property indicator_color6 0x0000FF
#property indicator_label6 "Sell Trend"

#define PLOT_MAXIMUM_BARS_BACK 5000
#define OMIT_OLDEST_BARS 50

//--- indicator buffers
double Buffer1[];
double Buffer2[];
double Buffer3[];
double Buffer4[];
double Buffer5[];
double Buffer6[];

input double Oversold = 30;
input double Overbought = 70;
input int Slow_MA_period = 200;
input int Fast_MA_period = 100;
datetime time_alert; //used when sending alert
input bool Audible_Alerts = true;
input bool Push_Notifications = true;
double myPoint; //initialized in OnInit
int RSI_handle;
double RSI[];
double Open[];
double Close[];
int MA_handle;
double MA[];
int MA_handle2;
double MA2[];
int MA_handle3;
double MA3[];
int MA_handle4;
double MA4[];
double Low[];
double High[];
int MA_handle5;
double MA5[];
int MA_handle6;
double MA6[];

void myAlert(string type, string message)
  {
   if(type == "print")
      Print(message);
   else if(type == "error")
     {
      Print(type+" | Trend Constraint V1.04 @ "+Symbol()+","+IntegerToString(Period())+" | "+message);
     }
   else if(type == "order")
     {
     }
   else if(type == "modify")
     {
     }
   else if(type == "indicator")
     {
      if(Audible_Alerts) Alert(type+" | Trend Constraint V1.04 @ "+Symbol()+","+IntegerToString(Period())+" | "+message);
      if(Push_Notifications) SendNotification(type+" | Trend Constraint V1.04 @ "+Symbol()+","+IntegerToString(Period())+" | "+message);
     }
  }

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {   
   SetIndexBuffer(0, Buffer1);
   PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, EMPTY_VALUE);
   PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1));
   PlotIndexSetInteger(0, PLOT_ARROW, 241);
   SetIndexBuffer(1, Buffer2);
   PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, EMPTY_VALUE);
   PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1));
   PlotIndexSetInteger(1, PLOT_ARROW, 242);
   SetIndexBuffer(2, Buffer3);
   PlotIndexSetDouble(2, PLOT_EMPTY_VALUE, EMPTY_VALUE);
   PlotIndexSetInteger(2, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1));
   PlotIndexSetInteger(2, PLOT_ARROW, 236);
   SetIndexBuffer(3, Buffer4);
   PlotIndexSetDouble(3, PLOT_EMPTY_VALUE, EMPTY_VALUE);
   PlotIndexSetInteger(3, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1));
   PlotIndexSetInteger(3, PLOT_ARROW, 238);
   SetIndexBuffer(4, Buffer5);
   PlotIndexSetDouble(4, PLOT_EMPTY_VALUE, EMPTY_VALUE);
   PlotIndexSetInteger(4, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1));
   SetIndexBuffer(5, Buffer6);
   PlotIndexSetDouble(5, PLOT_EMPTY_VALUE, EMPTY_VALUE);
   PlotIndexSetInteger(5, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1));
   //initialize myPoint
   myPoint = Point();
   if(Digits() == 5 || Digits() == 3)
     {
      myPoint *= 10;
     }
   RSI_handle = iRSI(NULL, PERIOD_CURRENT, 14, PRICE_CLOSE);
   if(RSI_handle < 0)
     {
      Print("The creation of iRSI has failed: RSI_handle=", INVALID_HANDLE);
      Print("Runtime error = ", GetLastError());
      return(INIT_FAILED);
     }
   
   MA_handle = iMA(NULL, PERIOD_CURRENT, 7, 0, MODE_SMMA, PRICE_CLOSE);
   if(MA_handle < 0)
     {
      Print("The creation of iMA has failed: MA_handle=", INVALID_HANDLE);
      Print("Runtime error = ", GetLastError());
      return(INIT_FAILED);
     }
   
   MA_handle2 = iMA(NULL, PERIOD_CURRENT, 400, 0, MODE_SMA, PRICE_CLOSE);
   if(MA_handle2 < 0)
     {
      Print("The creation of iMA has failed: MA_handle2=", INVALID_HANDLE);
      Print("Runtime error = ", GetLastError());
      return(INIT_FAILED);
     }
   
   MA_handle3 = iMA(NULL, PERIOD_CURRENT, 100, 0, MODE_EMA, PRICE_CLOSE);
   if(MA_handle3 < 0)
     {
      Print("The creation of iMA has failed: MA_handle3=", INVALID_HANDLE);
      Print("Runtime error = ", GetLastError());
      return(INIT_FAILED);
     }
   
   MA_handle4 = iMA(NULL, PERIOD_CURRENT, 200, 0, MODE_SMA, PRICE_CLOSE);
   if(MA_handle4 < 0)
     {
      Print("The creation of iMA has failed: MA_handle4=", INVALID_HANDLE);
      Print("Runtime error = ", GetLastError());
      return(INIT_FAILED);
     }
   
   MA_handle5 = iMA(NULL, PERIOD_CURRENT, Fast_MA_period, 0, MODE_SMA, PRICE_CLOSE);
   if(MA_handle5 < 0)
     {
      Print("The creation of iMA has failed: MA_handle5=", INVALID_HANDLE);
      Print("Runtime error = ", GetLastError());
      return(INIT_FAILED);
     }
   
   MA_handle6 = iMA(NULL, PERIOD_CURRENT, Slow_MA_period, 0, MODE_SMA, PRICE_CLOSE);
   if(MA_handle6 < 0)
     {
      Print("The creation of iMA has failed: MA_handle6=", INVALID_HANDLE);
      Print("Runtime error = ", GetLastError());
      return(INIT_FAILED);
     }
   
   return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime& time[],
                const double& open[],
                const double& high[],
                const double& low[],
                const double& close[],
                const long& tick_volume[],
                const long& volume[],
                const int& spread[])
  {
   int limit = rates_total - prev_calculated;
   //--- counting from 0 to rates_total
   ArraySetAsSeries(Buffer1, true);
   ArraySetAsSeries(Buffer2, true);
   ArraySetAsSeries(Buffer3, true);
   ArraySetAsSeries(Buffer4, true);
   ArraySetAsSeries(Buffer5, true);
   ArraySetAsSeries(Buffer6, true);
   //--- initial zero
   if(prev_calculated < 1)
     {
      ArrayInitialize(Buffer1, EMPTY_VALUE);
      ArrayInitialize(Buffer2, EMPTY_VALUE);
      ArrayInitialize(Buffer3, EMPTY_VALUE);
      ArrayInitialize(Buffer4, EMPTY_VALUE);
      ArrayInitialize(Buffer5, EMPTY_VALUE);
      ArrayInitialize(Buffer6, EMPTY_VALUE);
     }
   else
      limit++;
   datetime Time[];
   
   int RSIBuffer;
   int MABuffer;
   int RSIPeriod = 14;
   ArrayResize(RSI, rates_total);
   ArrayResize(Open, rates_total);
   ArrayResize(Close, rates_total);
   CopyOpen(NULL, 0, 0, rates_total, Open);
   CopyClose(NULL, 0, 0, rates_total, Close);
   if(CopyBuffer(RSI_handle, 0, 0, rates_total, RSI) < 0)
     {
      Print("Getting RSI values failed, not enough bars!");
     }
   ArrayResize(MA, rates_total);
   if(CopyBuffer(MA_handle, 0, 0, rates_total, MA) < 0)
     {
      Print("Getting MA values failed, not enough bars!");
     }
   ArrayResize(MA2, rates_total);
   if(CopyBuffer(MA_handle2, 0, 0, rates_total, MA2) < 0)
     {
      Print("Getting MA values failed, not enough bars!");
     }
   ArrayResize(MA3, rates_total);
   if(CopyBuffer(MA_handle3, 0, 0, rates_total, MA3) < 0)
     {
      Print("Getting MA values failed, not enough bars!");
     }
   ArrayResize(MA4, rates_total);
   if(CopyBuffer(MA_handle4, 0, 0, rates_total, MA4) < 0)
     {
      Print("Getting MA values failed, not enough bars!");
     }
   ArrayResize(Low, rates_total);
   if(CopyLow(NULL, 0, 0, rates_total, Low) < 0)
     {
      Print("Getting LOW values failed, not enough bars!");
     }
   ArrayResize(High, rates_total);
   if(CopyHigh(NULL, 0, 0, rates_total, High) < 0)
     {
      Print("Getting HIGH values failed, not enough bars!");
     }
   ArrayResize(MA5, rates_total);
   if(CopyBuffer(MA_handle5, 0, 0, rates_total, MA5) < 0)
     {
      Print("Getting MA values failed, not enough bars!");
     }
   ArrayResize(MA6, rates_total);
   if(CopyBuffer(MA_handle6, 0, 0, rates_total, MA6) < 0)
     {
      Print("Getting MA values failed, not enough bars!");
     }
   
   for(int i=limit-1; i>=0; i--)
     {
      if(i < rates_total-1 && time[i] != time[i+1]+PeriodSeconds())
        {
         continue;
        }
      Buffer1[i] = EMPTY_VALUE;
      Buffer2[i] = EMPTY_VALUE;
      Buffer3[i] = EMPTY_VALUE;
      Buffer4[i] = EMPTY_VALUE;
      Buffer5[i] = EMPTY_VALUE;
      Buffer6[i] = EMPTY_VALUE;

      // --- Indicator calculations
      // --- Buffer1 (Buy)
      if((Close[i] > MA[i] && MA[i] > MA2[i] && RSI[i] < Oversold) || (RSI[i] < Oversold && Close[i] > MA3[i]))
        {
         Buffer1[i] = Low[i] - 5 * myPoint;
         myAlert("indicator", "BUY OPPORTUNITY | RSI: " + DoubleToString(RSI[i], 2) + " | MA: " + DoubleToString(MA[i], 2));
        }
      
      // --- Buffer2 (Sell)
      if((Close[i] < MA[i] && MA[i] < MA2[i] && RSI[i] > Overbought) || (RSI[i] > Overbought && Close[i] < MA3[i]))
        {
         Buffer2[i] = High[i] + 5 * myPoint;
         myAlert("indicator", "SELL OPPORTUNITY | RSI: " + DoubleToString(RSI[i], 2) + " | MA: " + DoubleToString(MA[i], 2));
        }
      
      // --- Buffer3 (Buy Reversal)
      if(RSI[i] < Oversold && Close[i] > MA[i])
        {
         Buffer3[i] = Low[i] - 10 * myPoint;
         myAlert("indicator", "BUY REVERSAL | RSI: " + DoubleToString(RSI[i], 2) + " | MA: " + DoubleToString(MA[i], 2));
        }
      
      // --- Buffer4 (Sell Reversal)
      if(RSI[i] > Overbought && Close[i] < MA[i])
        {
         Buffer4[i] = High[i] + 10 * myPoint;
         myAlert("indicator", "SELL REVERSAL | RSI: " + DoubleToString(RSI[i], 2) + " | MA: " + DoubleToString(MA[i], 2));
        }
      
      // --- Buffer5 (Buy Trend)
      if(MA5[i] > MA6[i])
        {
         Buffer5[i] = Low[i] - 15 * myPoint;
         //Disabled myAlert from Buffer 5
         // myAlert("indicator", "BUY TREND | MA Fast: " + DoubleToString(MA5[i], 2) + " | MA Slow: " + DoubleToString(MA6[i], 2));
        }
      
      // --- Buffer6 (Sell Trend)
      if(MA5[i] < MA6[i])
        {
         Buffer6[i] = High[i] + 15 * myPoint;
         // Disabled myAlert from Buffer 6
         // myAlert("indicator", "SELL TREND | MA Fast: " + DoubleToString(MA5[i], 2) + " | MA Slow: " + DoubleToString(MA6[i], 2));
        }
     }
   return(rates_total);
  }


ソーシャルネットワークの統合(TelegramやWhatsAppなど)

この記事では、MetaTrader 5のTelegramとWhatsAppの統合、特にTrend Constraint指標について説明します。このプロセスは、リアルタイムで安全かつ便利な通知を提供することにより、MetaTrader 5の機能を大幅に向上させます。これらの統合は、取引活動の効率性、応答性、有効性を高め、今日のトレーダーにとって貴重なツールとなっています。これらのプラットフォームには膨大な数のユーザーがいるため、これらのコミュニティとシグナルを共有することは有益です。指標が生成したシグナルを、どのようにソーシャルメディアプラットフォームに発信できるかを掘り下げてみましょう。その機能を確認するために調査し、テストしました。

必要条件 

  • 最新のMetaTrader 5プラットフォームデスクトップ
  • 認証済みのWhatsappとTelegramアカウント(Androidはplayストアから、iOSはApp Storeからダウンロード)
  • Webブラウザ(例:Google Chrome
  • ミドルウェアのスクリプトをホストするサーバー

    Telegramとの統合

    手順1:Telegramボットの作成

    ボットを作成する:

    • Telegramを開き、「BotFather」ボットを検索します。
    • BotFatherでチャットを開始し、/newbotコマンドで新しいボットを作成します。
    • プロンプトに従って、ボットの名前とユーザー名を設定します。
    • BotFatherはトークンを提供します。このトークンを使ってTelegram APIとやり取りします。

    チャットIDを取得する:

    • ボットをTelegramグループに追加したり、チャットを開始したりできます
    • ブラウザでhttps://api.telegram.org/bot<YourBotToken>/getUpdatesを使用して更新を取得し、チャットIDを検索します
    • チャットでメッセージを送信し、もう一度URLをチェックしてチャットIDを見つけます

    チャットIDの取得に関するより包括的なガイドについては、githubをご覧ください。


    手順2:ミドルウェアスクリプトの作成

    TelegramのAPI経由でメッセージを送信するにはスクリプトが必要です。

    ミドルウェアのスクリプトを作成するために、私がおこなった調査に従ってPython言語を使用します。 このPythonスクリプトは、requestsライブラリを使って、ボット経由でTelegramチャットにメッセージを送信します。以下、スクリプトの各行について説明します。

    import requests
    

    PythonでHTTPリクエストをおこなうためのrequestsライブラリをインポートします。このスクリプトでは、Telegram Bot APIにPOSTリクエストを送信するために使用します。

    def send_telegram_message(chat_id, message, bot_token):
    

    send_telegram_messageという名前の関数を定義します。この関数は3つのパラメータを取ります。

      1. chat_id:ターゲットチャットの一意の識別子またはターゲットチャネルのユーザー名
      2. message:送信するテキストメッセージ
      3. bot_token:ボット作成時に@BotFatherから提供されるTelegramボットのトークン

        url = f"https://api.telegram.org/bot{bot_token}/sendMessage"
    

    この行は、提供されたbot_tokenを使用してTelegram Bot API メソッドsendMessageのURLを構築します。

        payload = {
            'chat_id': chat_id,
            'text': message
        }
    

    POSTリクエストのペイロードを作成します。この辞書には、sendMessageメソッドに必要なパラメータが含まれています。

    • chat_id:メッセージを送信するチャットのID
    • text:メッセージの内容

        response = requests.post(url, data=payload)
    

    この行は、requests.postメソッドを使用して、構築されたURLにペイロードデータとともにHTTP POSTリクエストを送信します。APIからのレスポンスはレスポンス変数に格納されます。

        return response.json()
    

    この行はレスポンスをJSON形式に変換して返します。このJSONレスポンスには通常、メッセージID、送信者、チャットの詳細など、送信されたメッセージに関する情報が含まれています。

    すべてのコードを組み合わせるとこうなります。

    import requests
    
    def send_telegram_message(chat_id, message, bot_token):
        url = f"https://api.telegram.org/bot{bot_token}/sendMessage"
        payload = {
            'chat_id': chat_id,
            'text': message
        }
        response = requests.post(url, data=payload)
        return response.json()
    
    
    


    手順3:ミドルウェアを使用するようにMetaTrader 5を設定する

    ミドルウェアのスクリプトにHTTPリクエストでアラートを送信するMQL5スクリプトを作成する

    コードの内訳を見て、各行を理解しましょう。

    void SendTelegramMessage(string chat_id, string message, string bot_token)
    

     SendTelegramMessageという名前の関数を定義します。

    関数内のパラメータ:

    • chat_id:メッセージが送信されるTelegramチャットIDを表す文字列
    • message:送信するメッセージを含む文字列
    • bot_token:Telegram APIでの認証に必要なボットトークンを表す文字列
    関数本体の初めの括弧

    {
        string url = "http://your-server-url/send_telegram_message";
    

     サーバのエンドポイントURLを変数urlに代入します。このURLは、メッセージをTelegramに転送するサーバーのアドレスです。

        char postData[];
        StringToCharArray("chat_id=" + chat_id + "&message=" + message + "&bot_token=" + bot_token, postData);
    

    postData配列:

    • 宣言:POSTリクエストデータを格納するchar型の配列postDataを宣言します。
    • 文字列から文字配列への変換:chat_id、message、bot_tokenパラメータを連結した文字列を文字配列に変換し、postDataに格納します。連結された文字列は、サーバーが要求する形式でPOSTリクエストの本文を形成します。

        char result[];
    

    Webリクエストからのレスポンスを保持するchar型の配列resultを宣言します。

        int res = WebRequest("POST", url, "", NULL, 0, postData, 0, result, NULL);
    

    Webリクエスト:

    • HTTPメソッド:POSTはリクエストタイプを示す
    • URL:リクエストを送信するエンドポイント
    • ヘッダー:空の文字列""は、追加ヘッダーがないことを意味します
    • Cookies:NULLはcookiesがないことを示します
    • タイムアウト:0はタイムアウトなしを指定します。
    • postData:POSTリクエストで送信されるデータ
    • 結果:応答が格納される場所
    • この関数は、レスポンスのHTTPステータスコードresを整数で返します。

        if (res != 200)
    

    レスポンスコードを確認します。レスポンスコードresと200 (HTTP OK)を比較します。200でない場合はエラーを示します。


    エラーハンドラ:

        {
            Print("Error sending message: ", GetLastError());
        }
    

    エラーメッセージを出力します。レスポンスコードが200でない場合、このブロックはGetLastError()を使用してエラーメッセージと最後のエラーコードを表示します。


    サクセスハンドラ:

        else
        {
            Print("Message sent successfully.");
        }
    

    成功メッセージを出力します。レスポンスコードが200の場合、このブロックはメッセージが正常に送信されたことを示す成功メッセージを表示します。

    この行でSendTelegramMessage関数は終了します。

     Telegramメッセージを送信するMQL5コード:

    void SendTelegramMessage(string chat_id, string message, string bot_token)
    {
        string url = "http://your-server-url/send_telegram_message";
        char postData[];
        StringToCharArray("chat_id=" + chat_id + "&message=" + message + "&bot_token=" + bot_token, postData);
        
        char result[];
        int res = WebRequest("POST", url, "", NULL, 0, postData, 0, result, NULL);
        if (res != 200)
        {
            Print("Error sending message: ", GetLastError());
        }
        else
        {
            Print("Message sent successfully.");
        }
    }
    
    
    

    上記のMQL5スクリプトは、サーバーのエンドポイントにWebリクエストをおこなうことで、Telegramチャットにメッセージを送信するように設計されています。使用例では、スクリプトが開始されたときに実行されるOnStartイベント内でSendTelegramMessage関数を使用する方法を示しています。WhatsAppとの統合については次のセクションで説明し、telegramとの統合は異なるソーシャルプラットフォームであっても意味があることを説明しました。これらのコードが機能するためには、必ずコードの一部にご自分の実際の認証情報を代入することを忘れないでください。


    WhatsAppとの統合

    手順1:メッセージングAPIプロバイダでの登録

    • プロバイダーを選択:WhatsAppとの統合にはTwilioが人気です。
    • アカウントを作成:Twilioに新規登録し、必要な認証を完了します。
    • API認証情報を取得:TwilioからAPI認証情報(アカウントSID、認証トークン)を取得します。

    手順2:ミドルウェアスクリプトの作成

    WhatsApp統合のためのミドルウェアPythonスクリプト:

    import requests
    
    def send_whatsapp_message(to, message, account_sid, auth_token):
        url = f"https://api.twilio.com/2010-04-01/Accounts/{account_sid}/Messages.json"
        payload = {
            'From': 'whatsapp:+14155238886',  # Twilio sandbox number
            'To': f'whatsapp:{to}',
            'Body': message
        }
        headers = {
            'Authorization': f'Basic {account_sid}:{auth_token}'
        }
        response = requests.post(url, data=payload, headers=headers)
        return response.json()
    
    
    


    手順3:ミドルウェアを使用するようにMetaTrader 5を設定する

    MQL5コードでWhatsApp通知を送信:

    void SendWhatsAppMessage(string to, string message, string account_sid, string auth_token)
    {
        string url = "http://your-server-url/send_whatsapp_message";
        char postData[];
        StringToCharArray("to=" + to + "&message=" + message + "&account_sid=" + account_sid + "&auth_token=" + auth_token, postData);
        
        char result[];
        int res = WebRequest("POST", url, "", NULL, 0, postData, 0, result, NULL);
        if (res != 200)
        {
            Print("Error sending message: ", GetLastError());
        }
        else
        {
            Print("Message sent successfully.");
        }
    }
    
    


    通知システムにおける仮想プライベートサービス(VPS)の威力

    仮想プライベートサービスはダウンタイムなしで継続的に稼動し、MetaTrader 5プラットフォームと通知システムが常にアクティブであることを保証します。これは、中断することなくリアルタイムの通知を受け取るために非常に重要です。VPSプロバイダーは堅牢で安定したインターネット接続を提供し、自宅やオフィスのネットワークで起こりうる切断のリスクを軽減します。  VPSサーバーは多くの場合、主要な金融取引所への高速接続が可能なデータセンターに設置されているため、遅延が短縮され、取引アラートや通知を受信して対処する速度が向上します。  共有ホスティングとは異なり、VPSは専用のCPU、RAM、ストレージリソースを提供し、MetaTrader 5の実行と通知の処理に安定したパフォーマンスを保証します。  VPSはインターネット接続があればどのデバイスからでもリモートアクセスが可能で、どこからでもMetaTrader 5プラットフォームを管理し、通知を受け取ることができます。


    結論

    WhatsAppとTelegramを統合するための土台を築き、私たちは指標のための強固な通知システムを構成することに成功しました。これらのシグナルは即座に共有されるため、この強化は大規模なコミュニティを惹きつける上で極めて重要です。開発者は、これらの人気のあるプラットフォームを通じて興味のあるトレーダーにこれらのシグナルをマーケティングすることにより、プラットフォームからソーシャルメディアチャンネルに直接送信する迅速かつ効率的な手段を提供し、資本化することができます。

    このアプローチにより、インターネットがあればいつでもどこでもシグナルにアクセスできるようになり、クリックするだけで簡単に共有できるようになります。トレーダーはシグナルへのアクセスにTelegramかWhatsAppを選択できます。さらなる統合の詳細については、パートIIで検討します。以下に参考ファイルを添付します。コメント欄で自由に議論してください。


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

    添付されたファイル |
    Telegram_mt5.mq5 (1.22 KB)
    WhatsApp_mt5.mq5 (1.26 KB)
    Candlestick Trend Constraintモデルの構築(第5回):通知システム(パート2) Candlestick Trend Constraintモデルの構築(第5回):通知システム(パート2)
    今日は、PythonとTelegram Bot APIと連携して、MQL5のパワーを活用した MetaTrader 5指標通知のための実用的なTelegram統合について説明します。ポイントが見逃がされることがないように、すべてを詳細に説明します。このプロジェクトが終了する頃には、ご自分のプロジェクトに応用できる貴重な洞察を得ることができるでしょう。
    独自のLLMをEAに統合する(第4部):GPUを使った独自のLLMの訓練 独自のLLMをEAに統合する(第4部):GPUを使った独自のLLMの訓練
    今日の人工知能の急速な発展に伴い、言語モデル(LLM)は人工知能の重要な部分となっています。私たちは、強力なLLMをアルゴリズム取引に統合する方法を考える必要があります。ほとんどの人にとって、これらの強力なモデルをニーズに応じて微調整し、ローカルに展開して、アルゴリズム取引に適用することは困難です。本連載では、この目標を達成するために段階的なアプローチをとっていきます。
    データサイエンスと機械学習(第24回):通常のAIモデルによるFX時系列予測 データサイエンスと機械学習(第24回):通常のAIモデルによるFX時系列予測
    外国為替市場において、過去を知らずに将来のトレンドを予測することは非常に困難です。過去の値を考慮して将来の予測をおこなうことができる機械学習モデルは非常に少ないです。この記事では、市場に勝つために古典的な(非時系列)人工知能モデルを使用する方法について説明します。
    ニューラルネットワークが簡単に(第79回):状態の文脈におけるFeature Aggregated Queries (FAQ) ニューラルネットワークが簡単に(第79回):状態の文脈におけるFeature Aggregated Queries (FAQ)
    前回の記事では、画像内のオブジェクトを検出する方法の1つを紹介しました。ただし、静的な画像の処理は、私たちが分析する価格のダイナミクスのような動的な時系列の処理とは多少異なります。この記事では、私たちが解決しようとしている問題にやや近い、ビデオ中の物体を検出する方法について考えます。