OriginalTimer.mqhファイルのコード全体記述は以下のようになっています。
//+------------------------------------------------------------------+
//| OriginalTimer.mqh |
//| MQL5ssei |
//| https://mqlinvestmentlab.com/|
//+------------------------------------------------------------------+
#property copyright "MQL5ssei"
#property link "https://mqlinvestmentlab.com/"
#define MINUTES_TO_SECONDS 60 // 1分を秒に変換する定数(60秒)
#define HOURS_TO_SECONDS 3600 // 1時間を秒に変換する定数(3600秒)
#define DAYS_TO_SECONDS 86400 // 1日を秒に変換する定数(86400秒)
#define WEEKS_TO_SECONDS 604800 // 1週間を秒に変換する定数(604800秒)
//タイマーセグメントを管理するための構造体
struct TimerSegment
{
bool enabled; // タイマーセグメントが有効かどうかを示すフラグ
int start_day; // タイマー開始日(0=日曜、1=月曜、...、6=土曜)
int start_hour; // タイマー開始時(0~23の間で指定)
int start_min; // タイマー開始分(0~59の間で指定)
int end_day; // タイマー終了日(0=日曜、1=月曜、...、6=土曜)
int end_hour; // タイマー終了時(0~23の間で指定)
int end_min; // タイマー終了分(0~59の間で指定)
};
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
class OriginalCNewBar
{
private:
datetime TimeArray[], //現在の時間を格納
LastTimeVar;//直近にチェックした時間
public:
void OriginalCNewBar();//配列「TimeArray」に時系列セットを施すコンストラクタ
//新しいバーがオープンした瞬間かどうかをチェックする
bool CheckNewBar(string parSymbol, ENUM_TIMEFRAMES parTimeframe);
};
//+------------------------------------------------------------------+
//コンストラクタOriginalCNewBarの処理実装記述
void OriginalCNewBar::OriginalCNewBar(void)
{
ArraySetAsSeries(TimeArray,true);//配列「TimeArray」を時系列にセットする
}
// 新しいバーがオープンしたかどうかをチェックするメンバ関数の実装
bool OriginalCNewBar::CheckNewBar(string parSymbol, ENUM_TIMEFRAMES parTimeframe)
{
// 初回実行かどうかを判定するフラグ
bool firstExe = false;
// 新しいバーがオープンしたかどうかを示すフラグ
bool newBarOpen = false;
// 指定されたシンボルと時間枠の現在と一つ前のバーの時間をTimeArrayにコピー
CopyTime(parSymbol, parTimeframe, 0, 2, TimeArray);
// LastTimeVarが0の場合、これが初回実行と判断
if(LastTimeVar == 0)
firstExe = true;
// TimeArrayの最新の時間がLastTimeVarより大きい場合、新しいバーと判断
if(TimeArray[0] > LastTimeVar)
{
// 初回実行ではない場合、newBarフラグをtrueに設定
if(firstExe == false)
newBarOpen = true;
// 最後にチェックしたバーのオープン時間を更新
LastTimeVar = TimeArray[0];
}
// 新しいバーの有無を返す
return(newBarOpen);
}
// 日付時間値を生成する関数
datetime GenerateTimestamp(int newHour = 0, int newMinute = 0)
{
MqlDateTime dateTimeDetails; // MqlDateTime構造体を使用して日時データを保存するための変数
TimeToStruct(TimeCurrent(), dateTimeDetails); // 現在のサーバーの時間を取得し、dateTimeDetails構造体に代入
dateTimeDetails.hour = newHour; // 時間を新しい値に設定
dateTimeDetails.min = newMinute; // 分を新しい値に設定
datetime constructedTime = StructToTime(dateTimeDetails); // MqlDateTime構造体値をdatetime値に変換
return(constructedTime); // 変換したdatetime値を返す
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
class CTradeSession
{
private:
//トレード開始時間と終了時間を格納する
datetime SessionStartTime, SessionEndTime;
//トレードタイマーのオンオフ状態を格納
bool timerStartedFlag ;
//トレードタイマーのオンオフ状態をチャートとエキスパートログに表示する関数
void DisplayTimerStatus(bool parTimerState);
public:
// 取引セッションがアクティブかどうかをチェックする関数
bool IsActive(datetime openTime, datetime closeTime, bool useLocalTime = false);
//毎日のトレードタイマーを作成する関数
bool DailySessionTimer(int parStartHour, int parStartMinute, int parEndHour, int parEndMinute, bool parLocalTime = false);
// 複数の取引時間帯を設定する関数
bool SegmentTimer(TimerSegment &parSegment[], bool parLocalTime=false);
//取引開始時間を確認する関数
datetime GetSessionStartTime() {return(SessionStartTime);};
//取引終了時間を確認する関数
datetime GetSessionEndTime() {return(SessionEndTime);};
};
// SegmentTimer
bool CTradeSession::SegmentTimer(TimerSegment &parSegment[], bool parLocalTime=false)
{
MqlDateTime today; // 現在の日時を格納するための変数
bool timerOn = false; // タイマーがオンかどうかを保持するフラグ
int timerCount = ArraySize(parSegment); // 渡されたタイマーセグメントの配列サイズを取得
for(int i = 0; i < timerCount; i++) // 各タイマーセグメントについてループ
{
if(parSegment[i].enabled == false)
continue; // タイマーセグメントが有効でなければ、次のループへ
SessionStartTime = GenerateTimestamp(parSegment[i].start_hour, parSegment[i].start_min); // 開始時間を設定
SessionEndTime = GenerateTimestamp(parSegment[i].end_hour, parSegment[i].end_min); // 終了時間を設定
TimeToStruct(SessionStartTime,today); // 開始時間を構造体に変換
int dayShift = parSegment[i].start_day - today.day_of_week;
// 開始曜日と現在の曜日との差を計算
if(dayShift != 0)
SessionStartTime += DAYS_TO_SECONDS * dayShift;
// 開始曜日が今日と異なれば、適切な曜日に調整
TimeToStruct(SessionEndTime,today); // 終了時間を構造体に変換
dayShift = parSegment[i].end_day - today.day_of_week;
// 終了曜日と現在の曜日との差を計算
if(dayShift != 0)
SessionEndTime +=DAYS_TO_SECONDS * dayShift;
// 終了曜日が今日と異なれば、適切な曜日に調整
timerOn = IsActive(SessionStartTime,SessionEndTime,parLocalTime); // 設定された時間内かどうかをチェック
if(timerOn == true)
break; // 一つでも条件を満たすタイマーセグメントがあればループを抜ける
}
DisplayTimerStatus(timerOn); // タイマーの状態に応じてメッセージを出力
return(timerOn); // タイマーがオンかどうかの結果を返す
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CTradeSession::DisplayTimerStatus(bool parTimerState)
{
// parTimerStateがtrueで、かつtimerStartedFlagがfalseの場合、タイマーが開始されたことを示す。
if(parTimerState == true && timerStartedFlag == false)
{
string message = "タイマー開始"; // "タイマー開始"を代入
Print(message); // メッセージをエキスパートログに出力
Comment(message); // メッセージをチャートに表示
timerStartedFlag = true; // timerStartedFlagをtrueに設定して、タイマーが開始されたことを記録
}
else
if(parTimerState == false && timerStartedFlag == true) // parTimerStateがfalseで、かつtimerStartedFlagがtrueの場合、タイマーが停止したことを示す。
{
string message = "タイマー停止"; // "タイマー停止"を代入
Print(message); // メッセージをエキスパートログに出力
Comment(message); // メッセージをチャートに表示
timerStartedFlag = false; // timerStartedFlagをfalseに設定して、タイマーが停止されたことを記録
}
}
// 取引セッションがアクティブかどうかをチェックする関数の実装
bool CTradeSession::IsActive(datetime openTime, datetime closeTime, bool useLocalTime = false)
{
// 開始時間が終了時間より後であるかどうかを確認
if(openTime >= closeTime)
{
// 開始時間と終了時間が不正である場合、警告メッセージを出力して処理を中止
Alert("エラー:開始時間または終了時間が不正です");
return false; // 不正な時間設定のため、falseを返す
}
// 現在時刻を取得する
datetime currentTime;
//ローカル時間を使うかどうかのチェック
if(useLocalTime == true)
currentTime = TimeLocal();
else
currentTime = TimeCurrent();
// 現在時刻が開始時間と終了時間の範囲内かどうかをチェック
bool timerOn = false; // タイマーがオンかどうかのフラグを初期化
if(currentTime >= openTime && currentTime < closeTime)
{
// 現在時刻が指定された時間範囲内にある場合、タイマーをオンにする
timerOn = true;
}
return timerOn; // タイマーの状態を返す
}
// Daily timer
bool CTradeSession::DailySessionTimer(int parStartHour, int parStartMinute, int parEndHour, int parEndMinute, bool parLocalTime=false)
{
// 現在の時間を取得
datetime currentTime;
if(parLocalTime == true)
currentTime = TimeLocal(); // ローカル時間を使用
else
currentTime = TimeCurrent(); // サーバー時間を使用
// セッションの開始時間を設定
SessionStartTime = GenerateTimestamp(parStartHour,parStartMinute);
// セッションの終了時間を設定
SessionEndTime = GenerateTimestamp(parEndHour,parEndMinute);
// セッションの終了時間が開始時間より前に設定されている場合、終了時間を調整する
if(SessionEndTime <= SessionStartTime)
{
SessionStartTime -= DAYS_TO_SECONDS; // 開始時間を1日分マイナスする
// 現在時刻が終了時間を過ぎていた場合、開始時間と終了時間を次の日にずらす
if(currentTime > SessionEndTime)
{
SessionStartTime += DAYS_TO_SECONDS;
SessionEndTime += DAYS_TO_SECONDS;
}
}
// セッションがアクティブかどうかを判断
bool timerOn = IsActive(SessionStartTime, SessionEndTime, parLocalTime);
// タイマーの状態を出力
DisplayTimerStatus(timerOn);
// タイマーがオンかオフかの状態を返す
return(timerOn);
}
//+------------------------------------------------------------------+