MQL5Book/Scripts/p4/FileTxtCsv.mq5
super.admin 1c8e83ce31 convert
2025-05-30 16:09:41 +02:00

152 lines
4.9 KiB
MQL5

//+------------------------------------------------------------------+
//| FileTxtCsv.mq5 |
//| Copyright 2021, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#include "..\..\Include\PRTF.mqh"
#include "..\..\Include\StringUtils.mqh"
#define LIMIT 10
const string txtfile = "MQL5Book/atomic.txt";
const string csvfile = "MQL5Book/atomic.csv";
const short delimiter = ',';
//+------------------------------------------------------------------+
//| Simple MqlRates-wrapper for setting data by field number |
//+------------------------------------------------------------------+
struct MqlRatesM : public MqlRates
{
template<typename T>
void set(int field, T v)
{
switch(field)
{
case 0:
this.time = (datetime)v;
break;
case 1:
this.open = (double)v;
break;
case 2:
this.high = (double)v;
break;
case 3:
this.low = (double)v;
break;
case 4:
this.close = (double)v;
break;
case 5:
this.tick_volume = (long)v;
break;
case 6:
this.spread = (int)v;
break;
case 7:
this.real_volume = (long)v;
break;
}
}
};
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
MqlRates rates[];
int n = PRTF(CopyRates(_Symbol, _Period, 0, LIMIT, rates)); // 10
const string columns[] = {"DateTime", "Open", "High", "Low", "Close", "Ticks", "Spread", "True"};
// last column name can be interpreted as "True Volume" and is used for FileReadBool
const string caption = StringCombine(columns, delimiter) + "\r\n";
// Part I. Writing TXT and CSV
// create new file or open existing one and empty it
int fh1 = PRTF(FileOpen(txtfile, FILE_TXT | FILE_ANSI | FILE_WRITE, delimiter)); // 1
int fh2 = PRTF(FileOpen(csvfile, FILE_CSV | FILE_ANSI | FILE_WRITE, delimiter)); // 2
// PRTF(FileWriteArray(fh1, rates)); // FILE_NOTBIN(5011)
PRTF(FileWriteString(fh1, caption));
PRTF(FileWriteString(fh2, caption));
for(int i = 0; i < n; ++i)
{
FileWrite(fh1, rates[i].time,
rates[i].open, rates[i].high, rates[i].low, rates[i].close,
rates[i].tick_volume, rates[i].spread, rates[i].real_volume);
FileWrite(fh2, rates[i].time,
rates[i].open, rates[i].high, rates[i].low, rates[i].close,
rates[i].tick_volume, rates[i].spread, rates[i].real_volume);
}
FileClose(fh1);
FileClose(fh2);
// Part II. Reading TXT and CSV with FileReadString
// open just written files for reading and testing
string read;
fh1 = PRTF(FileOpen(txtfile, FILE_TXT | FILE_ANSI | FILE_READ, delimiter)); // 1
fh2 = PRTF(FileOpen(csvfile, FILE_CSV | FILE_ANSI | FILE_READ, delimiter)); // 2
Print("===== Reading TXT");
do
{
read = PRTF(FileReadString(fh1));
}
while(StringLen(read) > 0);
Print("===== Reading CSV");
do
{
read = PRTF(FileReadString(fh2));
}
while(StringLen(read) > 0);
FileClose(fh1);
FileClose(fh2);
// Part III. Reading CSV with specific functions
// FileReadDatetime, FileReadNumber, FileReadBool
Print("===== Reading CSV (alternative)");
MqlRatesM r[1];// declare as array to print the struct easily by ArrayPrint
int count = 0; // number of records read
int column = 0;// monitor current column to change convertion types
const int maxColumn = ArraySize(columns);
fh2 = PRTF(FileOpen(csvfile, FILE_CSV | FILE_ANSI | FILE_READ, delimiter)); // 1
do
{
// Note: first record is not a data, it holds column titles
if(column)
{
if(count == 1) // demonstrate FileReadBool on 1-st record with titles
{
r[0].set(column, PRTF(FileReadBool(fh2)));
}
else
{
r[0].set(column, FileReadNumber(fh2));
}
}
else // 0-th column is a datetime
{
++count;
if(count > 1) // struct from previous line is ready
{
ArrayPrint(r, _Digits, NULL, 0, 1, 0);
}
r[0].time = FileReadDatetime(fh2);
}
column = (column + 1) % maxColumn;
}
while(_LastError == 0); // normal termination implies 5027 (FILE_ENDOFFILE)
// last struct print
if(column == maxColumn - 1)
{
ArrayPrint(r, _Digits, NULL, 0, 1, 0);
}
}
//+------------------------------------------------------------------+