トップ  >  ダウンロード  >  インジケータ  >  EA_EconomicDataRequest_TWEB(チャート上に経済指標表示)
スポンサーリンク
検索

↑の検索エンジンが表示されない人は、
↓の古い検索エンジンを使用して下さい。
カスタム検索
MQL4リファレンスツリー
EA_EconomicDataRequest_TWEB(チャート上に経済指標表示)

注意事項:
自動売買を行うEAや売買シグナルのソフトウェアの配布は行っておりません。
このページにあるのは管理人が自作した便利関数やインジケータです。
ソースコードも公開していますので、ご自由にカスタマイズして下さい。
その代わりどんな不具合があっても私は責任を負いません。


EA_EconomicDataRequest_TWEB.ex4 / .ex5
IND_EconomicDisplay.ex4 / .ex5



トレーダーズウェブFXサイトの市場カレンダーhttps://www.traderswebfx.jp/calendar/から
経済指標データを動的取得し、チャート上に直近の指標を表示します。



スレッドの関係で、Webサイトから経済指標データ取得はEA(EA_EconomicDataRequest_TWEB.ex4 / .ex5)で行い、CSVファイルを作成します。

チャート上に指標を表示するのはインジケータ(IND_EconomicDisplay.ex4 / .ex5)が行います。
インジケータはCSVファイルから指標データを取得してチャート上に表示します。

その為、EA(EA_EconomicDataRequest_TWEB.ex4 / .ex5)は必ず1つ動作させておく必要があります。
EAはCSVファイルを作成するだけですので、2つ以上動作させる必要はありませんし自動売買を許可する必要もありません。




正常動作している場合は、以下のようなCSVファイルが生成されます。


またインジケータ(IND_EconomicDisplay.ex4 / .ex5)にはパラメータを用意してあります。
FX業者によって異なるタイムゾーンの設定を選択出来る様にしてあります。
この設定が合っていないとチャート上に表示される時間がズレます。

表示フォントサイズの設定は、チャート上に表示される指標のフォントサイズに影響します。




注意事項:
2019/8/8にデータ取得先のTrader'S WEBのHTMLが変更され、jQueryを用いて経済指標が表示されるようになった為、
経済指標のソースコード取得が出来なくなりました。
修正対応しようが無い為、今後修正対応する予定はありません。
もしかしたら別サイトからデータ取得して新たにプログラム作成するかもしれませんが、その予定も未定です。
ソースコードはダウンロード出来るまま残しますので、ソースコードを参考にして各自作成して下さい。

EA_EconomicDataRequest_TWEB.ex4が行っていた処理を、 VisualStudioかPythonでTrader'S WEBのサイト情報をスクレイピングするプログラムを作れば使えると思うので、 チャレンジしてみて下さい。


(情報ソースからデータ取得出来なくなった為、使用出来ません。2019年8月8日)

変更履歴(EA)
Ver 変更内容
1.01 スペイン指標対応
1.02 アルゼンチン・ポーランド・ウクライナ指標対応
1.03 MQL5対応
1.04 スェーデン対応
1.05 新HTML対応

変更履歴(IND)
Ver 変更内容
1.01 バー表示数が少ない時に時系列配列外アクセスする不具合修正
1.02 MQL5対応
1.03 MQL5対応による時系列配列アクセス変更で発生した範囲外アクセス不具合修正
1.04 指標表示の背面オブジェクト再描画処理追加(MT4のみ)
1.05 指標表示範囲を16⇒48時間に拡大。
1.06 指標時間が未確定でも表示するように変更
1.07 新HTML対応






過去の問い合わせ内容


Q.インジケータIND_EconomicDisplay.ex4がチャート上に表示できません。バグ不具合みたいです。
A.まず、EA_EconomicDataRequest_TWEB.ex4を動作させて、csvファイルを生成させます。
データフォルダ\MQL4\FilesにEcoInfo.csvが生成されている事を確認して下さい。
csvファイルが正しく生成された場合は、


というメッセージが表示されます。

IND_EconomicDisplay.ex4はEcoInfo.csvからデータ取得して指標データを表示させている為、csvファイルが無い場合は表示されません。
また指標データは現在時刻から過去7200バー分までしか表示しない為、最後の終値がマーケットクローズから2日経過(1分足の場合)している場合は表示されません。
上記の理由から、バックテスト中も現在時刻から過去7200バー分までしか表示しない為、バックテスト中は基本的に動作しないものとお考え下さい。
それからチャートのヒストリカルデータが過去7200バー分存在しない場合は表示されません。

ソースコード


MQL4を勉強し始めた初期の頃に作成したもので、元々公開するつもりが無かったソースコードなので、可読性がかなり悪いです。
公開するにあたりコメント追記しましたが、元々適当に作成した物なので参考にならないかもしれません。

ソースコード:
EA_EconomicDataRequest_TWEB.mq4.mq4
//+------------------------------------------------------------------+
//|                                  EA_EconomicDataRequest_TWEB.mq4 
//|                                 Copyright 2015, Created by Yuki. 
//|                                       http://yukifx.web.fc2.com/ 
//|―――――――――――――――――――――――――――――――――|
//|処理概要:Webサイトから指標データを取得し、Filesフォルダに保存する
//+------------------------------------------------------------------+
//| date:        Ver:    detail
//| 15/05/30    1.00    new
//| 15/08/27    1.01    !変更    コード置換テーブルにスペイン追加
//| 15/10/20    1.02    !変更    コード置換テーブルにアルゼンチン・ポーランド・ウクライナ追加
//| 15/10/26    1.03    !変更    MQL5対応
//| 16/06/14    1.04    !変更    コード置換テーブルにスウェーデン追加
//| 18/07/26    1.05    !変更    新HTML対応
//|
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, Created by Yuki."
#property link      "http://yukifx.web.fc2.com/"
#property version   "1.03"
#property strict


// プログラムの説明
#property description "トレーダーズWEB FXサイト(http://www.traderswebfx.jp/calendar/)から指標スケジュールデータ(HTMLファイル)を取得し、取得したHTMLファイルをCSVファイルに変換出力します。"
#ifdef    __MQL4__
    #property description "ファイルは\"データフォルダ\\MQL4\\Files\"に保存されます。フォルダが読み取り専用になっている場合はエラーになります。"
#else
    #property description "ファイルは\"データフォルダ\\MQL5\\Files\"に保存されます。フォルダが読み取り専用になっている場合はエラーになります。"
#endif
#property description "このプログラムはEA用です。スレッドの関係でEAプログラムで作成していますが、自動売買は行いません。"

#include    <local\\local_errorcode_jp.mqh>                                        // エラーコード詳細を日本語で出力する

#define        ECONOMIC_WEBSITE_ADDRESS    "http://www.traderswebfx.jp/calendar/"    // Webサイトアドレス
#define        ECO_SAVE_FILENAME            "EcoInfo.html"                            // 取得したHTMLファイル名
#define        ECO_CSV_FILENAME            "EcoInfo.csv"                            // 出力するCSVファイル名


#define ReplaceWordIndex    0
#define SerchWordIndex        1

