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

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

MQL5のObjectFind関数は、指定したチャート上に特定の名称を持つグラフィカルオブジェクト(水平線、トレンドライン、ボタン、テキストなど)が存在するかどうかを確認するための関数です。

実務開発において、この関数は単に「線があるかないか」を調べる以上の重要な役割を担います。例えば、以下のようなシーンで必須となります。

  • 二重描画の防止: EAが起動するたびにラベルやボタンを生成する場合、既に存在するかをObjectFindでチェックしないと、同じオブジェクトを何度も作成しようとしてエラーや動作の重化を招きます。
  • 裁量トレードとの連携: ユーザーが手動で引いたライン(特定の名前を付けたもの)をEAに検知させ、そのラインに価格がタッチしたらエントリーする、といった「半自動売買」のロジックに不可欠です。
  • UI(ユーザーインターフェース)の制御: チャート上のボタンがクリックされて削除された場合など、オブジェクトの状態変化を監視するフラグとして機能します。

初心者がつまずきやすいポイントは、「戻り値が真偽値(true/false)ではない」という点です。この仕様を正しく理解することが、バグのないコードへの第一歩となります。

2. 構文と戻り値

ObjectFind関数の基本構文は以下の通りです。

int ObjectFind(
   long   chart_id,  // チャートID(0は現在のチャート)
   string name       // オブジェクトの名前
);

パラメーター解説

  1. chart_id: 対象とするチャートの識別子を指定します。EAが動いている現在のチャートを指す場合は「0」を入力します。
  2. name: 探したいオブジェクトの固有名称を文字列で指定します。

戻り値

  • オブジェクトが見つかった場合: そのオブジェクトが存在する「サブウィンドウのインデックス」を返します。メインウィンドウ(価格チャート)にある場合は「0」が返ります。
  • オブジェクトが見つからない場合: 「-1」を返します。

このため、単純に「存在するかどうか」を知りたい場合は、if(ObjectFind(0, name) >= 0) という条件式を使うのが定石です。

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

以下のサンプルは、チャート上に「EntryLine」という名前の水平線があるかどうかを確認し、存在しない場合のみ新しく線を引く、という実用的なスクリプトです。

//+------------------------------------------------------------------+
//|                                           ObjectFind_Example.mq5 |
//+------------------------------------------------------------------+
#property strict

void OnTick()
{
    string lineName = "EntryLine";
    double targetPrice = 150.50;

    // 1. ObjectFindを使ってオブジェクトの存在確認
    // 戻り値が 0 以上なら存在する、-1 なら存在しない
    int windowIndex = ObjectFind(0, lineName);

    if(windowIndex < 0)
    {
        // 2. オブジェクトが見つからない(-1)場合の処理
        Print("オブジェクトが見つかりません。新規作成します。");

        if(ObjectCreate(0, lineName, OBJ_HLINE, 0, 0, targetPrice))
        {
            // 作成成功後、色などのプロパティを設定
            ObjectSetInteger(0, lineName, OBJPROP_COLOR, clrRed);
            ObjectSetInteger(0, lineName, OBJPROP_WIDTH, 2);
            Print("水平線を作成しました。価格:", targetPrice);
        }
    }
    else
    {
        // 3. オブジェクトが見つかった場合の処理
        // 何番目のサブウィンドウにあるかを表示
        Print("オブジェクト '", lineName, "' はウィンドウ番号 ", windowIndex, " に既に存在します。");

        // 既存ラインの価格を取得してログに出力
        double currentLinePrice = ObjectGetDouble(0, lineName, OBJPROP_PRICE);
        Print("現在のライン設定価格: ", currentLinePrice);
    }
}

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

大文字・小文字の区別

MQL5のオブジェクト名は大文字と小文字を区別しません(ケース・インセンシティブ)。例えば “Line” と “LINE” は同じものとして扱われるため、命名規則には注意が必要です。

戻り値の判定ミス

初心者は if(ObjectFind(0, name) == 1)(1=見つかった、と勘違い)というコードを書きがちです。前述の通り、メインウィンドウにある場合は 0 が返るため、この判定では「見つからなかった」と誤認されます。必ず >= 0 または != -1 で判定してください。

描画の遅延(キャッシュ)

EAのロジックでオブジェクトを削除した直後に ObjectFind を実行すると、ごく稀にチャートの更新タイミングによって古い情報(削除前の状態)を拾ってしまうことがあります。精密な制御が必要な場合は、ChartRedraw() を併用してチャートの状態を強制更新することを検討してください。

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

アルゴリズムトレードにおいて、ObjectFindなどでロジックを組む技術と同じくらい重要なのが「実行環境」です。多くの開発者が自宅のPCでEAを稼働させますが、これはプロの視点から見ると非常にリスクが高い行為です。

FX市場はミリ秒単位で価格が変動しており、取引サーバーとの物理的な距離が「ネットワーク遅延(レイテンシ)」としてダイレクトに収益性を悪化させます。自宅の光回線では、パケットの往復に数十から数百ミリ秒を要し、その間に有利な価格は消滅してスリッページが発生します。この遅延は、どれほど優れたアルゴリズムを書いても技術的にカバーできません。極限まで約定スピードを高め、意図した価格で注文をヒットさせるには、証券会社のサーバーに近いデータセンターに設置された「専用のVPS(仮想専用サーバー)」を利用することが、勝つための最低条件となります。

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

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

コメント

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