【移植#47】生のHSTを読まずに履歴を一括CSV化 — 3通貨×500本をCopyRatesで書き出す¶

この記事の3行まとめ
- 古いHSTバイナリを直接解析せず、MT5の
CopyRates()から確定足を取得します - 初期設定では3通貨×500本を別々のCSVへ出力し、古い足から新しい足へ並べます
- 実機では全1,500行を元のレートと再照合し、時刻・OHLC・出来高・スプレッドの一致を確認しました
今回の原典は「HSTをCSVへ一括変換するPerlツール」¶
投稿日順で次に当たる2010年2月5日の記事は、MT4の履歴ファイルをCSVへ変換するPerlツールを紹介していました。
元記事「hstファイルをcsvに一括変換するPerlツール。」を読む
原典のツールは、ファイルまたはフォルダーをドラッグ&ドロップで受け取り、対象となるHSTファイルをまとめてCSVへ変換するものでした。フォルダーのサブ階層までは探索しない、単純な一括処理です。
当時の説明では、HSTファイルを次の固定長バイナリとして扱っていました。
- 先頭148バイト: ヘッダー
- 以降44バイトずつ: 日時、OHLC、出来高を含むレコード
この方法は、変換対象の形式とレコード配置が分かっている場合には高速です。一方、端末やファイル形式の世代が変わると、固定したバイト数や型の並びも見直さなければなりません。
今回は「複数の履歴をまとめてCSV化する」という目的だけを引き継ぎ、現在のMT5が提供する時系列APIから書き出します。
HSTを解析せず、端末に履歴を問い合わせる¶
配布インジケーターは、CopyRates()でMqlRates配列を取得します。
開始位置を1にしているのは、形成中の0番バーを除外するためです。エクスポートの途中で高値や終値が変わらない、確定済みの足だけを対象にします。
MqlRatesには次の情報がまとまっています。
| フィールド | CSV列 |
|---|---|
time | Date、Time |
open | Open |
high | High |
low | Low |
close | Close |
tick_volume | TickVolume |
spread | Spread |
real_volume | RealVolume |
生のHSTファイルを開かないため、ヘッダーのバイト数、レコード長、エンディアン、数値型の配置をエクスポーター側で決め打ちしません。
ただし、CopyRates()が成功するには、指定した銘柄と時間足の履歴が端末側で利用できる必要があります。未取得の履歴はダウンロードや構築が始まり、最初の呼び出しでは必要本数が返らないことがあります。
そのため、配布版は1秒タイマーで再試行し、全銘柄を必要本数取得できた時点で処理を完了します。完了後はタイマーを停止し、同じCSVを繰り返し上書きしません。
銘柄を選択してから一括処理する¶
初期設定の対象は次の3通貨です。
カンマで分割した後、空欄と重複を拒否し、各銘柄をSymbolSelect()で気配値表示へ追加してから履歴を取得します。
処理は対象銘柄ごとに次の順で進みます。
- 銘柄を選択する
- 確定済みの500本を取得する
- 時刻の昇順とOHLCの整合性を確認する
- 銘柄ごとのCSVへ500行を書き出す
- 全銘柄が成功したら
COMPLETEにする
1銘柄でも取得、検査、書込みに失敗すると完了扱いになりません。成功した件数だけを見て「だいたい終わった」と判定しない設計です。
CSVは古い足から新しい足へ並べる¶
CopyRates()で配列へコピーされたデータは、物理メモリ上では最も古い要素が先頭に置かれます。配布版はその順序を保ったまま、0番から末尾まで書き出します。
出力例は次のとおりです。
Date,Time,Open,High,Low,Close,TickVolume,Spread,RealVolume
2026.07.23,23:52,1.17789,1.17795,1.17786,1.17791,18,0,0
2026.07.23,23:53,1.17791,1.17796,1.17788,1.17794,24,0,0
日付と時刻を分離しているため、表計算ソフトでも列として扱いやすくなります。価格の小数桁は銘柄のSYMBOL_DIGITSに合わせます。
FileWrite()を使い、1行目に9列のヘッダー、その後に指定本数のデータ行を書きます。改行はMQL5のファイル関数に任せています。
出力先はMT5のファイルサンドボックス内です。初期設定では、端末固有のファイル領域に次の3ファイルが作られます。
任意の絶対パスへ直接書く方式ではありません。MQL5のFileOpen()が許可する領域に限定することで、出力場所の境界を明確にしています。
書き出す前に時系列とOHLCを検査する¶
CSVが作成できても、並びや値が壊れていれば変換成功とはいえません。配布版は各銘柄について、書込み前に次を確認します。
時系列¶
隣り合う日時が同一、または逆行していれば失敗です。CSV内の重複時刻や逆順を、そのまま後工程へ渡しません。
OHLC¶
各足について、少なくとも次の関係を満たすことを確認します。
さらに日時と各価格が正の値であることも確認します。
この検査は相場データの完全性を保証するものではありませんが、列ずれ、型の読み違い、明らかなOHLC破損を早い段階で見つける助けになります。
12バッファとCSV再読込みで独立検証した¶
画面上のCOMPLETEだけを合格条件にせず、配布インジケーターは12本の診断バッファを公開します。
- 全体が完了したか
- 要求ファイル数
- 出力成功数
- 失敗数
- 合計データ行数
- 1ファイルの行数
- 時刻が昇順か
- OHLC条件を満たすか
- 試行回数
- 最後のエラーコード
- 全銘柄で最も古い日時
- 全銘柄で最も新しい日時
検証EAは12バッファを読み取った後、作成された3つのCSVをインジケーターとは別経路で開き直しました。
各CSVについてヘッダー9列、データ500行、日時の重複なし、厳密な昇順、OHLC条件を確認しています。さらに、CSVの最終時刻を基準にCopyRates()から同じ500本を再取得し、日時、OHLC、ティック出来高、スプレッド、実出来高を全行で照合しました。
実行条件¶
| 項目 | 値 |
|---|---|
| MT5 Build | 5836 |
| 表示チャート | EURUSD・H1 |
| 出力対象 | EURUSD・USDJPY・GBPUSD |
| 出力時間足 | M1 |
| 本数 | 500本×3ファイル |
| 対象バー | 確定足 |
| 文字コード | UTF-8 |
| 区切り文字 | カンマ |
検証結果¶
| 確認項目 | 結果 |
|---|---|
| 配布インジケーターのコンパイル | 0エラー・0警告 |
| 独立検証EAのコンパイル | 0エラー・0警告 |
| 出力ファイル | 3 / 3 |
| データ行 | 1,500 |
| 各ファイルの行数 | 500 |
| 日時の重複 | なし |
| 日時の並び | 古い足→新しい足 |
| OHLC条件 | 全行PASS |
| 元レートとの全項目照合 | 全行PASS |
| 診断バッファ | 12本一致 |
| パネルオブジェクト | 12 |
| 実画面キャプチャー | 成功 |
| 売買注文 | なし |
検証時に作成したCSVは照合後に削除し、テスト用データを端末へ残していません。
ダウンロードと使い方¶
47_History_Batch_CSV_Exporter_v1_00.mq5 をダウンロード
MT5のIndicatorsへ保存してコンパイルし、任意のチャートへ適用してください。初回処理が完了すると、チャート左上のパネルにCOMPLETEと出力件数が表示されます。
入力パラメーターは次のとおりです。
| パラメーター | 初期値 | 役割 |
|---|---|---|
InpSymbols | EURUSD,USDJPY,GBPUSD | カンマ区切りの対象銘柄 |
InpTimeframe | PERIOD_M1 | 出力する時間足 |
InpBarsPerFile | 500 | 1銘柄あたりの確定足数 |
InpOutputFolder | MQL47_Export | ファイル領域内の出力フォルダー |
InpMaxSymbols | 10 | 受け付ける銘柄数の上限 |
InpShowPanel | true | 診断パネルを表示 |
ブローカーが銘柄名へ接尾辞を付けている場合は、実際の名称に合わせてください。たとえばEURUSD.aを利用する口座では、入力もEURUSD.aに変更します。
同名ファイルが存在する場合は上書きされます。必要なCSVは、次の実行前に別名で保存してください。
使えないこと・注意点¶
- このインジケーターはHSTファイルを直接読み込む変換ツールではありません。
- フォルダーを再帰探索せず、
InpSymbolsで指定した銘柄だけを処理します。 - CSVはティックデータではなく、指定時間足のバー情報です。
- 形成中の0番バーを除外するため、最新ティックまでの途中経過は含みません。
- 日時は取得したバーの開始時刻です。タイムゾーンは利用するブローカーのサーバー時刻に依存します。
- 週末、休場、取引停止などがあるため、隣接行の時刻が常に時間足と同じ間隔になるとは限りません。
- 必要な履歴が端末へ用意されるまで、処理が再試行されることがあります。
InpBarsPerFileは10〜100,000本に制限しています。大量出力ではメモリ使用量とファイルサイズが増えます。- 初期設定では最大10銘柄です。上限は変更できますが、入力値として50銘柄を超える設定は拒否します。
- 銘柄名からファイル名に使えない文字は
_へ置換します。 - 同じ安全なファイル名へ変換される特殊な銘柄名を複数指定する運用は避けてください。
- 出力成功後は自動更新しません。新しい確定足を追加する常時同期ツールではありません。
- CSVの値は端末が受け取った履歴です。配信元そのものの正確性までは保証しません。
- 表示とファイル出力だけを行い、注文、変更、取消、ポジション管理は行いません。
ロジック評価の結論¶
原典のPerlツールは、複数のHSTファイルを一括で扱える実用的な変換器でした。ただし、履歴ファイルの内部構造を148バイトのヘッダーと44バイトのレコードとして直接解釈する設計は、その形式を知っていることが前提です。
今回の移植では、ファイル形式を解析する責任を手放し、端末が公開しているMqlRatesを受け取る方式へ変えました。対象はファイル一覧ではなく銘柄一覧になりましたが、「複数の履歴を表計算や分析で扱えるCSVへまとめて出す」という目的は保っています。
さらに、確定足だけを対象にし、書込み前の時系列・OHLC検査と、書込み後の全行再照合を加えました。CSVが存在するだけで成功とせず、中身が元の履歴と一致するところまで確認しています。
古いバイナリ形式を読む必要が本当にあるなら、その仕様を版ごとに固定し、テストデータで解析結果を検証しなければなりません。しかし、現在の端末から現在の履歴を取り出す目的なら、まず公式APIを使う方が境界が明確です。
「ファイルを読めたか」ではなく、「必要な履歴を、期待した順序と列で、欠損なく書けたか」を合格条件にする。それが、今回の一括変換から引き継げる教訓です。
前後の記事¶
前: 【移植#46】DDEをやめて共有ファイルへ — Excel→MT5の文字列受信を安全にする
次: 【移植#48】アイコン改造をやめて端末識別バッジへ — 複数MT5を色と別名で見分ける