// コード置換テーブル(上から順に置換する)
const string ReplaceCodeTable[][2] = {
    // 時刻表記無し
     { ",,"        ,"<td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td>"}
    // 国名
    ,{"乳)"    ,"<td class=\"countryicon\"><img src=\"/images/common/icon_newzealand.png\"/>"}
    ,{"英)"    ,"<td class=\"countryicon\"><img src=\"/images/common/icon_uk.png\"/>"}
    ,{"南)"    ,"<td class=\"countryicon\"><img src=\"/images/common/icon_southafrica.png\"/>"}
    ,{"欧)"    ,"<td class=\"countryicon\"><img src=\"/images/common/icon_eu.png\"/>"}
    ,{"米)"    ,"<td class=\"countryicon\"><img src=\"/images/common/icon_america.png\"/>"}
    ,{"加)"    ,"<td class=\"countryicon\"><img src=\"/images/common/icon_canada.png\"/>"}
    ,{"独)"    ,"<td class=\"countryicon\"><img src=\"/images/common/icon_germany.png\"/>"}
    ,{"豪)"    ,"<td class=\"countryicon\"><img src=\"/images/common/icon_australia.png\"/>"}
    ,{"日)"    ,"<td class=\"countryicon\"><img src=\"/images/common/icon_japan.png\"/>"}
    ,{"土)"    ,"<td class=\"countryicon\"><img src=\"/images/common/icon_turkey.png\"/>"}
    ,{"中)"    ,"<td class=\"countryicon\"><img src=\"/images/common/icon_china.png\"/>"}
    ,{"仏)"    ,"<td class=\"countryicon\"><img src=\"/images/common/icon_france.png\"/>"}
    ,{"希)"    ,"<td class=\"countryicon\"><img src=\"/images/common/icon_eu.png\"/>"}
    ,{"伊)"    ,"<td class=\"countryicon\"><img src=\"/images/common/icon_eu.png\"/>"}
    ,{"瑞)"    ,"<td class=\"countryicon\"><img src=\"/images/common/icon_swiss.png\"/>"}
    ,{"西)"    ,"<td class=\"countryicon\"><img src=\"/images/common/icon_eu.png\"/>"}
    ,{"典)"    ,"<td class=\"countryicon\"><img src=\"/images/common/icon_sweden.png\"/>"}
    // 略名の無い国
    ,{"ア)"    ,"<td class=\"country\">アルゼンチン"}
    ,{"ポ)"    ,"<td class=\"country\">ポーランド"}
    ,{"ウ)"    ,"<td class=\"country\">ウクライナ"}
    ,{"メ)"    ,"<td class=\"country\">メキシコ"}
    ,{"ブ)"    ,"<td class=\"country\">ブラジル"}
    ,{"ノ)"    ,"<td class=\"country\">ノルウェー"}
    // HTMLフォーマット変更で追加された項目
    ,{"南)"    ,"<td class=\"country\">南アフリカ"}
    ,{"日)"    ,"<td class=\"country\">日本"}
    ,{"豪)"    ,"<td class=\"country\">オーストラリア"}
    ,{"英)"    ,"<td class=\"country\">英国"}
    ,{"米)"    ,"<td class=\"country\">米国"}
    ,{"独)"    ,"<td class=\"country\">ドイツ"}
    ,{"欧)"    ,"<td class=\"country\">ユーロ"}
    ,{"加)"    ,"<td class=\"country\">カナダ"}
    ,{"仏)"    ,"<td class=\"country\">フランス"}
    ,{"香)"    ,"<td class=\"country\">香港"}
    ,{"シ)"    ,"<td class=\"country\">シンガポール"}
    ,{"土)"    ,"<td class=\"country\">トルコ"}
    ,{"乳)"    ,"<td class=\"country\">ニュージーランド"}
    ,{"典)"    ,"<td class=\"country\">スウェーデン"}
    ,{"露)"    ,"<td class=\"country\">ロシア"}
    ,{"瑞)"    ,"<td class=\"country\">スイス"}
    ,{"中)"    ,"<td class=\"country\">中国"}
    ,{"印)"    ,"<td class=\"country\">インド"}
    // セパレート
    ,{"日,"    ,"日</td><td>"}
    ,{""    ,"<td class=\"forecast\">"}
    ,{""    ,"<td class=\"result\">"}
    // トップヘッダ
    ,{""    ,"<th class=\"date\">発表日</th>"}
    ,{""    ,"<th class=\"time\">時間</th>"}
    ,{""    ,"<th class=\"countryicon\"></th>"}
    ,{""    ,"<th class=\"country\">国名</th>"}
    ,{""    ,"<th class=\"index\">指標名</th>"}
    ,{""    ,"<th class=\"forecast\">予想</th>"}
    ,{""    ,"<th class=\"result\">前回の結果</th>"}
    ,{""    ,"<th class=\"result\">結果</th>"}
    // ヘッダ
    ,{""    ,"<th class=\"date\">"}
    ,{""    ,"<th class=\"time\">"}
    ,{""    ,"<td class=\"countryicon\">"}
    ,{""    ,"<th class=\"countryicon\">&nbsp;</th><th class=\"country\">国名</th><th class=\"index\">"}
    ,{""    ,"<th class=\"forecast\">"}
    ,{""    ,"<th class=\"result\">"}
    // HTMLコード
    ,{""    ,"<td class=\"index\">"}
    ,{""    ,"&nbsp;"}
    ,{""    ,"</td><td>"}
    ,{""    ,"</td>"}
    ,{""    ,"</th>"}
    ,{""    ,"<tr>"}
    ,{""    ,"<td>"}
};

sinput bool _Debug = false;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit() {
    EventSetTimer(1);

      
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
   EventKillTimer();
}

//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer() {
    
    static int timer_count = 0;
    bool       temp_ret;
    
    temp_ret = false;
    
    if ( timer_count >= ( 3600 * 4 ) ) {            // 4時間に1度データ取得する
        timer_count = 0;
    }

    if ( timer_count <= 0 ) {
        temp_ret = EconomicInfoRequest();   // WebサイトからHTMLデータ取得

        if ( temp_ret == true ) {
            EconomicInfoDataCreate();       // HTMLデータをCSVファイル作成
        }
    }

    timer_count++;
   
}


//+------------------------------------------------------------------+
//| 関数名    :EconomicInfoRequest
//| 概要    :Webサイト(トレーダーズWEB FXサイト)からHTMLソースコードを
//|              取得し、Filesフォルダに保存。
//| 備考    :無し
//| ―――――――――――――――――――――――――――――――――
//| 戻り値    :bool: 失敗時にfalseを返します
//| 引数    :無し
//+------------------------------------------------------------------+
bool EconomicInfoRequest(void) {

    string cookie=NULL,headers;
    char   post[],result[];
    int    res;
    string req_url;
    int    filehandle;
    bool   ret;
    static bool get_success = false;
    static bool ararted     = false;
    
    req_url = ECONOMIC_WEBSITE_ADDRESS;
    ret     = false;

    res = WebRequest( 
                    "GET",      // HTTPメソッド
                    req_url,    // URL
                    cookie,     // cookie
                    NULL,       // リファラ
                    5000,       // タイムアウト
                    post,       // HTTPメッセージ本体
                    0,          // HTTPメッセージサイズ
                    result,     // 応答データ配列
                    headers     // 応答ヘッダ
    );

    
    if( res == -1 ) {// エラーチェック
        Print("WebRequestエラー。",Get_ComErrorCodeStr( GetLastError()) );

        if ( ararted == false ) {
            ararted = true;
            MessageBox(
                        "ターミナルオプションの「エキスパートアドバイザータブ」の設定で\n '"
                        +req_url
                        +"' \nのURLを\n「Allow WebRequest for listed URL」のリストに追加して下さい。"
                        ,"HTTPリクエストエラー"
                        ,MB_ICONINFORMATION);
        }

        get_success = false;

    } else {
        if ( get_success == false ) {
            PrintFormat("Webサイトデータ取得成功。 取得ファイルサイズ =%d [KB]",ArraySize(result)/1024);
        }
        
        filehandle = FileOpen( ECO_SAVE_FILENAME , FILE_WRITE|FILE_BIN);   // 取得データ保存用のファイルを作成
        
        if( filehandle != INVALID_HANDLE) {                               // ファイルハンドラチェック
            FileWriteArray(filehandle,result,0,ArraySize(result));        // 取得データをファイルに書き込み
            FileClose(filehandle);                                        // ファイルハンドラ解放
            ret = true;
            get_success = true;
        } else {
            Print("FileOpenエラー。 ",Get_ComErrorCodeStr( GetLastError()) );
        }
    }
    
    return ret;
}


//+------------------------------------------------------------------+
//| 関数名    :EconomicInfoDataCreate
//| 概要    :取得したHTMLファイルを開き、指標データのみ抽出する
//| 備考    :無し
//| ―――――――――――――――――――――――――――――――――
//| 戻り値    :bool: 失敗時にfalseを返します
//| 引数    :無し
//+------------------------------------------------------------------+
bool EconomicInfoDataCreate(void) {

    int    filehandle;             // ファイルハンドラ
    bool   ret;
    
    ret        = false;
//    filehandle = FileOpen( ECO_SAVE_FILENAME , FILE_READ | FILE_TXT , 0 , CP_UTF8 );    // HTMLファイルを開く
//    filehandle = FileOpen( ECO_SAVE_FILENAME , FILE_READ | FILE_BIN | FILE_ANSI , 0 , CP_UTF8 );    // HTMLファイルを開く
    filehandle = FileOpen( ECO_SAVE_FILENAME , FILE_READ | FILE_TXT | FILE_ANSI , 0 , CP_UTF8 );    // HTMLファイルを開く


    if( filehandle != INVALID_HANDLE) {                                                    // ファイルハンドラチェック
        EcoFileTrim( filehandle );                                                        // 抽出処理関数を呼ぶ

        FileClose(filehandle);                                                            // ファイルクローズ
        ret = true;
    } else {
        Print("FileOpenエラー。 ",Get_ComErrorCodeStr( GetLastError()) );
    }

    return ret;

}

