【MQL5】SocketIsConnected関数の使い方と自動売買実装コード

1. SocketIsConnected関数の概要と実務での活用法

MQL5の SocketIsConnected 関数は、作成したネットワークソケットが現在サーバーに接続されているかどうかを確認するための関数です。

MQL5単体では難しい「独自サーバーへのリアルタイムな取引データの送信」や「Pythonなどで構築したAI(機械学習)モデルとの外部連携」を行う際、プログラムはTCP/IP通信を用いて外部とやり取りします。この際、「今、通信ルートが生きているか?」を判定するのがこの関数の役割です。

実務での活用シーンとつまずきポイント

実務開発において、初心者が最も陥りやすい罠は、「一度接続(SocketConnect)したから、ずっと繋がっているはずだ」という思い込みです。
ネットワークは、ルーターの瞬断やサーバー側のタイムアウトによって、コードの預かり知らぬところで頻繁に切断されます。切断された状態で SocketSend(データ送信)を試みるとエラーが発生し、最悪の場合、EA(エキスパートアドバイザー)の動作が停止したり、重要な約定チャンスを逃したりします。

そのため、通信を行う直前に必ず SocketIsConnected で生存確認を行い、切断されていれば再接続処理(リコネクト)を走らせるというフローが、堅牢なシステム構築の鉄則となります。

2. 構文と戻り値

SocketIsConnected 関数の構造は非常にシンプルです。

bool SocketIsConnected(
   int  socket      // ソケットハンドル
);

パラメーター

  • socket: SocketCreate 関数によって取得したソケットのハンドル(識別番号)を指定します。

戻り値

  • true: 指定したソケットが接続状態にある場合。
  • false: 切断されている、または無効なハンドルが指定された場合。

※内部的には、ソケットのステータスを確認し、システムレベルで切断が検知されていれば false を返します。

3. 具体的な使い方・実践サンプルコード

以下は、外部サーバーに接続し、ティックが更新されるたびに接続状態を確認して、切断されていたら再接続を試みる実用的なサンプルコードです。

// 外部サーバー設定
input string InpHost = "127.0.0.1"; // 接続先IPアドレス
input int    InpPort = 8080;        // ポート番号

int socket_handle = INVALID_HANDLE; // ソケットハンドル保持用

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit() {
   // 最初にソケットを作成して接続を試みる
   Reconnect();
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick() {
   // 1. 接続状態を確認
   if(!SocketIsConnected(socket_handle)) {
      Print("ネットワーク切断を検知しました。再接続を試みます...");
      Reconnect();
   }

   // 2. 接続されていればデータを送信(例:価格情報)
   if(SocketIsConnected(socket_handle)) {
      string message = Symbol() + ":" + DoubleToString(Bid, _Digits);
      uchar data[];
      StringToCharArray(message, data);

      // 送信実行
      if(SocketSend(socket_handle, data, ArraySize(data)) < 0) {
         Print("データ送信失敗。エラーコード: ", GetLastError());
      }
   }
}

//+------------------------------------------------------------------+
//| 接続・再接続用の関数                                               |
//+------------------------------------------------------------------+
void Reconnect() {
   // 既存のハンドルがあれば一度閉じる
   if(socket_handle != INVALID_HANDLE) {
      SocketClose(socket_handle);
   }

   // ソケットの新規作成
   socket_handle = SocketCreate();

   if(socket_handle != INVALID_HANDLE) {
      // サーバーへ接続(タイムアウトを5000msに設定)
      if(SocketConnect(socket_handle, InpHost, InpPort, 5000)) {
         Print("サーバーへの接続に成功しました。");
      } else {
         Print("サーバーへの接続に失敗。エラーコード: ", GetLastError());
      }
   }
}

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
   // 終了時はソケットを適切に閉じる
   if(socket_handle != INVALID_HANDLE) {
      SocketClose(socket_handle);
   }
}

4. 使用上の注意点とよくあるエラー

  1. 「繋がっている」=「正常に送れる」とは限らない
    SocketIsConnectedtrue を返しても、直後の SocketSend が失敗することがあります。これは「ハーフオープン(片側だけ切断)」の状態や、送信の瞬間にネットワークが途切れた場合に起こります。戻り値のみを過信せず、送信関数のエラーハンドリングも併用してください。

  2. Webリクエスト許可の設定
    MQL5でソケット通信(SocketCreate等)を使用する場合、MT5の設定画面(ツール > オプション > エキスパートアドバイザー)で「許可されたURLのリスト」に接続先アドレスを追加しておく必要があります。これを忘れると、関数自体が動作しません。

  3. ハンドルの管理
    SocketClose を行わずに SocketCreate を繰り返すと、ハンドルがリーク(メモリ漏洩)し、MT5の動作が重くなったり、新しい接続ができなくなったりします。必ず「閉じてから作る」という順序を守りましょう。

5. 【重要】自動売買における約定スピードと環境の罠

自動売買プログラムを構築するエンジニアとして、最も警戒すべきは「ネットワーク遅延(レイテンシ)」です。どんなに優れたロジックを SocketIsConnected で制御しても、物理的な通信環境が貧弱であれば、全ては水の泡となります。

自宅のPC環境でEAを稼働させる場合、ブローカーのサーバーとの距離や家庭用プロバイダーの不安定さが原因で、ミリ秒単位の約定遅延が発生します。このわずかな遅延が「滑り(スリッページ)」を引き起こし、バックテストでは利益が出ていたロジックを致命的な損失へと変えてしまうのです。プロレベルの自動売買において、ブローカーのデータセンターに近い専用VPS(仮想専用サーバー)の使用は、単なる推奨事項ではなく「必須条件」と言えます。安定した電源、高速なバックボーン、そして極限まで抑えられたレイテンシこそが、エンジニアが書いたコードの真価を発揮させる唯一の土台となります。

💡 この記事の内容を実運用で活かすには?

この記事の内容を実運用で活かすには、正しい環境が必要です。
特にVPSを使わないと、このロジックは再現できません。

コメント

タイトルとURLをコピーしました