MQL4の数学関数を体系的にまとめました。MathAbs()による絶対値、MathSqrt()による平方根、MathPow()による累乗、MathRound()・MathFloor()・MathCeil()による丸め処理、MathMax()・MathMin()による比較、MathLog()・MathExp()による対数・指数、三角関数、MathRand()による乱数生成、NormalizeDouble()による価格正規化まで、MT4 EA開発に必要な数学処理のすべてをコード付きで解説します。
目次
MQL4とMQL5の数学関数の違い
| 機能 | MQL4 | MQL5 |
|---|---|---|
| 基本関数 | 完全に同じ | 完全に同じ |
| NormalizeDouble | NormalizeDouble() | NormalizeDouble() |
| 乱数 | MathRand() / MathSrand() | MathRand() / MathSrand() |
| 統計関数 | なし | MathStats系(追加) |
MQL4の数学関数はMQL5と完全に互換性があります。コードの移植がそのままで可能な唯一のカテゴリです。
基本数学関数
| 関数 | 説明 | 例 |
|---|---|---|
| MathAbs(x) | 絶対値 | MathAbs(-5.3) = 5.3 |
| MathSqrt(x) | 平方根 | MathSqrt(9) = 3.0 |
| MathPow(base, exp) | 累乗 | MathPow(2, 10) = 1024.0 |
| MathExp(x) | eのx乗 | MathExp(1) = 2.718… |
| MathLog(x) | 自然対数(ln) | MathLog(2.718) ≈ 1.0 |
| MathLog10(x) | 常用対数 | MathLog10(100) = 2.0 |
| MathMod(x, y) | 剰余 | MathMod(10, 3) = 1.0 |
丸め関数
| 関数 | 説明 | 例 |
|---|---|---|
| MathRound(x) | 四捨五入 | MathRound(2.5) = 3, MathRound(2.4) = 2 |
| MathFloor(x) | 切り捨て(小さい方向) | MathFloor(2.9) = 2, MathFloor(-2.1) = -3 |
| MathCeil(x) | 切り上げ(大きい方向) | MathCeil(2.1) = 3, MathCeil(-2.9) = -2 |
void RoundingExample()
{
double value = 2.567;
Print("MathRound: ", MathRound(value)); // 3
Print("MathFloor: ", MathFloor(value)); // 2
Print("MathCeil: ", MathCeil(value)); // 3
// ロット計算での使い分け
double rawLots = 0.157;
double lotStep = 0.01;
// 切り捨て(安全側)
double safeLots = MathFloor(rawLots / lotStep) * lotStep; // 0.15
// 四捨五入
double roundLots = MathRound(rawLots / lotStep) * lotStep; // 0.16
Print("切り捨て: ", safeLots, " 四捨五入: ", roundLots);
}MathMax / MathMin
void MaxMinExample()
{
// 基本的な使い方
double a = MathMax(10.5, 20.3); // 20.3
double b = MathMin(10.5, 20.3); // 10.5
// ロットの範囲制限
double lots = 0.05;
double minLot = MarketInfo(Symbol(), MODE_MINLOT);
double maxLot = MarketInfo(Symbol(), MODE_MAXLOT);
lots = MathMax(lots, minLot); // 最小ロット以上
lots = MathMin(lots, maxLot); // 最大ロット以下
// 複数値の最大値(ネスト)
double highest = MathMax(High[1], MathMax(High[2], High[3]));
// SLの安全距離確保
double stopLevel = MarketInfo(Symbol(), MODE_STOPLEVEL) * Point;
double slDistance = MathMax(30 * Point, stopLevel);
}NormalizeDouble — 価格の正規化
double NormalizeDouble(
double value, // 正規化する値
int digits // 小数点以下の桁数
);
// 浮動小数点の誤差を除去し、指定桁数に丸めるvoid NormalizeExample()
{
// 浮動小数点の罠
double a = 1.1 + 2.2; // 3.3000000000000003 (!=3.3)
// NormalizeDoubleで正規化
double b = NormalizeDouble(1.1 + 2.2, 1); // 3.3
// EA開発では価格計算に必須
double sl = Ask - 30 * Point;
sl = NormalizeDouble(sl, Digits); // 必ず正規化
double tp = Ask + 50 * Point;
tp = NormalizeDouble(tp, Digits);
// ロットも正規化
double lots = 0.123456;
lots = NormalizeDouble(lots, 2); // 0.12
// 価格比較にも使う
double price1 = NormalizeDouble(1.23456, 5);
double price2 = NormalizeDouble(1.23457, 5);
if(MathAbs(price1 - price2) < Point)
Print("ほぼ同じ価格");
}NormalizeDoubleを使うべき場面
- OrderSend()のprice, sl, tp引数に渡す前
- OrderModify()のsl, tp引数に渡す前
- 価格の比較(==を使う前に正規化)
- ロット数の計算後
NormalizeDouble()はMQL4プログラミングで最も頻繁に使う関数の一つです。浮動小数点の計算誤差(例: 1.1 + 2.2 = 3.3000000000000003)を除去し、ブローカーが受け入れ可能な桁数に丸めます。OrderSend/OrderModifyの引数に渡す価格・SL・TPには必ずNormalizeDouble(value, Digits)を適用してください。
NormalizeDouble()はMQL4プログラミングで最も頻繁に使う関数の一つです。浮動小数点の計算誤差を除去し、ブローカーが受け入れ可能な桁数に丸めます。OrderSend/OrderModifyの引数に渡す価格・SL・TPには必ずNormalizeDouble(value, Digits)を適用してください。
三角関数
| 関数 | 説明 |
|---|---|
| MathSin(x) | 正弦(xはラジアン) |
| MathCos(x) | 余弦 |
| MathTan(x) | 正接 |
| MathArcsin(x) | 逆正弦 |
| MathArccos(x) | 逆余弦 |
| MathArctan(x) | 逆正接 |
| M_PI | 円周率 (3.14159…) |
MathRand / MathSrand — 乱数
int OnInit()
{
// 乱数シードの初期化(起動時に1回)
MathSrand(GetTickCount());
return INIT_SUCCEEDED;
}
// 0〜max の範囲の乱数
int RandomInt(int max)
{
return MathRand() % (max + 1);
}
// min〜maxの範囲の乱数
double RandomDouble(double min, double max)
{
return min + (max - min) * MathRand() / 32767.0;
}
// ランダムなエントリー遅延(過剰最適化防止)
void RandomDelay()
{
int delaySec = RandomInt(5); // 0〜5秒のランダム遅延
if(delaySec > 0)
Sleep(delaySec * 1000);
}浮動小数点の比較テクニック
- == での直接比較は危険:
if(price1 == price2)は浮動小数点誤差で失敗する可能性がある - 差分比較が安全:
if(MathAbs(price1 - price2) < Point) - NormalizeDouble後の比較:
if(NormalizeDouble(a - b, Digits) == 0) - ゼロとの比較も注意:
if(value > 0.0001)のように小さな閾値を使う
浮動小数点の比較テクニック
- == での直接比較は危険:
if(price1 == price2)は浮動小数点誤差で失敗する可能性がある - 差分比較が安全:
if(MathAbs(price1 - price2) < Point) - NormalizeDouble後の比較:
if(NormalizeDouble(a - b, Digits) == 0) - ゼロとの比較も注意:
if(value > 0.0001)のように小さな閾値を使う
実践: EA開発でよく使う数学パターン
// ポイント→pips変換
double PointsToPips(int points)
{
if(Digits == 3 || Digits == 5)
return points / 10.0;
return (double)points;
}
// pips→ポイント変換
int PipsToPoints(double pips)
{
if(Digits == 3 || Digits == 5)
return (int)MathRound(pips * 10);
return (int)MathRound(pips);
}
// 標準偏差の計算
double StdDev(double &data[], int count)
{
if(count < 2) return 0;
double sum = 0;
for(int i = 0; i < count; i++)
sum += data[i];
double mean = sum / count;
double variance = 0;
for(int i = 0; i < count; i++)
variance += MathPow(data[i] - mean, 2);
return MathSqrt(variance / (count - 1));
}
// リスクリワードレシオの計算
double RiskRewardRatio(double entry, double sl, double tp)
{
double risk = MathAbs(entry - sl);
double reward = MathAbs(tp - entry);
if(risk == 0) return 0;
return reward / risk;
}数学関数一覧(MQL5対応表)
| MQL4関数 | MQL5対応 | 説明 |
|---|---|---|
| MathAbs() | MathAbs() | 絶対値 |
| MathSqrt() | MathSqrt() | 平方根 |
| MathPow() | MathPow() | 累乗 |
| MathExp() | MathExp() | 指数関数 |
| MathLog() | MathLog() | 自然対数 |
| MathLog10() | MathLog10() | 常用対数 |
| MathRound() | MathRound() | 四捨五入 |
| MathFloor() | MathFloor() | 切り捨て |
| MathCeil() | MathCeil() | 切り上げ |
| MathMax() | MathMax() | 大きい方 |
| MathMin() | MathMin() | 小さい方 |
| MathMod() | MathMod() | 剰余 |
| MathRand() | MathRand() | 乱数(0〜32767) |
| MathSrand() | MathSrand() | 乱数シード設定 |
| NormalizeDouble() | NormalizeDouble() | 価格正規化 |
| MathSin/Cos/Tan() | MathSin/Cos/Tan() | 三角関数 |
まとめ
MQL4の数学関数はMQL5と完全互換で、移植がそのまま可能です。EA開発で特に重要なのは以下の関数です。
- NormalizeDouble() — 最重要。価格やロットの計算後には必ず呼ぶ
- MathFloor() — ロット計算で安全側に丸めるのに使う
- MathMax()/MathMin() — 範囲制限に使う(ロット、SL距離等)
- MathAbs() — 距離計算(SLまでのpips数等)に使う
次のステップとして、MQLリファレンス総合ガイドで他のカテゴリも学習しましょう。