//+------------------------------------------------------------------+
//| 関数名    :EcoFileTrim
//| 概要    :指定したファイルハンドル(取得したHTMLファイル)から、指標データのみ抽出しCSVファイルを作成する
//| 備考    :無し
//| ―――――――――――――――――――――――――――――――――
//| 戻り値    :無し
//| 引数    :int in_handle:ファイルハンドラ
//+------------------------------------------------------------------+
void EcoFileTrim( int in_handle) {

    ulong data_st,data_ed;      // 指標開始ファイルポンタ、指標衆力ファイルポインタ
    string get_str_array[];     // 抽出したテキストデータ配列

    data_st = SerchWordPointerTXT( in_handle , "<table class=\"scheduletable\">" , 0 , true );    // 指標データ開始ファイルポインタ取得
    data_ed = SerchWordPointerTXT( in_handle , "</table>" , data_st , false );                    // 指標データ終了ファイルポインタ取得


    EcoInfoRowCopy( in_handle , data_st , data_ed , get_str_array); // ファイルから指標データを抽出
    RowDataReplace( get_str_array);                                    // 抽出データをCSV形式に変換
    ReplaceDataFileWrite( get_str_array);                            // 変換したデータをCSVファイルへ出力

}


//+------------------------------------------------------------------+
//| 関数名    :SerchWordPointerTXT
//| 概要    :開いたファイルを指定した文字列で検索し、ファイルポインタを返す
//| 備考    :TXT指定で開いたファイルハンドル用
//| ―――――――――――――――――――――――――――――――――
//| 戻り値    :検索がヒットしたファイルポインタ
//| 引数    :int in_handle                :検索するファイルハンドル
//|         :string in_str                :検索する文字列
//|         :ulong start_pointer        :検索を開始するファイルポインタ位置
//|         :bool afterpoint            :trueの場合、ヒットした文字列の末尾のポインタを戻り値に返す。falseの場合先頭のポインタを返す。
//+------------------------------------------------------------------+
ulong SerchWordPointerTXT( int in_handle , string in_str , ulong start_pointer , bool afterpoint) {

    ulong  file_size;
    uchar  serch_char[];
    ulong  icount;
    bool   tempbool;
    int    strlength;
    string get_str;
    ulong  count_start;
    ulong  ret_pointer;

    file_size = FileSize(in_handle); // ファイルサイズ取得
    strlength = StringLen(in_str);   // 検索文字列の文字数取得
    
    count_start = start_pointer;     // ファイルポインタ検索開始位置調整
    if ( count_start >= file_size ) {
        count_start = file_size;
    }
    if ( count_start < 0 ) {
        count_start = 0;
    }
    ret_pointer = 0;



    for ( icount = count_start; icount < file_size; icount++ ) {      // ファイルの最後まで検索を行う
        tempbool = FileSeek( in_handle, (long)icount ,SEEK_SET );     // ファイルシーク位置変更
        
        if ( tempbool == false ) {                                    // ファイルシーク失敗時は終了
            break;
        }
        
        get_str = FileReadString(in_handle);                        // 変更したシーク位置のテキスト取得


        if ( get_str == in_str ) {                                    // 取得したテキストと検索文字列が一致
            ret_pointer = icount;
            if ( afterpoint == true ) {                                // オプション
                ret_pointer = FileTell(in_handle);                    // 現在(ヒットした文字列の末尾)のファイルポインタを返す
            }
            
            // テスト
            if ( _Debug == true ) {
                FileSeek( in_handle, (long)icount ,SEEK_SET );
                printf( "1:%d,%s" , ret_pointer , FileReadString(in_handle));
//                Print( "1:" + ret_pointer+" "+ FileReadString(in_handle));
                FileSeek( in_handle, (long)ret_pointer ,SEEK_SET );
                printf( "2:%d, %s" , ret_pointer , FileReadString(in_handle));
//                Print( "2:" + ret_pointer+" "+ FileReadString(in_handle));
            }
            
            break;                                                    // 検索文字列がヒットしたら、検索終了
        }
    }
    
    return ret_pointer;

}


//+------------------------------------------------------------------+
//| 関数名    :EcoInfoRowCopy
//| 概要    :取得したHTMLデータから、指標データのみ抽出
//| 備考    :無し
//| ―――――――――――――――――――――――――――――――――
//| 戻り値    :抽出した件数を返す
//| 引数    :int in_handle                :ファイルハンドラ
//|         :ulong fp_st                :抽出開始位置
//|         :ulong fp_ed                :抽出終了位置
//|         :string &in_str_array[]    :出力する文字列配列
//+------------------------------------------------------------------+
int EcoInfoRowCopy( int in_handle , ulong fp_st , ulong fp_ed , string &in_str_array[] ) {

    bool   tempbool;
    string get_str;
    string trim_str;
    int    icount;
    int    gcount;
    long   fp_diff;
    ulong  now_fp;
    
    const int rev_arraysize = 1000;
    gcount = 0;

    
    fp_diff = (long)fp_ed - (long)fp_st;

    if ( fp_diff <= 0 ) {
        printf("【%s】ファイルポインタ取得エラー",__FUNCTION__);
        return gcount;
    }
    
    ArrayResize(in_str_array,1,rev_arraysize);                    // 出力する文字列配列の動的配列領域確保

    tempbool = FileSeek( in_handle, (long)fp_st ,SEEK_SET );    // ファイルポインタを抽出開始位置に設定
    for ( icount = 0; icount < fp_diff; icount++ ) {
        now_fp = FileTell(in_handle);                            // 現在のファイルポインタが抽出終了位置に到達したら終了
        if ( fp_ed <= now_fp ) {
            break;
        }
        
        get_str = FileReadString(in_handle);                    // 現在のファイルポインタから文字列取得
        trim_str = StringTrimLeft(get_str);

        if ( _Debug == true && icount < 20 ) {
            printf( "生データ[%d]%d [%s]=>[%s]" , __LINE__ , icount, get_str , trim_str);
        }

        // 取得した文字列が、HTMLコードのみの場合はスルー
        if ( trim_str != "<tr>" && trim_str != "</tr>" && trim_str != "<tr class=\"odd\">"  ) {
            if ( icount > 10) {    // トップヘッダの10行は書き出ししない
                ArrayResize(in_str_array,gcount+1,rev_arraysize);    // 出力する文字列配列の動的配列領域確保
                in_str_array[gcount] = trim_str;                    // 指標データを動的配列に保存
                gcount++;                                            // 抽出件数をインクリメント
                }
        }
    }

    return gcount;

}


//+------------------------------------------------------------------+
//| 関数名    :RowDataReplace
//| 概要    :抽出した生データをCSV形式に変換
//| 備考    :無し
//| ―――――――――――――――――――――――――――――――――
//| 戻り値    :無し
//| 引数    :string &in_str_array[]:ファイルハンドラ
//+------------------------------------------------------------------+
void RowDataReplace( string &in_str_array[] ) {

    int rowdate_array_max;
    int tabledate_max;
    int icount,ccount;
    string base_str;
    string change_str;
    
    tabledate_max     = ArrayRange(ReplaceCodeTable,0); // 変換テーブルの配列数を取得
    rowdate_array_max = ArrayRange(in_str_array,0);        // 生データの配列数を取得
    
    //テスト
//    Print(tabledate_max, " ",rowdate_array_max );
    
    for ( icount = 0; icount < rowdate_array_max; icount++ ) { // 生データの配列数分繰り返す
        base_str = in_str_array[icount];
        change_str = StringTrimLeft(base_str);
        for ( ccount = 0; ccount < tabledate_max; ccount++ ) { // 変換テーブルの配列数分繰り返す
            // 生データの文字列内に、変換テーブルの文字列があれば置換する
            StringReplace(change_str , ReplaceCodeTable[ccount][SerchWordIndex],ReplaceCodeTable[ccount][ReplaceWordIndex]);
        }
        in_str_array[icount] = change_str;

        if ( _Debug == true && icount < 20 ) {
            printf( "置換[%d]%d [%s] => [%s] / [%s]" , __LINE__ , icount, base_str, in_str_array[icount] , change_str);
        }
    }
}

