MetaTrader5
MetaTrader 5のシンボル履歴を全てダウンロードする方法
皆さん、こんにちは!今日はMetaTrader 5を使って、シンボルのすべてのティックデータをダウンロードする方法についてお話しします。このエキスパートアドバイザー(EA)は、ユーザーのブローカーのマーケットウォッチをスキャンし、利用可能なティックをすべてダウンロードします。また、特定の日付までのティックもダウンロードできます。 この方法を使えば、バックテスト用のシンボル履歴を簡単に取得したり、そのティックからカスタムチャートを作成するのに役立ちます。 ティックデータは、データフォルダ内にキャッシュされるので、十分なハードドライブの空き容量を確保してくださいね。 シンボルのダウンロードをスムーズに行うために、まずはダウンロードマネージャーを用意します。 CDownloadManager構造体には、必要な情報が全て含まれています。 struct CDownloadManager { bool m_started, m_finished; string m_symbols[], m_current; int m_index;} この構造体では、以下の情報を管理します: ダウンロードの状態(開始/終了) スキャンするシンボルのリスト 現在のシンボル スキャン中のシンボルのインデックス また、ハードドライブへの読み書きが必要なので、シンボルに関しては、バイナリファイルから文字列を読み書きするための2つの簡単な関数を作成します。 ファイルに文字列を保存する関数: void writeStringToFile(int f, string thestring) { //シンボル文字列を保存 char sysave[]; int charstotal = StringToCharArray(thestring, sysave, 0, StringLen(thestring), CP_ACP); FileWriteInteger(f, charstotal, INT_VALUE); for(int i = 0; i < charstotal; i++) { FileWriteInteger(f, sysave[i], CHAR_VALUE); }} この関数は以下を受け取ります: ファイルハンドル f(書き込み用に開かれたファイル) ファイルに書き込む文字列 この関数は、文字列内の文字数を整数として書き込み、その後各文字を保存します。 ファイルから文字列を読み込む関数: string readStringFromFile(int f) { string result = ""; //シンボル文字列を読み込む char syload[]; int charstotal = (int)FileReadInteger(f, INT_VALUE); if(charstotal > 0) { ArrayResize(syload, charstotal, 0); for(int i = 0; i < charstotal; i++) { syload[i] = (char)FileReadInteger(f, CHAR_VALUE); } result = CharArrayToString(syload, 0, charstotal, CP_ACP); } return(result);} この関数は以下を受け取ります: ファイルハンドル f(バイナリとして読み込み用に開かれたファイル) この関数はファイル内で期待される文字数を整数として読み込み、その後、その文字をchar配列に読み込み、最終的に文字列を作成して返します。 次に、CDownloadManager構造体を初期化し、マーケットウォッチからデータを取得する方法を見ていきましょう。 //+------------------------------------------------------------------+//| マーケットウォッチからシンボルを取得 |//+------------------------------------------------------------------+void grab_symbols() { //! マーケットウォッチからのみ int s = SymbolsTotal(true); ArrayResize(m_symbols, s, 0); for(int i = 0; i < ArraySize(m_symbols); i++) { m_symbols[i] = SymbolName(i, true); }} 非常にシンプルな流れですね: マーケットウォッチに存在するシンボルの数を取得する m_symbols配列を必要なサイズにリサイズする 全シンボルをループし、シンボル名を取得する ダウンロードの管理を行うための関数も必要になります。これが実質的なマネージャーの役割を果たします: //+------------------------------------------------------------------+//| シンボルのダウンロードプロセスを管理 |//+------------------------------------------------------------------+void manage(string folder, string filename) { // 新規または継続のダウンロードを判定 if(ArraySize(m_symbols) > 0) { //開始されていない場合 if(!m_started) { m_started = true; //最初のシンボルに移動 m_current = m_symbols[0]; m_index = 1; save(folder, filename); if(_Symbol != m_current) { ChartSetSymbolPeriod(ChartID(), m_current, _Period); } else { ENUM_TIMEFRAMES new_period = PERIOD_M1; for(int p = 0; p < ArraySize(TFS); p++) { if(_Period != TFS[p]) { new_period = TFS[p]; break; } } ChartSetSymbolPeriod(ChartID(), m_current, new_period); } return; } //開始されている場合 else { m_index++; if(m_index
2025.02.22