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

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

MQL5のatan関数は、指定した数値の逆正接(アークタンジェント)を計算するための数学関数です。高校数学で習う「tanの逆関数」であり、直角三角形の「高さ ÷ 底辺」から、その「角度」を導き出す際に使用します。

FXのシステムトレード開発において、この関数は主に「トレンドの勢い(傾き)」を数値化するために活用されます。例えば、移動平均線(MA)がどの程度の角度で上昇しているかを計算し、「30度以上の急角度ならエントリー」といったロジックを組むことが可能です。

しかし、実務レベルでは「価格軸と時間軸の単位の違い」という壁にぶつかります。価格は「0.001」単位ですが、時間は「1バー(1分など)」単位です。この比率を正しく正規化してatanに渡さないと、チャートの見た目とはかけ離れた角度が算出されるため、注意が必要です。

2. 構文と戻り値

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

double atan(
   double value      // 正接(タンジェント)の値
);
  • パラメーター: value には、角度を求めたいタンジェントの値を入力します。通常は「(価格の変化量)÷(時間の経過量)」を代入します。
  • 戻り値: 計算結果がラジアン単位(-π/2 から π/2 の範囲)で返されます。
  • : 入出力ともに double 型です。

※私たちが普段目にする「度(0〜360度)」に変換するには、戻り値に 180 / M_PI を掛ける必要があります。

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

以下のコードは、25期間移動平均線(MA)の現在の「角度」を計算し、トレンドの強さを判定する実戦的なサンプルです。

//+------------------------------------------------------------------+
//| 移動平均線の角度を計算するサンプルEA                                     |
//+------------------------------------------------------------------+
#property strict

// 角度を度数法で取得する関数
double GetMAAngle(int shift)
{
   // MAのハンドルを取得(事前初期化を推奨)
   int maHandle = iMA(_Symbol, _Period, 25, 0, MODE_SMA, PRICE_CLOSE);

   double buffer[2];
   // 現在(shift)と1本前(shift+1)の値をコピー
   if(CopyBuffer(maHandle, 0, shift, 2, buffer) < 2) return 0.0;

   double priceDiff = buffer[1] - buffer[0]; // 価格の変化量(縦軸)

   // 価格の最小単位(Point)で割って正規化する(例: 0.01円の変化を10として扱う)
   double normalizedDiff = priceDiff / _Point;

   // 1バーあたりの変化量からラジアンを計算
   // atan(高さ / 底辺) ※底辺は1バーなので省略可能
   double radian = atan(normalizedDiff);

   // ラジアンを「度」に変換
   double angle = radian * (180.0 / M_PI);

   return angle;
}

void OnTick()
{
   double currentAngle = GetMAAngle(0);

   // 角度が20度以上なら上昇トレンド、-20度以下なら下降トレンドと判定
   if(currentAngle > 20.0)
      Comment("強力な上昇トレンド中:", DoubleToString(currentAngle, 2), "度");
   else if(currentAngle < -20.0)
      Comment("強力な下降トレンド中:", DoubleToString(currentAngle, 2), "度");
   else
      Comment("レンジ相場:", DoubleToString(currentAngle, 2), "度");
}

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

  1. ラジアンと度の混同:
    atanが返すのは「度」ではなく「ラジアン」です。if(atan(val) > 30) と書くと、「30ラジアン(約1718度)」と比較することになり、ロジックが全く機能しません。必ず 180 / M_PI を掛けて変換してください。

  2. 価格スケールの正規化:
    通貨ペアによって _Point(最小桁数)は異なります。USD/JPYの1pipsとEUR/USDの1pipsでは数値が桁違いに変わるため、_Point で割るなどして、どの通貨ペアでも同じ基準で角度が測れるよう調整が必要です。

  3. 計算対象の「底辺」の定義:
    上記の例では「1バー(底辺=1)」としていますが、例えば「5バー間の角度」を見たい場合は、atan(priceDiff / 5.0) のように底辺の長さを合わせる必要があります。

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

アルゴリズム取引において、atan関数などで精緻なトレンド分析を行っても、そのシグナルを執行する「環境」が劣悪であれば、全ての努力は水の泡となります。多くの開発者が陥る罠は、自宅のPCから一般的なインターネット回線を通じて自動売買を行ってしまうことです。

FX市場はミリ秒単位で価格が変動しており、自宅PCと証券会社サーバー間のネットワーク遅延(レイテンシ)は、注文価格と約定価格のズレ(スリッページ)を確実に引き起こします。特にボラティリティが高い局面では、数ミリ秒の遅れが致命的な損失に直結します。プロのクオンツやトレーダーが専用のVPS(仮想専用サーバー)を利用するのは、単に24時間稼働させるためだけではなく、証券会社のサーバーと同じデータセンター内に設置することで物理的な距離を短縮し、約定スピードを極限まで高めるためです。安定した利益を目指すのであれば、高速なネットワーク環境を備えたVPSの導入は、ロジックを磨くことと同じくらい重要な「勝つための必須条件」と言えます。

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

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

コメント

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