//+------------------------------------------------------------------+
//| 関数名    :ReplaceDataFileWrite
//| 概要    :CSV形式に変換したデータを、CSVファイルへ出力する
//| 備考    :無し
//| ―――――――――――――――――――――――――――――――――
//| 戻り値    :無し
//| 引数    :string &in_str_array[]:ファイルハンドラ
//+------------------------------------------------------------------+
void ReplaceDataFileWrite( string &in_str_array[] ) {

    int csvhandle;
    int array_max;
    int icount;

    csvhandle = FileOpen(ECO_CSV_FILENAME, FILE_WRITE | FILE_TXT , ',' ,CP_ACP);    // CSVファイルを作成する
    array_max = ArrayRange(in_str_array,0);                                            // 書き込むデータ配列数取得

    if( csvhandle != INVALID_HANDLE) {                                                // ファイルハンドラチェック
        for ( icount = 0; icount < array_max; icount++ ) {                            // 変換したデータを全て書き込む
            FileWriteString( csvhandle , in_str_array[icount]+"\n");
        }
        
        FileClose(csvhandle);                                                        // ファイルハンドラ解放
    } else {
        Print("FileOpenエラー。 ",Get_ComErrorCodeStr( GetLastError()) );
    }
    
}


ソースコード:
IND_EconomicDisplay.mq4
//+------------------------------------------------------------------+
//|                                          IND_EconomicDisplay.mq4 |
//|                                 Copyright 2015, Created by Yuki. |
//|                                       http://yukifx.web.fc2.com/ |
//+------------------------------------------------------------------+
//|処理概要:指標データ(CSVファイル)を取得し、チャート上に表示する
//+------------------------------------------------------------------+
//| date:        Ver:    detail
//| 15/06/01    1.00    new
//| 15/09/21    1.01    !変更    バー表示数が少ない時に時系列配列外アクセスする不具合修正
//| 15/10/26    1.02    !変更    MQL5対応
//| 15/11/12    1.03    !変更    MQL5対応による時系列配列アクセス変更で発生した範囲外アクセス不具合修正
//| 15/12/24    1.04    !変更    指標表示の背面オブジェ追加    EcoDispBackGround_Init
//| 16/01/04    1.05    !変更    指標表示範囲を16⇒48時間に拡大    EcoDetailTodayDisp
//|                        !変更    指標表示の背面オブジェクト再描画処理追加。EcoDispBackGround_Init
//| 16/01/13    1.06    !変更    指標時間が未確定でも表示するように変更。    EcoDetailTodayDisp,EcoFileRead
//| 18/07/26    1.07    !変更    新HTML対応
//|
//+------------------------------------------------------------------+

#property copyright "Copyright 2015, Created by Yuki."
#property link      "http://yukifx.web.fc2.com/"
#property version   "1.06"
#property strict
#property indicator_chart_window

// プログラムの説明
#property description "トレーダーズWEB FXサイト(http://www.traderswebfx.jp/calendar/)から"
#property description "取得した指標スケジュールデータ(CSV変換後のファイル)から、"
#property description "直近の指標データを取得し表示します。"
#property description "\n別途に指標データを取得するEA(EA_EconomicDataRequest_TWEB.mq4)を動作させる必要があります。"

#include    <local\\local_errorcode_jp.mqh>                                      // エラーコード詳細を日本語で出力する
#include    <local\\local_common_jpntime.mqh>                                    // タイムサーバー調整


#define        ECO_CSV_FILENAME            "EcoInfo.csv"                           // 出力するCSVファイル名
#define        RE_READTIME                 4000                                    // データ読み込み間隔(分解能:1sec)
#define        OBJ_ECO_HEAD                "OEH_"                                  // 指標表示オブジェクト用ヘッダ名
#define        OBJ_ECOBG_HEAD              "OEBGH_"                                // 指標背面オブジェクト用ヘッダ名
#define        ECODISP_OFFSETDIV           20                                      // チャート上に表示される指標のオフセットをチャート幅の何分割分にするか


enum        enum_ecofile_member {
    ECO_FILE_DAY        = 0    ,
    ECO_FILE_TIME            ,
    ECO_FILE_EXPECT            ,
    ECO_FILE_EXPECT_DUMMY    ,
    ECO_FILE_DETAIL            ,
    ECO_FILE_FORECAST        ,
    ECO_FILE_LASTRESULT        ,
    ECO_FILE_RESULT            ,
    ECO_FILE_ARRAY_MAX        
};


static    string    ReadEcoFileDataArray[][ECO_FILE_ARRAY_MAX];
const     int       rev_arraysize       = 1000;
          bool      FileOpenFlag        = false;
          int       DArraySize          = -1;
        
sinput    int       inp_fontsize        = 11;                   // 表示フォントサイズ(7~14)
sinput    bool      inp_ecobg           = true;                 // 指標表示バックグラウンド描画
sinput    int       inp_comment_xsize   = 25;                   // 枠の横幅上限
sinput    bool      inp_listoff         = false;                // 指標リスト非表示
sinput    bool      inp_disp_offset     = false;                // 表示オフセット
sinput    bool      inp_debug           = false;                // デバッグ

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit() {
    EventSetTimer(1);
    ArrayResize(ReadEcoFileDataArray,1,rev_arraysize);                    // 文字列配列の動的配列領域確保

    EcoDispBackGround_Init(true);

    return(INIT_SUCCEEDED);
}


//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
    EventKillTimer();
    ObjectsDeleteAll( 0 , OBJ_ECO_HEAD);
    ObjectsDeleteAll( 0 , OBJ_ECOBG_HEAD);
    Comment("");
}


//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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);
}

//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer() {

    static int    timer_count        = RE_READTIME;
    static int    period_count    = (Period()*60);
    bool        temp_ret;
    int            ret_count;
    static bool get_success = false;
    
    temp_ret = false;
    
    if ( timer_count >= RE_READTIME ) {            // 1時間(+α)に1度データ取得する
        ret_count    = EcoFileRead();
        DArraySize    = ret_count;
        
        if ( ret_count > 0 ) {
            timer_count = 0;
            
            FileOpenFlag = true;
            // test
            if ( get_success == false ) {
                Print("指標データ読込完了");
                get_success = true;
            }
            EcoDetail_AllDisp();
//            EcoDetailDisp( 0 , DArraySize );
        } else {
            FileOpenFlag = false;
            // test
            printf( "[%d]指標データ読み込み異常:%d", __LINE__ , ret_count );
            //Print("指標データ読込異常:" + (string)ret_count);
            get_success = false;
            Sleep(50000);
            
        }
    }
    
    if ( period_count >= (Period()*60) ) {
        EcoDetail_AllDisp();
        period_count = 0;
    }


    timer_count++;
    period_count++;

}


