【移植#52】HST直書きをやめる — 日足CSVをMT5カスタムシンボルへ安全に取り込む¶

この記事の3行まとめ
- 旧MT4のHSTバイナリを直接組み立てず、MT5のカスタムシンボルAPIへ日足CSVを渡します
- 日付、数値、時系列順、重複、OHLC、出来高を先に検査し、1行でも異常なら履歴を書き換えません
- 専用MT5では合成データ12行をM1/D1で往復照合し、4種類の異常CSVをすべて拒否しました
今回の原典は「CSVをHSTに変換する」¶
投稿日順で次に当たる2010年2月10日の記事は、日足CSVをPerlで旧MT4のHST形式へ変換し、オフラインチャートとして開く試みです。
元記事「csvをhstに変換してMT4に取り込んでみたPerl」を読む
原典では、CSVから読み取った日付、始値、高値、安値、終値、出来高を、当時のHSTヘッダーとレコード構造へ詰めています。対象例はETFの1321で、FX以外の価格系列をMT4のチャートで見たい、という目的でした。
「外部データをチャートへ載せる」という発想は、現在も有効です。
ただし、HSTを直接作る方法には、バイナリ構造、端末の世代、配置先、サーバー名、時間足表現への依存があります。フォーマットを少し取り違えるだけでも、読めない履歴や誤った価格を作りかねません。
そこで今回は、ファイル形式を自作せず、MT5が公開しているカスタムシンボルAPIへ置き換えます。
移植版の処理フロー¶
配布するのは、通常チャートへ一度セットして実行するカスタムインジケーターです。
処理は次の順序に固定しました。
- MT5のファイル領域からCSVを読む
- ヘッダーと全行を厳格に検査する
- 入力名のカスタムシンボルを作る
- 日足1行を「00:00に始まるM1バー1本」として並べる
- 指定期間だけを
CustomRatesReplace()で置換する CopyRates()で読み戻し、時刻・OHLC・出来高を照合する- 完了または拒否理由をチャート上へ表示する
FileOpen()は、端末が管理するファイル領域へアクセスします。任意のPCパスを入力させる構成にはしていません。
カスタムシンボルはCustomSymbolCreate()で作成します。名前が同じでも、ブローカー銘柄なら上書きせず拒否します。
履歴の反映にはCustomRatesReplace()を使います。このAPIが受け取るのはM1履歴なので、各日付の00:00へ日足OHLCを1本だけ置き、D1チャートではその日の足として集計させます。
CSVは7列・昇順に固定した¶
入力形式は次の7列です。
Date,Open,High,Low,Close,TickVolume,RealVolume
2026.07.06,40120,40480,39940,40360,18240,9150
2026.07.07,40420,40610,40110,40210,17680,8840
列名は大文字小文字を含めて完全一致、日付はYYYY.MM.DD、小数点はピリオドです。引用符付きフィールド、桁区切りのカンマ、空欄、指数表記は受け付けません。
この狭い形式にした理由は、曖昧な補正をしないためです。
| 検査 | 拒否する例 |
|---|---|
| 列数・ヘッダー | 列不足、余分な列、別名の見出し |
| 日付 | 2026/07/06、存在しない日付 |
| 価格 | 空欄、文字混入、0以下 |
| 出来高 | 負数、小数、文字混入 |
| 時系列 | 同じ日付が2行、前の日付へ逆行 |
| OHLC | 高値が始値・終値より低い、安値が始値・終値より高い |
| 行数 | InpMaxRowsを超える入力 |
全行の検査が終わるまで、カスタムシンボルの履歴には触れません。
途中まで正常なCSVで最後の1行だけ壊れていても、「正常だった行だけ取り込む」動作にはしません。ファイル単位で成功か拒否かを決めます。
HST直書きから何が変わったか¶
| 観点 | 旧方式 | 今回のMT5版 |
|---|---|---|
| 保存形式 | HSTバイナリを自前生成 | MqlRates配列をAPIへ渡す |
| 銘柄 | オフラインチャート用の履歴 | MT5のカスタムシンボル |
| 更新範囲 | ファイル全体の作り直し | CSVの先頭日〜末尾日だけ置換 |
| 入力検査 | 変換処理へ依存 | 書込み前に全行を検査 |
| 書込み後確認 | チャートを目視 | CopyRates()で全項目を往復照合 |
| エラー表示 | 変換側ログ | チャートの診断パネルとログ |
CustomRatesReplace()は、指定区間の履歴を完全に置換します。区間外の既存バーは残ります。
つまり「追加だけ」のつもりで古い日付を含むCSVを実行すると、その範囲にあった既存M1バーはCSVの内容へ置き換わります。対象名と日付範囲を実行前に確認してください。
書込み後の照合は非同期を前提にした¶
履歴置換APIが12行の受理を返しても、その直後の同じイベントでD1まで利用可能になるとは限りません。
実機では、履歴キャッシュの準備中にCopyRates()が一時的に履歴未生成を返しました。そこで、置換結果を成功扱いして終了するのではなく、タイマーイベントから読み戻しを再試行します。
void OnTimer()
{
if(!g_attempted)
RunImport();
else if(g_replace_done && !g_ready)
TryFinalizeImport();
UpdateBuffers();
DrawPanel();
}
読み戻した件数が一致した後は、各行について次を比較します。
- 開始時刻
- 始値・高値・安値・終値
- Tick Volume
- Real Volume
一致して初めてSTATUS COMPLETEとround-trip PASSを表示します。
専用MT5で正常系と異常系を検証した¶
記事画像は、配布コードを専用MT5のライブチャートで動かした実画面です。
価格系列は元記事の1321実データではありません。取込ロジックだけを再現可能に検証するため、40,000前後の合成OHLCを使っています。
実行条件¶
| 項目 | 値 |
|---|---|
| MT5 Build | 6061 |
| 実行元チャート | EURUSD・H1 |
| 確認チャート | カスタムシンボル・D1 |
| CSV | 合成日足12行 |
| 売買操作 | なし |
正常系¶
| 確認項目 | 結果 |
|---|---|
| 配布インジケーターのコンパイル | 0エラー・0警告 |
| CSV読込み | 12 / 12 |
CustomRatesReplace() | 12 / 12 |
| M1読戻し | 12 / 12 |
| D1集計 | 12 / 12 |
| 時刻・OHLC・出来高の往復照合 | 12 / 12 |
| カスタムシンボル判定 | 合格 |
| 注文件数 | 0 |
異常系¶
| 入力 | 期待 | 結果 |
|---|---|---|
| 日付重複 | 書込み前に拒否 | 合格 |
| 日付の逆順 | 書込み前に拒否 | 合格 |
| 不正なOHLC | 書込み前に拒否 | 合格 |
| 価格への文字混入 | 書込み前に拒否 | 合格 |
異常系では、対象名のカスタムシンボル自体が作られていないことも確認しました。
ダウンロードと使い方¶
52_CSV_Custom_Symbol_Importer_v1_00.mq5 をダウンロード
52_Sample_Daily_OHLCV.csv をダウンロード
.mq5をMT5のIndicatorsへ保存し、MetaEditorでコンパイルします- MT5の「ファイル」→「データフォルダを開く」から
MQL5/Filesを開きます - サンプルCSV、または同じ7列形式のCSVを配置します
- 通常のチャートへインジケーターをセットします
- ファイル名、カスタムシンボル名、価格桁数を入力します
- パネルが
COMPLETEとround-trip PASSになるまで待ちます - 気配値表示のカスタムシンボルからD1チャートを開きます
主な入力値は次のとおりです。
| パラメーター | 初期値 | 役割 |
|---|---|---|
InpFileName | 52_Sample_Daily_OHLCV.csv | 読み込むCSV |
InpCustomSymbol | MQL52_SAMPLE | 作成・更新するカスタムシンボル |
InpCustomGroup | MQLPort | カスタムシンボルの表示グループ |
InpDigits | 0 | 価格の小数桁 |
InpMaxRows | 100000 | 読込み行数の上限 |
InpVerifyTimeoutSec | 30 | 読戻し照合の待機上限(秒) |
InpShowPanel | true | 診断パネルの表示 |
同名のカスタムシンボルがすでに存在する場合、価格桁数が入力値と一致するときだけ更新します。
使えないこと・注意点¶
- カスタムシンボルは分析用です。ブローカーの実銘柄へ注文する機能ではありません。
- 日足CSVを00:00のM1バーへ変換します。日付がどの市場・タイムゾーン基準かは入力側で統一してください。
- 夏時間、祝日、取引時間、配当、株式分割、価格調整を自動推定しません。
- 指定した先頭日〜末尾日の既存履歴は置換されます。別名で試してから本番用データへ反映してください。
- 日付は昇順かつ重複なしにしてください。
- 価格桁数を誤ると丸め後のOHLCが変わります。
- 大きなCSVでは処理と履歴構築に時間がかかります。まず短い期間で確認してください。
- 合成12行の検証合格は、実データの正確性や投資成果を保証しません。
ロジック評価の結論¶
原典の価値は、外部にある価格系列をMT4のチャートへ持ち込み、普段の分析道具を使えるようにしたことです。
現在のMT5では、その目的のためにHSTバイナリを再現する必要はありません。
- CSVの契約を狭く決める
- 全行を検査してから書く
- 実銘柄とカスタムシンボルを区別する
- 変更する期間を明示する
- 書いた値をAPIで読み戻す
この5点へ置き換えることで、端末内部のファイル形式から距離を取りながら、同じ「外部データをチャートで見る」という目的を実現できます。
移植で残すべきなのは、古いバイナリ構造そのものではなく、外部データを取引プラットフォームの分析へ接続する発想です。
前後の記事¶
前: 【移植#51】指値注文を通信に使わない — 期限付き停止指令を検証するリモートHALTガード
次: 【移植#53】Delete→Undoをやめる — 選択中オブジェクトを安全に読む