In MQL4, it is possible to work with files containing a certain set of information. It may become necessary to write information in a file or to read it from a file for several reasons.
A file can be used to deliver information to another program. In this case, the file can be created by an application program and used by it as an information receiver. For example, the trading history of an account can be written to a file at the execution of an application. This file can be later opened by another program (e.g., Excel for drawing a balance graph).
In other cases, there is a need to deliver some information, for example, the news timetable, to an application. An executable program (e.g., an Expert Advisor) can read this information from the previously prepared file and consider it during calculating for graphical displaying of the messages on the screen or for making of trade decisions.
File Names and Directories
The name of a working file must be composed according to the requirements of the operating system. The name of any file used in MQL4 consists of two parts: the file name and the file extension separated by a dot, for example, News.txt. Technically, a file name has no relation to the file content, so a file name and extension can be set voluntarily by the programmer. A file name is usually chosen so that it represents the information the file contains.
Most programs are automatically launched on the user's PC, if the file is double-clicked with the mouse button. According to the file extension, the operating environment loads one or another program displaying the file content. Therefore, you should assign the file extension considering the program (if necessary) that will usually be used to view the file.
The most popular file types (the type is determined by its extension) are the following:
- .txt - text file, for viewing you should use Notepad, Word, FrontPage, etc.;
- .csv - file for building tables in Excel;
- .htm - file to be viewed in a browser, i.e. Internet Explorer, Netscape Navigator, etc.
There are three folders (with subfolders) that can contain working files:
- Terminal_folder\Experts\History\current broker\ - for history files;
- Terminal_folder\Experts\Files\ - for common usage;
- Terminal_folder\Tester\ Files\ - for files the are used for testing.
A working file can be saved in one of these folders or in their subfolders. In case of no available folder at the moment of file saving, the folder will be automatically created by the client terminal. Working with files in other directories is not involved.
Modes of File Operations
The technology of interaction between an application and a working file has several modes. In general, a file can be opened by several programs at the same time (within a PC or several PCs connected to the network). At the same time, the operational environment provides the full access to the file, namely the right to read the file and write the information in it, only to one program. The other programs can only read it. For example, if My_text.doc has already been opened by a text editor, then all the other programs will receive the notification before opening the file:
Fig. 146. Dialog box that appears when a program tries to access to the file that has already been opened by another program.
The execution of this technology guaranties that a file won't be modified simultaneously by two different programs. In order to allow an applicable program to interact with a file, you should open that file first. The mode of opening a file is specified in the FileOpen() function.
An application program can open several working files at a time. In order to allow the program to differentiate one file from another the file descriptor is set in accordance to every opened file.
File descriptor – unique number of the file that is opened by the program at the moment.
The FileOpen() function will return some integer value (this value is usually assigned to the 'handle' variable), if a file is opened successfully. That value is the file descriptor. Most functions that are intended to work with files suppose the use of a file descriptor as one of the formal parameters.
int FileOpen(string filename, int mode, int delimiter=';')
The function opens a file for inputing and/or outputting. The function returns a file descriptor or -1, in case of failure. Files can only be opened in the Terminal_folder\Experts \Files\ folder or in the Terminal_folder\Tester\Files\folder (in case of EA testing) or in their subfolders.
filename - name of the file;
mode - the mode of file opening; it can have the following values (or their combinations): FILE_BIN, FILE_CSV,
delimiter - the separator sign for csv-files. It is ';' by default.
The FILE_READ mode of file opening implies that a file will be used only for being read by a program. A trial to open a file in this mode can fail, in case of no available file with the specified name.
The FILE_WRITE mode of file opening involves that a file will be used for writing in by a program. A try to open a file in this mode results in opening a file of a zero length. Even if there was some information in the file before opening, it will be erased. A try to open a file in this mode can fail, in case the file was previously opened by another program (in the writing mode).
It is allowed to open a file in the FILE_READ|FILE_WRITE mode. This mode involves the possibility of reading and writing to a file. This mode is used, if you need to add some information to the file that already contains some other information. The function implies the obligatory usage of one of the modes, FILE_READ or FILE_WRITE, or their combination.
The FILE_BIN mode of file opening defines processing a working file as a binary one. The FILE_CSV mode of file opening defines processing of a working file as a text one. The function involves obligatory usage of one of the FILE_BIN or FILE_CSV modes. The simultaneous usage of FILE_BIN and FILE_CSV modes is prohibited
The function requires obligatory combination of FILE_READ, FILE_WRITE or FILE_READ|FILE_WRITE modes with the FILE_BIN or FILE_CSV mode. For example: it is necessary to use the combination of FILE_CSV|FILE_READ to read the information from a text file, and it is necessary to use the FILE_BIN|FILE_READ|FILE_WRITE combination to add an entry to a binary file.
No more than 32 files can be opened simultaneously within an executable module (of an applicable program, e.g., an Expert Advisor). The descriptors of the files that are opened in the module cannot be passed to other modules (libraries).
Content of File Entries
The information entries are written to a file without spaces with any combination of modes. The information entries are added one by one when using the FILE_BIN mode for forming a file. Depending on the type of information that is written to a file (and the functions that are used to do it) the symbols combination representing the end of the line ("\r\n") can be written between the groups of entries.
The information entries are separated by file separators (usually ';') when forming a file in the FILE_CSV mode, and the groups of entries (that compose a line) are separated with the combination of symbols that represent the end of the line ("\r\n").
File separator - special symbol; the entry that is written to a file to separate the information lines.
The file separator is used to separate the information entries only in the csv-files.
The common principle for entries composition in any files is that these entries are added according to the specific sequence without spaces. Properly, the entry consists of continuous sequence of symbols. Any file can be read by any program and (depending on the rules implemeted in it) can be displayed in some form on the screen. For example: we have the File_1.csv file that contains:
int FileOpen(string filename, int mode, int delimiter=';')
The File_1.csv file will be displayed in different ways in different text editors:
Fig. 147. File_1 representation in different programs (File_1.csv).
In this case, the "\r\n" symbol combination was interpreted by each of the programs (Excel and Notepad) as the evidence for formatting sequence: the sequence of symbols is represented in the next line after the "\r\n" combination of symbols, and the "\r\n" combination itself is not displayed in the editing window. At the same time, Excel is a table editor, so the ";" symbol was interpreted by the program as a separator of information to columns. Draw your attention that the ";" symbol is not displayed in the Excel window. Notepad is a text editor. The rules implemented in it do not suppose the division of information into columns, so the ";" symbol was not interpreted as a file separator, but it was interpreted as a part of information, so it is displayed on the screen.
The specified symbols (";" and "\r\n") are used to separate entries in MQL4.
Fig. 148. Variety of entries in working files.
The structure of information writing in different types of files is represented on the fig. 148. The top line shows the csv-file content, the bottom three lines show the structure of binary files. All these files are composed according to the rules of one or another function of writing in the file.
An entry in the csv-file is the sequence of string values (string type) that are separated with the file separator or with the sign of the end of the line. Both of them are interpreted as a sign of the end of the informative read value part when reading information (using standard MQL4 function for file reading). The string value can have the different length and it is unknown how much symbols are there, so the reading is performed before one of the separators is located.
The entries in two types of binary of binary files represent the sequences of data without any separators. This sequence of writing in is governed by the fixed length for a data of different types: 4 bytes for a data of the "int", "bool", "datetime" and "color" types, and 8 bytes (or 4 bytes, depending on the parameters of writing function) for a data of "double" type. In this case, there is no need of separators, because the reading is performed by the standard function for reading data of a specified type with a specified length. The last (the bottom one on the fig. 148) binary file contains the data of string type that is separated with the end of the line sign.
File pointer - a position in the file the reading of the next value starts from.
The "File pointer" notion is the same with "cursor" notion. The file pointer is defined with the position in the file. As far as reading goes on the pointer is moving to the right per one or several positions.
||Problem 36. Read the information about the important news from the file and display the graphical objects on the price chart (vertical lines) in accordance to the time of news publication.
Let the Terminal_Folder\Experts\Files\ folder contains the News.csv working file with the following content:
Fig. 149. Content of working file News.csv.
In this case, the file contains the information about five events that will happen in different countries at a different time. Each line contains two entries. The first entry is the string value that represent the information about date an time of the event. The second entry is the text description of the event. First three symbols of the second entry contain the name of currency (country) that the event concerns.
The solution consists of two parts. First of all we need to read the information from the working file and then use the received values as the coordinates of the graphical objects. The reading of information is performed by the FileReadString() function.
string FileReadString(int handle, int length=0)
The function reads the line from the current position of the file. It is suitable both for CSV and binary files. The line will be read till the separator is met in the text file. The specified number of symbols will be read in the binary files. In order to receive the information about an error you should call the GetLastError() function.
handle - the file descriptor that is returned by the FileOpen() function;
length - the number of characters to be read.
The need in news information processing appears only once at the beginning of trading, so, in this case, we can use a script to solve the problem 36. The timetablenews.mq4
script is intended to read the information from the file and display the graphical objects in the symbol window.
Alert("No file named ",File_Name);
Alert("Error while opening file ",File_Name);
if(Instr==One || Instr==Two)
FileClose( Handle );
The used variables are opened and described in block 2-3 of the EA. An attempt to open the file and the analysis of the results of this operation are performed in block 3-4. The FileOpen() function is used to open the file:
An attempt to open the file is not always successful. It can fail, if the file with the specified name is not available. When file opening fails (the file descriptor is a negative number) the necessary text message is displayed to the user and the execution of the start() function stops.
In case of successful opening of a file, control is passed to the operator of the "while" cycle (blocks 4-8). The reading of data from the file (block 5-6), transformation of data and its analysis (6-7 blocks) and creation of the graphical object with coordinates and parameters corresponding the last read information (block 7-8) are performed at each iteration.
The execution of the "while" cycle continues until the file pointer reaches the end of the file, i.e., there will be no information remaining to the right of the pointer. The FileIsEnding() function is used to analyze the position of the file pointer.
bool FileIsEnding(int handle)
The function returns TRUE if the file pointer is at the end of the file, otherwise it returns FALSE. In order to receive the information about an error you should use the GetLastError() function. The GetLastError() function will return the ERR_END_OF_FILE (4099) error, in case the end of the file is reached during the reading.
handle - file descriptor that is returned by the FileOpen() function.
The represented solution (timetablenews.mq4) involves that any number of news can be written to the News.csv file. News.csv file contains five entries corresponding to five events (news) in the mentioned example (fig. 149). In general, the number of lines may be from 0 to 20-30, depending on the amount of real events that must take place this day.
Reading entries from the file (that is identified by the "handle" variable) is performed in blocks 5-6:
The first and second lines of block 5-6 perform reading the information from the file until the nearest separator is met. The third and fourth lines perform checking: is the file pointer at the end of the line. If not, then the graphical objects will be formed via two read values further in the cycle. If it was initially known about the number of entries, then the analysis that is performed in the third and fourth lines would not be necessary. In this case, we would hardly specify the number of iterations in the cycle (e.g. 5) and would not perform an extra checking.
However, the number of entries is unknown, in this case. At the same time, in this example every event is described with two values that compose a line of the following kind: value, file separator, value, end of the line sign. In this case, it is supposed that if there is an entry (first value in the line) then the other one exists; but if there is no first entry then the second one does not exist, so there is no event and there is no need to create a graphical object. If both entries or one of them does not exist the pointer will move to the end of the file (i.e. the position in the file where no data to the right of the pointer exist) when a try to read it is performed. The checking performed in block 3-4 allows to discover this fact. If the noted checking (last two lines in block 5-6) is deleted, then needless object will be created while the program is running. Only after that the condition of "while" cycle ending will trigger and the control will be passed to block 8-9. In general, you should consider the logic of data representation in the file, sequence order of entries and separators, the number of lines, etc. while composing an algorithm for file reading. Each certain circumstance requires an individual algorithm.
Data read from the file has the string type. In order to use the received values for creating graphical objects you should transform the data to the necessary type. In block 6-7, the first (read in the next line) value is transformed to the "datetime" value and further will be used as the coordinate of the graphical object that corresponds the event. First three symbols from the second read string value are compared with the first and second triplet of symbols in the symbol name. If there is a coincidence then the graphical object receives the corresponding parameters: line style - solid and color - red (block 7-8). In other cases, the objects are displayed with the orange dotted line. You can observe the news lines in the symbol window as the result of the script execution:
Fig. 150. Graphical objects in the symbol window after
In such a way, the script can be executed in any symbol window. At the same time, every window will contain the solid red line that represent the events that concern this specific symbol, and the dotted lines that represent the vents concerning the other symbols' events. To display the text descriptions of the objects you should check the "Show object description" option in the Properties of security window (F8) => Common.
The previously opened file is closed in block 8-9 after the problem is solved, namely all the necessary objects are created. The file should be closed for the following reasons: on the first hand - not to spare extra PC resources and on the second hand to allow the other programs to access the file in the writing mode. It should be considered as normal to close the file as soon as all the information is read from it (or written in it) and its usage is not necessary anymore. The closing of file is performed by the FileClose() function.
void FileClose(int handle)
The function performs closing of a file that was previously opened by the FileOpen() function.
handle - file descriptor that is returned by the FileOpen() function.
In order to allow the trader to practically use the timetablenews.mq4 script, it must keep the method for creation of a file that contains the news timetable of some period. This type of file can be created using any text editor, however, in this case, the possibility of an error remains (sometimes a separator can be not specified erroneously). Lets examine a variant of working file creation using MQL4.
||Problem 37. Represent the code of the EA that creates a file for news timetable.
In general, an EA can be destined for creation of a file that contains any number of news. The examined here createfile.mq4
EA creates the working file that contains the information about not more than five events.
extern string Date_1="";
extern string Text_1="";
extern string Date_2="";
extern string Text_2="";
extern string Date_3="";
extern string Text_3="";
extern string Date_4="";
extern string Text_4="";
extern string Date_5="";
extern string Text_5="";
Alert("An error while opening the file. ",
"May be the file is busy by the other applictiom");
for(int i=0; i<=4; i++)
if(StringLen(Erray[i,0])== 0 ||
if(Qnt_Symb < 0)
Alert("Error writing to the file",GetLastError());
FileClose( Handle );
FileClose( Handle );
Alert("The ",File_Name," file created.");
The initial information is entered to the program using the external variables of the "string" type (block 1-2). The variables are opened and described in block 3-4. To make the processing convenient the data is written to the Erray string array. Every event (information that characterize news) is represented by two elements of the array in the second dimension. The size of the first dimension (the number of lines in the array) is defined with the number of news, in this case, 5. In order to prevent the manual entering of values while trying the EA on a demo-account you can load the settings of the EA file example_news.set; the file of the EA setting should be located in the Terminal_folder\presets \ folder.
Block 5-6 performs file opening. If the operation failed then the start() function ends working after the user has received the message. If the file is opened successfully then the control will be passed to the "for" cycle operator in block 6-7. In general, the number of input values, the size of the Erray array and the number of iterations can be increased to the necessary quantity.
The checking is performed every iteration: is one of the entered values empty. The length of the Erray array values is calculated for this aim. If one of them has the zero length then it is considered as the absence of the current and the next events, so the current iteration interrupts. The writing of values of two elements of the array to the file goes on as far as the empty value of the element is found. The FileWrite() function is used for writing the values to the csv-file.
int FileWrite(int handle, ...)
The function is intended for writing the information to a csv-file, the separator between the information is included in automatically. The sign representing the end of the line "\r\n" is added to the file after the information writing. The information is transformed from the numeric to the text format when outputted (see Print() function). The function returns the number of written symbols or the negative value, in case an error occur.
handle - file descriptor that is returned by the FileOpen() function;
... - data separated with commas. It cannot be more than 63 parameters.
The data of the "double", "int" types is automatically transformed to the string (the data of "color", "datetime" and "bool" types is considered as the integer numbers of the "int" type and transformed to the string, as well), the data of the "string" type is output as is, without transformation. The arrays cannot be passed as the parameters; arrays must be entered elementwise.
In the considered example the information is written to the file in the following line:
The separator (the symbol that is used as a separator is specified in the file opening function FileOpen(), in this case, ';') will be written after the Erray[i,0] value when writing to the file. The sign representing the end of the line "\r\n" is automatically placed at the end of the the FileWrite() function execution, i.e. at the end of writing. The same entry will be written on each next iteration of the "for" cycle. Every new entry starts from the position where the file separator of the last writing is placed. At the same time, the values of the next elements of the 'Erray' will be written to the file (indexes of the elements are increased by 1 on every iteration).
If the current writing to the file is successful the the control is passed to the next iteration. If the writing in the file fails then the file will be closed by the FileClose() function after the message is displayed to the user, and the start() function finishes its working.
If all writings to the file are successfully performed then the control is passed to the file closing function FileClose() in block 7-8 after the execution of the "for" cycle is finished. In this case, the message about the successful file creation is displayed, after that the start() function execution will be finished. The News.csv file shown on the fig. 149 will be created after the EA execution is finished.
Function for Performing File Operations
||The closing of the file that was previously opened by the FileOpen() function.
||Deleting of the file. The files can only be deleted if they are located at the terminal_folder\experts\files (terminal_folder\tester\files, in case of testing the EA) folder or in its subfolders.
||Flushing all the information that is left in the file input-output bufer to the hard disk.
||Returns TRUE if the file pointer is at the end of the file, otherwise - returns FALSE. If the end of the file is reached during the file reading, the GetLastError() function will return the ERR_END_OF_FILE (4099) error.
||It returns TRUE, if the file pointer is at the end of the line of the CSV-file. Otherwise, it returns FALSE.
||Opens a file for inputting and/or outputting. The function returns the file descriptor of the opened file of -1, in case it fails.
||Opens a file in the current history folder (termial_folder\history\server_name) or in its subfolders. The function returns the file descriptor or -1, in case it fails.
||The function reads the specified number of elements from the binary file to the array. The array must have enough size before reading. The function returns the number of practically read elements.
||The function reads the number of double accuracy with the floating point (double) from the current position of the binary file. The size of the number may the following: 8 bytes (double) and 4 bytes (float).
||The function reads the integer number from the current position of the binary file. The size of the number may be the following: 1, 2 or 4 bytes. If the size of the number is not specified then the system will try to read it as it was the 4 byte integer number.
||Reading the number from the current position of the CSV-file until the separator is met. It can be applied only to csv-files.
||The function reads the line from the current position of the file. It can be applied both for csv and binary files. The line in the text file will be read until the separator is met. The specified number of symbols in the line will be read in the binary files.
||The function moves the separator to the new position that is the displacement from the beginning, end or the current position of the file in bytes. The next reading or writing starts from the new position. If the pointer moving is performed successfully then the function will return TRUE, otherwise - FALSE.
||The function returns the size of the file in bytes.
||The function returns the shift of file pointer from the beginning of the file.
||The function is intended to write the information to the csv-file, the separator is placed automatically between the information. The end of the line sign "\r\n" is added to the file after the writing is finished. The numeric data is transformed to the text format during the ouptputting process. The function returns the the number of written symbols or a negative value if an error occurs.
||The function writes the array to the binary file.
||The function writes the number with the floating point to the binary file.
||The function writes the integer number value in the binary file.
||The function writes the line to the binary file from the current position. It returns the number of practically written bytes or a negative value, in case an error occurs.
To get the detailed information about these and other functions you should take a look at the documentation at MQL4.community, at MetaQuotes Ltd. website or at the "Help" section of MetaEditor.