//+------------------------------------------------------------------+
//| 関数名    :EcoFileRead
//| 概要    :
//| 備考    :無し
//| ―――――――――――――――――――――――――――――――――
//| 戻り値    :読み込んだレコード数を返します
//| 引数    :無し
//+------------------------------------------------------------------+
int EcoFileRead( void ) {

    int        csvhandle;
    int        icount;
    int        mcount;
    int        arr_count;
    ulong    file_size;
    string    get_str;
    bool    tempbool;
    string    change_date;
    


    csvhandle    = FileOpen(ECO_CSV_FILENAME, FILE_READ | FILE_CSV , ',' ,CP_ACP);    // CSVファイルを開く
    mcount        = 0;
    arr_count    = 0;

    if ( csvhandle == INVALID_HANDLE ) {                                            // ファイルオープンエラー
        arr_count    = -1;
        Print("FileOpenエラー。 ",Get_ComErrorCodeStr( GetLastError()) );
        Sleep(50000);
    } else {
        arr_count    = 0;
        file_size    = FileSize(csvhandle);                                            // ファイルサイズ取得
        
        tempbool = FileSeek( csvhandle, 0 ,SEEK_SET );                                 // ファイルシーク位置設定

        ArrayResize(ReadEcoFileDataArray,(int)file_size * ECO_FILE_ARRAY_MAX,rev_arraysize);            // 文字列配列の動的配列領域確保

        for ( icount = 1; icount < (int)file_size; icount++ ) {                      // ファイルの最後まで検索を行う
            get_str = FileReadString(csvhandle);
            
            // テスト
            if ( inp_debug == true && icount < 20) {
                printf("CSV取得[%d]%d/%d str=[%s]",__LINE__,icount,file_size,get_str);
            }
            
            ReadEcoFileDataArray[arr_count][mcount] = get_str;
            mcount++;
            if ( mcount >= ECO_FILE_ARRAY_MAX ) {
                mcount = 0;
                arr_count++;
            }
            
//            if ( mcount < ECO_FILE_ARRAY_MAX ) {
//                ArrayResize(ReadEcoFileDataArray,(int)icount,rev_arraysize);        // 文字列配列の動的配列領域確保
//                ReadEcoFileDataArray[arr_count][mcount] = get_str;
//                //テスト
//                if ( inp_debug == true && icount < 20) {
//                    //printf("CSV配列セット[%d][%d][%d]=[%s]",__LINE__ ,arr_count,mcount,ReadEcoFileDataArray[arr_count][mcount] );
//                }
//            }
//
//            if ( FileIsLineEnding (csvhandle) == true ) {
//                mcount = 0;
//                arr_count++;
//
//            } else {
//                mcount++;
//            }
            
            if ( FileIsEnding(csvhandle) == true ) {
                break;
            }
        }

        FileClose(csvhandle);                                                        // ファイルハンドラ解放

        MqlDateTime    temp_sttime;
        TimeToStruct(TimeCurrent() , temp_sttime);

        // 読み取った日付をMT4用フォーマットに変換
        for ( icount = 0 ; icount < arr_count;icount++ ) {
            if ( ReadEcoFileDataArray[icount][ECO_FILE_DAY] != "" ) {
                change_date = ReadEcoFileDataArray[icount][ECO_FILE_DAY];
                StringReplace(change_date,"月",".");
                StringReplace(change_date,"日","");
                ReadEcoFileDataArray[icount][ECO_FILE_DAY] = StringFormat("%d.%s",temp_sttime.year,change_date);
            } else {
                ReadEcoFileDataArray[icount][ECO_FILE_DAY] = "";
            }

        }
    }
    

    if ( inp_debug == true ) {
        for ( icount = 0 ; icount < 20;icount++ ) {
            printf("[%d][%d]:DAY=%s,TIME=%s,DETAIL=%s,EX=%s,DUMMY=%s,RESULT=%s,RESULT2=%s",__LINE__,icount
            ,ReadEcoFileDataArray[icount][ECO_FILE_DAY]
            ,ReadEcoFileDataArray[icount][ECO_FILE_TIME]
            ,ReadEcoFileDataArray[icount][ECO_FILE_DETAIL]
            ,ReadEcoFileDataArray[icount][ECO_FILE_EXPECT]
            ,ReadEcoFileDataArray[icount][ECO_FILE_EXPECT_DUMMY]
            ,ReadEcoFileDataArray[icount][ECO_FILE_LASTRESULT]
            ,ReadEcoFileDataArray[icount][ECO_FILE_RESULT]
            );
        }
    }
    
    return arr_count;

}

//+------------------------------------------------------------------+
//| EcoDetail_AllDisp                                     
//+------------------------------------------------------------------+
void EcoDetail_AllDisp( void ) {

    int dispbars;
    int temp_period;
    int icount;
    int start_index;
    
    temp_period = Period();
    
    if ( temp_period == 0 ) {
        temp_period = 1;
    }
    
    dispbars = 7200 / Period(); // 過去二日分のバー数

    ObjectsDeleteAll( 0 , OBJ_ECO_HEAD);
    Calculate_JpnTime(0);
    
    start_index = -60;
    if ( Period() == PERIOD_M1 ) {
        start_index = -180;
    }

//    for ( icount = start_index ; icount < dispbars ; icount++ ) {

    double lowrate;
    lowrate = Low[iLowest(  Symbol(), Period(), MODE_LOW , (int)ChartGetInteger(0,CHART_FIRST_VISIBLE_BAR,0) , 1 )];
    //printf( "[%d]%g" , __LINE__ , lowrate );
    
    for ( icount = dispbars ; icount > start_index ; icount-- ) {
        EcoDetailDisp( icount , DArraySize , lowrate );
    }
    EcoDetailTodayDisp();

}



//+------------------------------------------------------------------+
//| EcoDetailDisp                                     
//+------------------------------------------------------------------+
void EcoDetailDisp( int in_index , int in_array_size , double in_lowrate) {
    
    double      dispposi[2];
    double      dispoffset;
    datetime    temp_nowtime;
    datetime    temp_now_jptime;
    datetime    tempeco_margin1,tempeco_margin2;
    datetime    tempeco_date;
    string      ecoobjst[2];
    string      tempecodetail;
    st_jpntime  jpntime;
    int         icount;
    int         hit_count;
    int         temp_fontsize;
    long        nowmaxbars;
    MqlDateTime temp_sttime;
//    double        temp_getrate[];
    double      temp_getrate;
    
    hit_count        = 0;

    
    nowmaxbars = SeriesInfoInteger(Symbol(),Period(),SERIES_BARS_COUNT);
    
    if ( nowmaxbars <= ( in_index + 1) ) {
        return;
    }
    
    if ( in_index >= 0 ) {
        temp_nowtime    = (datetime)Time[in_index];
    } else {
        temp_nowtime    = (datetime)(Time[0] + Period() * 60 * MathAbs(in_index));
        
    }

    jpntime = Get_TimeJPN();
    
    temp_now_jptime    = temp_nowtime + (jpntime.gmt_diff * 3600);
    temp_fontsize    = inp_fontsize;
    
    if ( temp_fontsize < 7 ) {
        temp_fontsize = 7;
    }
    if ( temp_fontsize > 14 ) {
        temp_fontsize = 14;
    }
    
    datetime    disp_xtime;
    double        disp_yrate;
    bool        f_bool;
    static    double        f_count;
    f_bool = false;
    if ( in_index > 0 ) {
        f_count = 0;
    }
    
    for ( icount = 1 ; icount < in_array_size ; icount++ ) {        // 取得した指標分だけ繰り返す(初回分はヘッダなので除く)
        if ( ReadEcoFileDataArray[icount][ECO_FILE_DAY] == "" ) {
            continue;                                                // 日付記載が無い場合は次へ
        }
        
        if ( ReadEcoFileDataArray[icount][ECO_FILE_TIME] == "" ) {
            continue;                                                // 時刻記載が無い場合は次へ
        }
        
        tempeco_date    = StringToTime(ReadEcoFileDataArray[icount][ECO_FILE_DAY] + " " + ReadEcoFileDataArray[icount][ECO_FILE_TIME]);
        TimeToStruct(tempeco_date,temp_sttime);
        tempeco_margin1 = temp_now_jptime;
        tempeco_margin2 = temp_now_jptime + ( Period() * 60 );
        
        // 指標名・時間制限表示
        if ( tempeco_margin1 <= tempeco_date && tempeco_date <= tempeco_margin2 ) {
            if ( f_bool == false ) {
                f_bool = true;
                f_count++;
            }

//            ecoobjst[0] = OBJ_ECO_HEAD + "s" + (string)temp_sttime.day +"D"+ TimeToString(tempeco_date,TIME_MINUTES) +" "+ ReadEcoFileDataArray[icount][ECO_FILE_DETAIL];
            ecoobjst[0] = StringFormat( "%ss%dD%s %s",OBJ_ECO_HEAD,temp_sttime.day,TimeToString(tempeco_date,TIME_MINUTES),ReadEcoFileDataArray[icount][ECO_FILE_DETAIL]);
            ecoobjst[1] = OBJ_ECO_HEAD + "a" + TimeToString(temp_now_jptime,TIME_DATE | TIME_MINUTES);
    
            //オブジェクト名の長さは40byteまで。それ以上はエラーになる。(StringLenは全角半角の区別が出来ないので30文字トリムする)
            if ( StringLen(ecoobjst[0]) >= 31 ) {
                ecoobjst[0] =StringSubstr( ecoobjst[0] , 0 , 30 );
            }

            if ( in_index >= 0 ) {
                temp_getrate = High[in_index];
            } else {
                temp_getrate = in_lowrate;
            }

            double temppoint;
            SymbolInfoDouble(Symbol(),SYMBOL_POINT,temppoint);

            dispposi[0] = temp_getrate     + (  1 * temppoint * 10 );
//            dispposi[0] = High[temp_in_index]     + (  1 * Point * 10 );
            dispposi[1] = dispposi[0]            - (  1 * temppoint * 10 );

            if (ObjectFind( 0, ecoobjst[0] ) == -1 ) {
                
//                tempecodetail = ReadEcoFileDataArray[icount][ECO_FILE_TIME] + " " + ReadEcoFileDataArray[icount][ECO_FILE_DETAIL];
                tempecodetail = StringFormat( "%s %s%s", ReadEcoFileDataArray[icount][ECO_FILE_TIME] , ReadEcoFileDataArray[icount][ECO_FILE_EXPECT_DUMMY] , ReadEcoFileDataArray[icount][ECO_FILE_DETAIL] );

                if ( StringLen(tempecodetail) >= 41 ) {                                // 念の為40文字トリム
                    tempecodetail =StringSubstr( tempecodetail , 0 , 40 );
                }
                
                dispoffset = Get_WindowHighLowDiff();                                // 重複表示時のオフセット

                disp_xtime = (temp_nowtime - (3 * Period() * 60) );
                disp_yrate = dispposi[0] + ((hit_count + f_count) * dispoffset );
                
#ifdef __MQL5__                                                     // MT5のみ処理する
                    disp_yrate += ( dispoffset * 1.5);
#endif
                
                bool right_back;
                right_back = true;
                if ( in_index <= 0 ) {
                    ObjectDelete(ecoobjst[0]);
                    right_back = false;
                }
                
                ObjectCreate(    0, ecoobjst[0], OBJ_TEXT,0
                                , disp_xtime                // 表示位置X
//                                ,(Time[temp_in_index] - (3 * Period() * 60) )        // 表示位置X
                                , disp_yrate            // 表示位置Y
                                );
                                
//                ObjectSetText(    0, ecoobjst[0], tempecodetail , temp_fontsize , "MS ゴシック" , White);
                ObjectSetString(    0, ecoobjst[0],OBJPROP_TEXT,tempecodetail);
                ObjectSetInteger(   0, ecoobjst[0],OBJPROP_FONTSIZE,temp_fontsize);
                ObjectSetString(    0, ecoobjst[0],OBJPROP_FONT,"MS ゴシック");
                ObjectSetInteger(   0, ecoobjst[0],OBJPROP_COLOR,clrLime);
//                ObjectSetInteger(    0, ecoobjst[0],OBJPROP_COLOR,White);
                ObjectSetInteger(   0, ecoobjst[0],OBJPROP_SELECTABLE,false);
                ObjectSetInteger(   0, ecoobjst[0],OBJPROP_SELECTED,false);
                ObjectSetInteger(   0, ecoobjst[0],OBJPROP_HIDDEN,false);

                if ( in_index >= 0 ) {
                    ObjectSetInteger(    0, ecoobjst[0],OBJPROP_ANCHOR,ANCHOR_CENTER);
                } else {
                    ObjectSetInteger(    0, ecoobjst[0],OBJPROP_ANCHOR,ANCHOR_LEFT);
                }
                ObjectSetInteger(    0, ecoobjst[0],OBJPROP_BACK,right_back);                  // オブジェクトの背景表示設定

                if ( in_index <= 0 ) {
                    ObjectDelete(ecoobjst[1]);
                }

                if (ObjectFind( 0, ecoobjst[1]) == -1) {
                    ObjectCreate(            0, ecoobjst[1],OBJ_ARROW,0,temp_nowtime, dispposi[1] + f_count * dispoffset );
//                    ObjectCreate(    ecoobjst[1],OBJ_ARROW,0,Time[temp_in_index], dispposi[1]  );
//                    ObjectSetInteger(        0, ecoobjst[1],OBJPROP_ARROWCODE, SYMBOL_ARROWDOWN);
                    ObjectSetInteger(        0, ecoobjst[1],OBJPROP_ARROWCODE, 242);
                    if ( temp_fontsize == 7 ) {
                        ObjectSetInteger(        0, ecoobjst[1],OBJPROP_WIDTH, 1);
                    } else if ( temp_fontsize == 8 || temp_fontsize == 9 ) {
                        ObjectSetInteger(        0, ecoobjst[1],OBJPROP_WIDTH, 2);
                    } else {
                        ObjectSetInteger(        0, ecoobjst[1],OBJPROP_WIDTH, 3);
                    }
                    ObjectSetInteger(        0, ecoobjst[1],OBJPROP_FONTSIZE,temp_fontsize);
                    ObjectSetInteger(        0, ecoobjst[1],OBJPROP_COLOR,clrLime);
//                    ObjectSetInteger(        0, ecoobjst[1],OBJPROP_COLOR,White);
                    ObjectSetInteger(        0, ecoobjst[1],OBJPROP_SELECTABLE,false);
                    ObjectSetInteger(        0, ecoobjst[1],OBJPROP_SELECTED,false);
                    ObjectSetInteger(        0, ecoobjst[1],OBJPROP_HIDDEN,false);
                    ObjectSetInteger(        0, ecoobjst[1],OBJPROP_ANCHOR,ANCHOR_CENTER);
                    ObjectSetInteger(        0, ecoobjst[1],OBJPROP_BACK,right_back);                  // オブジェクトの背景表示設定
                }

                hit_count++ ;
            }
        }
        
        
    }
    
    
}

