MathIsValidNumber関数の働き・役割
MathIsValidNumber関数は、指定された実数(小数点を含む数値や負の数、ゼロも含む範囲の数)が有効な数値であるかどうかを確認するために使用されます。浮動小数点数(非常に大きな数や非常に小さな数を効率的に表現できる数値形式)には、無限大(正および負)や「非数」(NaN:Not a Number)といった特殊な値が含まれる場合がありますが、MathIsValidNumber関数はその数値がこれらの特殊な値に該当しないかどうかを判定します。
MathIsValidNumber関数の引数について
bool MathIsValidNumber(
double number // チェックする数
);
MathIsValidNumber関数の引数は以下の通りです。
引数の説明
- number
- 種類: 浮動小数点数型(double)
- 説明: 有効性を確認する浮動小数点数を指定します。この引数に指定された数値が、通常の実数か、無限大やNaNといった特殊な値であるかがチェックされます。
MathIsValidNumber関数の戻り値について
MathIsValidNumber関数の戻り値は、指定した浮動小数点数が有効な実数であるかどうかを示すブール型(trueまたはfalse)です。
- true
引数に指定された数値が有効な実数である場合に返されます。これは、通常の範囲内にある浮動小数点数(正規数)であることを意味します。 - false
引数に指定された数値が無効な場合に返されます。ここで無効とは、その数値が正または負の無限大、もしくはNaN(非数)であることを指します。この戻り値により、数値が不正かどうかを確認することができます。
この戻り値を活用することで、トレード判断や計算の途中で発生する異常値を見つけ出し、処理を分岐させることが可能です。
MathIsValidNumber関数を使ったサンプルコード
//+------------------------------------------------------------------+
//| スクリプトプログラムの開始関数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- NaN(数ではない)をテスト
// NaNは数値として扱えない特殊な値を表します
double nan = double("nan");
PrintFormat("テスト NaN: %G は %s です, MathIsValidNumber(NaN)=%s",
nan,
EnumToString(MathClassify(nan)),
(string)MathIsValidNumber(nan)); // NaNかどうかの確認を出力
//--- 無限大の値をテスト
// infは正または負の無限大を表す特殊な値です
double inf = double("inf");
PrintFormat("テスト 無限大: %G は %s です, MathIsValidNumber(inf)=%s",
inf,
EnumToString(MathClassify(inf)),
(string)MathIsValidNumber(inf)); // 無限大かどうかの確認を出力
//--- 正常な(通常の)数値をテスト
// 通常の範囲内にある浮動小数点数
double normal = 1.2345e6;
PrintFormat("テスト 通常の値: %G は %s です, MathIsValidNumber(normal)=%s",
normal,
EnumToString(MathClassify(normal)),
(string)MathIsValidNumber(normal)); // 通常の数値かどうかの確認を出力
//--- 非正規数をテスト
// 非正規数とは、正規の最小値より小さい数を意味します
double sub_normal = DBL_MIN / 2.0;
PrintFormat("テスト 非正規数: %G は %s です, MathIsValidNumber(sub_normal)=%s",
sub_normal,
EnumToString(MathClassify(sub_normal)),
(string)MathIsValidNumber(sub_normal)); // 非正規数かどうかの確認を出力
//--- ゼロの値をテスト
// ゼロ(符号付きゼロも含む)を判別
double zero = 0.0 / (-1); // -0 を生成
PrintFormat("テスト ゼロ: %G は %s です, MathIsValidNumber(zero)=%s",
zero,
EnumToString(MathClassify(zero)),
(string)MathIsValidNumber(zero)); // ゼロかどうかの確認を出力
}
/*
結果:
テスト NaN: NAN は FP_NAN です, MathIsValidNumber(NaN)=false
テスト 無限大: INF は FP_INFINITE です, MathIsValidNumber(inf)=false
テスト 通常の値: 1.2345E+06 は FP_NORMAL です, MathIsValidNumber(normal)=true
テスト 非正規数: 1.11254E-308 は FP_SUBNORMAL です, MathIsValidNumber(sub_normal)=true
テスト ゼロ: -0 は FP_ZERO です, MathIsValidNumber(zero)=true
*/
//+------------------------------------------------------------------+
サンプルコード解説1: OnStart関数部分その1
//+------------------------------------------------------------------+
//| スクリプトプログラムの開始関数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- NaN(数ではない)をテスト
// NaNは数値として扱えない特殊な値を表します
double nan = double("nan");
PrintFormat("テスト NaN: %G は %s です, MathIsValidNumber(NaN)=%s",
nan,
EnumToString(MathClassify(nan)),
(string)MathIsValidNumber(nan)); // NaNかどうかの確認を出力
このサンプルコードは、MQL5のスクリプトで浮動小数点数の型を判別するために使用されるMathClassify関数をテストしています。ここでは、OnStart関数の中で、特殊な浮動小数点数である「NaN(Not a Number、数ではない)」の状態を確認しています。
OnStart関数
OnStart関数は、スクリプトが実行されたときに自動的に呼び出される関数です。ここでは、特定の数値の状態を確認するための処理が記述されています。
NaN(数ではない)についてのテスト
- NaNの生成
NaN(Not a Number)は、数として認識されない特殊な値です。例えば、不正な数値計算(0での除算や無効な関数の引数)によって生成されます。このコードでは、double関数で文字列「nan」を指定し、NaNを生成しています。
※double(“nan”);という表記は、文字列 “nan” を double型に変換するために使われています。これは、キャストの一種であり、特定の文字列を浮動小数点数の特殊な値(NaN: Not a Number、数ではない状態)に変換するための操作です。一般的に、nanという文字列をdouble型に変換すると、「数値ではない」ことを示すNaNとして扱われます。NaNは、計算上で定義できない結果(例:0での除算など)や、エラーのある値を示すために使用されます。double関数を使ってnanを生成することで、数値の型や計算エラーを確認するテストにも使われる表現です。 - MathClassify関数でのNaN判定
MathClassify関数を使用し、生成されたnanがどのような型かを確認しています。この関数は、数値がNaNかどうかを判断し、その結果をENUM_FP_CLASS列挙体の値として返します。NaNの場合、戻り値はFP_NANとなります。 - PrintFormat関数での出力
PrintFormat関数を使って、テスト結果を出力しています。出力される内容は以下の通りです。
- nanの値(NAN)
- MathClassify関数の判別結果(FP_NAN)
- MathIsValidNumber関数によるNaNの有効性チェック結果
MathIsValidNumber関数について
MathIsValidNumber関数は、指定した数値が「有効な実数」かどうかをチェックします。正の無限大や負の無限大、またはNaNである場合にはfalseを返し、通常の数値であればtrueを返します。NaNが無効な数値であるため、この場合はfalseが出力されます。
サンプルコード解説2:OnStart関数部分その2
//--- 無限大の値をテスト
// infは正または負の無限大を表す特殊な値です
double inf = double("inf");
PrintFormat("テスト 無限大: %G は %s です, MathIsValidNumber(inf)=%s",
inf,
EnumToString(MathClassify(inf)),
(string)MathIsValidNumber(inf)); // 無限大かどうかの確認を出力
この部分のコードでは、浮動小数点数の特殊な値である「無限大」を扱っています。無限大とは、正の無限大や負の無限大のことを指し、通常の数値計算で扱えない大きさの数値です。この値を用いてMathClassify関数がどのように動作するかを確認しています。
無限大の生成とテスト
ここでは、文字列 “inf” をdouble型に変換することで無限大を生成しています。この変換によってinfという変数には無限大の値が格納されます。無限大は、特に数学的な計算で数が極端に大きくなりすぎた場合や、範囲外の値が求められたときに出現することが多い特殊な値です。
PrintFormat関数の使用とフォーマット指定子
PrintFormat関数を使って、無限大のテスト結果をエキスパートログに出力しています。PrintFormat関数では、フォーマット指定子を使って値の出力形式を指定します。ここで使われている指定子と、それに対応する値について説明します。
- %G は浮動小数点数を出力する指定子で、通常の数値や無限大、NaNのような特殊な値も出力します。この指定子に対応する値はinfです。ここではinfが無限大の値として表示されます。
- %s は文字列を出力する指定子です。ここではEnumToString関数によって取得された文字列が出力されます。EnumToString関数は、MathClassify関数が返す列挙体の識別子(例えばFP_INFINITEなど)を文字列に変換します。これにより、無限大の型がわかりやすく文字列として出力されます。
- MathIsValidNumber関数の結果も出力されています。この関数は、無限大が有効な数値かどうかをチェックします。ここで得られる結果は無限大の数値ではないためfalseとなり、出力されるのは文字列“false”です。
変換された文字列の出力
上記の各指定子に対応する値によって、無限大のテスト結果がエキスパートログに出力されます。この一連のコードによって、無限大の値が正常に判別されていることを確認でき、MathClassify関数やMathIsValidNumber関数がどのように機能するかを理解する助けとなります。
サンプルコード解説3:OnStart関数部分その3
//--- 正常な(通常の)数値をテスト
// 通常の範囲内にある浮動小数点数
double normal = 1.2345e6;
PrintFormat("テスト 通常の値: %G は %s です, MathIsValidNumber(normal)=%s",
normal,
EnumToString(MathClassify(normal)),
(string)MathIsValidNumber(normal)); // 通常の数値かどうかの確認を出力
この部分のコードでは、通常の範囲内にある浮動小数点数を使って、MathClassify関数がどのように分類するかをテストしています。ここで使用されている数値は「1.2345e6」で、これは「1.2345 × 10の6乗」、つまり1234500という値を表します。指数表記を使うことで、大きな数や小さな数を短く簡潔に表現しています。
通常の数値の生成とテスト
double型の変数normalに「1.2345e6」という通常の範囲内の数値を代入し、MathClassify関数で分類を行っています。MathClassify関数は、この数値が通常の浮動小数点数(正規数)であると判定します。
※1.2345e6は「1.2345 × 10の6乗」という意味です。つまり、1.2345e6は1234500を表しています。
PrintFormat関数の使用とフォーマット指定子
PrintFormat関数を用いて、テスト結果をエキスパートログに出力しています。この関数では、指定子を使って出力形式を指定しており、それぞれの指定子が異なる値に対応しています。
%G
は浮動小数点数の指定子です。ここでは、normalに代入された通常の数値が表示されます。%G
は、指定された数値が指数表記に適している場合には指数表記で、そうでない場合には通常の小数表記で表示されます。%s
は文字列を出力する指定子です。MathClassify関数の戻り値であるENUM_FP_CLASS列挙体の識別子をEnumToString関数で文字列に変換し、識別結果をわかりやすく表示しています。この場合、MathClassify関数はnormalが通常の数値であることを判別し、戻り値としてFP_NORMALを返します。この結果はEnumToString関数で文字列「FP_NORMAL」として出力されます。- MathIsValidNumber関数は、数値が有効であるかを確認します。通常の数値は有効な数値とみなされるため、結果としてtrueが返され、文字列“true”として表示されます。
変換された文字列の出力
上記の指定子に対応する値によって、正常な数値が正しく判別されていることがエキスパートログに出力されます。このテストによって、通常の数値を扱う場合でもMathClassify関数やMathIsValidNumber関数が正常に動作することが確認できます。
サンプルコード解説4:OnStart関数部分その4
//--- 非正規数をテスト
// 非正規数とは、正規の最小値より小さい数を意味します
double sub_normal = DBL_MIN / 2.0;
PrintFormat("テスト 非正規数: %G は %s です, MathIsValidNumber(sub_normal)=%s",
sub_normal,
EnumToString(MathClassify(sub_normal)),
(string)MathIsValidNumber(sub_normal)); // 非正規数かどうかの確認を出力
この部分のコードでは、通常の浮動小数点数の範囲よりも小さい「非正規数」をテストしています。非正規数とは、正規数(通常の範囲内の数)として表現できない小さな数値を指します。これにより、浮動小数点数の最小値(DBL_MIN)をさらに小さくした値が「非正規数」として分類されることを確認できます。
非正規数の生成とテスト
非正規数を生成するために、DBL_MIN(浮動小数点数で表現できる最小の正規数)を2で割った値をsub_normalに代入しています。この数値は通常の正規数として扱えない小さな値となり、MathClassify関数で非正規数として分類されます。
PrintFormat関数の使用とフォーマット指定子
PrintFormat関数を使用して、エキスパートログに非正規数のテスト結果を出力しています。ここでもフォーマット指定子を使用して、異なるデータを適切に出力しています。
%G
は浮動小数点数を出力する指定子で、通常の数値や特殊な値(無限大や非正規数)も表現します。ここではsub_normalに代入された非正規数の値が表示されます。%Gは指数表記や通常表記の両方で表示可能で、数値に応じて最適な形式を選びます。%s
は文字列を出力する指定子で、MathClassify関数によって返されるENUM_FP_CLASS列挙体の識別子をEnumToString関数で文字列に変換したものが出力されます。このコードではMathClassify関数が非正規数を判別し、FP_SUBNORMALが戻り値として返されます。この結果はEnumToString関数で「FP_SUBNORMAL」という文字列に変換され、ログに表示されます。- MathIsValidNumber関数も使用されています。非正規数は有効な数値と見なされるため、この関数はtrueを返します。この結果は文字列“true”として出力されます。
変換された文字列の出力
上記のフォーマット指定子に基づき、非正規数として判別された結果がエキスパートログに出力されます。このテストにより、MathClassify関数とMathIsValidNumber関数が非正規数に対しても正常に動作することが確認されます。
サンプルコード解説5:OnStart関数部分その5
//--- ゼロの値をテスト
// ゼロ(符号付きゼロも含む)を判別
double zero = 0.0 / (-1); // -0 を生成
PrintFormat("テスト ゼロ: %G は %s です, MathIsValidNumber(zero)=%s",
zero,
EnumToString(MathClassify(zero)),
(string)MathIsValidNumber(zero)); // ゼロかどうかの確認を出力
}
この部分のコードでは、ゼロの値をテストしています。ゼロには「正のゼロ」と「負のゼロ」が存在し、符号が付いたゼロも区別されます。ここでは、負のゼロを生成し、MathClassify関数でその分類を確認しています。
ゼロの生成とテスト
double型の変数zeroに、0.0を-1で割った値を代入しています。これにより、符号が負のゼロ(-0)が生成されます。この符号付きゼロがMathClassify関数で分類され、ゼロとして識別されることを確認します。
PrintFormat関数の使用とフォーマット指定子
PrintFormat関数を使って、ゼロのテスト結果をエキスパートログに出力しています。ここでのフォーマット指定子と、それに対応する値について説明します。
- %G は浮動小数点数を出力する指定子で、通常の数値やゼロを表示します。ここでは、zeroに代入された負のゼロの値が出力されます。%Gは数値がゼロの場合も符号を保持して表示するため、-0のように負のゼロもそのまま表現されます。
- %s は文字列を出力する指定子です。MathClassify関数の戻り値であるENUM_FP_CLASS列挙体の識別子をEnumToString関数で文字列に変換し、判別結果をわかりやすく表示します。この場合、MathClassify関数はゼロの値をFP_ZEROとして識別し、EnumToString関数で「FP_ZERO」という文字列として出力されます。
- MathIsValidNumber関数は、ゼロが有効な数値であるかを確認します。ゼロは有効な数値とみなされるため、結果としてtrueが返され、文字列“true”として出力されます。
変換された文字列の出力
これらの指定子に基づき、ゼロ(符号付きゼロ含む)が正しく判別されていることがエキスパートログに出力されます。このコードによって、MathClassify関数とMathIsValidNumber関数がゼロの値に対しても適切に動作することが確認できます。
MathIsValidNumber関数を使ってEAを作る際のアイディア
MathIsValidNumber関数を活用することで、エキスパートアドバイザー(EA)内で異常な数値の監視やエラーチェックを実現し、トレード判断の安定性を高めることができます。
計算エラーの検出とフィルタリング
インジケータやカスタム計算の結果がNaNや無限大となった場合、MathIsValidNumber関数を使ってそれを検出し、無効な値がEAのロジックに影響しないようフィルタリングすることが可能です。たとえば、計算結果が無効な数値の場合、その値を無視して再計算する、もしくは初期値に戻して処理を続行するようにすれば、誤ったトレード判断を防ぐことができます。
異常値によるトレード停止機能
トレード中に異常な値が発生した場合、即座にトレードを停止させることでリスクを軽減できます。例えば、ボラティリティが急激に増加してインジケータの値が無限大に達した場合、トレードを一時停止する機能をMathIsValidNumber関数を使って実装できます。これにより、異常な市場状況や計算の失敗による損失を最小限に抑えることが可能です。
データ検証とデバッグの自動化
MathIsValidNumber関数を使って、EA内で使用する全ての数値を検証する仕組みを追加し、異常値をログに出力する機能を構築することも有効です。この機能により、どの計算で無効な値が発生したのかを追跡でき、EAのデバッグやパフォーマンス分析が容易になります。また、異常な値が発生する頻度を記録することで、EAの安定性を改善する手がかりを得られます。
異常値検出によるアラート機能
トレード実行前にMathIsValidNumber関数を用いて、エントリーの判断に使う価格やインジケータの値が有効かどうかをチェックし、無効な場合にはアラートを出す仕組みも役立ちます。これにより、計算の異常が原因で誤ったエントリーが実行されるのを防ぎ、手動でトレード管理を行う際にも早期に問題に気付くことができます。
MathIsValidNumber関数を使うことで、EAが扱う数値の信頼性を高め、不正確なデータによるエラーを事前に防ぐ設計が可能です。