恥は/dev/nullへ by 初心者

プログラミング素人がのろのろと学んだことをつづっています♪

3市場の現地時刻を表示するインディケーター

【追記】

初めてこの記事をアップした当時はロンドンやニューヨークがサマータイム期間かどうかをパラメーターで指定する仕様になっていましたが、その後、サマータイム期間かどうかを調べる関数を作成したので、このインディケーターにもその関数を組み込みました。

この結果、サマータイム期間かどうかを指定するパラメーターは除去しました。

【追記 ここまで】 


 

ネット上に3市場の現在時刻を表示するインディケーターがありました。

裁量トレードをやっている時に便利そうだなと思った一方で、フォント、表示色、文字サイズなどを自分好みにしたかったので、自分で作ってみました。

 

スクリーンショット

f:id:philojuan:20201102183654p:plain

 

ロンドンのサマータイム期間は10月最後の日曜日までですが、ニューヨークのサマータイム期間は11月最初の日曜日までです。このため、ニューヨークだけサマータイムという期間が10月の末に存在します。

その期間は以下のようになります(実際の画像)。

f:id:philojuan:20201103091625p:plain

 

 

コード

//------------------------------------------------------------------
//  FileName : ShowMarketTimes.mq4
//------------------------------------------------------------------
#property copyright "Copyright 2020, PHILOJUAN"
#property link      "https://uhoho.hatenablog.jp/"
#property version   "1.00"
#property strict
#property indicator_chart_window

input color mtColor = C'227, 2, 132'; // 表示色
input int fontsize  = 12;             // フォントサイズ
input int ctXdis    = 440;            // 表示位置(X軸)
input int ctYdis    = 2;              // 表示位置(Y軸)

// 時差用変数
datetime LondonOffset, NYOffset;

// 都市名
string LonLabel = "LON ";
string NYLabel  = "NY ";

// サマータイム期間
bool LondonSummerTime = false;
bool NYSummerTime     = false;

int OnInit()
{
    EventSetTimer(1);

    // ロンドンがサマータイムならtrueを代入
    LondonSummerTime = LondonIsSummerTime(TimeLocal(), 9, false);

    // NYがサマータイムならtrueを代入
    // 引数2と引数3は省略(デフォルト値が使われる)
    NYSummerTime     = NewYorkIsSummerTime(TimeLocal(), 9, false);

    // ロンドンがサマータイムの時
    if(LondonSummerTime)
    {
        LondonOffset = 28800;   // 時差を28800秒にする
        LonLabel  = "LON_Sum "; // 都市名を LON_Sum にする
    }
    // ロンドンがサマータイムではない時
    else
    {
        LondonOffset = 32400; // 時差を32400秒にする
        LonLabel  = "LON ";   // 都市名を LON にする(パラメーター変更時等を考慮)
    }

    // ニューヨークがサマータイムの時
    if(NYSummerTime)
    {
        NYOffset = 46800;     // 時差を46800秒にする
        NYLabel  = "NY_Sum "; // 都市名を NY_Sum にする
    }
    // ニューヨークがサマータイムではない時
    else
    {
        NYOffset = 50400;    // 通常の時差は50400秒
        NYLabel  = "NY ";    // 都市名を NY にする(パラメーター変更時等を考慮)
    }

    return(INIT_SUCCEEDED);
}

int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
{
    return(rates_total);
}

void OnTimer()
{
    // 3市場の時刻
    datetime TokyoTime  = TimeLocal(); // 東京時刻を基準とする
    datetime LondonTime = TokyoTime - LondonOffset;
    datetime NYTime     = TokyoTime - NYOffset;

    string marketTimes = "TKY "   + IntegerToString(TimeHour(TokyoTime))  + ":" + IntegerToString(TimeMinute(TokyoTime), 2, '0')  + "   "
                         + LonLabel + IntegerToString(TimeHour(LondonTime)) + ":" + IntegerToString(TimeMinute(LondonTime), 2, '0') + "   "
                         + NYLabel  + IntegerToString(TimeHour(NYTime))     + ":" + IntegerToString(TimeMinute(NYTime), 2, '0');

    ObjectDelete(0, "ShowMarketTimes");
    MakeLabel("ShowMarketTimes", ctXdis, ctYdis, 20, 25);
    ObjectSetText("ShowMarketTimes", marketTimes, fontsize, "Arial Rounded MT Bold", mtColor);

}

void OnDeinit(const int reason)
{
    EventKillTimer();
    ObjectDelete(0, "ShowMarketTimes");
}

//--------------------------------------------------------------------------
// ラベル作成関数
//--------------------------------------------------------------------------
void MakeLabel(string objName,   // ラベルオブジェクトの名前
               int xDistance,    // ラベル配置位置の起点(X軸)
               int yDistance,    // ラベル配置位置の起点(Y軸)
               int xSize,        // ラベルのサイズ(横)
               int ySize         // ラベルのサイズ(縦)
              )
{
    ObjectCreate(objName, OBJ_LABEL, 0, 0, 0);
    ObjectSet(objName, OBJPROP_CORNER, CORNER_LEFT_UPPER);
    ObjectSet(objName, OBJPROP_XDISTANCE, xDistance);
    ObjectSet(objName, OBJPROP_YDISTANCE, yDistance);
    ObjectSet(objName, OBJPROP_XSIZE, xSize);
    ObjectSet(objName, OBJPROP_YSIZE, ySize);
    ObjectSet(objName, OBJPROP_SELECTABLE, false);
    ObjectSet(objName, OBJPROP_HIDDEN, true);
}