//+------------------------------------------------------------------+
//| Get_WindowHighLowDiff                              |
//+------------------------------------------------------------------+
double Get_WindowHighLowDiff( void ) {
    
    double temprate;
    double temp_unitrate;
    double temp_div;
    double charthigh,chartlow;
    long   tempdigits;
    
    temp_div        = ECODISP_OFFSETDIV;

    charthigh        = ChartGetDouble( 0, CHART_PRICE_MAX);
    chartlow        = ChartGetDouble( 0, CHART_PRICE_MIN);
    
    temprate        = charthigh - chartlow;                        
    tempdigits        = SymbolInfoInteger(Symbol(),SYMBOL_DIGITS);

//    temprate        = WindowPriceMax(0) - WindowPriceMin(0);    // 添え字はチャートインデックス
    temp_unitrate    = NormalizeDouble(temprate / temp_div,(int)tempdigits);
//    temp_unitrate    = NormalizeDouble(temprate / temp_div,Digits);
    
    
    return temp_unitrate;
    
}



//+------------------------------------------------------------------+
//| EcoDetailTodayDisp                                |
//+------------------------------------------------------------------+
void EcoDetailTodayDisp( void ) {

    datetime    ecodate, rangesttime , rangeedtime;
    int            remain_stmin,  remain_sthour;
    int            intstmin;

    int            icount;
    string        ecoday, eco_marge;
    string        stmin;
    st_jpntime    jpntime;

    MqlDateTime    temp_sttime;

    string        temp_str;
    int            temp_hit;
    int            temp_strlen;
    int            temp_maxstrlen;

    jpntime = Get_TimeJPN();


    rangesttime    = jpntime.now_jpntime - 3600 * 2;
    rangeedtime    = jpntime.now_jpntime + 3600 * 48;
    
    if ( inp_disp_offset == true ) {
        eco_marge    = "\n\n\n\n";
    } else {
        eco_marge    = "";
    }
    temp_hit    = 0;
    temp_maxstrlen = 0;
    
//    for ( icount = DArraySize-1; icount >= 0  ; icount-- ) {
    for ( icount = 0; icount < DArraySize  ; icount++ ) {

        if ( ReadEcoFileDataArray[icount][ECO_FILE_TIME] != "" ) {
            ecodate        = StringToTime( ReadEcoFileDataArray[icount][ECO_FILE_DAY] + " " +ReadEcoFileDataArray[icount][ECO_FILE_TIME] );
        } else {
            ecodate        = StringToTime( ReadEcoFileDataArray[icount][ECO_FILE_DAY] + " " +"23:59:00" );
        }
//        ecoday        = (string)TimeDay(ecodate);

        TimeToStruct(ecodate,temp_sttime);
        ecoday = (string)temp_sttime.day;

        
        
        if ( rangesttime <= ecodate  && ecodate <= rangeedtime) {

            if ( stmin == "-" ) {
                intstmin    = 0;
            } else {
                intstmin    = (int)StringToInteger(stmin);

                remain_stmin = (int)((ecodate - jpntime.now_jpntime - (intstmin*60)) / 60);
                if ( remain_stmin > 0 ) {
                    remain_sthour = remain_stmin / 60;
                    remain_stmin  = (int)(MathMod(remain_stmin,60));
                } else {
                    remain_sthour = 0;
                    remain_stmin  = 0;
                }

            }
            
            
//            eco_marge += ecoday + "日 " + TimeToString(StringToTime(ReadEcoFileDataArray[icount][ECO_FILE_TIME]),TIME_MINUTES) + " " ;
//            eco_marge += ReadEcoFileDataArray[icount][ECO_FILE_DETAIL] + "\n";

            if ( ReadEcoFileDataArray[icount][ECO_FILE_TIME] != "" ) {
//                temp_str  =  ecoday + "日 " + TimeToString(StringToTime(ReadEcoFileDataArray[icount][ECO_FILE_TIME]),TIME_MINUTES) + " " ;
                temp_str = StringFormat( "%s日 %s " , ecoday , TimeToString(StringToTime(ReadEcoFileDataArray[icount][ECO_FILE_TIME]),TIME_MINUTES));
            } else {
                temp_str  =  ecoday + "日 " + "xx:xx" + " " ;
            }
//            temp_str  += ReadEcoFileDataArray[icount][ECO_FILE_DETAIL] + "\n";
            temp_str  += StringFormat( "%s%s\n" ,ReadEcoFileDataArray[icount][ECO_FILE_EXPECT_DUMMY],ReadEcoFileDataArray[icount][ECO_FILE_DETAIL]);
            eco_marge += temp_str;

            temp_hit++;

            temp_strlen = StringLen(temp_str);
            if ( temp_strlen > temp_maxstrlen) {
                temp_maxstrlen = temp_strlen;
            }
            
        }
    }

    if ( inp_listoff == false ) {
        EcoDispBackGround_Modify( temp_maxstrlen , temp_hit);
        Comment(eco_marge);
    }
    
}


