GetTickCount64関数の働き・役割
GetTickCount64関数は、システムが起動してから現在までの経過時間をミリ秒単位で取得するために使用されます。この関数は、システムの起動後の経過時間を正確に計測する必要がある場面で役立ちます。
GetTickCount関数とは異なり、GetTickCount64関数は64ビットの整数型であるため、オーバーフロー(数値がその型で扱える最大値を超えて初期化される現象)の影響を受けません。システムが長時間稼働し続けても、計測が正しく行われることが特徴です。
GetTickCount64関数の引数について
ulong GetTickCount64();
GetTickCount64関数は、引数を持たない関数です。特定のパラメータを設定することなく、呼び出すだけでシステムの起動から現在までの経過時間を取得します。
GetTickCount64関数の戻り値について
GetTickCount64関数は、システムの起動から現在までの経過時間をミリ秒単位で返します。戻り値のデータ型は、符号なし64ビット整数(ulong型)です。
この戻り値によって、長時間にわたるシステムの稼働状況を精確に把握できます。GetTickCount関数とは異なり、GetTickCount64関数はオーバーフロー(数値が型の最大値を超えてリセットされる現象)の影響を受けません。これにより、システムが何日間、何週間稼働し続けても正確な経過時間が取得可能です。
GetTickCount64関数を使う際の注意点
GetTickCount64関数はオーバーフローの影響を受けませんが、類似の関数であるGetTickCount関数とは異なる動作をします。GetTickCount関数は32ビットの整数型を使用しており、システムが49.7日連続で稼働するとオーバーフロー(数値が型の最大値を超えて初期化される現象)を起こします。その結果、計測値がゼロに戻り、正しい時間計測ができなくなる場合があります。
一方、GetTickCount64関数は64ビットの整数型を使用しているため、オーバーフローの問題が発生せず、コンピュータが長期間継続して稼働していても正確な経過時間を取得できます。
GetTickCount64関数を使ったサンプルコード
#define MAX_SIZE 40
//+------------------------------------------------------------------+
//| 40個のフィボナッチ数の計算時間を測定するスクリプト |
//+------------------------------------------------------------------+
void OnStart()
{
//--- フィボナッチ数列を格納するための配列を定義(サイズはMAX_SIZE)
long fib_array[MAX_SIZE];
//--- GetTickCount64関数を使用して、計算開始時の時刻をミリ秒単位で取得
ulong start = GetTickCount64();
//--- フィボナッチ数列の計算を行うループ(MAX_SIZEの数だけ計算する)
for(int i = 0; i < MAX_SIZE; i++)
fib_array[i] = TestFibo(i); // i番目のフィボナッチ数を計算して配列に格納
//--- 再度GetTickCount64関数を使用して、かかった時間を計算(ミリ秒単位)
ulong time = GetTickCount64() - start;
//--- 計算したフィボナッチ数列をエキスパートログに出力
ArrayPrint(fib_array); // 配列fib_arrayの内容をログに表示
//--- 計算にかかった時間をエキスパートログに出力
//--- %dは整数のフォーマット指定子、%I64uは64ビット符号なし整数のフォーマット指定子
PrintFormat("Calculating the first %d Fibonacci numbers took %I64u ms", MAX_SIZE, time);
}
//+------------------------------------------------------------------+
//| 指定された番号のフィボナッチ数を再帰的に計算する関数 |
//+------------------------------------------------------------------+
long TestFibo(long n)
{
//--- フィボナッチ数列の最初の2つのメンバは常に1
if(n < 2)
return(1); // 0番目と1番目のフィボナッチ数は1
//--- それ以降のフィボナッチ数は、前の2つの数の和で計算される
//--- 再帰的にn-2とn-1のフィボナッチ数を求め、その合計を返す
return(TestFibo(n - 2) + TestFibo(n - 1));
}
サンプルコードに使われた関数や文法要素の簡単な解説
OnStart関数
OnStart関数は、スクリプトが実行されるときに最初に呼び出される関数です。この関数の中で、フィボナッチ数列の計算と計算にかかった時間の測定を行っています。MQL5のスクリプトは、OnStart関数が終了すると自動的に完了します。
GetTickCount64関数
GetTickCount64関数は、システムが起動してからの経過時間をミリ秒単位で返す関数です。コードでは、この関数を使用してフィボナッチ数列を計算する処理にかかった時間を測定しています。この関数の戻り値は64ビットの整数で、オーバーフローの心配がないため、長時間稼働しているシステムでも正確な時間を取得することができます。
TestFibo関数
TestFibo関数は、指定された番号のフィボナッチ数を再帰的に計算するオリジナル関数です。フィボナッチ数列は、前の2つの数の和によって次の数が決まるため、TestFibo関数は自身を再帰的に呼び出して計算を行います。
具体的には、フィボナッチ数列の最初の2つの値(0番目と1番目)は常に1です。それ以降の値は、n-2とn-1のフィボナッチ数の合計で計算されます。この再帰呼び出しによって、効率的にフィボナッチ数列を求めることができます。
配列と定数の定義と使用
fib_arrayという配列は、40個のフィボナッチ数を保存するために使用されます。配列のサイズは定数MAX_SIZEとして定義され、配列の中に順番にフィボナッチ数が格納されます。この定数MAX_SIZEは配列のサイズを指定しており、40個のフィボナッチ数を計算するために用いられます。これにより、コード全体の可読性が向上し、変更が容易になります。この配列を使うことで、計算したフィボナッチ数列を後で参照したり、ログに出力したりすることができます。
各種変数
コード内で使用されているstartとtimeは、GetTickCount64関数で計測した時間を格納する変数です。startはフィボナッチ数列の計算が始まる時点の時間を、timeは計算が終わった後に経過した時間を表します。fib_arrayという配列には計算されたフィボナッチ数列が順次格納されます。
ArrayPrint関数
ArrayPrint関数は、指定された配列の内容をエキスパートログに出力するための関数です。ここでは、計算した40個のフィボナッチ数がすべてログに表示され、デバッグや確認が簡単に行えるようになっています。
PrintFormat関数
PrintFormat関数は、フォーマット指定子を使ってメッセージをエキスパートログに出力する関数です。コードでは、フィボナッチ数列の計算にかかった時間を表示するために使用されています。%dは整数を、%I64uは64ビットの符号なし整数をフォーマットして出力する指定子です。
for文
for文は、指定された回数だけ処理を繰り返す制御文です。このサンプルコードでは、for文を使用してMAX_SIZE(40回)だけフィボナッチ数を計算し、配列に格納しています。iはループのインデックス(通し番号)として機能し、0からMAX_SIZEまで増加します。
return文
return文は、関数の処理を終了し、呼び出し元に制御を戻すために使用されます。OnStart関数では、最後にreturnを使用してスクリプトの実行を終了しています。
再帰処理の解説
TestFibo関数では、再帰という手法が使われています。再帰とは、関数が自分自身を呼び出す手法であり、フィボナッチ数列のように規則的に前の値を利用して次の値を計算する場合に便利です。ただし、再帰呼び出しは計算コストが高いため、再帰の深さが深くなるとパフォーマンスに影響する場合があります。長い数列を計算する場合は、再帰の使用に注意が必要です。
ulong型の使用
GetTickCount64関数の戻り値や、計算にかかった時間を格納するために、ulong型(符号なし64ビット整数型)が使用されています。この型を使用することで、非常に大きな数値でも正確に扱うことができ、オーバーフローを避けることが可能です。長時間にわたるシステム稼働の時間計測に適しています。
これらの要素が組み合わさって、フィボナッチ数列の計算とその処理時間の測定を実現しています。
補足:フィボナッチ数列について
フィボナッチ数列は、最初の2つの数は1で始まり、それ以降の数は、前の2つの数を足し合わせた値で決まるような性質の数列です。
フィボナッチ数列は以下のように生成されます。
1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89…
例えば、3番目の数(2)は1番目と2番目の数(1 + 1)を足して得られ、4番目の数(3)は2番目と3番目の数(1 + 2)を足したものです。このように、数列は無限に続いていきます。
フィボナッチ数列は自然界や芸術、数学などさまざまな分野で見られるパターンです。たとえば、ひまわりの種の配置や貝殻の形状など、自然の中にもフィボナッチ数列が関係する現象が見られます。また、株式市場の動向を予測するテクニカル分析の一環としてもフィボナッチ数列が使われることがあります。
この数列を計算するアルゴリズムは非常に単純ですが、計算を続けると次第に大きな数値が生成されるため、プログラム上での応用や練習に適した題材でもあります。
この関数を使ってEAを作る際のアイディア
GetTickCount64関数は、EA(エキスパートアドバイザ)の中で時間を正確に管理するために有用です。この関数を活用することで、時間に基づいたトレード戦略や処理の最適化が可能になります。以下は、GetTickCount64関数を用いたEA開発のアイディアです。
1. トレード間隔の制御
EAが短時間に複数の取引を行わないように、前回のトレードからの経過時間をGetTickCount64関数で計測し、一定時間が経過した場合にのみ新たなトレードを行う仕組みを作成できます。これにより、過剰取引を防ぎ、取引の精度を向上させることが可能です。
2. トレードの時間測定
トレード戦略や分析にかかる時間を計測することで、EAのパフォーマンスを確認し、必要に応じて最適化することができます。特に、大量のデータ処理や複雑な計算を行うEAでは、処理時間の把握が重要です。GetTickCount64関数を使って処理時間を測定し、パフォーマンスを改善する手がかりにできます。
3. タイムアウト機能の実装
EAがサーバーや外部システムとの通信を行う際、応答が遅れる場合があります。このような状況では、GetTickCount64関数を使って一定時間内に応答がない場合に処理を中断するタイムアウト機能を実装することができます。これにより、長時間待ち続けることを防ぎ、より効率的な処理が可能になります。
4. 時間依存のトレード戦略
市場のオープンから一定時間経過後にトレードを開始する、特定の時間が経過したらポジションを自動的にクローズするなど、時間に基づくトレード戦略を実装できます。時間に基づくルールは、相場の特定の時間帯に発生するパターンを利用したトレード戦略に役立ちます。
5. 処理の効率化
複雑なEAでは、多くのデータやアルゴリズムを扱うため、処理にかかる時間が長くなることがあります。GetTickCount64関数を使って処理時間を計測し、効率の悪い部分を特定することで、EAの動作を最適化できます。時間のかかる処理を短縮することで、EAの全体的なパフォーマンスが向上します。
これらのアイディアを活用すれば、GetTickCount64関数を使って、時間を正確に管理し、トレード戦略の効率や精度を向上させることができます。