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

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

MQL5のfloor関数は、指定した数値の「小数点以下を切り捨てて、その数値以下の最大の整数を返す」関数です。数学用語で言う「床関数」にあたります。

FXの自動売買(EA)開発において、この関数は単なる端数処理以上の重要な役割を持ちます。実務で最も多用されるのは、「証拠金維持率を守るための安全なロット計算」です。

例えば、計算上のロット数が「1.056」となった際、四捨五入(round)して「1.06」に繰り上げると、わずかに必要証拠金が足りず注文が拒否されるリスクがあります。一方、floorを使って「1.05」に切り捨てることで、口座資金の範囲内に確実に収める「守りの設計」が可能になります。

初心者がつまずきやすいポイントは、「マイナスの値」を扱う際の挙動です。後述する「注意点」で詳しく解説しますが、プラスの時と同じ感覚で使うと、意図しない計算結果を招くことがあるため注意が必要です。

2. 構文と戻り値

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

double floor(
   double value    // 対象となる数値
);

パラメーター

  • value: 切り捨てを行いたいdouble型の数値を指定します。

戻り値

  • 指定した数値以下の最大の整数をdouble型で返します。
  • 戻り値自体は整数(1.0, 2.0など)ですが、型はdoubleである点に注意してください。もしint型として扱いたい場合は、キャスト(型変換)が必要です。

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

実務で最も一般的な「ブローカーの最小刻み(ロットステップ)に合わせたロット計算」の例を紹介します。

//+------------------------------------------------------------------+
//| ロット数を計算し、ステップ単位で安全に切り捨てる関数                    |
//+------------------------------------------------------------------+
double CalculateSafeLot(double rawLot)
{
   // 1. ブローカーのロット刻み(例:0.01)を取得
   double step = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);

   if(step <= 0) return 0.0;

   // 2. floor関数を使用して、ステップ単位で切り捨てを行う
   // 例:rawLot=1.056, step=0.01 の場合
   // 1.056 / 0.01 = 105.6
   // floor(105.6) = 105.0
   // 105.0 * 0.01 = 1.05
   double roundedLot = floor(rawLot / step) * step;

   // 3. 最小ロット・最大ロットの制限をチェック
   double minLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
   double maxLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);

   if(roundedLot < minLot) roundedLot = minLot;
   if(roundedLot > maxLot) roundedLot = maxLot;

   return roundedLot;
}

// EAのオンティックイベントなどでの使用例
void OnTick()
{
   double myRiskLot = 1.05678; // 複雑な計算から算出されたロット
   double finalLot = CalculateSafeLot(myRiskLot);

   Print("元のロット: ", myRiskLot, " -> 切り捨て後のロット: ", finalLot);
   // 出力結果例:元のロット: 1.05678 -> 切り捨て後のロット: 1.05
}

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

① マイナス値の挙動に注意

floorは「その数値以下の最大の整数」を返します。
floor(1.8)1.0
floor(-1.8)-2.0(-1.0ではありません)

マイナスの価格差などを扱う際、単純に「0方向への切り捨て(絶対値を小さくする)」を期待している場合は、floorではなくtrunc関数を使用すべきです。

② 浮動小数点数の精度問題

コンピュータの特性上、double型の数値には微細な誤差が含まれます。
極めて稀に、内部的に「1.0」が「0.999999999999」として扱われている場合、floorを通すと「0.0」になってしまうことがあります。これを防ぐには、floor(value + 0.0000000001) のように極小の値を足す(エプソン補正)などの工夫が実務では行われます。

③ 型の不一致

floorの戻り値はdoubleです。配列のインデックス(int型)などにそのまま代入しようとすると、コンパイル警告が出ます。整数として利用する場合は、(int)floor(value)のように明示的にキャストしましょう。

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

アルゴリズムの論理構成が完璧であっても、それだけで勝てるほどFXの世界は甘くありません。特にミリ秒単位の価格変化を捉えるシストレにおいて、実行環境の「物理的距離」は勝率に直結します。自宅のPCや一般的な光回線では、プロバイダーを経由する際のネットワーク遅延(レイテンシ)が発生し、EAが注文を出してからサーバーに届くまでに致命的なタイムラグが生じます。この数ミリ秒の遅れが、スリッページによるリクオートや約定拒否を引き起こし、バックテストでは右肩上がりだったロジックを無残な損失へと変えてしまうのです。

約定スピードを極限まで高め、ロジック本来のパフォーマンスを引き出すには、取引サーバーの至近距離に位置する専用のVPS(仮想専用サーバー)が不可欠です。24時間365日、安定した低レイテンシ環境で稼働させることは、エンジニアとして「コードを書くこと」と同じくらい重要なリスク管理と言えます。プロのクオンツエンジニアが自宅PCで本番運用をしないのは、それが技術的に「勝負にならない」ことを知っているからです。本格的な運用を目指すなら、まずはインフラ環境をプロ仕様に整えることから始めてください。

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

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

コメント

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