//+------------------------------------------------------------------+
//| EcoDispBackGround_Init                                |
//+------------------------------------------------------------------+
void EcoDispBackGround_Init( bool ini_init ) {

#ifdef __MQL5__
    return;                                                                // MT5では処理しない
#endif

    if ( inp_listoff != false ) {
        return;
    }


    string objstr;
    int    chart_id = 0;
    objstr = OBJ_ECOBG_HEAD + "rectangle";
    
    if ( inp_ecobg == false ) {
//        return;
    }

    static int    checkcount = 0;
    
    if ( ini_init == false ) {
        checkcount++;
        if ( checkcount > 100 ) {
            checkcount = 0;
        } else {
            return;
        }
    }

    ObjectCreate(chart_id,    objstr, OBJ_RECTANGLE_LABEL, 0 , 0 , 0 );

    ObjectSetInteger(chart_id,objstr,OBJPROP_BACK,false);                // オブジェクトの背景表示設定
    ObjectSetInteger(chart_id,objstr,OBJPROP_SELECTABLE,false);          // オブジェクトの選択可否設定
    ObjectSetInteger(chart_id,objstr,OBJPROP_SELECTED,false);            // オブジェクトの選択状態

    ObjectSetInteger(chart_id,objstr,OBJPROP_CORNER,CORNER_LEFT_UPPER);  // コーナーアンカー設定
    ObjectSetInteger(chart_id,objstr,OBJPROP_XDISTANCE,0);               // X座標
    if ( inp_disp_offset == true ) {
        ObjectSetInteger(chart_id,objstr,OBJPROP_YDISTANCE,62);              // Y座標
    } else {
        ObjectSetInteger(chart_id,objstr,OBJPROP_YDISTANCE,12);              // Y座標
    }
    ObjectSetInteger(chart_id,objstr,OBJPROP_XSIZE,100);                 // ボタンサイズ幅
    ObjectSetInteger(chart_id,objstr,OBJPROP_YSIZE,150);                 // ボタンサイズ高さ

    ObjectSetInteger(chart_id,objstr,OBJPROP_BGCOLOR, clrBlack );        // 背景色
    ObjectSetInteger(chart_id,objstr,OBJPROP_BORDER_COLOR,clrWhite);     // 枠色
    ObjectSetInteger(chart_id,objstr,OBJPROP_BORDER_TYPE,BORDER_FLAT);   // ボーダータイプ

}

//+------------------------------------------------------------------+
//| EcoDispBackGround_Modify                                |
//+------------------------------------------------------------------+
void EcoDispBackGround_Modify( int in_x , int in_y) {

    int    fontsize;
    int    chart_id = 0;
    string objstr;
    objstr = OBJ_ECOBG_HEAD + "rectangle";
    int        temp_high;
    int        temp_wide;
//    const int max_wide = 25;

    int max_wide;
    max_wide = inp_comment_xsize;


    if ( inp_ecobg == false ) {
//        return;
    }

    EcoDispBackGround_Init(false);

    fontsize = 9;
    
    temp_wide    = in_x;
    if ( temp_wide > max_wide ) {
        temp_wide = max_wide;
    }
    
    temp_high = in_y + (int)(in_y / 3) + 2;
    

    ObjectSetInteger(chart_id,objstr,OBJPROP_XSIZE,fontsize   * temp_wide );       // ボタンサイズ幅
    ObjectSetInteger(chart_id,objstr,OBJPROP_YSIZE,fontsize   * temp_high );       // ボタンサイズ高さ

}


ソースコード:
local_common_jpntime.mqh.mqh
//+------------------------------------------------------------------+
//|                                         local_common_jpntime.mqh 
//|                                 Copyright 2015, Created by Yuki. 
//|                                       http://yukifx.web.fc2.com/ 
//|―――――――――――――――――――――――――――――――――|
//|概要:サーバー時間から日本時間を算出する
//+------------------------------------------------------------------+
//| date:        Ver:    detail
//| 15/05/22    1.00    new
//| 15/07/31    1.01    !変更 入力パラメータ:タイムゾーン選択の初期値をGMT+2(DST:GMT+3)に変更
//|                                                                  
//+------------------------------------------------------------------+

#ifndef LOCAL_COMMON_TIMER   // 2重インクルード対策
#define LOCAL_COMMON_TIMER 1

#property copyright "Copyright 2015, Created by Yuki."
#property link      "http://yukifx.web.fc2.com/"


#define    SUMMERTIME_DATETIME_STR                ".03.09 02:00"
#define    WINTERTIME_DATETIME_STR                ".11.02 02:00"

#define JPN_GMT                                9

#define FXCMUK_APIDL_TIMEZONE                "2017.6.24"        // FXCMUKからAPI_DLしたデータはGMTになる。
                                                            

enum ENUM_MARKET {
    MARKET_JPOP = 0,
    MARKET_JPCL,
    MARKET_EUOP,
    MARKET_NYOP,
    MARKET_FIX,
    MARKET_NYCL,
    MARKET_MAX
};

// GMT0の時間
static const int GMT0_MarketStartHour[2][MARKET_MAX] = {
    {    3,  9, 11,    15,    19,    0},        // ウインタータイム
    {    3,  9, 10,    14,    18,    23}        // サマータイム
};

static const int MarketStartTime[2][MARKET_MAX] = {
    {    9, 15, 17,    23,    1,    6},        // ウインタータイム
    {    9, 15, 16,    22,    0,    5}         // サマータイム
};
static const string MarketStartTimeStr[MARKET_MAX] = {
    "JPOP",    "JPCL","EUOP",    "NYOP",    "FIX",    "NYCL"
};


enum enum_gmt{            // GMTタイプ
    gmt_0        = 0,     // GMT
    gmt_2        = 2,     // GMT+2 (DST:GMT+3)
    gmt_9        = 9,     // GMT+9
    gmt_fxcm    = 10      // FXCMバックテストGMT -> GMT+2/3
};

struct    st_jpntime {                          // 日本時間構造体

    datetime    now_jpntime;                    // 日本時間
    datetime    now_ustime;                     // us時間
    int         gmt_diff;                       // GMT差分時間
    bool        dst;                            // サマータイムbool
    ENUM_MARKET enum_market;                    // マーケットENUM

//    string        str_market;                     // マーケット
//    string        str_dow;                        // 曜日

};

// 入力パラメータ
sinput    enum_gmt    BASE_GMT_JPY            = gmt_2;            // タイムゾーン選択

// 静的変数
static    st_jpntime    St_JPNTime_Data;

