第二十三章 文件函数
这是一组关于文档工作的函数。
出于安全考虑,工作文件必须严格由MQL5语言管理。使用MQL5实施文件操作的文件意味着不能位于文件沙箱之外。
这是一组关于文档工作的函数。
有两个目录(包含子目录)用于放置工作文档:
• terminal_data_folder\MQL5\FILES\
(客户端菜单中点击"文件" -->
"打开数据文件夹");
• 安装在电脑中所有客户端的共用文件夹 ———— 通常在 C:\Documents and Settings\All Users\Application Data\MetaQuotes\Terminal\Common\Files
目录中。
这是一组关于文档工作的函数。
通过使用TerminalInfoString()函数,以及使用ENUM_TERMINAL_INFO_STRING 表达式,可以在程序中获得这些目录的名称:
//--- 存储程序端数据的文件夹 string terminal_data_path=TerminalInfoString(TERMINAL_DATA_PATH); //--- 客户端常用文件夹 string common_data_path=TerminalInfoString(TERMINAL_COMMONDATA_PATH);
禁止使用来自其它目录的文件。 文件函数允许使用所谓的“命名管道”。 要做到这一点,只需使用适当的参数调用FileOpen()函数即可。
函数 | 功能 |
---|---|
FileFindFirst | 根据指定的过滤条件开始搜索目录中的文件(查找) |
FileFindNext | 继续通过FileFindFirst()函数启动的搜索(查找下一个) |
FileFindClose | 结束搜索程序 |
FileOpen | 打开指定名称的文件,并且带上 标帜(标帜用于说明打开文件的用途)。 |
FileDelete | 删除指定文件 |
FileFlush | 将 输入/输出 文件缓冲区中的所有数据写入磁盘 |
FileGetInteger | 获得文件的 整数型 属性 |
FileIsEnding | 读取过程中定义文件末尾 |
FileIsLineEnding | 读取过程中定义文本行的末尾 |
FileClose | 关闭之前打开的文件 |
FileIsExist | 检测文件是否存在 |
FileCopy | 从本地或者共享文件夹中复制一个原文件到另一个目标文件 |
FileMove | 移动或者重命名文件 |
FileReadArray | 从BIN类型文件中读取任何类型的数组,除了字符串外 |
FileReadBool | 从CSV类型的文件中的当前位置读取一个字符串, 直到遇到分隔符(或直到文本行的末尾)为止, 并将读取的字符串转换为bool类型的值 |
FileReadDatetime | 从CSV文件中读取一种格式的字符串: “YYYY.MM.DD HH:MM:SS”, “YYYY.MM.DD” 或“HH:MM:SS” ---- 并将其转换为 日期时间值 |
FileReadDouble | 从文件指针当前位置读取 双精度值 |
FileReadFloat | 从文件指针当前位置读取 浮点值 |
FileReadInteger | 从文件指针当前位置读取 整型,短整型或者字符型值 |
FileReadLong | 从文件指针当前位置读取 长整型值 |
FileReadNumber | 从CSV类型的文件中的当前位置读取一个字符串, 直到遇到分隔符(或直到文本行的末尾)为止, 并将读取的字符串转换为 双精度值 |
FileReadString | 在文件中文件指针当前位置读取 字符串 |
FileReadStruct | 从二进制文件中,文件指针的当前位置,开始读取数据,作为形式参数传递给结构 |
FileSeek | 根据指定的字节数,移动文件指针的位置到相对位置 |
FileSize | 返回相应打开文件大小 |
FileTell | 返回相应打开文件的文件指针的当前位置 |
FileWrite | 向CSV或者TXT类型文件写入数据 |
FileWriteArray | 写入任何类型的数组到BIN类型文件,除字符串以外 |
FileWriteDouble | 从文件指针当前位置写入 双精度型值 到二进制文件 |
FileWriteFloat | 从文件指针当前位置写入 浮点型值 到二进制文件 |
FileWriteInteger | 从文件指针当前位置写入 整型值 到二进制文件 |
FileWriteLong | 从文件指针当前位置写入 长整型值 到二进制文件 |
FileWriteString | 从文件指针当前位置写入 字符串参数值 到BIN或者TXT文件 |
FileWriteStruct | 从文件指针当前位置写入 传递到结构的参数 到二进制文件 |
FileLoad | 将指定二进制文件的所有数据读取到 数组类型 或 简单结构的传递数组中 |
FileSave | 将传递数组所有元素写入二进制文件作为参数 |
FolderCreate | 在文件目录创建一个文件夹 |
FolderDelete | 删除选定的目录。如果文件夹不是空的,那么无法删除。 |
FolderClean | 删除指定文件夹中所有文件 |
使用FileOpen()打开文件时,在路径中指定的所有子文件夹都会自动创建(如果没有的话)。
# 23.1 FileFindFirst
此函数根据指定的过滤条件开始搜索文件夹中(包含子文件夹)的文件(查找文件)。
long FileFindFirst(
const string file_filter, // 字符串 - 搜寻过滤器
string& returned_filename, // 找到的文件名或子目录名
int common_flag=0 // 定义搜索
);
2
3
4
5
参数
file_filter
[in] 搜索过滤条件。与\Files 目录相关联的子目录(或者嵌套子目录的序列),需要寻找文件的地方,指定在过滤条件中。
returned_filename
[out] 返回参数,这里,如果成功,则此变量中保存的是第一个找到的文件或子目录名称。仅返回文件名(包括扩展名),无论它们是否在搜索过滤条件中指定,都不会包括目录和子目录名称。
common_flag
[in] 标帜,决定文件位置,如果common_flag = FILE_COMMON,表示文件在为所有客户端的共用文件夹中 \Terminal\Common\Files。否则,文件放置在客户端的数据文件夹中。
返回值
返回被搜索对象的句柄,它应该用于通过FileFindNext()函数进一步分类文件和子目录,返回搜索物件的句柄,它应该用于在没有关于过滤器的文件和子目录时(尤其是目录为空时),通过函数或INVALID_HANDLE进一步分类文件和子目录。搜索之后,句柄必须使用FileFindClose()函数来关闭。
返回搜索对象的句柄,当没有与过滤条件相符合的文件和子目录时(在特定情况下 ---- 当目录为空时),应该用FileFindNext()函数 或 INVALID_HANDLE进一步对文件和子目录进行排序。 搜索后,必须使用FileFindClose()函数关闭句柄。
注意
出于安全考虑,工作文件必须严格由MQL5语言管理。使用MQL5实施文件操作的文件意味着不能位于文件沙箱之外。
示例:
//--- 显示启动脚本时的导入参量的窗口
#property script_show_inputs
//--- 过滤条件
input string InpFilter="Dir1\\*";
//+------------------------------------------------------------------+
//| 脚本程序开始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
string file_name;
string int_dir="";
int i=1,pos=0,last_pos=-1;
//--- 搜索最后一个反斜杠
while(!IsStopped())
{
pos=StringFind(InpFilter,"\\",pos+1);
if(pos>=0)
last_pos=pos;
else
break;
}
//--- 过滤器包含文件夹名称
if(last_pos>=0)
int_dir=StringSubstr(InpFilter,0,last_pos+1);
//--- 获得搜索句柄在本地文件夹的根目录
long search_handle=FileFindFirst(InpFilter,file_name);
//--- 检查 FileFindFirst() 是否成功执行
if(search_handle!=INVALID_HANDLE)
{
//--- 检查循环中传递的字符串是否是文件或目录名称
do
{
ResetLastError();
//--- 如果这是一个文件,函数返回true,如果是目录,它返回错误 ERR_FILE_IS_DIRECTORY
FileIsExist(int_dir+file_name);
PrintFormat("%d : %s name = %s",i,GetLastError()==ERR_FILE_IS_DIRECTORY ? "Directory" : "File",file_name);
i++;
}
while(FileFindNext(search_handle,file_name));
//--- 关闭搜索句柄
FileFindClose(search_handle);
}
else
Print("Files not found!");
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
相关参考 FileFindNext, FileFindClose
# 23.2 FileFindNext
继续通过FileFindFirst()函数启动的搜索条件(查找下一个)。
bool FileFindNext(
long search_handle, // 搜索处理程序
string& returned_filename // 找到的文件或子目录的名称
);
2
3
4
参数
search_handle [in]
搜索处理,通过 FileFindFirst()恢复。
returned_filename [out]
找到的下一个文件或子目录名称。仅返回文件名(包括扩展名),无论它们是否在搜索过滤条件中指定,都不会包括目录和子目录名称。 返回值 如果成功,返回true值,否则返回false值。
示例:
//--- 启动脚本时显示输入参数的窗口
#property script_show_inputs
//--- 过滤条件
input string InpFilter="*";
//+------------------------------------------------------------------+
//| 脚本程序启动开始 |
//+------------------------------------------------------------------+
void OnStart()
{
string file_name;
int i=1;
//--- 在本地文件夹根目录下接收搜索句柄
long search_handle=FileFindFirst(InpFilter,file_name);
//--- 检查FileFindFirst()函数是否成功执行
if(search_handle!=INVALID_HANDLE)
{
//--- 检查循环中传递的字符串是否是文件或目录名称
do
{
ResetLastError();
//--- 如果是文件,函数将返回true,如果是目录,函数将生成错误ERR_FILE_IS_DIRECTORY。
FileIsExist(file_name);
PrintFormat("%d : %s name = %s",i,GetLastError()==ERR_FILE_IS_DIRECTORY ? "Directory" : "File",file_name);
i++;
}
while(FileFindNext(search_handle,file_name));
//--- 关闭搜索句柄
FileFindClose(search_handle);
}
else
Print("Files not found!");
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
相关参考 FileFindFirst, FileFindClose
# 23.3 FileFindClose
此函数关闭搜索处理。
void FileFindClose(
long search_handle // 搜索处理程序
);
2
3
参数
search_handle
[in] 通过 FileFindFirst()启动的搜索处理。
返回值
无返回值。
注意
必须调用函数来释放系统资源。
示例:
//--- 启动脚本时启动输入参数的窗口
#property script_show_inputs
//--- 过滤条件
input string InpFilter="*";
//+------------------------------------------------------------------+
//| 脚本程序启动函数 |
//+------------------------------------------------------------------+
void OnStart()
{
string file_name;
int i=1;
//--- 在本地文件夹根目录下接收搜索句柄
long search_handle=FileFindFirst(InpFilter,file_name);
//--- 检查FileFindFirst()函数是否成功执行
if(search_handle!=INVALID_HANDLE)
{
//--- 检查循环中传递的字符串是否是文件或目录名称
do
{
ResetLastError();
//--- 如果是文件,函数将返回true,如果是目录,函数将生成错误5018。
FileIsExist(file_name);
PrintFormat("%d : %s name = %s",i,GetLastError()==5018 ? "Directory" : "File",file_name);
i++;
}
while(FileFindNext(search_handle,file_name));
//--- 关闭搜索句柄
FileFindClose(search_handle);
}
else
Print("Files not found!");
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
相关参考 FileFindFirst, FileFindNext
# 23.4 FileIsExist
检测文件是否存在。
bool FileIsExist(
const string file_name, // 文件名
int common_flag=0 // 搜索区
);
2
3
4
参数
file_name
[in] 被检测的文件名
common_flag=0
[in] 标帜,决定文件位置,如果common_flag = FILE_COMMON,表示文件在为所有客户端的共用文件夹中 \Terminal\Common\Files。否则,文件放置在客户端的数据文件夹中。
返回值
如果指定文件存在返回true值。
注意
检测的文件可能是一个子文件夹目录。这种情况下,FileIsExist()函数将返回false,_LastError变量将会记录错误5018 - "这是一个目录,而不是文件" (请见FileFindFirst 函数示例)。
出于安全考虑,工作文件必须严格由MQL5语言管理。使用MQL5实施文件操作的文件意味着不能位于文件沙箱之外。
如果common_flag = FILE_COMMON,表示文件在为所有客户端的共用文件夹中 \Terminal\Common\Files,否则函数在客户端的数据文件夹中寻找文件 (MQL5 \ Files 或 MQL5 \ Tester \ Files 在本例的测试中)。
示例:
//--- 启动脚本时显示输入参数的窗口
#property script_show_inputs
//--- 旧文件的日期
input datetime InpFilesDate=D'2013.01.01 00:00';
//+------------------------------------------------------------------+
//| 脚本程序启动函数 |
//+------------------------------------------------------------------+
void OnStart()
{
string file_name; // 存储文件名称的变量
string filter="*.txt"; // 搜索文件的过滤器
datetime create_date; // 文件创建日期
string files[]; // 文件名称列表
int def_size=25; // 默认数组大小
int size=0; // 文件名称
//--- 为数组分配内存
ArrayResize(files,def_size);
//--- 在本地文件夹根目录下接收搜索句柄
long search_handle=FileFindFirst(filter,file_name);
//--- 检查FileFindFirst()函数是否成功执行
if(search_handle!=INVALID_HANDLE)
{
//--- 在循环中搜索文件
do
{
files[size]=file_name;
//--- 增加数组大小
size++;
if(size==def_size)
{
def_size+=25;
ArrayResize(files,def_size);
}
//--- 重置错误值
ResetLastError();
//--- 接收文件创建日期
create_date=(datetime)FileGetInteger(file_name,FILE_CREATE_DATE,false);
//--- 检查文件是否是旧的
if(create_date<InpFilesDate)
{
PrintFormat("%s file deleted!",file_name);
//--- 删除旧文件
FileDelete(file_name);
}
}
while(FileFindNext(search_handle,file_name));
//--- 关闭搜索句柄
FileFindClose(search_handle);
}
else
{
Print("Files not found!");
return;
}
//--- 检查已保留哪些文件
PrintFormat("Results:");
for(int i=0;i<size;i++)
{
if(FileIsExist(files[i]))
PrintFormat("%s file exists!",files[i]);
else
PrintFormat("%s file deleted!",files[i]);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
相关参考
FileFindFirst
# 23.5 FileOpen
打开指定名称的文件,并且带上 标帜(标帜用于说明打开文件的用途)。
int FileOpen(
string file_name, // 文件名
int open_flags, // 标帜的组合
short delimiter='\t', // 分隔符
uint codepage=CP_ACP // 字符集代码
);
2
3
4
5
6
参数
file_name
[in] 文件名称可以包括子文件夹,如果文件标帜为 写入(WRITE),就会创建子文件夹。
open_flags
[in] 标帜的组合。决定文件的操作方式,标帜的定义如下: FILE_READ为读取打开 FILE_WRITE 为写入展开 FILE_BIN 二进制读写模式(不转换字符串) FILE_CSV 打CSV类型文件(所有项目转换成unicode字符串 或 ansi类型,并用分隔符分开) FILE_TXT 简单的文本文件(与csv相同,但不考虑分隔符) FILE_ANSI ANSI类型的行(单字节的字符) FILE_UNICODE UNICODE类型的(双字节字符) FILE_SHARE_READ 从几个程序共享读取 FILE_SHARE_WRITE 从几个程序共享写入 FILE_COMMON 所有客户端的共同文件夹中的文件位置 \Terminal\Common\Files.
delimiter='\t'
[in] 在txt或者csv文件中使用的分隔符,如果csv文件没有指定标识符,默认为 table(8个空格),如果txt文件没有指定标识符,就不使用分隔符。如果分隔符清晰建立成0,不使用分隔符。
codepage=CP_ACP
[in] 字符编码集,最常使用的是 字符编码集 提供的枚举值常量。
返回值
如果文件成功打开,函数返回文件的句柄处理,然后访问文件数据,失败则返回 INVALID_HANDLE。
注意
出于安全考虑,工作文件必须严格由MQL5语言管理。使用MQL5实施文件操作的文件意味着不能位于文件沙箱之外。
如果文件应该以特定的编码方式(指定包含 字符编码集 的codepage参数)读取,请确保设置FILE_ANSI标帜。如果没有指定的FILE_ANSI标帜,则文本文件将以Unicode形式读取,而无需进行任何转换。
文件在客户端子文件夹 MQL5\Files(或 testing_agent_directory\MQL5\Files)中打开,如果指定了FILE_COMMON标帜,则文件在所有客户端的共同文件中打开。
"命名管道"可以根据以下规则打开: • 管道名称 是一个字符串,应该如下所示:"\servername\pipe\pipename", 这里servername ---- 网络中的服务器名称,而pipename是管道名称。如果管道用在同一个计算机上,服务器名称可以忽略,但有一个点应该被插入以替代它:"\.\pipe\pipename"。尝试连接管道的客户应该知道其名称。
• FileFlush() 和 FileSeek() 在从管道读取和写入的顺序操作之间,应该在文件开始时被调用。
特殊符号 '' 应该用于显示字符串。因此,'' 应该在MQL5应用程序编写名称时,使用双杠。这意味着上面示例应该显示如下代码:"\\servername\pipe\pipename"。
使用 命名管道 的更多信息可以查看文章"通过MetaTrader 5沟通使用命名管道,而非DLLs "
示例:
//+------------------------------------------------------------------+
//| 启动函数的脚本程序 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 错误的打开文件方法
string terminal_data_path=TerminalInfoString(TERMINAL_DATA_PATH);
string filename=terminal_data_path+"\\MQL5\\Files\\"+"fractals.csv";
int filehandle=FileOpen(filename,FILE_WRITE|FILE_CSV);
if(filehandle 0)
{
Print("Failed to open the file by the absolute path ");
Print("Error code ",GetLastError());
}
//--- “文件沙盒效应”中正确的工作方法
ResetLastError();
filehandle=FileOpen("fractals.csv",FILE_WRITE|FILE_CSV);
if(filehandle!=INVALID_HANDLE)
{
FileWrite(filehandle,TimeCurrent(),Symbol(), EnumToString(_Period));
FileClose(filehandle);
Print("FileOpen OK");
}
else Print("Operation FileOpen failed, error ",GetLastError());
//---在MQL5\Files\中创建附着目录的另一个示例
string subfolder="Research";
filehandle=FileOpen(subfolder+"\\fractals.txt",FILE_WRITE|FILE_CSV);
if(filehandle!=INVALID_HANDLE)
{
FileWrite(filehandle,TimeCurrent(),Symbol(), EnumToString(_Period));
FileClose(filehandle);
Print("The file must be created in the folder "+terminal_data_path+"\\"+subfolder);
}
else Print("File open failed, error ",GetLastError());
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
相关参考
FileFindFirst, 创建文件夹, 打开文件标记
# 23.6 FileClose
关闭先前通过 FileOpen() 打开的文件。
void FileClose(
int file_handle // 文件句柄
);
2
3
参数 file_handle [in] 由FileOpen()返回的文件描述符。 返回值 无返回值。
示例:
//--- 启动脚本时显示输入参数的窗口
#property script_show_inputs
//--- 输入参数
input string InpFileName="file.txt"; // 文件名称
input string InpDirectoryName="Data"; // 目录名称
input int InpEncodingType=FILE_ANSI; // ANSI=32 或 UNICODE=64
//+------------------------------------------------------------------+
//| 脚本程序启动函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 打印文件将要使用的路径
PrintFormat("Working %s\\Files\\ folder",TerminalInfoString(TERMINAL_DATA_PATH));
//--- 重置错误值
ResetLastError();
//--- 打开阅读文件(如果文件不存在,错误将产生)
int file_handle=FileOpen(InpDirectoryName+"//"+InpFileName,FILE_READ|FILE_TXT|InpEncodingType);
if(file_handle!=INVALID_HANDLE)
{
//--- 打印文件内容
while(!FileIsEnding(file_handle))
Print(FileReadString(file_handle));
//--- 关闭文件
FileClose(file_handle);
}
else
PrintFormat("Error, code = %d",GetLastError());
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 23.7 FileCopy
此函数从本地或者共享文件夹中复制一个原始文件到另一个目标文件中。
bool FileCopy(
const string src_file_name, // 源文件名称
int common_flag, // 位置
const string dst_file_name, // 目标文件名称
int mode_flags // 存取访问模式
);
2
3
4
5
6
参数
src_file_name
[in] 复制的文件名称。
common_flag
[in] 标帜,决定文件位置,如果common_flag = FILE_COMMON,表示文件在为所有客户端的共用文件夹中 \Terminal\Common\Files。否则,文件放置在客户端的数据文件夹中。(例如,common_flag=0)。
dst_file_name
[in] 结果文件名。
mode_flags
[in] 存取访问标帜。此参数只包括2个标签:FILE_REWRITE 和/或 FILE_COMMON ---忽略其它标签。如果文件已经存在,但未指定FILE_REWRITE标帜,文件就不能再写入,函数返回错误值。
返回值
若失败函数返回false。
注意
出于安全考虑,工作文件必须严格由MQL5语言管理。使用MQL5实施文件操作的文件意味着不能位于文件沙箱之外。
如果目标文件已经存在,则将根据mode_flags参数中FILE_REWRITE标帜的可用性进行复制。
示例:
//--- 启动脚本时显示输入参数的窗口
#property script_show_inputs
//--- 输入参数
input string InpSrc="source.txt"; // 源
input string InpDst="destination.txt"; // 复制
input int InpEncodingType=FILE_ANSI; // ANSI=32 或 UNICODE=64
//+------------------------------------------------------------------+
//| 脚本程序启动函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 显示源内容(它必须存在)
if(!FileDisplay(InpSrc))
return;
//--- 检查复制文件是否已经存在(可能没有创建)
if(!FileDisplay(InpDst))
{
//--- 复制文件不存在,无FILE_REWRITE标识复制 (正确复制)
if(FileCopy(InpSrc,0,InpDst,0))
Print("File is copied!");
else
Print("File is not copied!");
}
else
{
//--- 复制文件已经存在,尝试无FILE_REWRITE标识复制(不正确复制)
if(FileCopy(InpSrc,0,InpDst,0))
Print("File is copied!");
else
Print("File is not copied!");
//--- InpDst 文件的内容保持不变
FileDisplay(InpDst);
//--- 再次使用FILE_REWRITE标识复制(如果文件存在,正确复制)
if(FileCopy(InpSrc,0,InpDst,FILE_REWRITE))
Print("File is copied!");
else
Print("File is not copied!");
}
//--- 接收InpSrc文件复制
FileDisplay(InpDst);
}
//+------------------------------------------------------------------+
//| 阅读文件内容 |
//+------------------------------------------------------------------+
bool FileDisplay(const string file_name)
{
//--- 重置错误值
ResetLastError();
//--- 打开文件
int file_handle=FileOpen(file_name,FILE_READ|FILE_TXT|InpEncodingType);
if(file_handle!=INVALID_HANDLE)
{
//--- 在循环中显示文件内容
Print("+---------------------+");
PrintFormat("File name = %s",file_name);
while(!FileIsEnding(file_handle))
Print(FileReadString(file_handle));
Print("+---------------------+");
//--- 关闭文件
FileClose(file_handle);
return(true);
}
//--- 打开文件失败
PrintFormat("%s is not opened, error = %d",file_name,GetLastError());
return(false);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# 23.8 FileDelete
在客户端本地文件夹中删除指定文件。
bool FileDelete(
const string file_name, // 要删除的文件名
int common_flag=0 // 要删除的文件位置
);
2
3
4
参数
file_name
[in] 文件名称。
common_flag=0
[in] 标帜,决定文件位置,如果common_flag = FILE_COMMON,表示文件在为所有客户端的共用文件夹中 \Terminal\Common\Files。否则,文件放置在客户端的数据文件夹中。
返回值
如果失败函数返回 false。
注意
出于安全考虑,工作文件必须严格由MQL5语言管理。使用MQL5实施文件操作的文件意味着不能位于文件沙箱之外。
删除客户端中本地文件夹中的指定文件(MQL5\files or MQL5\tester\files in case of testing). 如果common_flag = FILE_COMMON,函数就会从所有客户端的共用文件中删除文件。
示例:
//--- 启动脚本时显示输入参数的窗口
#property script_show_inputs
//--- 旧文件的日期
input datetime InpFilesDate=D'2013.01.01 00:00';
//+------------------------------------------------------------------+
//| 脚本程序启动函数 |
//+------------------------------------------------------------------+
void OnStart()
{
string file_name; // 存储文件名称的变量
string filter="*.txt"; // 搜索文件的过滤器
datetime create_date; // 文件创建日期
string files[]; // 文件名称列表
int def_size=25; // 默认数组大小
int size=0; // 文件名称
//--- 为数组分配内存
ArrayResize(files,def_size);
//--- 在本地文件夹根目录下接收搜索句柄
long search_handle=FileFindFirst(filter,file_name);
//--- 检查FileFindFirst()函数是否成功执行
if(search_handle!=INVALID_HANDLE)
{
//--- 在循环中搜索文件
do
{
files[size]=file_name;
//--- 增加数组大小
size++;
if(size==def_size)
{
def_size+=25;
ArrayResize(files,def_size);
}
//--- 重置错误值
ResetLastError();
//--- 接收文件创建日期
create_date=(datetime)FileGetInteger(file_name,FILE_CREATE_DATE,false);
//--- 检查文件是否是旧的
if(create_date<InpFilesDate)
{
PrintFormat("%s file deleted!",file_name);
//--- 删除旧文件
FileDelete(file_name);
}
}
while(FileFindNext(search_handle,file_name));
//--- 关闭搜索句柄
FileFindClose(search_handle);
}
else
{
Print("Files not found!");
return;
}
//--- 检查已保留哪些文件
PrintFormat("Results:");
for(int i=0;i<size;i++)
{
if(FileIsExist(files[i]))
PrintFormat("%s file exists!",files[i]);
else
PrintFormat("%s file deleted!",files[i]);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# 23.9 FileMove
从本地或共用文件夹中移动一个文件到另一个文件夹中。
bool FileMove(
const string src_file_name, // 进行移动操作的文件名
int common_flag, // 位置
const string dst_file_name, // 目标文件名
int mode_flags // 访问模式
);
2
3
4
5
6
参数
src_file_name
[in] 移动/重命名的文件名称。
common_flag
[in] 标帜,决定文件位置,如果common_flag = FILE_COMMON,表示文件在为所有客户端的共用文件夹中 \Terminal\Common\Files。否则,文件放置在客户端的数据文件夹中。
dst_file_name
[in] 操作后的文件名称。
mode_flags
[in] 访问标帜。此参量只包括2个标签:FILE_REWRITE 和/或 FILE_COMMON ----忽略另外标签。如果文件已经存在并且FILE_REWRITE 标帜未指定,文件不会被写入,函数返回false值。
返回值
如果失败,函数返回false值。
注意
出于安全考虑,工作文件必须严格由MQL5语言管理。使用MQL5实施文件操作的文件意味着不能位于文件沙箱之外。
如果目标文件已经存在,则将根据mode_flags参数中FILE_REWRITE标帜的可用性进行复制。
示例:
//--- 启动脚本时显示输入参数的窗口
#property script_show_inputs
//--- 输入参数
input string InpSrcName="data.txt";
input string InpDstName="newdata.txt";
input string InpSrcDirectory="SomeFolder";
input string InpDstDirectory="OtherFolder";
//+------------------------------------------------------------------+
//| 脚本程序启动函数 |
//+------------------------------------------------------------------+
void OnStart()
{
string local=TerminalInfoString(TERMINAL_DATA_PATH);
string common=TerminalInfoString(TERMINAL_COMMONDATA_PATH);
//--- 接收文件路径
string src_path;
string dst_path;
StringConcatenate(src_path,InpSrcDirectory,"//",InpSrcName);
StringConcatenate(dst_path,InpDstDirectory,"//",InpDstName);
//--- 检查源文件是否存在(如果不 - 退出)
if(FileIsExist(src_path))
PrintFormat("%s file exists in the %s\\Files\\%s folder",InpSrcName,local,InpSrcDirectory);
else
{
PrintFormat("Error, %s source file not found",InpSrcName);
return;
}
//--- 检查结果文件是否已经存在
if(FileIsExist(dst_path,FILE_COMMON))
{
PrintFormat("%s file exists in the %s\\Files\\%s folder",InpDstName,common,InpDstDirectory);
//--- 如果文件存在,移动应该通过FILE_REWRITE标识来完成
ResetLastError();
if(FileMove(src_path,0,dst_path,FILE_COMMON|FILE_REWRITE))
PrintFormat("%s file moved",InpSrcName);
else
PrintFormat("Error! Code = %d",GetLastError());
}
else
{
PrintFormat("%s file does not exist in the %s\\Files\\%s folder",InpDstName,common,InpDstDirectory);
//--- 如果文件不存在,移动应该无需通过FILE_REWRITE标识来完成
ResetLastError();
if(FileMove(src_path,0,dst_path,FILE_COMMON))
PrintFormat("%s file moved",InpSrcName);
else
PrintFormat("Error! Code = %d",GetLastError());
}
//--- 文件被移动;我们去看看
if(FileIsExist(dst_path,FILE_COMMON) && !FileIsExist(src_path,0))
Print("Success!");
else
Print("Error!");
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
相关参考 FileIsExist
# 23.10 FileFlush
将 输入/输出 文件缓冲区中的所有保留数据写入到磁盘中。
void FileFlush(
int file_handle // 文件句柄
);
2
3
参数
file_handle
[in] 通过FileOpen()返回文件描述。
返回值
没有返回值。
注意
当在程序中编辑文件时,可能在过一段时间之后才会实际上发现数据已经写入。要即时在文件中保存数据,请使用FileFlush()函数。如果没有使用此函数,则磁盘中还未保存的部分数据,将只会在使用FileClose()函数关闭文件时写入。
当写入数据具有特定值时,应使用该函数。应该记住,频繁的函数调用可能会影响程序的运行速度。
函数FileFlush ()必须在 读取 和 写入 文件操作之间调用。
示例:
//--- 启动脚本时显示输入参数的窗口
#property script_show_inputs
//--- 编写的文件名称
input string InpFileName="example.csv"; // 文件名
//+------------------------------------------------------------------+
//| 脚本程序启动函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 重置错误值
ResetLastError();
//--- 打开文件
int file_handle=FileOpen(InpFileName,FILE_READ|FILE_WRITE|FILE_CSV);
if(file_handle!=INVALID_HANDLE)
{
//--- 写入文件数据
for(int i=0;i<1000;i++)
{
//--- 调用编写函数
FileWrite(file_handle,TimeCurrent(),SymbolInfoDouble(Symbol(),SYMBOL_BID),SymbolInfoDouble(Symbol(),SYMBOL_ASK));
//--- 每128次迭代时,在磁盘中保存数据
if((i & 127)==127)
{
//--- 现在,数据将位于文件并且不会丢失,以防严重的错误。
FileFlush(file_handle);
PrintFormat("i = %d, OK",i);
}
//--- 0.01 秒暂停
Sleep(10);
}
//--- 关闭文件
FileClose(file_handle);
}
else
PrintFormat("Error, code = %d",GetLastError());
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
相关参考 FileClose
# 23.11 FileGetInteger
获得文件的 整数型 属性。该函数有两个变体。
- 通过文件句柄获得属性。
long FileGetInteger(
int file_handle, // 文件句柄
ENUM_FILE_PROPERTY_INTEGER property_id // 属性ID
);
2
3
4
- 通过文件名称获得属性。
long FileGetInteger(
const string file_name, // 文件名
ENUM_FILE_PROPERTY_INTEGER property_id, // 属性 ID
bool common_folder=false // 文件在本地文件夹查看(false)
);
2
3
4
5
参数
file_handle
[in] 通过FileOpen()返回的文件描述。
file_name
[in] 文件名。
property_id
[in] 文件属性ID。取值范围是ENUM_FILE_PROPERTY_INTEGER枚举值之一。如果使用函数的第二种变体,您只能收到以下属性的值:FILE_EXISTS,FILE_CREATE_DATE,FILE_MODIFY_DATE, FILE_ACCESS_DATE 和 FILE_SIZE。
common_folder=false
[in] 标帜,决定文件位置,如果common_flag = FILE_COMMON,表示文件在为所有客户端的共用文件夹中 \Terminal\Common\Files。否则,文件放置在客户端的数据文件夹中。
返回值
属性的值。如果错误,则返回 -1。想要获得错误代码,请使用GetLastError()函数。
如果在通过名称获得属性时指定文件夹,函数无论如何都将有5018错误(ERR_MQL_FILE_IS_DIRECTORY),虽然返回值可能是正确的。
注意
函数经常改变错误代码。如果成功完成,错误代码重置为NULL。
示例:
//--- 启动脚本时显示输入参数的窗口
#property script_show_inputs
//--- 输入参数
input string InpFileName="data.csv";
input string InpDirectoryName="SomeFolder";
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
string path=InpDirectoryName+"//"+InpFileName;
long l=0;
//--- 打开文件
ResetLastError();
int handle=FileOpen(path,FILE_READ|FILE_CSV);
if(handle!=INVALID_HANDLE)
{
//--- 打印有关文件的所有信息
Print(InpFileName," file info:");
FileInfo(handle,FILE_EXISTS,l,"bool");
FileInfo(handle,FILE_CREATE_DATE,l,"date");
FileInfo(handle,FILE_MODIFY_DATE,l,"date");
FileInfo(handle,FILE_ACCESS_DATE,l,"date");
FileInfo(handle,FILE_SIZE,l,"other");
FileInfo(handle,FILE_POSITION,l,"other");
FileInfo(handle,FILE_END,l,"bool");
FileInfo(handle,FILE_IS_COMMON,l,"bool");
FileInfo(handle,FILE_IS_TEXT,l,"bool");
FileInfo(handle,FILE_IS_BINARY,l,"bool");
FileInfo(handle,FILE_IS_CSV,l,"bool");
FileInfo(handle,FILE_IS_ANSI,l,"bool");
FileInfo(handle,FILE_IS_READABLE,l,"bool");
FileInfo(handle,FILE_IS_WRITABLE,l,"bool");
//--- 关闭文件
FileClose(handle);
}
else
PrintFormat("%s file is not opened, ErrorCode = %d",InpFileName,GetLastError());
}
//+------------------------------------------------------------------+
//| 显示文件属性的值 |
//+------------------------------------------------------------------+
void FileInfo(const int handle,const ENUM_FILE_PROPERTY_INTEGER id,
long l,const string type)
{
//--- 接收属性值
ResetLastError();
if((l=FileGetInteger(handle,id))!=-1)
{
//--- 接收的值,以正确格式显示
if(!StringCompare(type,"bool"))
Print(EnumToString(id)," = ",l ? "true" : "false");
if(!StringCompare(type,"date"))
Print(EnumToString(id)," = ",(datetime)l);
if(!StringCompare(type,"other"))
Print(EnumToString(id)," = ",l);
}
else
Print("Error, Code = ",GetLastError());
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
相关参考
文件操作, 文件属性
# 23.12 FileIsEnding
在读取过程中定义文件的结尾。
bool FileIsEnding(
int file_handle // 文件句柄
);
2
3
参数
file_handle
[in] 通过FileOpen()返回的文件描述。
返回值
如果在读取或移动文件指针的过程中已达到文件结尾,则函数返回true。
注意
要定义文件结尾,该函数尝试从这里读取下一个字符串。如果字符串不存在,函数返回true,否则返回false。
示例:
//--- 启动脚本时显示输入参数的窗口
#property script_show_inputs
//--- 输入参数
input string InpFileName="file.txt"; // 文件名称
input string InpDirectoryName="Data"; // 目录名称
input int InpEncodingType=FILE_ANSI; // ANSI=32 或 UNICODE=64
//+------------------------------------------------------------------+
//| 脚本程序启动函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 打印文件将要使用的路径
PrintFormat("Working %s\\Files\\ folder",TerminalInfoString(TERMINAL_DATA_PATH));
//--- 重置错误值
ResetLastError();
//--- 打开文件,用于读取(如果文件不存在,错误将产生)
int file_handle=FileOpen(InpDirectoryName+"//"+InpFileName,FILE_READ|FILE_TXT|InpEncodingType);
if(file_handle!=INVALID_HANDLE)
{
//--- 打印文件内容
while(!FileIsEnding(file_handle))
Print(FileReadString(file_handle));
//--- 关闭文件
FileClose(file_handle);
}
else
PrintFormat("Error, code = %d",GetLastError());
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 23.13 FileIsLineEnding
在读取文件的过程中定义文本文件中一行的结尾。
bool FileIsLineEnding(
int file_handle // 文件句柄
);
2
3
参数
file_handle
[in] 通过FileOpen()返回的文件描述。。
返回值
如果读取 txt 文件 或 csv文件过程中到达一行的末尾,返回真值(字符CR-LF)。
示例: (此处使用的示例文件,是在执行FileWriteString函数示例期间获得的)
//+------------------------------------------------------------------+
//| Demo_FileIsLineEnding.mq5 |
//| Copyright 2013, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property indicator_chart_window
#property indicator_buffers 5
#property indicator_plots 1
//---- 图 Label1
#property indicator_label1 "Overbought & Oversold"
#property indicator_type1 DRAW_COLOR_BARS
#property indicator_color1 clrRed, clrBlue
#property indicator_style1 STYLE_SOLID
#property indicator_width1 2
//--- 读取数据的参数
input string InpFileName="RSI.csv"; // 文件名称
input string InpDirectoryName="Data"; // 目录名称
//--- 指标缓冲区
double open_buff[];
double high_buff[];
double low_buff[];
double close_buff[];
double color_buff[];
//--- 买超变量
int ovb_ind=0;
int ovb_size=0;
datetime ovb_time[];
//--- 卖超变量
int ovs_ind=0;
int ovs_size=0;
datetime ovs_time[];
//+------------------------------------------------------------------+
//| 自定义指标初始化函数 |
//+------------------------------------------------------------------+
int OnInit()
{
//--- 默认数组大小的变量
int ovb_def_size=100;
int ovs_def_size=100;
//--- 为数组分配内存
ArrayResize(ovb_time,ovb_def_size);
ArrayResize(ovs_time,ovs_def_size);
//--- 打开文件
ResetLastError();
int file_handle=FileOpen(InpDirectoryName+"//"+InpFileName,FILE_READ|FILE_CSV|FILE_ANSI);
if(file_handle!=INVALID_HANDLE)
{
PrintFormat("%s file is available for reading",InpFileName);
PrintFormat("File path: %s\\Files\\",TerminalInfoString(TERMINAL_DATA_PATH));
double value;
//--- 读取文件数据
while(!FileIsEnding(file_handle))
{
//--- 读取字符串的第一个值
value=FileReadNumber(file_handle);
//--- 根据函数结果读取不同的数组
if(value>=70)
ReadData(file_handle,ovb_time,ovb_size,ovb_def_size);
else
ReadData(file_handle,ovs_time,ovs_size,ovs_def_size);
}
//--- 关闭文件
FileClose(file_handle);
PrintFormat("Data is written, %s file is closed",InpFileName);
}
else
{
PrintFormat("Failed to open %s file, Error code = %d",InpFileName,GetLastError());
return(INIT_FAILED);
}
//--- 绑定数组
SetIndexBuffer(0,open_buff,INDICATOR_DATA);
SetIndexBuffer(1,high_buff,INDICATOR_DATA);
SetIndexBuffer(2,low_buff,INDICATOR_DATA);
SetIndexBuffer(3,close_buff,INDICATOR_DATA);
SetIndexBuffer(4,color_buff,INDICATOR_COLOR_INDEX);
//---- 设置图表上看不到的指标值
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0);
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| 读取文件的字符串数据 |
//+------------------------------------------------------------------+
void ReadData(const int file_handle,datetime &arr[],int &size,int &def_size)
{
bool flag=false;
//--- 读取直至到达字符串或文件的末尾
while(!FileIsLineEnding(file_handle) && !FileIsEnding(file_handle))
{
//--- 读取数量后转变这里
if(flag)
FileReadNumber(file_handle);
//--- 存储当前日期
arr[size]=FileReadDatetime(file_handle);
size++;
//--- 必要时增加数组大小
if(size==def_size)
{
def_size+=100;
ArrayResize(arr,def_size);
}
//--- 滑过第一迭代
flag=true;
}
}
//+------------------------------------------------------------------+
//| 自定义指标迭代函数 |
//+------------------------------------------------------------------+
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[])
{
ArraySetAsSeries(time,false);
ArraySetAsSeries(open,false);
ArraySetAsSeries(high,false);
ArraySetAsSeries(low,false);
ArraySetAsSeries(close,false);
//--- 还未处理的柱的循环
for(int i=prev_calculated;i<rates_total;i++)
{
//--- 默认为0
open_buff[i]=0;
high_buff[i]=0;
low_buff[i]=0;
close_buff[i]=0;
color_buff[i]=0;
//--- 检查任何日期是否仍然存在
if(ovb_ind<ovb_size)
for(int j=ovb_ind;j<ovb_size;j++)
{
//--- 如果日期一致,柱形在超买区域
if(time[i]==ovb_time[j])
{
open_buff[i]=open[i];
high_buff[i]=high[i];
low_buff[i]=low[i];
close_buff[i]=close[i];
//--- 0 - 红色
color_buff[i]=0;
//--- 增加计数器
ovb_ind=j+1;
break;
}
}
//--- 检查是否任何数据仍然存在
if(ovs_ind<ovs_size)
for(int j=ovs_ind;j<ovs_size;j++)
{
//--- 如果日期一致,柱形在超卖区域
if(time[i]==ovs_time[j])
{
open_buff[i]=open[i];
high_buff[i]=high[i];
low_buff[i]=low[i];
close_buff[i]=close[i];
//--- 1 - 蓝色
color_buff[i]=1;
//--- 增加计数器
ovs_ind=j+1;
break;
}
}
}
//--- 返回prev_calculated值,以便下次调用
return(rates_total);
}
//+------------------------------------------------------------------+
//| ChartEvent 事件处理程序 |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
const long &lparam,
const double &dparam,
const string &sparam
)
{
//--- 根据比例更改指标宽度
if(ChartGetInteger(0,CHART_SCALE)>3)
PlotIndexSetInteger(0,PLOT_LINE_WIDTH,2);
else
PlotIndexSetInteger(0,PLOT_LINE_WIDTH,1);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# 23.14 FileReadArray
从BIN类型文件中读取任何类型的数组,除了字符串外(可以是一个结构数组,但不包括字符串,和 动态数组)。
uint FileReadArray(
int file_handle, // 文件句柄
void& array[], // 要记录的数组
int start=0, // 开始编写数组位置
int count=WHOLE_ARRAY // 读取计数
);
2
3
4
5
6
参数
file_handle
[in] 通过FileOpen()返回的文件描述。
array[]
[out] 用于接收加载数据的数组。
start=0
[in] 写入数组的开始索引位置。
count=WHOLE_ARRAY
[in] 读取元素的数量。默认读取整个数组 (count=WHOLE_ARRAY)。
返回值
读取元素的数量。
注意
字符串数组只能从TXT类型文件中读取,如果必要的话,函数会尝试增加数组大小。
示例 (此处使用的示例文件,是在执行FileWriteArray函数示例期间获得的)
//--- 启动脚本时显示输入参数的窗口
#property script_show_inputs
//--- 输入参数
input string InpFileName="data.bin";
input string InpDirectoryName="SomeFolder";
//+------------------------------------------------------------------+
//| 存储价格数据的结构 |
//+------------------------------------------------------------------+
struct prices
{
datetime date; // 日期
double bid; // 卖价
double ask; // 买价
};
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 结构数组
prices arr[];
//--- 文件路径
string path=InpDirectoryName+"//"+InpFileName;
//--- 打开文件
ResetLastError();
int file_handle=FileOpen(path,FILE_READ|FILE_BIN);
if(file_handle!=INVALID_HANDLE)
{
//--- 读取来自数组文件的所有数据
FileReadArray(file_handle,arr);
//--- 接收数组大小
int size=ArraySize(arr);
//--- 打印数组数据
for(int i=0;i<size;i++)
Print("Date = ",arr[i].date," Bid = ",arr[i].bid," Ask = ",arr[i].ask);
Print("Total data = ",size);
//--- 关闭文件
FileClose(file_handle);
}
else
Print("File open failed, error ",GetLastError());
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
相关参考
变量, FileWriteArray
# 23.15 FileReadBool
从CSV类型的文件中的当前位置读取一个字符串,直到遇到分隔符(或直到文本行的末尾)为止,并将读取的字符串转换为bool类型的值
bool FileReadBool(
int file_handle // 文件句柄
);
2
3
参数
file_handle
[in] 通过FileOpen()返回的文件描述。
返回值
按行读取可以设置为“true”,“false”或整数“0”或“1”的符号表示。非零值被转换为逻辑真值。该函数返回转换后的值。
示例 (此处使用的示例文件,是在执行FileWrite函数示例期间获得的)
//+------------------------------------------------------------------+
//| Demo_FileReadBool.mq5 |
//| Copyright 2013, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots 2
//---- 图 Label1
#property indicator_label1 "UpSignal"
#property indicator_type1 DRAW_ARROW
#property indicator_color1 clrRed
#property indicator_style1 STYLE_SOLID
#property indicator_width1 4
//---- 图 Label2
#property indicator_label2 "DownSignal"
#property indicator_type2 DRAW_ARROW
#property indicator_color2 clrRed
#property indicator_style2 STYLE_SOLID
#property indicator_width2 4
//--- 读取数据的参数
input string InpFileName="MACD.csv"; // 文件名称
input string InpDirectoryName="Data"; // 目录名称
//--- 全局变量
int ind=0; // 指数
double upbuff[]; // 向上箭头的指标缓冲区
double downbuff[]; // 向下箭头的指标缓冲区
bool sign_buff[]; // 信号数组 (true - 买入, false - 卖出)
datetime time_buff[]; // 信号到达时间数组
int size=0; // 信号数组大小
//+------------------------------------------------------------------+
//| 自定义指标初始化函数 |
//+------------------------------------------------------------------+
int OnInit()
{
//--- 打开文件
ResetLastError();
int file_handle=FileOpen(InpDirectoryName+"//"+InpFileName,FILE_READ|FILE_CSV);
if(file_handle!=INVALID_HANDLE)
{
PrintFormat("%s file is open for reading",InpFileName);
//--- 首先,阅读信号的数量
size=(int)FileReadNumber(file_handle);
//--- 为数组分配内存
ArrayResize(sign_buff,size);
ArrayResize(time_buff,size);
//--- 读取文件数据
for(int i=0;i<size;i++)
{
//--- 信号时间
time_buff[i]=FileReadDatetime(file_handle);
//--- 信号价值
sign_buff[i]=FileReadBool(file_handle);
}
//--- 关闭文件
FileClose(file_handle);
}
else
{
PrintFormat("Failed to open %s file, Error code = %d",InpFileName,GetLastError());
return(INIT_FAILED);
}
//--- 绑定数组
SetIndexBuffer(0,upbuff,INDICATOR_DATA);
SetIndexBuffer(1,downbuff,INDICATOR_DATA);
//--- 设置PLOT_ARROW中绘制的交易品种代码
PlotIndexSetInteger(0,PLOT_ARROW,241);
PlotIndexSetInteger(1,PLOT_ARROW,242);
//---- 设置图表上看不到的指标值
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0);
PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,0);
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| 自定义指标迭代函数 |
//+------------------------------------------------------------------+
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[])
{
ArraySetAsSeries(time,false);
ArraySetAsSeries(low,false);
ArraySetAsSeries(high,false);
//--- 还未处理的柱的循环
for(int i=prev_calculated;i<rates_total;i++)
{
//--- 默认为0
upbuff[i]=0;
downbuff[i]=0;
//--- 检查任何日期是否仍然存在
if(ind<size)
{
for(int j=ind;j<size;j++)
{
//--- 如果日期一致,使用文件的值
if(time[i]==time_buff[j])
{
//--- 根据信号绘制箭头
if(sign_buff[j])
upbuff[i]=high[i];
else
downbuff[i]=low[i];
//--- 增加计数器
ind=j+1;
break;
}
}
}
}
//--- 返回prev_calculated 值,以便下次调用
return(rates_total);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
相关参考 布尔类型, FileWrite
# 23.16 FileReadDatetime
从CSV文件中读取一种格式的字符串: “YYYY.MM.DD HH:MM:SS”, “YYYY.MM.DD” 或 “HH:MM:SS” ---- 并将其转换为 日期时间值
datetime FileReadDatetime(
int file_handle // 文件句柄
);
2
3
参数
file_handle
[in] 通过FileOpen()返回的文件描述。
返回值
日期时间类型 值。
示例 (此处使用的示例文件,是在执行FileWrite函数示例期间获得的)
//+------------------------------------------------------------------+
//| Demo_FileReadDateTime.mq5 |
//| Copyright 2013, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots 2
//---- 图 Label1
#property indicator_label1 "UpSignal"
#property indicator_type1 DRAW_ARROW
#property indicator_color1 clrRed
#property indicator_style1 STYLE_SOLID
#property indicator_width1 4
//---- 图 Label2
#property indicator_label2 "DownSignal"
#property indicator_type2 DRAW_ARROW
#property indicator_color2 clrRed
#property indicator_style2 STYLE_SOLID
#property indicator_width2 4
//--- 读取数据的参数
input string InpFileName="MACD.csv"; // 文件名称
input string InpDirectoryName="Data"; // 目录名称
//--- 全局变量
int ind=0; // 指数
double upbuff[]; // 向上箭头的指标缓冲区
double downbuff[]; // 向下箭头的指标缓冲区
bool sign_buff[]; // 信号数组 (true - 买入,false - 卖出)
datetime time_buff[]; // 信号到达时间数组
int size=0; // 信号数组大小
//+------------------------------------------------------------------+
//| 自定义指标初始化函数 |
//+------------------------------------------------------------------+
int OnInit()
{
//--- 打开文件
ResetLastError();
int file_handle=FileOpen(InpDirectoryName+"//"+InpFileName,FILE_READ|FILE_CSV);
if(file_handle!=INVALID_HANDLE)
{
PrintFormat("%s file is open for reading",InpFileName);
//--- 首先,阅读信号的数量
size=(int)FileReadNumber(file_handle);
//--- 为数组分配内存
ArrayResize(sign_buff,size);
ArrayResize(time_buff,size);
//--- 读取文件数据
for(int i=0;i<size;i++)
{
//--- 信号时间
time_buff[i]=FileReadDatetime(file_handle);
//--- 信号价值
sign_buff[i]=FileReadBool(file_handle);
}
//--- 关闭文件
FileClose(file_handle);
}
else
{
PrintFormat("Failed to open %s file, Error code = %d",InpFileName,GetLastError());
return(INIT_FAILED);
}
//--- 绑定数组
SetIndexBuffer(0,upbuff,INDICATOR_DATA);
SetIndexBuffer(1,downbuff,INDICATOR_DATA);
//--- 设置PLOT_ARROW中绘制的交易品种代码
PlotIndexSetInteger(0,PLOT_ARROW,241);
PlotIndexSetInteger(1,PLOT_ARROW,242);
//---- 设置图表上看不到的指标值
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0);
PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,0);
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| 自定义指标迭代函数 |
//+------------------------------------------------------------------+
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[])
{
ArraySetAsSeries(time,false);
ArraySetAsSeries(low,false);
ArraySetAsSeries(high,false);
//--- 还未处理的柱的循环
for(int i=prev_calculated;i<rates_total;i++)
{
//--- 默认为0
upbuff[i]=0;
downbuff[i]=0;
//--- 检查任何日期是否仍然存在
if(ind<size)
{
for(int j=ind;j<size;j++)
{
//--- 如果日期一致,使用文件的值
if(time[i]==time_buff[j])
{
//--- 根据信号绘制箭头
if(sign_buff[j])
upbuff[i]=high[i];
else
downbuff[i]=low[i];
//--- 增加计数器
ind=j+1;
break;
}
}
}
}
//--- 返回prev_calculated 值,以便下次调用
return(rates_total);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
相关参考 日期时间类型, 字符串到时间, 时间到字符串, FileWrite
# 23.17 FileReadDouble
从文件指针当前位置读取 双精度值。
double FileReadDouble(
int file_handle // 文件句柄
);
2
3
参数
file_handle 参数
[in] 通过FileOpen()返回的文件描述。。 参数
返回值 参数
双精度类型值。 参数
注意 参数
关于错误的更多细节,请调用 GetLastError()。 参数
示例 (此处使用的示例文件,是在执行FileWriteDouble函数示例期间获得的)
//+------------------------------------------------------------------+
//| Demo_FileReadDouble.mq5 |
//| Copyright 2013, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots 1
//---- 图 Label1
#property indicator_label1 "MA"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrGreen
#property indicator_style1 STYLE_SOLID
#property indicator_width1 2
#property indicator_separate_window
//--- 读取数据的参数
input string InpFileName="MA.csv"; // 文件名称
input string InpDirectoryName="Data"; // 目录名称
//--- 全局变量
int ind=0;
int size=0;
double ma_buff[];
datetime time_buff[];
//--- 指标缓冲区
double buff[];
//+------------------------------------------------------------------+
//| 自定义指标初始化函数 |
//+------------------------------------------------------------------+
int OnInit()
{
//--- 打开文件
ResetLastError();
int file_handle=FileOpen(InpDirectoryName+"//"+InpFileName,FILE_READ|FILE_BIN);
if(file_handle!=INVALID_HANDLE)
{
PrintFormat("%s file is available for reading",InpFileName);
PrintFormat("File path: %s\\Files\\",TerminalInfoString(TERMINAL_DATA_PATH));
//--- 首先,阅读文件中的数据量
size=(int)FileReadDouble(file_handle);
//--- 为数组分配内存
ArrayResize(ma_buff,size);
ArrayResize(time_buff,size);
//--- 读取文件数据
for(int i=0;i<size;i++)
{
time_buff[i]=(datetime)FileReadDouble(file_handle);
ma_buff[i]=FileReadDouble(file_handle);
}
//--- 关闭文件
FileClose(file_handle);
PrintFormat("Data is written, %s file is closed",InpFileName);
}
else
{
PrintFormat("Failed to open %s file, Error code = %d",InpFileName,GetLastError());
return(INIT_FAILED);
}
//--- 绑定数组和指数为0的指标缓冲区
SetIndexBuffer(0,buff,INDICATOR_DATA);
//---- 设置图表上看不到的指标值
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0);
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| 自定义指标迭代函数 |
//+------------------------------------------------------------------+
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[])
{
ArraySetAsSeries(time,false);
//--- 还未处理的柱的循环
for(int i=prev_calculated;i<rates_total;i++)
{
//--- 默认为0
buff[i]=0;
//--- 检查任何日期是否仍然存在
if(ind<size)
{
for(int j=ind;j<size;j++)
{
//--- 如果日期一致,使用文件的值
if(time[i]==time_buff[j])
{
buff[i]=ma_buff[j];
//--- 增加计数器
ind=j+1;
break;
}
}
}
}
//--- 返回prev_calculated 值,以便下次调用
return(rates_total);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
相关参考 真实型(双精度型,浮点型), 字符串到双精度, 双精度到字符串, FileWriteDouble
# 23.18 FileReadFloat
从文件指针当前位置读取单精度 浮点值。
float FileReadFloat(
int file_handle // 文件句柄
);
2
3
参数
file_handle
[in] 通过FileOpen()返回的文件描述。
返回值
浮点类型值。
注意
关于错误的更多细节,请调用 GetLastError()。
示例 (此处使用的示例文件,是在执行FileWriteFloat函数示例期间获得的)
//+------------------------------------------------------------------+
//| Demo_FileReadFloat.mq5 |
//| Copyright 2013, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_plots 1
//---- 图 Label1
#property indicator_label1 "CloseLine"
#property indicator_type1 DRAW_COLOR_LINE
#property indicator_color1 clrRed,clrBlue
#property indicator_style1 STYLE_SOLID
#property indicator_width1 2
//--- 读取数据的参数
input string InpFileName="Close.bin"; // 文件名称
input string InpDirectoryName="Data"; // 目录名称
//--- 全局变量
int ind=0;
int size=0;
double close_buff[];
datetime time_buff[];
//--- 指标缓冲区
double buff[];
double color_buff[];
//+------------------------------------------------------------------+
//| 自定义指标初始化函数 |
//+------------------------------------------------------------------+
int OnInit()
{
int def_size=100;
//--- 为数组分配内存
ArrayResize(close_buff,def_size);
ArrayResize(time_buff,def_size);
//--- 打开文件
ResetLastError();
int file_handle=FileOpen(InpDirectoryName+"//"+InpFileName,FILE_READ|FILE_BIN);
if(file_handle!=INVALID_HANDLE)
{
PrintFormat("%s file is available for reading",InpFileName);
PrintFormat("File path: %s\\Files\\",TerminalInfoString(TERMINAL_DATA_PATH));
//--- 读取文件数据
while(!FileIsEnding(file_handle))
{
//--- 阅读时间和价格的值
time_buff[size]=(datetime)FileReadDouble(file_handle);
close_buff[size]=(double)FileReadFloat(file_handle);
size++;
//--- 如果超过增加数组大小
if(size==def_size)
{
def_size+=100;
ArrayResize(close_buff,def_size);
ArrayResize(time_buff,def_size);
}
}
//--- 关闭文件
FileClose(file_handle);
PrintFormat("Data is read, %s file is closed",InpFileName);
}
else
{
PrintFormat("Failed to open %s file, Error code = %d",InpFileName,GetLastError());
return(INIT_FAILED);
}
//--- 绑定数组和指标缓冲区
SetIndexBuffer(0,buff,INDICATOR_DATA);
SetIndexBuffer(1,color_buff,INDICATOR_COLOR_INDEX);
//---- 设置图表上看不到的指标值
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0);
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| 自定义指标迭代函数 |
//+------------------------------------------------------------------+
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[])
{
ArraySetAsSeries(time,false);
//--- 还未处理的柱的循环
for(int i=prev_calculated;i<rates_total;i++)
{
//--- 默认为0
buff[i]=0;
color_buff[i]=0; // 默认为红色
//--- 检查任何日期是否仍然存在
if(ind<size)
{
for(int j=ind;j<size;j++)
{
//--- 如果日期一致,使用文件的值
if(time[i]==time_buff[j])
{
//--- 接收价格
buff[i]=close_buff[j];
//--- 如果当前价格超过之前的价格,为蓝色
if(buff[i-1]>buff[i])
color_buff[i]=1;
//--- 增加计数器
ind=j+1;
break;
}
}
}
}
//--- 返回prev_calculated 值,以便下次调用
return(rates_total);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
相关参考
真实型(双精度型,浮点型), FileReadDouble, FileWriteFloat
# 23.19 FileReadInteger
从文件指针当前位置读取 整型,短整型或者字符型值,取决于规定字节长度。
int FileReadInteger(
int file_handle, // 文件句柄
int size=INT_VALUE // 读取字节的长度
);
2
3
4
参数
file_handle
[in] 通过FileOpen()返回的文件描述。
size=INT_VALUE
[in] 应该读取的字节数(最多4个)。提供相应的常量:CHAR_VALUE = 1,SHORT_VALUE = 2和INT_VALUE = 4,因此函数可以读取字符型(char),短整型(short) 或 整数型(int)的值。
返回值
整数型(int)的值。该函数的结果必须明确的(显式)转换为目标类型,即确定为需要读取的数据类型。由于返回了整数型(int)类型的值,因此可以轻松将其转换为任何整数值。文件指针就是被读取的字节数偏移量。
注意
当读取少于4个字节时,收到的结果总是正的。 如果读取一个或两个字节,则可以通过确定的(显式)转换为 字符型char(1字节) 或 短整型short(2个字节)来确定数字的符号。因为没有相应的基础类型,所以读取三字节数字的符号并不重要。
示例 (此处使用的示例文件,是在执行FileWriteInteger函数示例期间获得的)
//+------------------------------------------------------------------+
//| Demo_FileReadInteger.mq5 |
//| Copyright 2013, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots 1
//---- 图 Label1
#property indicator_label1 "Trends"
#property indicator_type1 DRAW_SECTION
#property indicator_color1 clrRed
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//--- 读取数据的参数
input string InpFileName="Trend.bin"; // 文件名称
input string InpDirectoryName="Data"; // 目录名称
//--- 全局变量
int ind=0;
int size=0;
datetime time_buff[];
//--- 指标缓冲区
double buff[];
//+------------------------------------------------------------------+
//| 自定义指标初始化函数 |
//+------------------------------------------------------------------+
int OnInit()
{
int def_size=100;
//--- 为数组分配内存
ArrayResize(time_buff,def_size);
//--- 打开文件
ResetLastError();
int file_handle=FileOpen(InpDirectoryName+"//"+InpFileName,FILE_READ|FILE_BIN);
if(file_handle!=INVALID_HANDLE)
{
PrintFormat("%s file is available for reading",InpFileName);
PrintFormat("File path: %s\\Files\\",TerminalInfoString(TERMINAL_DATA_PATH));
//--- 附加变量
int arr_size;
uchar arr[];
//--- 读取文件数据
while(!FileIsEnding(file_handle))
{
//--- 找出多少交易品种用于编写时间
arr_size=FileReadInteger(file_handle,INT_VALUE);
ArrayResize(arr,arr_size);
for(int i=0;i<arr_size;i++)
arr[i]=(char)FileReadInteger(file_handle,CHAR_VALUE);
//--- 存储时间价值
time_buff[size]=StringToTime(CharArrayToString(arr));
size++;
//--- 如果超过增加数组大小
if(size==def_size)
{
def_size+=100;
ArrayResize(time_buff,def_size);
}
}
//--- 关闭文件
FileClose(file_handle);
PrintFormat("Data is read, %s file is closed",InpFileName);
}
else
{
PrintFormat("Failed to open %s file, Error code = %d",InpFileName,GetLastError());
return(INIT_FAILED);
}
//--- 绑定数组和指标缓冲区
SetIndexBuffer(0,buff,INDICATOR_DATA);
//---- 设置图表上看不到的指标值
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0);
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| 自定义指标迭代函数 |
//+------------------------------------------------------------------+
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[])
{
ArraySetAsSeries(time,false);
ArraySetAsSeries(close,false);
//--- 还未处理的柱的循环
for(int i=prev_calculated;i<rates_total;i++)
{
//--- 默认为0
buff[i]=0;
//--- 检查任何日期是否仍然存在
if(ind<size)
{
for(int j=ind;j<size;j++)
{
//--- 如果日期一致,使用文件的值
if(time[i]==time_buff[j])
{
//--- 接收价格
buff[i]=close[i];
//--- 增加计数器
ind=j+1;
break;
}
}
}
}
//--- 返回prev_calculated 值,以便下次调用
return(rates_total);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
相关参考 整数到字符串, 字符串到整数, 整数类型, FileWriteInteger
# 23.20 FileReadLong
从文件指针当前位置读取 长整型值(8字节)。
long FileReadLong(
int file_handle // 文件句柄
);
2
3
参数
file_handle
[in] 通过FileOpen()返回的文件描述。
返回值
长整型值。
示例 (此处使用的示例文件,是在执行FileWriteLong函数示例期间获得的)
//+------------------------------------------------------------------+
//| Demo_FileReadLong.mq5 |
//| Copyright 2013, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property indicator_buffers 1
#property indicator_plots 1
//---- 图 Label1
#property indicator_label1 "Volume"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrYellow
#property indicator_style1 STYLE_SOLID
#property indicator_width1 2
#property indicator_separate_window
//--- 读取数据的参数
input string InpFileName="Volume.bin"; // 文件名称
input string InpDirectoryName="Data"; // 目录名称
//--- 全局变量
int ind=0;
int size=0;
long volume_buff[];
datetime time_buff[];
//--- 指标缓冲区
double buff[];
//+------------------------------------------------------------------+
//| 自定义指标初始化函数 |
//+------------------------------------------------------------------+
int OnInit()
{
//--- 打开文件
ResetLastError();
int file_handle=FileOpen(InpDirectoryName+"//"+InpFileName,FILE_READ|FILE_BIN);
if(file_handle!=INVALID_HANDLE)
{
PrintFormat("%s file is open for writing",InpFileName);
PrintFormat("File path: %s\\Files\\",TerminalInfoString(TERMINAL_DATA_PATH));
//--- 首先,阅读文件中的数据量
size=(int)FileReadLong(file_handle);
//--- 为数组分配内存
ArrayResize(volume_buff,size);
ArrayResize(time_buff,size);
//--- 读取文件数据
for(int i=0;i<size;i++)
{
time_buff[i]=(datetime)FileReadLong(file_handle);
volume_buff[i]=FileReadLong(file_handle);
}
//--- 关闭文件
FileClose(file_handle);
PrintFormat("Data is read, %s file is closed",InpFileName);
}
else
{
PrintFormat("Failed to open %s file, Error code = %d",InpFileName,GetLastError());
return(INIT_FAILED);
}
//--- 绑定数组和指数为0的指标缓冲区
SetIndexBuffer(0,buff,INDICATOR_DATA);
//---- 设置图表上看不到的指标值
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0);
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| 自定义指标迭代函数 |
//+------------------------------------------------------------------+
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[])
{
ArraySetAsSeries(time,false);
//--- 还未处理的柱的循环
for(int i=prev_calculated;i<rates_total;i++)
{
//--- 默认为0
buff[i]=0;
//--- 检查任何日期是否仍然存在
if(ind<size)
{
for(int j=ind;j<size;j++)
{
//--- 如果日期一致,使用文件的值
if(time[i]==time_buff[j])
{
buff[i]=(double)volume_buff[j];
ind=j+1;
break;
}
}
}
}
//--- 返回prev_calculated值,以便下次调用
return(rates_total);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
相关参考
整数类型, FileReadInteger, FileWriteLong
# 23.21 FileReadNumber
从CSV类型的文件中的当前位置读取一个字符串,直到遇到分隔符(或直到文本行的末尾)为止,并将读取的字符串转换为 双精度值。
double FileReadNumber(
int file_handle // 文件句柄
);
2
3
参数
file_handle
[in] 通过FileOpen()返回的文件描述。
返回值
双精度型值。
示例 (此处使用的示例文件,是在执行FileWriteString函数示例期间获得的)
//+------------------------------------------------------------------+
//| Demo_FileReadNumber.mq5 |
//| Copyright 2013, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property indicator_chart_window
#property indicator_buffers 5
#property indicator_plots 1
//---- 图 Label1
#property indicator_label1 "Overbought & Oversold"
#property indicator_type1 DRAW_COLOR_BARS
#property indicator_color1 clrRed, clrBlue
#property indicator_style1 STYLE_SOLID
#property indicator_width1 2
//--- 读取数据的参数
input string InpFileName="RSI.csv"; // 文件名称
input string InpDirectoryName="Data"; // 目录名称
//--- 指标缓冲区
double open_buff[];
double high_buff[];
double low_buff[];
double close_buff[];
double color_buff[];
//--- 超买变量
int ovb_ind=0;
int ovb_size=0;
datetime ovb_time[];
//--- 超卖变量
int ovs_ind=0;
int ovs_size=0;
datetime ovs_time[];
//+------------------------------------------------------------------+
//| 自定义指标初始化函数 |
//+------------------------------------------------------------------+
int OnInit()
{
//--- 默认数组大小的变量
int ovb_def_size=100;
int ovs_def_size=100;
//--- 为数组分配内存
ArrayResize(ovb_time,ovb_def_size);
ArrayResize(ovs_time,ovs_def_size);
//--- 打开文件
ResetLastError();
int file_handle=FileOpen(InpDirectoryName+"//"+InpFileName,FILE_READ|FILE_CSV|FILE_ANSI);
if(file_handle!=INVALID_HANDLE)
{
PrintFormat("%s file is available for reading",InpFileName);
PrintFormat("File path: %s\\Files\\",TerminalInfoString(TERMINAL_DATA_PATH));
double value;
//--- 读取文件数据
while(!FileIsEnding(file_handle))
{
//--- 读取字符串的第一个值
value=FileReadNumber(file_handle);
//--- 根据函数结果读取不同的数组
if(value>=70)
ReadData(file_handle,ovb_time,ovb_size,ovb_def_size);
else
ReadData(file_handle,ovs_time,ovs_size,ovs_def_size);
}
//--- 关闭文件
FileClose(file_handle);
PrintFormat("Data is written, %s file is closed",InpFileName);
}
else
{
PrintFormat("Failed to open %s file, Error code = %d",InpFileName,GetLastError());
return(INIT_FAILED);
}
//--- 绑定数组
SetIndexBuffer(0,open_buff,INDICATOR_DATA);
SetIndexBuffer(1,high_buff,INDICATOR_DATA);
SetIndexBuffer(2,low_buff,INDICATOR_DATA);
SetIndexBuffer(3,close_buff,INDICATOR_DATA);
SetIndexBuffer(4,color_buff,INDICATOR_COLOR_INDEX);
//---- 设置图表上看不到的指标值
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0);
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| 读取文件的字符串数据 |
//+------------------------------------------------------------------+
void ReadData(const int file_handle,datetime &arr[],int &size,int &def_size)
{
bool flag=false;
//--- 阅读直至到达字符串或文件的末尾
while(!FileIsLineEnding(file_handle) && !FileIsEnding(file_handle))
{
//--- 阅读数量后转变这里
if(flag)
FileReadNumber(file_handle);
//--- 存储当前日期
arr[size]=FileReadDatetime(file_handle);
size++;
//--- 必要时增加数组大小
if(size==def_size)
{
def_size+=100;
ArrayResize(arr,def_size);
}
//--- 滑过第一迭代
flag=true;
}
}
//+------------------------------------------------------------------+
//| 自定义指标迭代函数 |
//+------------------------------------------------------------------+
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[])
{
ArraySetAsSeries(time,false);
ArraySetAsSeries(open,false);
ArraySetAsSeries(high,false);
ArraySetAsSeries(low,false);
ArraySetAsSeries(close,false);
//--- 还未处理的柱的循环
for(int i=prev_calculated;i<rates_total;i++)
{
//--- 默认为0
open_buff[i]=0;
high_buff[i]=0;
low_buff[i]=0;
close_buff[i]=0;
color_buff[i]=0;
//--- 检查任何日期是否仍然存在
if(ovb_ind<ovb_size)
for(int j=ovb_ind;j<ovb_size;j++)
{
//--- 如果日期一致,柱形在超买区域
if(time[i]==ovb_time[j])
{
open_buff[i]=open[i];
high_buff[i]=high[i];
low_buff[i]=low[i];
close_buff[i]=close[i];
//--- 0 - 红色
color_buff[i]=0;
//--- 增加计数器
ovb_ind=j+1;
break;
}
}
//--- 检查是否任何数据仍然存在
if(ovs_ind<ovs_size)
for(int j=ovs_ind;j<ovs_size;j++)
{
//--- 如果日期一致,柱形在超卖区域
if(time[i]==ovs_time[j])
{
open_buff[i]=open[i];
high_buff[i]=high[i];
low_buff[i]=low[i];
close_buff[i]=close[i];
//--- 1 - 蓝色
color_buff[i]=1;
//--- 增加计数器
ovs_ind=j+1;
break;
}
}
}
//--- 返回prev_calculated值,以便下次调用
return(rates_total);
}
//+------------------------------------------------------------------+
//| ChartEvent 事件处理程序 |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
const long &lparam,
const double &dparam,
const string &sparam
)
{
//--- 根据比例更改指标宽度
if(ChartGetInteger(0,CHART_SCALE)>3)
PlotIndexSetInteger(0,PLOT_LINE_WIDTH,2);
else
PlotIndexSetInteger(0,PLOT_LINE_WIDTH,1);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
相关参考
FileWriteString
# 23.22 FileReadString
在文件中文件指针当前位置读取 字符串。
string FileReadString(
int file_handle, // 文件句柄
int length=-1 // 字符串长度
);
2
3
4
参数
file_handle
[in] 通过FileOpen()返回的文件描述。
length=-1
[in] 读取的字符串长度。
返回值
读取一行(字符串)。
注意
当从二进制(BIN)文件读取时。必须指定要读取的字符串的长度。从txt文件读取时,不需要指定字符串长度,字符串将从当前位置开始读取,直到遇到换行符“\ r \ n”为止。从csv文件读取时,也不需要指定字符串长度,字符串将从当前位置读到最近的一个 分隔符 或 直到文本字符串结束字符为止。
如果打开文件时,使用了 FILE_ANSI 标帜, ,则按行读取将会转换到 同一 字符代码集。
示例 (此处使用的示例文件,是在执行FileWriteInteger函数示例期间获得的)
//--- 启动脚本时显示输入参数的窗口
#property script_show_inputs
//--- 读取数据的参数
input string InpFileName="Trend.bin"; // 文件名称
input string InpDirectoryName="Data"; // 目录名称
//+------------------------------------------------------------------+
//| 脚本程序启动函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 打开文件
ResetLastError();
int file_handle=FileOpen(InpDirectoryName+"//"+InpFileName,FILE_READ|FILE_BIN|FILE_ANSI);
if(file_handle!=INVALID_HANDLE)
{
PrintFormat("%s file is available for reading",InpFileName);
PrintFormat("File path: %s\\Files\\",TerminalInfoString(TERMINAL_DATA_PATH));
//--- 附加变量
int str_size;
string str;
//--- 读取文件数据
while(!FileIsEnding(file_handle))
{
//--- 找出多少交易品种用于编写时间
str_size=FileReadInteger(file_handle,INT_VALUE);
//--- 读取字符串
str=FileReadString(file_handle,str_size);
//--- 打印字符串
PrintFormat(str);
}
//--- 关闭文件
FileClose(file_handle);
PrintFormat("Data is read, %s file is closed",InpFileName);
}
else
PrintFormat("Failed to open %s file, Error code = %d",InpFileName,GetLastError());
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
相关参考 字符串类型, 数据转换, FileWriteInteger
# 23.23 FileReadStruct
从二进制文件中,文件指针的当前位置,开始读取数据,作为形式参数传递给结构。
uint FileReadStruct(
int file_handle, // 文件句柄
const void& struct_object, // 读取的目标结构
int size=-1 // 字节中结构大小
);
2
3
4
5
参数
file_handle
[in] 打开二进制文件的文件描述句柄。
struct_object
[out] 这个结构的对象。该结构不应该包含字符串,动态数组或虚函数。
size=-1
[in] 应该读取的字节数。如果未指定大小 或 指定的值 大于 结构定义的大小,则会使用指定结构的大小为准。
返回值
如果成功,函数返回读取的字节数量,文件指针通过相同的字节数量移动。
示例 (此处使用的示例文件,是在执行FileWriteStruct函数示例期间获得的)
//+------------------------------------------------------------------+
//| Demo_FileReadStruct.mq5 |
//| Copyright 2013, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property indicator_separate_window
#property indicator_buffers 4
#property indicator_plots 1
//---- 图 Label1
#property indicator_label1 "Candles"
#property indicator_type1 DRAW_CANDLES
#property indicator_color1 clrOrange
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
#property indicator_separate_window
//--- 接收数据的参数
input string InpFileName="EURUSD.txt"; // 文件名称
input string InpDirectoryName="Data"; // 目录名称
//+------------------------------------------------------------------+
//| 存储蜡烛图数据的结构 |
//+------------------------------------------------------------------+
struct candlesticks
{
double open; // 开盘价
double close; // 收盘价
double high; // 最高价
double low; // 最低价
datetime date; // 日期
};
//--- 指标缓冲区
double open_buff[];
double close_buff[];
double high_buff[];
double low_buff[];
//--- 全局变量
candlesticks cand_buff[];
int size=0;
int ind=0;
//+------------------------------------------------------------------+
//| 自定义指标初始化函数 |
//+------------------------------------------------------------------+
int OnInit()
{
int default_size=100;
ArrayResize(cand_buff,default_size);
//--- 打开文件
ResetLastError();
int file_handle=FileOpen(InpDirectoryName+"//"+InpFileName,FILE_READ|FILE_BIN|FILE_COMMON);
if(file_handle!=INVALID_HANDLE)
{
PrintFormat("%s file is available for reading",InpFileName);
PrintFormat("File path: %s\\Files\\",TerminalInfoString(TERMINAL_COMMONDATA_PATH));
//--- 读取文件数据
while(!FileIsEnding(file_handle))
{
//--- 编写数组数据
FileReadStruct(file_handle,cand_buff[size]);
size++;
//--- 检查数组是否超过
if(size==default_size)
{
//--- 增加数组维数
default_size+=100;
ArrayResize(cand_buff,default_size);
}
}
//--- 关闭文件
FileClose(file_handle);
PrintFormat("Data is read, %s file is closed",InpFileName);
}
else
{
PrintFormat("Failed to open %s file, Error code = %d",InpFileName,GetLastError());
return(INIT_FAILED);
}
//--- 指标缓冲区映射
SetIndexBuffer(0,open_buff,INDICATOR_DATA);
SetIndexBuffer(1,high_buff,INDICATOR_DATA);
SetIndexBuffer(2,low_buff,INDICATOR_DATA);
SetIndexBuffer(3,close_buff,INDICATOR_DATA);
//--- 空值
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0);
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| 自定义指标迭代函数 |
//+------------------------------------------------------------------+
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[])
{
ArraySetAsSeries(time,false);
//--- 还未处理的蜡烛图的循环
for(int i=prev_calculated;i<rates_total;i++)
{
//--- 默认为0
open_buff[i]=0;
close_buff[i]=0;
high_buff[i]=0;
low_buff[i]=0;
//--- 检查任何日期是否仍然存在
if(ind<size)
{
for(int j=ind;j<size;j++)
{
//--- 如果日期一致,使用文件的值
if(time[i]==cand_buff[j].date)
{
open_buff[i]=cand_buff[j].open;
close_buff[i]=cand_buff[j].close;
high_buff[i]=cand_buff[j].high;
low_buff[i]=cand_buff[j].low;
//--- 增加计数器
ind=j+1;
break;
}
}
}
}
//--- 返回prev_calculated 值,以便下次调用
return(rates_total);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
相关参考
结构和类, FileWriteStruct
# 23.24 FileSeek
根据指定的字节数,移动文件指针的位置到相对位置。
bool FileSeek(
int file_handle, // 文件句柄
long offset, // 字节
ENUM_FILE_POSITION origin // 参考位置
);
2
3
4
5
参数
file_handle
[in] 通过FileOpen()返回的文件描述。
offset
[in] 字节偏移步长(也许获取负值)。
origin
[in] 移动的起始点。取值范围是 ENUM_FILE_POSITION枚举值之一。
返回值
如果成功返回true, 否则false。关于错误的更多细节,请调用 GetLastError()。
注意
如果FileSeek()函数的执行导致负移位(超出文件的“水平边界”),则文件指针将被设置到文件开头处。
如果指针位置的设置超出文件的“右边界”(大于文件大小),则下一次写入文件将不会从文件末尾执行,而会从设置的指针位置执行。在这种情况下,将为前一个文件的末尾 和 指针位置设置一个不确定的值。
示例 :
//+------------------------------------------------------------------+
//| Demo_FileSeek.mq5 |
//| Copyright 2013, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
//--- 启动脚本时显示输入参数的窗口
#property script_show_inputs
//--- 输入参数
input string InpFileName="file.txt"; // 文件名称
input string InpDirectoryName="Data"; // 目录名称
input int InpEncodingType=FILE_ANSI; // ANSI=32 或 UNICODE=64
//+------------------------------------------------------------------+
//| 脚本程序启动函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 指定生成随机数字的变量值
_RandomSeed=GetTickCount();
//--- 字符串起始点位置的变量
ulong pos[];
int size;
//--- 重置错误值
ResetLastError();
//--- 打开文件
int file_handle=FileOpen(InpDirectoryName+"//"+InpFileName,FILE_READ|FILE_TXT|InpEncodingType);
if(file_handle!=INVALID_HANDLE)
{
PrintFormat("%s file is available for reading",InpFileName);
//--- 接收文件中每个字符串的起始位置
GetStringPositions(file_handle,pos);
//--- 定义文件中的字符串数量
size=ArraySize(pos);
if(!size)
{
//--- 如果文件没有字符串,则停止
PrintFormat("%s file is empty!",InpFileName);
FileClose(file_handle);
return;
}
//--- 随机选择一个字符串数
int ind=MathRand()%size;
//--- 字符串起始点的转换位置
if(FileSeek(file_handle,pos[ind],SEEK_SET)==true)
{
//--- 阅读和打印ind数字的字符串
PrintFormat("String text with %d number: \"%s\"",ind,FileReadString(file_handle));
}
//--- 关闭文件
FileClose(file_handle);
PrintFormat("%s file is closed",InpFileName);
}
else
PrintFormat("Failed to open %s file, Error code = %d",InpFileName,GetLastError());
}
//+-------------------------------------------------------------------------------+
//| 函数定义了文件中每个字符串的起始点并在arr数组放置它 |
//| |
//+-------------------------------------------------------------------------------+
void GetStringPositions(const int handle,ulong &arr[])
{
//--- 默认数组大小
int def_size=127;
//--- 为数组分配内存
ArrayResize(arr,def_size);
//--- 字符串计数器
int i=0;
//--- 如果这不是文件结尾,那么至少有一个字符串
if(!FileIsEnding(handle))
{
arr[i]=FileTell(handle);
i++;
}
else
return; // 文件为空,退出
//--- 根据编码定义字节转换
int shift;
if(FileGetInteger(handle,FILE_IS_ANSI))
shift=1;
else
shift=2;
//--- 通过循环中的字符串
while(1)
{
//--- 阅读字符串
FileReadString(handle);
//--- 检查文件结尾
if(!FileIsEnding(handle))
{
//--- 存储下一个字符串的位置
arr[i]=FileTell(handle)+shift;
i++;
//--- 如果超过增加数组大小
if(i==def_size)
{
def_size+=def_size+1;
ArrayResize(arr,def_size);
}
}
else
break; // 文件结尾,退出
}
//--- 定义数组的实际大小
ArrayResize(arr,i);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# 23.25 FileSiez
函数返回文件字节大小。
ulong FileSize(
int file_handle // 文件句柄
);
2
3
参数
file_handle
[in] 通过FileOpen()返回的文件描述。
返回值
整型值。
注意
关于错误的更多细节,请调用 GetLastError()。
示例 :
//--- 启动脚本时显示输入参数的窗口
#property script_show_inputs
//--- 输入参数
input ulong InpThresholdSize=20; // 千字节的文件门槛大小
input string InpBigFolderName="big"; // 大型文件的文件夹
input string InpSmallFolderName="small"; // 小型文件的文件夹
//+------------------------------------------------------------------+
//| 脚本程序启动函数 |
//+------------------------------------------------------------------+
void OnStart()
{
string file_name; // 存储文件名称的变量
string filter="*.csv"; // 搜索文件的过滤器
ulong file_size=0; // 文件的字节大小
int size=0; // 文件数
//--- 打印我们将要使用的文件路径
PrintFormat("Working in %s\\Files\\ folder",TerminalInfoString(TERMINAL_COMMONDATA_PATH));
//--- 接收所有程序端普通文件夹根目录下的搜索程序
long search_handle=FileFindFirst(filter,file_name,FILE_COMMON);
//--- 检查FileFindFirst()是否成功执行
if(search_handle!=INVALID_HANDLE)
{
//--- 根据大小循环移动文件
do
{
//--- 打开文件
ResetLastError();
int file_handle=FileOpen(file_name,FILE_READ|FILE_CSV|FILE_COMMON);
if(file_handle!=INVALID_HANDLE)
{
//--- 接收文件大小
file_size=FileSize(file_handle);
//--- 关闭文件
FileClose(file_handle);
}
else
{
PrintFormat("Failed to open %s file, Error code = %d",file_name,GetLastError());
continue;
}
//--- 打印文件大小
PrintFormat("Size of %s file is equal to %d bytes",file_name,file_size);
//--- 定义移动文件的路径
string path;
if(file_size>InpThresholdSize*1024)
path=InpBigFolderName+"//"+file_name;
else
path=InpSmallFolderName+"//"+file_name;
//--- 移动文件
ResetLastError();
if(FileMove(file_name,FILE_COMMON,path,FILE_REWRITE|FILE_COMMON))
PrintFormat("%s file is moved",file_name);
else
PrintFormat("Error, code = %d",GetLastError());
}
while(FileFindNext(search_handle,file_name));
//--- 关闭搜索程序
FileFindClose(search_handle);
}
else
Print("Files not found!");
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# 23.26 FileTell
返回相应打开文件的文件指针的当前位置。
ulong FileTell(
int file_handle // 文件句柄
);
2
3
参数
file_handle
[in] 通过FileOpen()返回的文件描述。
返回值
对应从文件开头 到 指针当前位置,以字节数表示。
注意
关于错误的更多细节,请调用 GetLastError()。
示例:
//+------------------------------------------------------------------+
//| Demo_FileTell.mq5 |
//| Copyright 2013, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
//--- 启动脚本时显示输入参数的窗口
#property script_show_inputs
//--- 输入参数
input string InpFileName="file.txt"; // 文件名称
input string InpDirectoryName="Data"; // 目录名称
input int InpEncodingType=FILE_ANSI; // ANSI=32 或 UNICODE=64
//+------------------------------------------------------------------+
//| 脚本程序启动函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 指定生成随机数字的变量值
_RandomSeed=GetTickCount();
//--- 字符串起始点位置的变量
ulong pos[];
int size;
//--- 重置错误值
ResetLastError();
//--- 打开文件
int file_handle=FileOpen(InpDirectoryName+"//"+InpFileName,FILE_READ|FILE_TXT|InpEncodingType);
if(file_handle!=INVALID_HANDLE)
{
PrintFormat("%s file is available for reading",InpFileName);
//--- 接收文件中每个字符串的起始位置
GetStringPositions(file_handle,pos);
//--- 定义文件中的字符串数量
size=ArraySize(pos);
if(!size)
{
//--- 如果文件没有字符串,则停止
PrintFormat("%s file is empty!",InpFileName);
FileClose(file_handle);
return;
}
//--- 随机选择一个字符串数
int ind=MathRand()%size;
//--- 字符串起始点的转换位置
FileSeek(file_handle,pos[ind],SEEK_SET);
//--- 阅读和打印ind数字的字符串
PrintFormat("String text with %d number: \"%s\"",ind,FileReadString(file_handle));
//--- 关闭文件
FileClose(file_handle);
PrintFormat("%s file is closed",InpFileName);
}
else
PrintFormat("Failed to open %s file, Error code = %d",InpFileName,GetLastError());
}
//+-------------------------------------------------------------------------------+
//| 函数定义了文件中每个字符串的起始点并在arr数组放置它 |
//| |
//+-------------------------------------------------------------------------------+
void GetStringPositions(const int handle,ulong &arr[])
{
//--- 默认数组大小
int def_size=127;
//--- 为数组分配内存
ArrayResize(arr,def_size);
//--- 字符串计数器
int i=0;
//--- 如果这不是文件结尾,那么至少有一个字符串
if(!FileIsEnding(handle))
{
arr[i]=FileTell(handle);
i++;
}
else
return; // 文件为空,退出
//--- 根据编码定义字节转换
int shift;
if(FileGetInteger(handle,FILE_IS_ANSI))
shift=1;
else
shift=2;
//--- 通过循环中的字符串
while(1)
{
//--- 阅读字符串
FileReadString(handle);
//--- 检查文件结尾
if(!FileIsEnding(handle))
{
//--- 存储下一个字符串的位置
arr[i]=FileTell(handle)+shift;
i++;
//--- 如果超过增加数组大小
if(i==def_size)
{
def_size+=def_size+1;
ArrayResize(arr,def_size);
}
}
else
break; // 文件结尾,退出
}
//--- 定义数组的实际大小
ArrayResize(arr,i);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# 23.27 FileWrite
向CSV或者TXT类型文件写入数据。该函数用于将数据写入CSV文件,分隔符将自动插入,除非其等于0。在写入文件后,会添加行结束字符“\ r \ n”。
uint FileWrite(
int file_handle, // 文件句柄
... // 记录参数的列表
);
2
3
4
参数
file_handle
[in] 通过FileOpen()返回的文件描述。
...
[in] 参数表由逗号分开,写入文件中,写入参数的数量最高为63个。
返回值
写入的字节数。
注意
数量转换成文本输出(参看Print()函数)。双精度数据以小数点后16位精确度输出,数据以传统或科学模式显示-依据该模式是最紧凑的。浮点型数据以小数点后5位显示,为了以不同精确度输出真实数字或以清晰的指定模式,使用 DoubleToString()。
数字将在输出中转换为文本(请参阅Print()函数)。双精度型数据以小数点后16位的精度输出,数据可以按 传统 或 科学形式 显示 ---- 取决于哪种格式更紧凑。浮点类型的数据在小数点后显示5位数字。要以不同的 精度 或 以明确指定的格式 输出实数,请使用DoubleToString()。
布尔类型数量以true" 或者 "false"字符串显示,日期时间类型的数字以"YYYY.MM.DD HH:MI:SS"的格式显示。
示例 :
//+------------------------------------------------------------------+
//| Demo_FileWrite.mq5 |
//| Copyright 2013, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
//--- 启动脚本时显示输入参数的窗口
#property script_show_inputs
//--- 接收程序端数据的参数
input string InpSymbolName="EURUSD"; // 货币组
input ENUM_TIMEFRAMES InpSymbolPeriod=PERIOD_H1; // 时间帧
input int InpFastEMAPeriod=12; // 快速 EMA 周期
input int InpSlowEMAPeriod=26; // 慢速 EMA 周期
input int InpSignalPeriod=9; // 不同平均周期
input ENUM_APPLIED_PRICE InpAppliedPrice=PRICE_CLOSE; // 价格类型
input datetime InpDateStart=D'2012.01.01 00:00'; // 复制起始日期的数据
//--- 编写文件数据的参数
input string InpFileName="MACD.csv"; // 文件名称
input string InpDirectoryName="Data"; // 目录名称
//+------------------------------------------------------------------+
//| 脚本程序启动函数 |
//+------------------------------------------------------------------+
void OnStart()
{
datetime date_finish; // 复制结束日期的数据
bool sign_buff[]; // 信号数组 (true - 买入,false - 卖出)
datetime time_buff[]; // 信号到达时间数组
int sign_size=0; // 信号数组大小
double macd_buff[]; // 指标值数组
datetime date_buff[]; // 指标日期数组
int macd_size=0; // 指标数组大小
//--- 结束时间是当前时间
date_finish=TimeCurrent();
//--- 接收 MACD 指标句柄
ResetLastError();
int macd_handle=iMACD(InpSymbolName,InpSymbolPeriod,InpFastEMAPeriod,InpSlowEMAPeriod,InpSignalPeriod,InpAppliedPrice);
if(macd_handle==INVALID_HANDLE)
{
//--- 接收指标句柄失败
PrintFormat("Error when receiving indicator handle. Error code = %d",GetLastError());
return;
}
//--- 循环直至指标计算所有值
while(BarsCalculated(macd_handle)==-1)
Sleep(10); // 暂停允许指标计算所有值
//--- 复制某段时间周期的指标值
ResetLastError();
if(CopyBuffer(macd_handle,0,InpDateStart,date_finish,macd_buff)==-1)
{
PrintFormat("Failed to copy indicator values. Error code = %d",GetLastError());
return;
}
//--- 复制相应的指标值时间
ResetLastError();
if(CopyTime(InpSymbolName,InpSymbolPeriod,InpDateStart,date_finish,date_buff)==-1)
{
PrintFormat("Failed to copy time values. Error code = %d",GetLastError());
return;
}
//--- 释放指标占据的内存
IndicatorRelease(macd_handle);
//--- 接收缓冲区大小
macd_size=ArraySize(macd_buff);
//--- 分析数据,保存数组的指标信号
ArrayResize(sign_buff,macd_size-1);
ArrayResize(time_buff,macd_size-1);
for(int i=1;i<macd_size;i++)
{
//--- 买入信号
if(macd_buff[i-1]<0 && macd_buff[i]>=0)
{
sign_buff[sign_size]=true;
time_buff[sign_size]=date_buff[i];
sign_size++;
}
//--- 卖出信号
if(macd_buff[i-1]>0 && macd_buff[i]<=0)
{
sign_buff[sign_size]=false;
time_buff[sign_size]=date_buff[i];
sign_size++;
}
}
//--- 打开编写指标值的文件(如果文件不在,则自动创建)
ResetLastError();
int file_handle=FileOpen(InpDirectoryName+"//"+InpFileName,FILE_READ|FILE_WRITE|FILE_CSV);
if(file_handle!=INVALID_HANDLE)
{
PrintFormat("%s file is available for writing",InpFileName);
PrintFormat("File path: %s\\Files\\",TerminalInfoString(TERMINAL_DATA_PATH));
//--- 首先,写下信号的数量
FileWrite(file_handle,sign_size);
//--- 写下文件的信号时间和信号值
for(int i=0;i<sign_size;i++)
FileWrite(file_handle,time_buff[i],sign_buff[i]);
//--- 关闭文件
FileClose(file_handle);
PrintFormat("Data is written, %s file is closed",InpFileName);
}
else
PrintFormat("Failed to open %s file, Error code = %d",InpFileName,GetLastError());
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
相关参考 注释, 打印, 字符串格式化
# 23.28 FileWriteArray
写入任何类型的数组到BIN类型文件,除字符串以外(可以是不包含字符串 或 动态数组的结构数组)。
uint FileWriteArray(
int file_handle, // 文件句柄
const void& array[], // 数组
int start=0, // 数组中的开始索引编号
int count=WHOLE_ARRAY // 单元号
);
2
3
4
5
6
参数
file_handle
[in] 通过FileOpen()返回的文件描述。
array[]
[out] 记录数组。
start=0
[in] 数组的索引开始位置(第一个记录元素的索引编号)。
count=WHOLE_ARRAY
[in] 要写入的项目元素数量(WHOLE_ARRAY意味着数组中的全部元素都将被写入文件中)。
返回值
记录元素项目的总数量。
注意
字符串数组可以记录在TXT文件中,字符串可以自动以 "\r\n"字节结尾,依据文件的字符代码集类型 ANSI 或者 UNICODE,字符串可以转换成ANSI编码。
示例 :
//+------------------------------------------------------------------+
//| Demo_FileWriteArray.mq5 |
//| Copyright 2013, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
//--- 输入参数
input string InpFileName="data.bin";
input string InpDirectoryName="SomeFolder";
//+------------------------------------------------------------------+
//| 存储价格数据的结构 |
//+------------------------------------------------------------------+
struct prices
{
datetime date; // 日期
double bid; // 买入价
double ask; // 卖出价
};
//--- 全局变量
int count=0;
int size=20;
string path=InpDirectoryName+"//"+InpFileName;
prices arr[];
//+------------------------------------------------------------------+
//| 专家初始化函数 |
//+------------------------------------------------------------------+
int OnInit()
{
//--- 为数组分配内存
ArrayResize(arr,size);
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| 专家去初始化函数 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- 如果计数,编写其余的计数字符串<n
WriteData(count);
}
//+------------------------------------------------------------------+
//| 专家订单号函数 |
//+------------------------------------------------------------------+
void OnTick()
{
//--- 保存数组数据
arr[count].date=TimeCurrent();
arr[count].bid=SymbolInfoDouble(Symbol(),SYMBOL_BID);
arr[count].ask=SymbolInfoDouble(Symbol(),SYMBOL_ASK);
//--- 显示当前数据
Print("Date = ",arr[count].date," Bid = ",arr[count].bid," Ask = ",arr[count].ask);
//--- 增加计数器
count++;
//--- 如果填写数组,向文件写入数据和零
if(count==size)
{
WriteData(size);
count=0;
}
}
//+------------------------------------------------------------------+
//| 向文件写下数组的n元素 |
//+------------------------------------------------------------------+
void WriteData(const int n)
{
//--- 打开文件
ResetLastError();
int handle=FileOpen(path,FILE_READ|FILE_WRITE|FILE_BIN);
if(handle!=INVALID_HANDLE)
{
//--- 向文件结尾写下数组数据
FileSeek(handle,0,SEEK_END);
FileWriteArray(handle,arr,0,n);
//--- 关闭文件
FileClose(handle);
}
else
Print("Failed to open the file, error ",GetLastError());
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
相关参考 变量 , FileSeek
# 23.29 FileWriteDouble
从文件指针当前位置写入 双精度型值 到二进制文件。
uint FileWriteDouble(
int file_handle, // 文件句柄
double value // 书写值
);
2
3
4
参数
file_handle
[in] 通过FileOpen()返回的文件描述。
value
[in] 双精度类型值。
返回值
如果成功,函数返回写入的字节数(在这种情况下sizeof(double)= 8)。文件指针移动的步长与字节数相同。
示例 :
//+------------------------------------------------------------------+
//| Demo_FileWriteDouble.mq5 |
//| Copyright 2013, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
//--- 启动脚本时显示输入参数的窗口
#property script_show_inputs
//--- 接收程序端数据的参数
input string InpSymbolName="EURJPY"; // 货币组
input ENUM_TIMEFRAMES InpSymbolPeriod=PERIOD_M15; // 时间帧
input int InpMAPeriod=10; // 平滑期
input int InpMAShift=0; // 指标变化
input ENUM_MA_METHOD InpMAMethod=MODE_SMA; // 平滑类型
input ENUM_APPLIED_PRICE InpAppliedPrice=PRICE_CLOSE; // 价格类型
input datetime InpDateStart=D'2013.01.01 00:00'; // 复制起始日期的数据
//--- 编写文件数据的参数
input string InpFileName="MA.csv"; // 文件名称
input string InpDirectoryName="Data"; // 目录名称
//+------------------------------------------------------------------+
//| 脚本程序启动函数 |
//+------------------------------------------------------------------+
void OnStart()
{
datetime date_finish=TimeCurrent();
double ma_buff[];
datetime time_buff[];
int size;
//--- 接收 MA 指标句柄
ResetLastError();
int ma_handle=iMA(InpSymbolName,InpSymbolPeriod,InpMAPeriod,InpMAShift,InpMAMethod,InpAppliedPrice);
if(ma_handle==INVALID_HANDLE)
{
//--- 接收指标句柄失败
PrintFormat("Error when receiving indicator handle. Error code = %d",GetLastError());
return;
}
//--- 循环直至指标计算所有值
while(BarsCalculated(ma_handle)==-1)
Sleep(20); // 暂停允许指标计算所有值
PrintFormat("Indicator values starting from %s will be written to the file",TimeToString(InpDateStart));
//--- 复制指标值
ResetLastError();
if(CopyBuffer(ma_handle,0,InpDateStart,date_finish,ma_buff)==-1)
{
PrintFormat("Failed to copy the indicator values. Error code = %d",GetLastError());
return;
}
//--- 复制相应的柱形到达时间
ResetLastError();
if(CopyTime(InpSymbolName,InpSymbolPeriod,InpDateStart,date_finish,time_buff)==-1)
{
PrintFormat("Failed to copy time values. Error code = %d",GetLastError());
return;
}
//--- 接收缓冲区大小
size=ArraySize(ma_buff);
//--- 释放指标占据的内存
IndicatorRelease(ma_handle);
//--- 打开编写指标值的文件(如果文件不在,则自动创建)
ResetLastError();
int file_handle=FileOpen(InpDirectoryName+"//"+InpFileName,FILE_READ|FILE_WRITE|FILE_BIN);
if(file_handle!=INVALID_HANDLE)
{
PrintFormat("%s file is available for writing",InpFileName);
PrintFormat("File path: %s\\Files\\",TerminalInfoString(TERMINAL_DATA_PATH));
//--- 首先,写下数据样本的大小
FileWriteDouble(file_handle,(double)size);
//--- 写下文件的指标时间和值
for(int i=0;i<size;i++)
{
FileWriteDouble(file_handle,(double)time_buff[i]);
FileWriteDouble(file_handle,ma_buff[i]);
}
//--- 关闭文件
FileClose(file_handle);
PrintFormat("Data is written, %s file is closed",InpFileName);
}
else
PrintFormat("Failed to open %s file, Error code = %d",InpFileName,GetLastError());
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
相关参考 真实型(双精度型,浮点型)
# 23.30 FileWriteFloat
从文件指针当前位置写入 单精度浮点型(float)值 到二进制文件。
uint FileWriteFloat(
int file_handle, // 文件句柄
float value // 被写入的值
);
2
3
4
参数
file_handle
[in] 通过FileOpen()返回的文件描述
value
[in] 浮点类型值。
返回值
如果成功,函数返回写入的字节数(在这种情况下sizeof(double)= 4)。文件指针移动的步长与字节数相同。
示例 :
//+------------------------------------------------------------------+
//| Demo_FileWriteFloat.mq5 |
//| Copyright 2013, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
//--- 启动脚本时显示输入参数的窗口
#property script_show_inputs
//--- 接收程序端数据的参数
input string InpSymbolName="EURUSD"; // 货币组
input ENUM_TIMEFRAMES InpSymbolPeriod=PERIOD_M15; // 时间帧
input datetime InpDateStart=D'2013.01.01 00:00'; // 复制起始日期的数据
//--- 编写文件数据的参数
input string InpFileName="Close.bin"; // 文件名称
input string InpDirectoryName="Data"; // 目录名称
//+------------------------------------------------------------------+
//| 脚本程序启动函数 |
//+------------------------------------------------------------------+
void OnStart()
{
datetime date_finish=TimeCurrent();
double close_buff[];
datetime time_buff[];
int size;
//--- 重置错误值
ResetLastError();
//--- 复制每个柱的收盘价
if(CopyClose(InpSymbolName,InpSymbolPeriod,InpDateStart,date_finish,close_buff)==-1)
{
PrintFormat("Failed to copy close price values. Error code = %d",GetLastError());
return;
}
//--- 复制每个柱形的时间
if(CopyTime(InpSymbolName,InpSymbolPeriod,InpDateStart,date_finish,time_buff)==-1)
{
PrintFormat("Failed to copy the time values. Error code = %d",GetLastError());
return;
}
//--- 接收缓冲区大小
size=ArraySize(close_buff);
//--- 打开编写指标值的文件(如果文件不在,则自动创建)
ResetLastError();
int file_handle=FileOpen(InpDirectoryName+"//"+InpFileName,FILE_READ|FILE_WRITE|FILE_BIN);
if(file_handle!=INVALID_HANDLE)
{
PrintFormat("%s file is open for writing",InpFileName);
PrintFormat("File path: %s\\Files\\",TerminalInfoString(TERMINAL_DATA_PATH));
//--- 写下文件的收盘价时间和值
for(int i=0;i<size;i++)
{
FileWriteDouble(file_handle,(double)time_buff[i]);
FileWriteFloat(file_handle,(float)close_buff[i]);
}
//--- 关闭文件
FileClose(file_handle);
PrintFormat("Data is written, %s file is closed",InpFileName);
}
else
PrintFormat("Failed to open %s file, Error code = %d",InpFileName,GetLastError());
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
相关参考 真实型(双精度型,浮点型), FileWriteDouble
# 23.31 FileWriteInteger
从文件指针当前位置写入 整型值 到二进制文件。
uint FileWriteInteger(
int file_handle, // 文件句柄
int value, // 被编写值
int size=INT_VALUE // 字节大小
);
2
3
4
5
参数
file_handle
[in] 通过FileOpen()返回的文件描述。
value
[in] 整数值。
size = INT_VALUE
[in] 可以写入的字节数量(最多包括4字节)。提供类似常量:CHAR_VALUE=1, SHORT_VALUE=2 和 INT_VALUE=4,因此函数可以写入 字符型,无符号字符型,短整型,无符号短整型,整数型 或 无符号整数型的整数值。
返回值
如果成功,函数返回写入的字节数。文件指针移动的步长与字节数相同。
示例 :
//+------------------------------------------------------------------+
//| Demo_FileWriteInteger.mq5 |
//| Copyright 2013, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
//--- 启动脚本时显示输入参数的窗口
#property script_show_inputs
//--- 接收程序端数据的参数
input string InpSymbolName="EURUSD"; // 货币组
input ENUM_TIMEFRAMES InpSymbolPeriod=PERIOD_H1; // 时间帧
input datetime InpDateStart=D'2013.01.01 00:00'; // 复制起始日期的数据
//--- 编写文件数据的参数
input string InpFileName="Trend.bin"; // 文件名称
input string InpDirectoryName="Data"; // 目录名称
//+------------------------------------------------------------------+
//| 脚本程序启动函数 |
//+------------------------------------------------------------------+
void OnStart()
{
datetime date_finish=TimeCurrent();
double close_buff[];
datetime time_buff[];
int size;
//--- 重置错误值
ResetLastError();
//--- 复制每个柱的收盘价
if(CopyClose(InpSymbolName,InpSymbolPeriod,InpDateStart,date_finish,close_buff)==-1)
{
PrintFormat("Failed to copy the values of close prices. Error code = %d",GetLastError());
return;
}
//--- 复制每个柱形的时间
if(CopyTime(InpSymbolName,InpSymbolPeriod,InpDateStart,date_finish,time_buff)==-1)
{
PrintFormat("Failed to copy time values. Error code = %d",GetLastError());
return;
}
//--- 接收缓冲区大小
size=ArraySize(close_buff);
//--- 打开编写值的文件(如果文件不在,则自动创建)
ResetLastError();
int file_handle=FileOpen(InpDirectoryName+"//"+InpFileName,FILE_READ|FILE_WRITE|FILE_BIN);
if(file_handle!=INVALID_HANDLE)
{
PrintFormat("%s file is available for writing",InpFileName);
PrintFormat("File path: %s\\Files\\",TerminalInfoString(TERMINAL_DATA_PATH));
//---
int up_down=0; // 趋势标识
int arr_size; // arr 数组大小
uchar arr[]; // uchar 类型数组
//--- 写下文件的时间值
for(int i=0;i<size-1;i++)
{
//--- 比较当前柱和下一柱的收盘价
if(close_buff[i]<=close_buff[i+1])
{
if(up_down!=1)
{
//--- 使用FileWriteInteger写下文件的日期值
StringToCharArray(TimeToString(time_buff[i]),arr);
arr_size=ArraySize(arr);
//--- 首先,写下数组中的交易品种数量
FileWriteInteger(file_handle,arr_size,INT_VALUE);
//--- 写下交易品种
for(int j=0;j<arr_size;j++)
FileWriteInteger(file_handle,arr[j],CHAR_VALUE);
//--- 改变趋势标识
up_down=1;
}
}
else
{
if(up_down!=-1)
{
//--- 使用FileWriteInteger写下文件的日期值
StringToCharArray(TimeToString(time_buff[i]),arr);
arr_size=ArraySize(arr);
//--- 首先,写下数组中的交易品种数量
FileWriteInteger(file_handle,arr_size,INT_VALUE);
//--- 写下交易品种
for(int j=0;j<arr_size;j++)
FileWriteInteger(file_handle,arr[j],CHAR_VALUE);
//--- 改变趋势标识
up_down=-1;
}
}
}
//--- 关闭文件
FileClose(file_handle);
PrintFormat("Data is written, %s file is closed",InpFileName);
}
else
PrintFormat("Failed to open %s file, Error code = %d",InpFileName,GetLastError());
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
相关参考
整数到字符串, 字符串到整数, 整数类型
# 23.32 FileWriteLong
从文件指针当前位置写入 长整型值 到二进制文件。
uint FileWriteLong(
int file_handle, // 文件句柄
long value // 被写入的值
);
2
3
4
参数
file_handle
[in] 通过FileOpen()返回的文件描述。
value
[in] 长整型值。
返回值
如果成功,函数返回写入的字节数(在这种情况下sizeof(long)= 8)。文件指针移动的步长与字节数相同。
示例 :
//+------------------------------------------------------------------+
//| Demo_FileWriteLong.mq5 |
//| Copyright 2013, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
//--- 启动脚本时显示输入参数的窗口
#property script_show_inputs
//--- 接收程序端数据的参数
input string InpSymbolName="EURUSD"; // 货币组
input ENUM_TIMEFRAMES InpSymbolPeriod=PERIOD_H1; // 时间帧
input datetime InpDateStart=D'2013.01.01 00:00'; // 复制起始日期的数据
//--- 编写文件数据的参数
input string InpFileName="Volume.bin"; // 文件名称
input string InpDirectoryName="Data"; // 目录名称
//+------------------------------------------------------------------+
//| 脚本程序启动函数 |
//+------------------------------------------------------------------+
void OnStart()
{
datetime date_finish=TimeCurrent();
long volume_buff[];
datetime time_buff[];
int size;
//--- 重置错误值
ResetLastError();
//--- 复制每个柱的跳动量
if(CopyTickVolume(InpSymbolName,InpSymbolPeriod,InpDateStart,date_finish,volume_buff)==-1)
{
PrintFormat("Failed to copy values of the tick volume. Error code = %d",GetLastError());
return;
}
//--- 复制每个柱形的时间
if(CopyTime(InpSymbolName,InpSymbolPeriod,InpDateStart,date_finish,time_buff)==-1)
{
PrintFormat("Failed to copy time values. Error code = %d",GetLastError());
return;
}
//--- 接收缓冲区大小
size=ArraySize(volume_buff);
//--- 打开编写指标值的文件(如果文件不在,则自动创建)
ResetLastError();
int file_handle=FileOpen(InpDirectoryName+"//"+InpFileName,FILE_READ|FILE_WRITE|FILE_BIN);
if(file_handle!=INVALID_HANDLE)
{
PrintFormat("%s file is available for writing",InpFileName);
PrintFormat("File path: %s\\Files\\",TerminalInfoString(TERMINAL_DATA_PATH));
//--- 首先,写下数据样本的大小
FileWriteLong(file_handle,(long)size);
//--- 写下文件的时间和交易量值
for(int i=0;i<size;i++)
{
FileWriteLong(file_handle,(long)time_buff[i]);
FileWriteLong(file_handle,volume_buff[i]);
}
//--- 关闭文件
FileClose(file_handle);
PrintFormat("Data is written, %s file is closed",InpFileName);
}
else
PrintFormat("Failed to open %s file, Error code = %d",InpFileName,GetLastError());
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
相关参考 整数类型, FileWriteInteger
# 23.33 FileWriteString
从文件指针当前位置写入 字符串参数值 到BIN或者TXT文件。当写入CSV或TXT文件时:如果在一个字符串中出现了'\ n'(LF),但前一个字符却不是'\ r'(CR),则在自动在 \ n之前添加缺少的 '\ r'。
uint FileWriteString(
int file_handle, // 文件句柄
const string text_string, // 要编写的字符串
int length=-1 // 交易品种数量
);
2
3
4
5
参数
file_handle
[in] 通过FileOpen()返回的文件描述。
text_string
[in] 字符串。
length=-1
[in] 您想要写入的字符数量。将字符串写入二进制(BIN)文件需要设置此参数。如果未指定大小,则全部末尾没有0的字符串都能被写入。如果指定数值 小于 字符串的长度,则会写入尾部没有0的字符串的一部分。如果指定数值 大于 字符串长度,则该字符串会填充适当数量的0。对于CSV和TXT类型的文件,该参数将被忽略,并且字符串会被完全写入。
返回值
如果成功,函数返回写入的字节数。文件指针移动的步长与字节数相同。
注意
当通过FILE_UNICODE 标帜(或者没有 FILE_ANSI标帜)打开写入文件时,写入的字节数量是字符串字节的两倍大。当写入文件以FILE_ANSI标帜打开时,字节写入数量会与字符串字节数量一致。
示例 :
//+------------------------------------------------------------------+
//| Demo_FileWriteString.mq5 |
//| Copyright 2013, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
//--- 启动脚本时显示输入参数的窗口
#property script_show_inputs
//--- 接收程序端数据的参数
input string InpSymbolName="EURUSD"; // 货币组
input ENUM_TIMEFRAMES InpSymbolPeriod=PERIOD_H1; // 时间帧
input int InpMAPeriod=14; // MA周期
input ENUM_APPLIED_PRICE InpAppliedPrice=PRICE_CLOSE; // 价格类型
input datetime InpDateStart=D'2013.01.01 00:00'; // 复制起始日期的数据
//--- 编写文件数据的参数
input string InpFileName="RSI.csv"; // 文件名称
input string InpDirectoryName="Data"; // 目录名称
//+------------------------------------------------------------------+
//| 脚本程序启动函数 |
//+------------------------------------------------------------------+
void OnStart()
{
datetime date_finish; // 复制结束日期的数据
double rsi_buff[]; // 指标值数组
datetime date_buff[]; // 指标日期数组
int rsi_size=0; // 指标数组大小
//--- 结束时间是当前时间
date_finish=TimeCurrent();
//--- 接收 RSI 指标句柄
ResetLastError();
int rsi_handle=iRSI(InpSymbolName,InpSymbolPeriod,InpMAPeriod,InpAppliedPrice);
if(rsi_handle==INVALID_HANDLE)
{
//--- 接收指标句柄失败
PrintFormat("Error when receiving indicator handle. Error code = %d",GetLastError());
return;
}
//--- 循环直至指标计算所有值
while(BarsCalculated(rsi_handle)==-1)
Sleep(10); // 暂停允许指标计算所有值
//--- 复制某段时间周期的指标值
ResetLastError();
if(CopyBuffer(rsi_handle,0,InpDateStart,date_finish,rsi_buff)==-1)
{
PrintFormat("Failed to copy indicator values. Error code = %d",GetLastError());
return;
}
//--- 复制相应的指标值时间
ResetLastError();
if(CopyTime(InpSymbolName,InpSymbolPeriod,InpDateStart,date_finish,date_buff)==-1)
{
PrintFormat("Failed to copy time values. Error code = %d",GetLastError());
return;
}
//--- 释放指标占据的内存
IndicatorRelease(rsi_handle);
//--- 接收缓冲区大小
rsi_size=ArraySize(rsi_buff);
//--- 打开编写指标值的文件(如果文件不在,则自动创建)
ResetLastError();
int file_handle=FileOpen(InpDirectoryName+"//"+InpFileName,FILE_READ|FILE_WRITE|FILE_CSV|FILE_ANSI);
if(file_handle!=INVALID_HANDLE)
{
PrintFormat("%s file is available for writing",InpFileName);
PrintFormat("File path: %s\\Files\\",TerminalInfoString(TERMINAL_DATA_PATH));
//--- 准备附加变量
string str="";
bool is_formed=false;
//--- 写下形成超买和超卖区域的日期
for(int i=0;i<rsi_size;i++)
{
//--- 检查指标值
if(rsi_buff[i]>=70 || rsi_buff[i]<=30)
{
//--- 如果该值是该区域的第一个值
if(!is_formed)
{
//--- 添加值和日期
str=(string)rsi_buff[i]+"\t"+(string)date_buff[i];
is_formed=true;
}
else
str+="\t"+(string)rsi_buff[i]+"\t"+(string)date_buff[i];
//--- 移动到下个循环迭代
continue;
}
//--- 检查标识
if(is_formed)
{
//--- 字符串形成,将其写入文件
FileWriteString(file_handle,str+"\r\n");
is_formed=false;
}
}
//--- 关闭文件
FileClose(file_handle);
PrintFormat("Data is written, %s file is closed",InpFileName);
}
else
PrintFormat("Failed to open %s file, Error code = %d",InpFileName,GetLastError());
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
相关参考 字符串类型, 字符串格式化
# 23.34 FileWriteStruct
从文件指针当前位置写入 传递到结构的参数 到二进制文件。
uint FileWriteStruct(
int file_handle, // 文件句柄
const void& struct_object, // 连接一个物件
int size=-1 // 写入字节大小
);
2
3
4
5
参数
file_handle
[in] 通过FileOpen()返回的文件描述。
struct_object
[in] 参考这个结构的对象。该结构不应该包含字符串,动态数组或虚函数。
size=-1
[in] 您想要记录的字节数。如果未指定大小或指定的字节数 大于 结构的大小,则会写入整个结构。
返回值
如果成功,函数返回写入的字节数。文件指针移动的步长与字节数相同。
//+------------------------------------------------------------------+
//| Demo_FileWiteStruct.mq5 |
//| Copyright 2013, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
//--- 启动脚本时显示输入参数的窗口
#property script_show_inputs
//--- 接收程序端数据的参数
input string InpSymbolName="EURUSD"; // 货币组
input ENUM_TIMEFRAMES InpSymbolPeriod=PERIOD_H1; // 时间帧
input datetime InpDateStart=D'2013.01.01 00:00'; // 复制起始日期的数据
//--- 编写文件数据的参数
input string InpFileName="EURUSD.txt"; // 文件名称
input string InpDirectoryName="Data"; // 目录名称
//+------------------------------------------------------------------+
//| 存储蜡烛图数据的结构 |
//+------------------------------------------------------------------+
struct candlesticks
{
double open; // 开盘价
double close; // 收盘价
double high; // 最高价
double low; // 最低价
datetime date; // 日期
};
//+------------------------------------------------------------------+
//| 脚本程序启动函数 |
//+------------------------------------------------------------------+
void OnStart()
{
datetime date_finish=TimeCurrent();
int size;
datetime time_buff[];
double open_buff[];
double close_buff[];
double high_buff[];
double low_buff[];
candlesticks cand_buff[];
//--- 重置错误值
ResetLastError();
//--- 接收范围内柱形到达时间
if(CopyTime(InpSymbolName,InpSymbolPeriod,InpDateStart,date_finish,time_buff)==-1)
{
PrintFormat("Failed to copy time values. Error code = %d",GetLastError());
return;
}
//--- 接收范围内柱形的最高价
if(CopyHigh(InpSymbolName,InpSymbolPeriod,InpDateStart,date_finish,high_buff)==-1)
{
PrintFormat("Failed to copy values of high prices. Error code = %d",GetLastError());
return;
}
//--- 接收范围内柱形的最低价
if(CopyLow(InpSymbolName,InpSymbolPeriod,InpDateStart,date_finish,low_buff)==-1)
{
PrintFormat("Failed to copy values of low prices. Error code = %d",GetLastError());
return;
}
//--- 接收范围内柱形的开盘价
if(CopyOpen(InpSymbolName,InpSymbolPeriod,InpDateStart,date_finish,open_buff)==-1)
{
PrintFormat("Failed to copy values of open prices. Error code = %d",GetLastError());
return;
}
//--- 接收范围内柱形的收盘价
if(CopyClose(InpSymbolName,InpSymbolPeriod,InpDateStart,date_finish,close_buff)==-1)
{
PrintFormat("Failed to copy values of close prices. Error code = %d",GetLastError());
return;
}
//--- 定义数组维数
size=ArraySize(time_buff);
//--- 在结构数组保存所有数据
ArrayResize(cand_buff,size);
for(int i=0;i<size;i++)
{
cand_buff[i].open=open_buff[i];
cand_buff[i].close=close_buff[i];
cand_buff[i].high=high_buff[i];
cand_buff[i].low=low_buff[i];
cand_buff[i].date=time_buff[i];
}
//--- 打开用于编写文件结构数组的文件(如果文件不在,则自动创建)
ResetLastError();
int file_handle=FileOpen(InpDirectoryName+"//"+InpFileName,FILE_READ|FILE_WRITE|FILE_BIN|FILE_COMMON);
if(file_handle!=INVALID_HANDLE)
{
PrintFormat("%s file is open for writing",InpFileName);
PrintFormat("File path: %s\\Files\\",TerminalInfoString(TERMINAL_COMMONDATA_PATH));
//--- 准备字节数量的计数器
uint counter=0;
//--- 写下循环数组值
for(int i=0;i<size;i++)
counter+=FileWriteStruct(file_handle,cand_buff[i]);
PrintFormat("%d bytes of information is written to %s file",InpFileName,counter);
PrintFormat("Total number of bytes: %d * %d * %d = %d, %s",size,5,8,size*5*8,size*5*8==counter ? "Correct" : "Error");
//--- 关闭文件
FileClose(file_handle);
PrintFormat("Data is written, %s file is closed",InpFileName);
}
else
PrintFormat("Failed to open %s file, Error code = %d",InpFileName,GetLastError());
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
相关参考 结构和类
# 23.35 FileLoad
将指定二进制文件的所有数据读取到 数组类型 或 简单结构的传递数组中。该函数允许您快速的将已知类型的数据读入相应的数组。
bool FileLoad(
int file_name, // 文件名
const void& buffer[], // 数值类型或简单结构的数组
int common_flag=0 // 在<data_folder>\MQL5\Files\ 默认的搜索文件位置的标帜
);
2
3
4
5
参数
file_name
[in] 用于读取数据的文件名称。
buffer
[out] 数值类型 或 简单结构数组。
common_flag=0
[in] 标帜,决定文件位置,如果common_flag = FILE_COMMON,表示文件在为所有客户端的共用文件夹中 \Terminal\Common\Files。否则,文件放置在客户端的数据文件夹中。
返回值
读取的元素数量 或 错误时返回 -1。
注意
FileLoad()函数从文件中读取数组元素大小的整倍数。假设文件大小为10个字节,并且该函数将数据读入双精度(double)类型的数组(sizeof(double)= 8)。在这种情况下,函数将只读取8个字节,文件末尾的剩余2个字节将被删除,并且函数FileLoad()将返回1(读取1个元素)。
例如:
//+------------------------------------------------------------------+
//| Demo_FileLoad.mq5 |
//| Copyright 2016, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property copyright "Copyright 2016, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property script_show_inputs
//--- 输入参数
input int bars_to_save=10; // Number of bars
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
string filename=_Symbol+"_rates.bin";
MqlRates rates[];
//---
int copied=CopyRates(_Symbol,_Period,0,bars_to_save,rates);
if(copied!=-1)
{
PrintFormat(" CopyRates(%s) copied %d bars",_Symbol,copied);
//--- 报价写入文件
if(!FileSave(filename,rates,FILE_COMMON))
PrintFormat("FileSave() failed, error=%d",GetLastError());
}
else
PrintFormat("Failed CopyRates(%s), error=",_Symbol,GetLastError());
//--- 现在阅读这些返回到文件的报价
ArrayFree(rates);
long count=FileLoad(filename,rates,FILE_COMMON);
if(count!=-1)
{
Print("Time\tOpen\tHigh\tLow\tClose\tTick Voulme\tSpread\tReal Volume");
for(int i=0;i<count;i++)
{
PrintFormat("%s\t%G\t%G\t%G\t%G\t%I64u\t%d\t%I64u",
TimeToString(rates[i].time,TIME_DATE|TIME_SECONDS),
rates[i].open,rates[i].high,rates[i].low,rates[i].close,
rates[i].tick_volume,rates[i].spread,rates[i].real_volume);
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
相关参考 Structures and Classes,FileReadArra,FileReadStruct
# 23.36 FileSave
将传递数组所有元素写入二进制文件作为参数。该函数允许您快速写入数值类型或简单结构的数组为一个字符串。
bool FileSave(
int file_name, // 文件名
const void& buffer[], // 数值类型或简单结构的数组
int common_flag=0 // 文件标识,默认文件写入<data_folderɬ\MQL5\Files\
);
2
3
4
5
参数
file_name
[in] 用于写入数据数组的文件名称。
buffer
[in] 数值类型或 简单结构数组。
common_flag=0
[in] 标帜,决定文件位置,如果common_flag = FILE_COMMON,表示文件在为所有客户端的共用文件夹中 \Terminal\Common\Files。否则,文件放置在客户端的数据文件夹中。
返回值
如果失败返回false。
例如:
//+------------------------------------------------------------------+
//| Demo_FileSave.mq5 |
//| Copyright 2016, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property script_show_inputs
//--- 输入参数
input int ticks_to_save=1000; // Number of ticks
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
string filename=_Symbol+"_ticks.bin";
MqlTick ticks[];
u//---
int copied=CopyTicks(_Symbol,ticks,COPY_TICKS_ALL,0,ticks_to_save);
if(copied!=-1)
{
PrintFormat(" CopyTicks(%s) copied %d ticks",_Symbol,copied);
//--- 如果报价历史被同步,错误代码等于零
if(!GetLastError()==0)
PrintFormat("%s: Ticks are not synchronized, error=%d",_Symbol,copied,_LastError);
//--- 报价写入文件
if(!FileSave(filename,ticks,FILE_COMMON))
PrintFormat("FileSave() failed, error=%d",GetLastError());
}
else
PrintFormat("Failed CopyTicks(%s), Error=",_Symbol,GetLastError());
//--- 现在将这些报价读入文件
ArrayFree(ticks);
long count=FileLoad(filename,ticks,FILE_COMMON);
if(count!=-1)
{
Print("Time\tBid\tAsk\tLast\tVolume\tms\tflags");
for(int i=0;i<count;i++)
{
PrintFormat("%s.%03I64u:\t%G\t%G\t%G\t%I64u\t0x%04x",
TimeToString(ticks[i].time,TIME_DATE|TIME_SECONDS),ticks[i].time_msc%1000,
ticks[i].bid,ticks[i].ask,ticks[i].last,ticks[i].volume,ticks[i].flags);
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
相关参考 结构 和 类,FileWriteArray,FileWriteStruct
# 23.37 FolderCreate
在文件夹中创建一个文件夹 (依据 common_flag的值 )。
bool FolderCreate(
string folder_name, // 带有新文件夹名的字符串
int common_flag=0 // 范围
);
2
3
4
参数
folder_name
[in] 想要新建的目录文件夹的名称,包括文件夹的全部路径。
common_flag=0
[in] 标帜,决定文件位置,如果common_flag = FILE_COMMON,表示为所有客户端的共用文件夹中 \Terminal\Common\Files。否则,表示在客户端的 数据文件夹 中。
返回值
如果成功返回true, 否则返回 false。
注意
出于安全考虑,工作文件必须严格由MQL5语言管理。使用MQL5实施文件操作的文件意味着不能位于文件沙箱之外。
示例 :
//+------------------------------------------------------------------+
//| Demo_FolderCreate.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
//--- 描述
#property description "The script shows a sample use of FolderCreate()."
#property description "An external parameter defines the folder for creating folders."
#property description "After running the script, a structure of folders is created"
//--- 启动脚本时显示输入参数对话框
#property script_show_inputs
//--- 输入参数定义脚本运行的文件夹
input bool common_folder=false; // 所有程序端的共享文件夹
int flag=0; // 标识值决定了运行文件操作的位置
//+------------------------------------------------------------------+
//| 脚本程序启动函数 |
//+------------------------------------------------------------------+
void OnStart()
{
string working_folder;
//--- 设置标识值,如果外部参数common_folder==true
if(common_folder)
{
flag=FILE_COMMON;
//--- 找出我们正在工作的文件夹
working_folder=TerminalInfoString(TERMINAL_COMMONDATA_PATH)+"\\MQL5\\Files";
}
else working_folder=TerminalInfoString(TERMINAL_DATA_PATH)+"\\MQL5\\Files";
//--- 将被创建在MQL5\Files文件夹的文件夹
string root="Folder_A";
if(CreateFolder(working_folder,root,flag))
{
//--- 在Child_Folder_B1创建子文件夹
string folder_B1="Child_Folder_B1";
string path=root+"\\"+folder_B1; // 基于结构创建文件夹名称
if(CreateFolder(working_folder,path,flag))
{
//--- 在该文件夹创建3个子文件夹
string folder_C11="Child_Folder_C11";
string child_path=path+"\\"+folder_C11;// 基于结构创建文件夹名称
CreateFolder(working_folder,child_path,flag);
//--- 第二个子文件夹
string folder_C12="Child_Folder_C12";
child_path=path+"\\"+folder_C12;
CreateFolder(working_folder,child_path,flag);
//--- 第三个子文件夹
string folder_C13="Child_Folder_C13";
child_path=path+"\\"+folder_C13;
CreateFolder(working_folder,child_path,flag);
}
}
//---
}
//+------------------------------------------------------------------+
//| 试图创建文件夹并显示信息 |
//+------------------------------------------------------------------+
bool CreateFolder(string working_folder,string folder_path,int file_flag)
{
//--- 调试信息
PrintFormat("folder_path=%s",folder_path);
//--- 试图创建MQL5\Files路径相关的文件夹
if(FolderCreate(folder_path,file_flag))
{
//--- 向已创建的文件夹显示整个路径
PrintFormat("Folder %s has been created",working_folder+"\\"+folder_path);
//--- 重置错误代码
ResetLastError();
//--- 返回成功结果
return true;
}
else
PrintFormat("Failed to create folder %s. Error code %d",working_folder+folder_path,GetLastError());
//--- 失败
return false;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
相关参考
FileOpen(), FolderClean(), FileCopy()
# 23.38 FolderDelete
删除指定的目录文件夹。如果文件夹不是空的,那么无法删除。
bool FolderDelete(
string folder_name, // 带有要删除的文件夹名的字符串
int common_flag=0 // 范围
);
2
3
4
参数
folder_name
[in] 想要删除的目录文件夹名称,包括文件夹的全部路径。
common_flag=0
[in] 标帜,决定文件位置,如果common_flag = FILE_COMMON,表示文件在为所有客户端的共用文件夹中 \Terminal\Common\Files。否则,文件放置在客户端的数据文件夹中。
返回值
如果成功返回true, 否则false。
注意
出于安全考虑,工作文件必须严格由MQL5语言管理。使用MQL5实施文件操作的文件意味着不能位于文件沙箱之外。
如果目录文件夹中至少包含一个文件 和/或 子目录,该目录就不能被删除,必须先清理。使用 FolderClean()函数可以清理文件夹中所有文件或者子目录。
示例 :
//+------------------------------------------------------------------+
//| Demo_FolderDelete.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
//--- 描述
#property description "The script shows a sample use of FolderDelete()."
#property description "First two folders are created; one of them is empty, the second one contains a file."
#property description "When trying to delete a non-empty folder, an error is returned and a warning is shown."
//--- 启动脚本时显示输入参数对话框
#property script_show_inputs
//--- 输入参数
input string firstFolder="empty"; // 空文件夹
input string secondFolder="nonempty";// 将会创建文件的文件夹
string filename="delete_me.txt"; // 将在secondFolder文件夹创建的文件名称
//+------------------------------------------------------------------+
//| 脚本程序启动函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 在这里写下文件句柄
int handle;
//--- 找出我们正在工作的文件夹
string working_folder=TerminalInfoString(TERMINAL_DATA_PATH)+"\\MQL5\\Files";
//--- 调试信息
PrintFormat("working_folder=%s",working_folder);
//--- 试图创建MQL5\Files路径相关的空文件夹
if(FolderCreate(firstFolder,0)) // 0 意味着我们在程序端的本地文件夹工作
{
//--- 向已创建的文件夹输入全路径
PrintFormat("Folder %s has been created",working_folder+"\\"+firstFolder);
//--- 重置错误代码
ResetLastError();
}
else
PrintFormat("Failed to create folder %s. Error code %d",working_folder+"\\"+firstFolder, GetLastError());
//--- 现在使用FileOpen()函数创建一个非空文件夹
string filepath=secondFolder+"\\"+filename; // 形成我们想要打开写在不存在文件夹中的路径文件
handle=FileOpen(filepath,FILE_WRITE|FILE_TXT); // 这种情况下FILE_WRITE标识是必须的,请见Help查询FileOpen
if(handle!=INVALID_HANDLE)
PrintFormat("File %s has been opened for reading",working_folder+"\\"+filepath);
else
PrintFormat("Failed to create file %s in folder %s. Error code=",filename,secondFolder, GetLastError());
Comment(StringFormat("Prepare to delete folders %s and %s", firstFolder, secondFolder));
//--- 短暂停顿5秒来阅读图表中的信息
Sleep(5000); // Sleep() 不能用在指标中!
//--- 显示询问用户的对话框
int choice=MessageBox(StringFormat("Do you want to delete folders %s and %s?", firstFolder, secondFolder),
"Deleting folders",
MB_YESNO|MB_ICONQUESTION); // 两个按钮 - "Yes" 和 "No"
//--- 根据选定的变量运行一个行为
if(choice==IDYES)
{
//--- 从图表删除评论
Comment("");
//--- 添加信息到“专家”日志
PrintFormat("Trying to delete folders %s and %s",firstFolder, secondFolder);
ResetLastError();
//--- 删除空文件夹
if(FolderDelete(firstFolder))
//--- 由于文件夹为空,应该会出现以下信息
PrintFormat("Folder %s has been successfully deleted",firstFolder);
else
PrintFormat("Failed to delete folder %s. Error code=%d", firstFolder, GetLastError());
ResetLastError();
//--- 删除包含文件的文件夹
if(FolderDelete(secondFolder))
PrintFormat("Folder %s has been successfully deleted", secondFolder);
else
//--- 由于文件夹包含文件,应该会出现下列信息
PrintFormat("Failed to delete folder %s. Error code=%d", secondFolder, GetLastError());
}
else
Print("Deletion canceled");
//---
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
相关参考 FileOpen(), FolderClean(), FileMove()
# 23.39 FolderClean
此函数用于删除指定文件夹中所有文件。
bool FolderClean(
string folder_name, // 带有已删除的文件夹名的字符串
int common_flag=0 // 范围
);
2
3
4
参数
folder_name
[in] 想要删除所有文件的目录文件夹名称,包括文件夹的全部路径。
common_flag=0
[in] 标帜,决定文件位置,如果common_flag = FILE_COMMON,表示文件在为所有客户端的共用文件夹中 \Terminal\Common\Files。否则,文件放置在客户端的数据文件夹中。
返回值
如果成功返回true, 否则false。
注意
出于安全考虑,工作文件必须严格由MQL5语言管理。使用MQL5实施文件操作的文件意味着不能位于文件沙箱之外。
请慎重使用该函数,所有文件和子目录都会被彻底删除。
示例 :
//+------------------------------------------------------------------+
//| Demo_FolderClean.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
//--- 描述
#property description "The script shows a sample use of FolderClean()."
#property description "First, files are created in the specified folder using the FileOpen() function."
#property description "Then, before the files are deleted, a warning is shown using MessageBox()."
//--- 启动脚本时显示输入参数对话框
#property script_show_inputs
//--- 输入参数
input string foldername="demo_folder"; // 在MQL5/Files/创建一个文件夹
input int files=5; // 要创建和删除的文件数量
//+------------------------------------------------------------------+
//| 脚本程序启动函数 |
//+------------------------------------------------------------------+
void OnStart()
{
string name="testfile";
//--- 首先在程序端数据文件夹打开或创建文件
for(int N=0;N<files;N++)
{
//--- 'demo_folder\testfileN.txt'格式的文件名称
string filemane=StringFormat("%s\\%s%d.txt",foldername,name,N);
//--- 打开用于编写的标识文件,在这种情况下将会自动创建'demo_folder'
int handle=FileOpen(filemane,FILE_WRITE);
//--- 找出FileOpen()函数是否成功
if(handle==INVALID_HANDLE)
{
PrintFormat("Failed to create file %s. Error code",filemane,GetLastError());
ResetLastError();
}
else
{
PrintFormat("File %s has been successfully opened",filemane);
//--- 打开的文件不再需要,所以请关闭它
FileClose(handle);
}
}
//--- 检查文件夹中的文件数量
int k=FilesInFolder(foldername+"\\*.*",0);
PrintFormat("Totally the folder %s contains %d files",foldername,k);
//--- 显示询问用户的对话框
int choice=MessageBox(StringFormat("You are going to delete %d files from folder %s. Do you want to continue?",foldername,k),
"Deleting files from the folder",
MB_YESNO|MB_ICONQUESTION); // 两个按钮 - "Yes" 和 "No"
ResetLastError();
//--- 根据选定的变量运行一个行为
if(choice==IDYES)
{
//--- 开始删除文件
PrintFormat("Trying to delete all files from folder %s",foldername);
if(FolderClean(foldername,0))
PrintFormat("Files have been successfully deleted, %d files left in folder %s",
foldername,
FilesInFolder(foldername+"\\*.*",0));
else
PrintFormat("Failed to delete files from folder %s. Error code %d",foldername,GetLastError());
}
else
PrintFormat("Deletion canceled");
//---
}
//+------------------------------------------------------------------+
//| 在指定文件夹返回文件数量 |
//+------------------------------------------------------------------+
int FilesInFolder(string path,int flag)
{
int count=0;
long handle;
string filename;
//---
handle=FileFindFirst(path,filename,flag);
//--- 如果至少一个文件被找到,请搜索更多的文件
if(handle!=INVALID_HANDLE)
{
//--- 显示文件名称
PrintFormat("File %s found",filename);
//--- 增加找到的文件/文件夹的计数器
count++;
//--- 在所有文件/文件夹中开始搜索
while(FileFindNext(handle,filename))
{
PrintFormat("File %s found",filename);
count++;
}
//--- 完成时不要忘记关闭搜索句柄
FileFindClose(handle);
}
else // 获得句柄失败
{
PrintFormat("Files search in folder %s failed",path);
}
//--- 返回结果
return count;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
相关参考 FileFindFirst, FileFindNext, FileFindClose