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

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

ウィリアムズの%R(Williams’ Percent Range)を算出するiWPR関数は、相場の「買われすぎ・売られすぎ」を判断するためのオシレーター系インジケーターを呼び出す関数です。ラリー・ウィリアムズによって開発されたこの指標は、0%から-100%の範囲で推移し、ストキャスティクスと似た動きをしますが、目盛りが反転しているのが特徴です。

実務での活用とつまずきポイント:
MQL4から移行してきた開発者が最もつまずきやすいのは、「関数を呼ぶだけで値が返ってくるわけではない」という点です。MQL5のiWPRは、指標の計算設定を行う「ハンドル」を返すのみであり、実際の数値を取得するにはCopyBuffer関数を併用する必要があります。

実務では、単体での逆張り(-20%以上で売り、-80%以下で買い)に使用するよりも、トレンドフォロー中の「押し目・戻り」のタイミングを計るフィルターとして活用するのが非常に効果的です。強いトレンド中には-20%や-80%に張り付く「張り付き」現象が起こるため、他のトレンド系指標(移動平均線など)と組み合わせるのがプロの定石です。

2. 構文と戻り値

iWPR関数の基本的な構文は以下の通りです。

int  iWPR(
   string           symbol,       // 通貨ペア名(NULLで現在のチャート)
   ENUM_TIMEFRAMES  period,       // 時間軸(0で現在の時間軸)
   int              calc_period   // 平均化期間(一般的には14)
   );

戻り値:
– 成功した場合:インジケーターのハンドル(int型の識別番号)
– 失敗した場合:INVALID_HANDLE

取得したハンドルは、EAの実行中に使い回すため、通常はOnInit関数内で一度だけ取得し、グローバル変数に格納しておきます。

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

以下は、iWPRの値が-80を下回った状態から上抜けた時に買い、-20を上回った状態から下抜けた時に売りを行う、シンプルなEAの雛形です。

//+------------------------------------------------------------------+
//|                                              Sample_iWPR_EA.mq5  |
//|                                  Copyright 2023, Quant Engineer  |
//+------------------------------------------------------------------+
#property strict

// 入力パラメーター
input int      WPR_Period = 14;          // WPRの期間
input double   WPR_Upper  = -20.0;       // 買われすぎライン
input double   WPR_Lower  = -80.0;       // 売られすぎライン

// グローバル変数
int            handleWPR;                // iWPRのハンドルを保持

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
   // iWPRのハンドルを取得
   handleWPR = iWPR(_Symbol, _Period, WPR_Period);

   // ハンドルの取得に失敗した場合の処理
   if(handleWPR == INVALID_HANDLE)
   {
      Print("iWPRハンドルの取得に失敗しました。");
      return(INIT_FAILED);
   }

   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
   double wprValues[];              // 値を格納する動的配列
   ArraySetAsSeries(wprValues, true); // 最新のバーをインデックス0にする

   // ハンドルを使ってデータを配列にコピー(最新2本分)
   if(CopyBuffer(handleWPR, 0, 0, 2, wprValues) < 2)
   {
      Print("データのコピーに失敗しました。");
      return;
   }

   double currentWPR = wprValues[0];  // 最新のWPR値
   double lastWPR    = wprValues[1];  // 1本前のWPR値

   // --- 売買ロジック ---
   // 買いサイン:-80を上抜けたとき
   if(lastWPR <= WPR_Lower && currentWPR > WPR_Lower)
   {
      Print("買いシグナル発生: ", currentWPR);
      // ここにオーダー処理を記述
   }

   // 売りサイン:-20を下抜けたとき
   if(lastWPR >= WPR_Upper && currentWPR < WPR_Upper)
   {
      Print("売りシグナル発生: ", currentWPR);
      // ここにオーダー処理を記述
   }
}

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   // ハンドルの解放(メモリ管理)
   IndicatorRelease(handleWPR);
}

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

  1. ハンドルの作成場所に注意
    iWPR関数をOnTickの中で毎回呼び出してはいけません。ティックごとに新しい計算オブジェクトが生成され、メモリを食いつぶし、PCやVPSの動作を著しく重くします。必ずOnInitで一度だけ取得してください。
  2. 配列の時系列設定
    CopyBufferで取得したデータは、デフォルトでは古い順に並んでいます。ArraySetAsSeries(array, true)を使用しないと、index[0]が最新の価格にならないため、ロジックが逆転するバグの原因になります。
  3. データ不足のチェック
    MT5の起動直後などは過去のチャートデータが十分に読み込まれていない場合があります。CopyBufferの戻り値が要求した個数(サンプルでは2)に満たない場合は、計算を行わないようにガードをかけるのが堅牢なコードのコツです。

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

プロのクオンツエンジニアとして、ロジック以上に重視すべきなのが実行環境のネットワーク遅延(レイテンシ)です。どれほどiWPRで正確なエントリーポイントを算出したとしても、ご自宅のPCから家庭用回線で注文を出している場合、ブローカーのサーバーに届くまでに数十〜数百ミリ秒の遅延が発生します。このわずかなラグの間に価格が滑り(スリッページ)、本来得られるはずだった利益が削られ、最悪の場合は約定拒否(リクオート)に繋がります。

FXの自動売買において、ミリ秒単位の遅れは致命的な損失に直結します。極限まで約定スピードを高め、スリッページを最小限に抑えるには、ブローカーの取引サーバーに物理的に近い距離に設置された専用のVPS(仮想専用サーバー)を利用することが必須条件です。24時間安定した稼働と、ネットワーク遅延の極小化を実現して初めて、バックテストの結果に近いパフォーマンスをリアル口座で再現することが可能になります。

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

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

コメント

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