//+------------------------------------------------------------------+
//| 関数名    :Calculate_JpnTime
//| 概要    :指定したバーの時間から日本時間を算出する。
//| 備考    :無し
//| ―――――――――――――――――――――――――――――――――
//| 戻り値    :無し
//| 引数    :int in_nowpos バー数を指定する (0指定は現在時間)
//+------------------------------------------------------------------+
void Calculate_JpnTime( int in_nowpos ) {

    datetime    now_jptime;                 // 日本時間
    datetime    summerinday;                // サマータイム開始日時
    datetime    summeroutday;               // サマータイム終了日時
    datetime    servertime;                 // サーバー時間
    int         diff_gmt;                   // 内部GMT差分
    int         local_nowbar;
    bool        dst_season;                 // サマータイム期間判定結果 true:サマータイム false:ウインタータイム

    enum_gmt    select_gmt;                 // タイムゾーン

    datetime    changetime;
    changetime    = StrToTime(FXCMUK_APIDL_TIMEZONE);

    datetime    ustime;
    
    local_nowbar = in_nowpos;
    if ( Bars <= in_nowpos ) {
        local_nowbar = Bars - 1;
    }

//    if ( 0 > in_nowpos ) {
//        local_nowbar = 0;
//    }

    if ( 0 > in_nowpos ) {
        ustime = Time[0] + ( MathAbs(in_nowpos) * Period() * 60 );
    } else {
        ustime = Time[local_nowbar];
    }

    
    
    if ( BASE_GMT_JPY == gmt_fxcm ) {
        if ( ustime < changetime) {
            select_gmt = gmt_0;
        } else {
            select_gmt = gmt_2;
        }
    } else {
        select_gmt = BASE_GMT_JPY;
    }

    diff_gmt        = JPN_GMT - (int)select_gmt;
    servertime      = ustime;                                            // チャート上の時間取得
    now_jptime      = (servertime) + (diff_gmt * 3600);                  // 日本時間を算出

    
    // GMT判定後の日本時間算出
    summerinday  =  StrToTime((string)TimeYear(servertime) + SUMMERTIME_DATETIME_STR); // サマータイム開始日時
    summeroutday =  StrToTime((string)TimeYear(servertime) + WINTERTIME_DATETIME_STR); // サマータイム終了日時

    if ( servertime >= summerinday && servertime <= summeroutday ) {
        // サマータイム
        dst_season    = true;
        
    } else { 
        // ウインタータイム
        dst_season    = false;
    }

    dst_season = CheckDST(dst_season , servertime );

    if ( dst_season == true ) {
        if ( select_gmt == gmt_2 ) {             // サマータイムで影響するGMTのみ処理する
            if ( select_gmt == gmt_2 ) {         // サマータイムはGMTを1時間スライドする
                diff_gmt    = diff_gmt - 1 ;
                now_jptime    = (servertime) + ( diff_gmt * 3600);
            }
        }
    }

    St_JPNTime_Data.gmt_diff        = diff_gmt;
    St_JPNTime_Data.now_jpntime     = now_jptime;
    St_JPNTime_Data.now_ustime      = ustime;
    St_JPNTime_Data.dst             = dst_season;
    St_JPNTime_Data.enum_market     = GetMarketEnum( now_jptime , dst_season );
//    St_JPNTime_Data.str_market        = GetMarketStr( St_JPNTime_Data.enum_market );
//    St_JPNTime_Data.str_dow           = GetDowString( now_jptime );

    ////デバッグプリント用
//    printf("チャート時間[%d]:%s, 日本時間:%s , GMT:%d , サマータイム:%d",
//        in_nowpos,
//        TimeToStr(servertime,TIME_DATE|TIME_SECONDS),
//        TimeToStr(St_JPNTime_Data.now_jpntime,TIME_DATE|TIME_SECONDS),
//        St_JPNTime_Data.gmt_diff,
//        dst_season
//        );

}

//+------------------------------------------------------------------+
//| 関数名    :CheckDST
//| 概要    :サーバー時間のサマータイムは週末に切り替わるのでその対応
//| 備考    :3/9~11/2以外の場合に変更する
//| ―――――――――――――――――――――――――――――――――
//| 戻り値    :bool DST(true:サマータイム)
//| 引数    :bool DST判定結果
//+------------------------------------------------------------------+
bool CheckDST( bool in_dst , datetime in_time ) {
    
    bool retsdt;
    
    retsdt = in_dst;
    
    // 2015 - 2016年の冬時間タイム
    if ( StrToTime("2015.11.01 00:00") < in_time && in_time <= StrToTime("2016.3.13 00:00")  ) {
        retsdt = false;
    }

    // 2016 - 2017年の夏時間タイム
    if ( StrToTime("2016.3.13 00:00") < in_time && in_time <= StrToTime("2016.11.6 00:00")  ) {
        retsdt = true;
    }

    // 2016 - 2017年の冬時間タイム
    if ( StrToTime("2016.11.06 00:00") < in_time && in_time <= StrToTime("2017.3.12 00:00")  ) {
        retsdt = false;
    }

    // 2017 - 2018年の夏時間タイム
    if ( StrToTime("2017.3.12 00:00") < in_time && in_time <= StrToTime("2017.11.5 00:00")  ) {
        retsdt = true;
    }

    // 2017 - 2018年の冬時間タイム
    if ( StrToTime("2017.11.05 00:00") < in_time && in_time <= StrToTime("2018.3.11 00:00")  ) {
        retsdt = false;
    }

    
    return retsdt;
    
}



// ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■

//+------------------------------------------------------------------+
//| 関数名    :Get_TimeJPN
//| 概要    :算出済みの日本時間を返します。
//| 備考    :事前にCommon_TimeCulate()を呼び出す必要があります。
//| ―――――――――――――――――――――――――――――――――
//| 戻り値    :st_jpntime 日本時間構造体の値を返します
//| 引数    :無し
//+------------------------------------------------------------------+
st_jpntime Get_TimeJPN( void ) {
    return St_JPNTime_Data;
}


//+------------------------------------------------------------------+
//| 関数名    :Cov_Us2JpnTime
//| 概要    :USTIMEをJPNTIMEに変換
//| 備考    :
//| ―――――――――――――――――――――――――――――――――
//| 戻り値    :datetime JPNTIME
//| 引数    :無し
//+------------------------------------------------------------------+
datetime Cov_Us2JpnTime( datetime in_ustime ) {
    
    datetime jptime;
    
    jptime = in_ustime + ( St_JPNTime_Data.gmt_diff * 3600 );
    
    return jptime;
}

//+------------------------------------------------------------------+
//| 関数名    :Cov_Us2JpnTime
//| 概要    :USTIMEをJPNTIMEに変換
//| 備考    :
//| ―――――――――――――――――――――――――――――――――
//| 戻り値    :datetime JPNTIME
//| 引数    :無し
//+------------------------------------------------------------------+
datetime Cov_Jpn2UsTime( datetime in_jptime ) {
    
    datetime ustime;
    
    ustime = in_jptime - ( St_JPNTime_Data.gmt_diff * 3600 );
    
    return ustime;
}

//+------------------------------------------------------------------+
//| マーケットENUM取得
//+------------------------------------------------------------------+
ENUM_MARKET GetMarketEnum( datetime in_date , bool in_dst ) {

    ENUM_MARKET ret = MARKET_JPOP;
    int now_hour = TimeHour(in_date);
    
    if ( MarketStartTime[in_dst][MARKET_FIX] <= now_hour && now_hour < MarketStartTime[in_dst][MARKET_NYCL] ) {
        ret = MARKET_FIX;
    }
    if ( MarketStartTime[in_dst][MARKET_NYCL] <= now_hour && now_hour < MarketStartTime[in_dst][MARKET_JPOP] ) {
        ret = MARKET_NYCL;
    }
    if ( MarketStartTime[in_dst][MARKET_JPOP] <= now_hour && now_hour < MarketStartTime[in_dst][MARKET_JPCL] ) {
        ret = MARKET_JPOP;
    }
    if ( MarketStartTime[in_dst][MARKET_JPCL] <= now_hour && now_hour < MarketStartTime[in_dst][MARKET_EUOP] ) {
        ret = MARKET_JPCL;
    }
    if ( MarketStartTime[in_dst][MARKET_EUOP] <= now_hour && now_hour < MarketStartTime[in_dst][MARKET_NYOP] ) {
        ret = MARKET_EUOP;
    }
    if ( MarketStartTime[in_dst][MARKET_NYOP] <= now_hour ) {
        ret = MARKET_NYOP;
    }
    if ( MarketStartTime[in_dst][MARKET_FIX] > now_hour ) {
        ret = MARKET_NYOP;
    }
    

    return ret;
    

}

//+------------------------------------------------------------------+
//| マーケット名
//+------------------------------------------------------------------+
string GetMarketStr( ENUM_MARKET in_market ) {
    string ret = MarketStartTimeStr[0];
    
    if ( in_market < MARKET_MAX ) {
        ret = MarketStartTimeStr[in_market];
    }
    return ret;
}

//+------------------------------------------------------------------+
//| 曜日取得
//+------------------------------------------------------------------+
string GetDowString( datetime in_date ) {

    int tempdow;
    string jpndow;
    tempdow        = TimeDayOfWeek( in_date );

    switch (tempdow) {
        case SUNDAY:
            jpndow = "日";
        break;
        case MONDAY:
            jpndow = "月";
        break;
        case TUESDAY:
            jpndow = "火";
        break;
        case WEDNESDAY:
            jpndow = "水";
        break;
        case THURSDAY:
            jpndow = "木";
        break;
        case FRIDAY:
            jpndow = "金";
        break;
        case SATURDAY:
            jpndow = "土";
        break;
    }
    
    return jpndow;

    
}
#endif





スポンサーリンク
スポンサーリンク


Copyright ©2015 MT4でEA自作しちゃお~ All Rights Reserved.


Top

inserted by FC2 system