//--------------------------------------------------------------------------
// ロンドンがサマータイム期間か調べる関数
//--------------------------------------------------------------------------
// [説明]
//   引数として指定したローカル日時が英国のサマータイム期間ならtrueを返す。
//   サマータイム期間でない場合はfalseを返す。
// [引数]
//   第1引数:ローカル日時
//            【引数の例】TimeLocal()
//   第2引数:ローカル時間とUTCとの時差
//            【引数の例】日本時間は「UTC +9:00」なので、第2引数は 9
//   第3引数:サマータイムの開始日時と終了日時をエキスパートに表示する
//            【引数の例】表示するならtrue、表示しないならfalse
//--------------------------------------------------------------------------
bool LondonIsSummerTime(datetime localTime, int offset, bool printDate)
{
    datetime currentUTC = localTime - (offset * 3600);  // 1時間は3600秒
    
    string thisYear = IntegerToString(TimeYear(currentUTC));

    datetime March31 = StringToTime(thisYear + ".03.31 01:00");

    int dayOfMarch31 = TimeDayOfWeek(March31);

    int diffFromSun = 0;

    if(dayOfMarch31) diffFromSun = dayOfMarch31 * 86400;

    datetime MarchLastSun = March31 - diffFromSun;

    // チェック用
    if(printDate) printf("ロンドンサマータイム開始日時(UTC時刻): " + TimeToStr(MarchLastSun));
    
    // エラーチェック用コード
    if(TimeDayOfWeek(MarchLastSun)) Alert("ERROR: MarchLastSun is not Sunday!");

    datetime Oct31 = StringToTime(thisYear + ".10.31 01:00");

    int dayOfOct31 = TimeDayOfWeek(Oct31);

    if(dayOfOct31) diffFromSun = dayOfOct31 * 86400;
    else diffFromSun = 0; // 3月の計算でこの変数を使っているので上書きが必要

    datetime OctLastSun = Oct31 - diffFromSun;

    // チェック用
    if(printDate) printf("ロンドンサマータイム終了日時(UTC時刻): " + TimeToStr(OctLastSun));

    // エラーチェック用コード
    if(TimeDayOfWeek(OctLastSun)) Alert("ERROR: OctLastSun is not Sunday!");

    bool res = false;

    if(currentUTC >= MarchLastSun && currentUTC < OctLastSun){
        res = true;
    }

    return res;
}

//--------------------------------------------------------------------------
// NYがサマータイム期間か調べる関数
//--------------------------------------------------------------------------
// [説明]
//   引数として指定したローカル日時が、NYのサマータイム期間ならtrueを返す。
//   サマータイム期間でない場合はfalseを返す。
// [引数]
//   第1引数:ローカル日時
//            【引数の例】TimeLocal()
//   第2引数:ローカル時間とUTCとの時差
//            【引数の例】日本時間は「UTC +9:00」なので、第2引数は 9
//   第3引数:サマータイムの開始日時と終了日時をエキスパートに表示する
//            【引数の例】表示するならtrue、表示しないならfalse
//--------------------------------------------------------------------------
bool NewYorkIsSummerTime(datetime localTime, int offset, bool printDate)
{
    datetime currentUTC = localTime - (offset * 3600);  // 1時間は3600秒
    
    string thisYear = IntegerToString(TimeYear(currentUTC));

    datetime MarchFirst = StringToTime(thisYear + ".03.01 07:00");

    int dayOfMarchFirst = TimeDayOfWeek(MarchFirst);

    int diffFromSun = 0;
    
    if(dayOfMarchFirst) diffFromSun = (14 - dayOfMarchFirst) * 86400;
    else diffFromSun = 7 * 86400;

    datetime MarchSecondSun = MarchFirst + diffFromSun;

    // チェック用
    if(printDate) printf("NYサマータイム開始日時(UTC時刻): " + TimeToStr(MarchSecondSun));
    
    // エラーチェック用コード
    if(TimeDayOfWeek(MarchSecondSun)) Alert("ERROR: MarchSecondSun is not Sunday!");

    datetime NovFirst = StringToTime(thisYear + ".11.01 06:00");

    int dayOfNovFirst = TimeDayOfWeek(NovFirst);

    diffFromSun = 0; // 3月第2日曜日の処理にこの変数を使っているのでリセット
    if(dayOfNovFirst) diffFromSun = (7 - dayOfNovFirst) * 86400;

    datetime NovFirstSun = NovFirst + diffFromSun;

    // チェック用
    if(printDate) printf("NYサマータイム終了日時(UTC時刻): " + TimeToStr(NovFirstSun));

    // エラーチェック用コード
    if(TimeDayOfWeek(NovFirstSun)) Alert("ERROR: NovFirstSun is not Sunday!");

    bool res = false;

    if(currentUTC >= MarchSecondSun && currentUTC < NovFirstSun){
        res = true;
    }

    return res;
}