
MQL4 ファイル操作関数を体系的にまとめました。FileOpen()によるファイルオープン、FileClose()によるクローズ、FileWrite()/FileWriteString()による書き込み、FileReadString()/FileReadNumber()による読み込み、FileDelete()によるファイル削除、CSV/テキスト/バイナリの各モード、FileIsExist()によるファイル存在確認、トレードログの保存、設定ファイルの読み込みまで、MT4 EA開発に必要なファイル操作のすべてをコード付きで解説します。

MQL4とMQL5のファイル操作の違い
| 機能 | MQL4 | MQL5 |
|---|---|---|
| 基本関数 | ほぼ同じ | ほぼ同じ |
| ファイルパス | MQL4/Files/フォルダ | MQL5/Files/フォルダ |
| 共通フォルダ | FILE_COMMON フラグ | FILE_COMMON フラグ |
| Unicode | FILE_ANSI / FILE_UNICODE | 同じ |
| フォルダ操作 | FolderCreate/Delete(ビルド600+) | FolderCreate/Delete/Clean |
MQL4のファイル操作はセキュリティ上、MQL4/Files/フォルダ(またはテスター使用時はtester/files/)内でのみ実行できます。このサンドボックスの外にはアクセスできません。
FileOpen:ファイルを開く
int FileOpen(
string file_name, // ファイル名(Files/フォルダ内の相対パス)
int open_flags, // オープンフラグの組み合わせ
short delimiter = 't', // CSVの区切り文字
uint codepage = CP_ACP // コードページ
);
// 戻り値: ファイルハンドル(失敗時はINVALID_HANDLE)オープンフラグ
| フラグ | 説明 |
|---|---|
| FILE_READ | 読み込み用 |
| FILE_WRITE | 書き込み用 |
| FILE_BIN | バイナリモード |
| FILE_CSV | CSVモード(区切り文字対応) |
| FILE_TXT | テキストモード |
| FILE_ANSI | ANSIエンコーディング |
| FILE_UNICODE | Unicodeエンコーディング |
| FILE_COMMON | 共通フォルダを使用 |
- 通常:
MQL4/Files/フォルダ内のみアクセス可能 - テスター:
tester/files/フォルダにリダイレクトされる - FILE_COMMON: ターミナル共通フォルダ(
AppData/Roaming/MetaQuotes/Terminal/Common/Files/) - サブフォルダの作成:
FolderCreate("subfolder")(ビルド600+) - 絶対パスは指定できない(セキュリティ上の制約)
- 通常:
MQL4/Files/フォルダ内のみアクセス可能 - テスター:
tester/files/フォルダにリダイレクトされる - FILE_COMMON: ターミナル共通フォルダ(
AppData/Roaming/MetaQuotes/Terminal/Common/Files/) - 絶対パスは指定できない(セキュリティ上の制約)
CSVファイルの書き込み
void WriteTradeLog(int ticket, string action, double lots, double price)
{
string filename ="TradeLog_" + Symbol() +".csv";
int handle = FileOpen(filename, FILE_READ|FILE_WRITE|FILE_CSV, ',');
if(handle == INVALID_HANDLE)
{
Print("ファイルオープン失敗:", GetLastError());
return;
}
// ファイル末尾に移動
FileSeek(handle, 0, SEEK_END);
// ファイルが空ならヘッダーを書く
if(FileTell(handle) == 0)
FileWrite(handle,"DateTime","Action","Symbol","Ticket","Lots","Price","Balance","Equity");
// データ行を書き込み
FileWrite(handle,
TimeToStr(TimeCurrent(), TIME_DATE|TIME_SECONDS),
action,
Symbol(),
ticket,
DoubleToStr(lots, 2),
DoubleToStr(price, Digits),
DoubleToStr(AccountBalance(), 2),
DoubleToStr(AccountEquity(), 2)
);
FileClose(handle);
}CSVファイルの読み込み
void ReadTradeLog()
{
string filename ="TradeLog_" + Symbol() +".csv";
int handle = FileOpen(filename, FILE_READ|FILE_CSV, ',');
if(handle == INVALID_HANDLE)
{
Print("ファイルが見つかりません");
return;
}
// ヘッダー行をスキップ
string header = FileReadString(handle);
int lineCount = 0;
while(!FileIsEnding(handle))
{
string dateTime = FileReadString(handle);
string action = FileReadString(handle);
string symbol = FileReadString(handle);
int ticket = (int)FileReadNumber(handle);
double lots = FileReadNumber(handle);
double price = FileReadNumber(handle);
double balance = FileReadNumber(handle);
double equity = FileReadNumber(handle);
if(StringLen(dateTime) > 0)
{
Print(dateTime,"", action,"", symbol," ticket=", ticket," lots=", lots);
lineCount++;
}
}
FileClose(handle);
Print("読み込み完了:", lineCount,"行");
}FILE_READ|FILE_WRITEを同時に指定すると、既存ファイルを開いて読み書きできます。FILE_WRITEのみだとファイルが空になります。既存ファイルに追記する場合は、必ずFILE_READ|FILE_WRITEで開いてからFileSeek(handle, 0, SEEK_END)でファイル末尾に移動してください。
FILE_READ|FILE_WRITEを同時に指定すると、既存ファイルを開いて読み書きできます。FILE_WRITEのみだとファイルが空になります。既存ファイルに追記する場合は、必ずFILE_READ|FILE_WRITEで開いてからFileSeek(handle, 0, SEEK_END)でファイル末尾に移動してください。
テキストファイル操作
// テキストファイルへの書き込み
void WriteTextLog(string message)
{
string filename ="EA_Log.txt";
int handle = FileOpen(filename, FILE_READ|FILE_WRITE|FILE_TXT|FILE_ANSI);
if(handle == INVALID_HANDLE) return;
FileSeek(handle, 0, SEEK_END);
FileWriteString(handle,
TimeToStr(TimeCurrent(), TIME_DATE|TIME_SECONDS) +"" + message +"n");
FileClose(handle);
}
// テキストファイルの全文読み込み
string ReadTextFile(string filename)
{
int handle = FileOpen(filename, FILE_READ|FILE_TXT|FILE_ANSI);
if(handle == INVALID_HANDLE)
return"";
int size = (int)FileSize(handle);
string content = FileReadString(handle, size);
FileClose(handle);
return content;
}バイナリファイル操作
// 構造体をバイナリで保存
struct TradeRecord
{
int ticket;
int type;
double lots;
double openPrice;
datetime openTime;
};
void SaveTradeRecords(TradeRecord &records[], int count)
{
int handle = FileOpen("trades.bin", FILE_WRITE|FILE_BIN);
if(handle == INVALID_HANDLE) return;
// レコード数を最初に保存
FileWriteInteger(handle, count);
for(int i = 0; i < count; i++)
{
FileWriteInteger(handle, records[i].ticket);
FileWriteInteger(handle, records[i].type);
FileWriteDouble(handle, records[i].lots);
FileWriteDouble(handle, records[i].openPrice);
FileWriteInteger(handle, (int)records[i].openTime);
}
FileClose(handle);
}
int LoadTradeRecords(TradeRecord &records[])
{
int handle = FileOpen("trades.bin", FILE_READ|FILE_BIN);
if(handle == INVALID_HANDLE) return 0;
int count = FileReadInteger(handle);
ArrayResize(records, count);
for(int i = 0; i < count; i++)
{
records[i].ticket = FileReadInteger(handle);
records[i].type = FileReadInteger(handle);
records[i].lots = FileReadDouble(handle);
records[i].openPrice = FileReadDouble(handle);
records[i].openTime = (datetime)FileReadInteger(handle);
}
FileClose(handle);
return count;
}ファイルユーティリティ関数
| 関数 | 説明 |
|---|---|
| FileIsExist(filename) | ファイルの存在確認 |
| FileDelete(filename) | ファイルの削除 |
| FileMove(src, dst, flag) | ファイルの移動/リネーム |
| FileCopy(src, flag, dst, flag) | ファイルのコピー |
| FileSize(handle) | ファイルサイズ(バイト) |
| FileTell(handle) | 現在のファイル位置 |
| FileSeek(handle, offset, origin) | ファイル位置の移動 |
| FileFlush(handle) | バッファのフラッシュ |
| FileIsEnding(handle) | ファイル末尾かどうか |
| FileIsLineEnding(handle) | 行末かどうか |
| FolderCreate(path) | フォルダの作成(ビルド600+) |
| FolderDelete(path) | フォルダの削除(ビルド600+) |
void FileUtilityExample()
{
string filename ="test.txt";
// 存在確認
if(FileIsExist(filename))
Print("ファイルが存在します");
else
Print("ファイルが存在しません");
// ファイル削除
if(FileIsExist("old_log.txt"))
FileDelete("old_log.txt");
// フォルダ作成(ビルド600+)
FolderCreate("Logs");
FolderCreate("Logs2024");
// 共通フォルダへの書き込み(複数EAで共有)
int handle = FileOpen("shared_data.txt",
FILE_WRITE|FILE_TXT|FILE_COMMON);
if(handle != INVALID_HANDLE)
{
FileWriteString(handle,"共有データ");
FileClose(handle);
}
}実践: 設定ファイルの読み書き
// key=value形式の設定ファイル読み込み
string ReadSetting(string filename, string key, string defaultValue ="")
{
int handle = FileOpen(filename, FILE_READ|FILE_TXT|FILE_ANSI);
if(handle == INVALID_HANDLE)
return defaultValue;
string result = defaultValue;
while(!FileIsEnding(handle))
{
string line = FileReadString(handle);
int eqPos = StringFind(line,"=");
if(eqPos > 0)
{
string k = StringSubstr(line, 0, eqPos);
string v = StringSubstr(line, eqPos + 1);
StringTrimLeft(k); StringTrimRight(k);
StringTrimLeft(v); StringTrimRight(v);
if(k == key)
{
result = v;
break;
}
}
}
FileClose(handle);
return result;
}
// 使用例
void LoadSettings()
{
double riskPercent = StrToDouble(ReadSetting("ea_config.ini","RiskPercent","2.0"));
int maxPositions = StrToInteger(ReadSetting("ea_config.ini","MaxPositions","3"));
string allowedPairs = ReadSetting("ea_config.ini","AllowedPairs","USDJPY,GBPJPY");
Print("Risk:", riskPercent,"% MaxPos:", maxPositions," Pairs:", allowedPairs);
}ファイル操作関数一覧(MQL5対応表)
| MQL4関数 | MQL5対応 | 説明 |
|---|---|---|
| FileOpen() | FileOpen() | ファイルを開く |
| FileClose() | FileClose() | ファイルを閉じる |
| FileWrite() | FileWrite() | CSVフィールド書き込み |
| FileWriteString() | FileWriteString() | 文字列書き込み |
| FileWriteInteger() | FileWriteInteger() | 整数書き込み |
| FileWriteDouble() | FileWriteDouble() | 浮動小数点書き込み |
| FileReadString() | FileReadString() | 文字列読み込み |
| FileReadNumber() | FileReadNumber() | 数値読み込み |
| FileReadInteger() | FileReadInteger() | 整数読み込み |
| FileReadDouble() | FileReadDouble() | 浮動小数点読み込み |
| FileDelete() | FileDelete() | ファイル削除 |
| FileIsExist() | FileIsExist() | 存在確認 |
| FileSize() | FileSize() | サイズ取得 |
| FileSeek() | FileSeek() | 位置移動 |
| FileTell() | FileTell() | 現在位置取得 |
まとめ
MQL4 ファイル操作関数はMQL5とほぼ同じで、移植性が高いカテゴリです。実際に試したところ、FileOpen()後のFileClose()を忘れると実行中にファイルハンドルが枯渇します。ポイントは以下の通りです。
- ファイルはMQL4/Files/フォルダ内でのみ操作可能:セキュリティサンドボックス
- FileOpen()後は必ずFileClose()する:ファイルハンドルのリークを防ぐ
- FILE_COMMONで複数EA間のデータ共有が可能
- CSVモードはFileWrite()、テキストモードはFileWriteString()を使い分ける
次のステップとして、MQLリファレンス総合ガイドで他のカテゴリも学習しましょう。
EA本番運用では損失リスクが伴います。十分なバックテストと動作確認を経てから本番口座で稼働させてください。
MQL4ファイル操作 よくある質問
MQL4のファイル操作の基本は?
FileOpen()でファイルを開き、FileWrite()/FileWriteString()で書き込み、FileClose()で閉じる流れが基本です。ファイルはMQL4/Filesフォルダ(データフォルダ内)に保存されます。OnDeinit()でのFileClose()呼び出しを忘れずに行ってください。
MQL4でCSVファイルを書き込む方法は?
FileOpen(name, FILE_CSV|FILE_WRITE, “,”)でCSVモードで開き、FileWrite(handle, col1, col2)で1行書き込みます。FILE_ANSIを追加するとANSIエンコードになります。追記はFILE_READ|FILE_WRITEでFileSeek()してから書き込みます。
MQL4のファイル保存場所はどこですか?
MQL4/Filesフォルダ(MT4データフォルダ内)が標準保存先です。TerminalPath()でMT4インストールフォルダのパスを取得できます。FILE_COMMONフラグ(MQL4.56以降)で共通フォルダへの保存も可能です。
MQL4でファイルが存在するか確認する方法は?
FileIsExist(filename)でファイルの存在確認ができます。FileOpen()で開けたか(戻り値が-1でないか)でも確認できます。ファイルオープン失敗時はGetLastError()でエラーコードを確認し、ハンドルをINVALID_HANDLEと比較してチェックします。
MQL4でEAのトレードログを記録する方法は?
FileOpen()でFILE_WRITE|FILE_TXTモードで開き、FileWriteString()でタイムスタンプ付きログ行を追記します。TimeToStr(TimeCurrent())でタイムスタンプを生成します。ただし頻繁な書き込みはパフォーマンスに影響するため、バッファリングを検討してください。
MQL4とMQL5のファイル操作の違いは?
基本的なAPIは同じですが、MQL5ではFileFindFirst()/FileFindNext()によるファイル検索が追加されました。FILE_COMMONフラグはMQL5でより完全にサポートされています。MQL4ではFILE_ANSIとFILE_UNICODEのエンコード指定が重要です。
MQL4リファレンス 関連記事
- MQL4 取引関数:OrderSend・OrderClose・ポジション管理
- MQL4 インジケーター関数:iMA・iRSI・iCustom
- MQL4 口座・マーケット情報:ロット計算
- MQL4 イベントハンドラ:OnInit・OnTick
- MQL4 エラーコード:リトライパターン
- MQL4 時間・日付関数:取引時間フィルター
- EA始め方ガイド:MT4へのEA設定手順
⚠ リスクに関する注意事項
本記事は情報提供を目的としており、特定の金融商品の売買を推奨するものではありません。FX取引はレバレッジ取引の特性上、預託した証拠金以上の損失が生じる可能性があります。取引の際は、ご自身の判断と責任において行ってください。詳しくは特定商取引法に基づく表記をご確認ください。






