Bars関数の働き・役割
Bars関数は、指定された銘柄と期間の履歴内のバーの数を返すために使用されます。この関数は2つの形式で呼び出すことができます。
1つ目は履歴内のすべてのバーをリクエストする場合、2つ目は選択された時間間隔内のバーをリクエストする場合です。バーの数を取得することで、過去の価格データを分析し、トレード戦略の検証やインジケータ(指標)の計算に役立てることができます。
Bars関数の引数について
Bars関数の引数は以下の通りです。この関数は2つの書式を持つオーバーロード関数です。
書式1
int Bars(
string symbol_name, // 銘柄名
ENUM_TIMEFRAMES timeframe // 期間
);
symbol_name
銘柄名を指定します。例えば、”EURUSD”や”GBPJPY”などのシンボル(特定の文字や記号)を指定します。
timeframe
時間枠を指定します。ENUM_TIMEFRAMES列挙型を使用し、M1(1分足)やD1(日足)などの期間を指定します。
書式2
int Bars(
string symbol_name, // 銘柄名
ENUM_TIMEFRAMES timeframe, // 期間
datetime start_time, // 開始日付と時刻
datetime stop_time // 終了日付と時刻
);
symbol_name
銘柄名を指定します。書式1と同様にシンボルを指定します。
timeframe
時間枠を指定します。書式1と同様にENUM_TIMEFRAMES列挙型を使用します。
start_time
履歴内の最初のバーの時刻を指定します。dateTime型で日付と時刻を指定します。
stop_time
履歴内の最後のバーの時刻を指定します。dateTime型で日付と時刻を指定します。
Bars関数の戻り値について
Bars関数は、指定された条件に基づいてバーの数を返します。戻り値の内容は、指定する引数によって異なります。
書式1の戻り値
指定された銘柄と期間の全履歴内のバーの数を返します。戻り値はint型で、履歴内のバーの総数を表します。
書式2の戻り値
指定された銘柄と期間、および開始日付と終了日付の範囲内のバーの数を返します。戻り値はint型で、指定された時間間隔でのバーの総数を表します。
Bars関数を使う際の注意点
Bars関数を呼び出す前に、指定されたパラメータに基づいた時系列データが端末に存在しているかどうかを確認する必要があります。時系列データが端末に存在しない場合、Bars関数はゼロを返します。この場合、取引サーバとデータが同期されていない可能性があります。
また、指定した範囲の日付でバーの数をリクエストする際には、その範囲に含まれる開始時刻のバーのみがカウントされます。例えば、週足バーの数をリクエストする場合、指定した範囲の開始時刻が週の開始時刻(日曜日)でなければ、正しい結果が得られないことがあります。この点に注意して、範囲を指定する必要があります。
Bars関数を使って特定の範囲のバーの数を取得する際、start_timeとstop_timeの指定が適切でないと、期待した結果が得られない場合があります。具体的には、取引が行われない期間(例えば、週末や祝日など)を範囲に含めると、バーの数がゼロになることがあります。
最後に、Bars関数の呼び出し後、データの同期状況を確認するために、SeriesInfoInteger関数を使用して、SERIES_SYNCHRONIZEDフラグをチェックすることが推奨されます。これにより、データが完全に同期されているかどうかを確認し、信頼性の高い結果を得ることができます。
Bars関数を使ったサンプルコード
以下に、Bars関数を使用して履歴内のバーの数を取得するサンプルコードを示します。
// OnStart関数はスクリプトの実行が開始されたときに自動的に呼び出されます
void OnStart()
{
// 銘柄名と期間を指定して、履歴内の全てのバーの数を取得します
int bars = Bars(_Symbol, _Period);
// 取得したバーの数が0より大きいかをチェックします
if(bars > 0)
{
// 端末の履歴内のバーの数をエキスパートログに出力します
Print("現在のシンボル-期間の履歴内のバーの数 = ", bars);
}
else // バーが存在しない場合
{
// 銘柄のデータがサーバ上のデータと同期されていない可能性があるため、同期を試みます
bool synchronized = false; // 同期完了フラグ
int attempts = 0; // 試行回数カウンタ
// 最大5回の試行で同期を待ちます
while(attempts < 5)
{
// SERIES_SYNCHRONIZEDフラグを使用して同期完了を確認します
if(SeriesInfoInteger(Symbol(), 0, SERIES_SYNCHRONIZED))
{
// 同期完了。フラグを立ててループを終了します
synchronized = true;
break;
}
// 試行回数を増加させます
attempts++;
// 次の試行まで10ミリ秒待機します
Sleep(10);
}
// 同期が完了したかどうかをチェックします
if(synchronized)
{
// 端末の履歴内のバーの数を再度エキスパートログに出力します
Print("現在のシンボル-期間の履歴内のバーの数 = ", Bars(_Symbol, _Period));
// 履歴内の最初の日付をエキスパートログに出力します
Print("現在のシンボル-期間の履歴内の最初の日付 = ", (datetime)SeriesInfoInteger(Symbol(), 0, SERIES_FIRSTDATE));
// サーバ上の履歴内の最初の日付をエキスパートログに出力します
Print("サーバのシンボルの履歴内の最初の日付 = ", (datetime)SeriesInfoInteger(Symbol(), 0, SERIES_SERVER_FIRSTDATE));
}
else
{
// データの同期が実現しなかった場合のエラーメッセージをエキスパートログに出力します
Print("バーの数を取得できませんでした: ", _Symbol);
}
}
}
関数と文法要素の解説
OnStart関数
OnStart関数は、スクリプトが開始されたときに自動的に呼び出される関数です。この関数内にスクリプトのメインロジックを記述します。
Bars関数
Bars関数は、指定された銘柄と期間の履歴内のバーの数を返します。引数として銘柄名と時間枠を指定します。戻り値は履歴内のバーの総数です。
定義済み変数
_Symbolと_Periodは、現在の銘柄名と時間枠を表す定義済み変数です。これらを使用することで、現在アクティブな銘柄と時間枠を簡単に取得できます。
if文とelse文
if文は、条件が真の場合に特定のコードブロックを実行します。else文は、if文の条件が偽の場合に実行されるコードブロックを指定します。このサンプルでは、バーの数が0より大きい場合とそうでない場合の処理を分けています。
Print関数
Print関数は、指定されたメッセージをエキスパートログに出力します。デバッグや情報の確認に使用されます。
SeriesInfoInteger関数
SeriesInfoInteger関数は、指定された時系列データの情報を取得するために使用されます。ここでは、SERIES_SYNCHRONIZEDフラグをチェックしてデータがサーバと同期されているかどうかを確認します。
while文
while文は、条件が真である間、繰り返しコードブロックを実行します。このサンプルでは、最大5回の試行で同期を待つために使用されています。
break文
break文は、ループを強制的に終了するために使用されます。同期が完了した時点でループを終了するために使用されています。
Sleep関数
Sleep関数は、指定されたミリ秒(1/1000秒)数だけスクリプトの実行を一時停止します。ここでは、同期を待つ間に短い待機時間を設けるために使用されています。
インクリメント
インクリメント(attempts++)は、変数の値を1増やす操作です。ここでは、試行回数を増やすために使用されています。
タイプキャスト
タイプキャスト((datetime))は、特定のデータ型に変換する操作です。ここでは、SeriesInfoInteger関数の戻り値をdateTime型に変換して日付として出力しています。
このコードでは、Bars関数を使用して履歴内のバーの数を取得し、その結果に基づいてエキスパートログに出力します。もしバーの数がゼロの場合、データの同期を試み、再度バーの数を取得して出力します。
指定したインターバルでのバーの数をリクエストする例
// OnStart関数はスクリプトの実行が開始されたときに自動的に呼び出されます
void OnStart()
{
// 各種日付をdatetime型で指定します
datetime date1 = D'2016.09.02 23:55'; // 金曜日
datetime date2 = D'2016.09.05 00:00'; // 月曜日
datetime date3 = D'2016.09.08 00:00'; // 木曜日
// 1時間足で特定の期間内のバーの数を取得します
int n = Bars(_Symbol, PERIOD_H1, D'2016.09.02 02:05', D'2016.09.02 10:55');
// 取得したバーの数をエキスパートログに出力します
Print("バーの数: ", n); // 『バーの数:8』を出力、2時間バーが含まれ、11時間バーは含まれません
// 日足で特定の期間内のバーの数を取得します
n = Bars(_Symbol, PERIOD_D1, date1, date2);
// 取得したバーの数をエキスパートログに出力します
Print("バーの数: ", n); // 『バーの数:1』を出力、範囲内に1つの日足バー(月曜日のもの)の開始時刻のみ入っている為
// 週足で特定の期間内のバーの数を取得します
n = Bars(_Symbol, PERIOD_W1, date2, date3);
// 取得したバーの数をエキスパートログに出力します
Print("バーの数: ", n); // 『バーの数:0』を出力、範囲内に1つの日足バーの開始時刻も入らなかった為
}
関数と文法要素の解説
このサンプルコードでは、Bars関数を使用して特定の期間内のバーの数を取得し、その結果をエキスパートログに出力します。以下に、各部分の挙動と出力内容について説明します。
日付の指定
まず、dateTime型の変数として特定の日付と時刻を指定しています。この日付は、バーの数を取得する範囲を定義するために使用されます。
1時間足のバーの数を取得
1時間足(H1)の期間内で特定の範囲(2016年9月2日02:05から2016年9月2日10:55)に存在するバーの数を取得します。この場合、取得したバーの数は8です。範囲内に2時間バーが含まれ、11時間バーは含まれていないため、8つのバーが出力されます。
日足のバーの数を取得
日足(D1)の期間内で特定の範囲(2016年9月2日23:55から2016年9月5日00:00)に存在するバーの数を取得します。この場合、取得したバーの数は1です。この範囲内には1つの日足バー(月曜日のバー)の開始時刻のみが含まれているためです。
週足のバーの数を取得
週足(W1)の期間内で特定の範囲(2016年9月5日00:00から2016年9月8日00:00)に存在するバーの数を取得します。この場合、取得したバーの数は0です。この範囲内には週足バーの開始時刻が含まれていないため、バーの数は0となります。
このコードでは、Bars関数を使用して異なる時間枠と期間でバーの数を取得し、各期間内のバーの数をエキスパートログに出力しています。それぞれの結果は、指定した範囲内のバーの数を正確に反映しています。