//+------------------------------------------------------------------+ //| CSVReader.mqh | //| Copyright (c) 2019, Marketeer | //| https://www.mql5.com/ru/articles/5913 | //+------------------------------------------------------------------+ #include #include input GroupSettings SCV_Settings; // C S V S E T T I N G S input string CSVDelimiter = ";" /*mql5 signals use ';' instead of ','*/; // · Delimiter class CSVConverter { private: class File { int file; public: File(const string name, const int flags, const short delimiter) { file = FileOpen(name, flags, delimiter, CP_UTF8); } File(const string name, const int flags) { file = FileOpen(name, flags); } bool isOpened() { return (file != INVALID_HANDLE); } int handle() { return file; } ~File() { if(file != INVALID_HANDLE) FileClose(file); } }; public: static IndexMap *ReadCSV(const string inputFileName) { // history.csv - 13 columns, positions.csv - 10 columns int columns = StringFind(inputFileName, ".history.csv") > 0 ? 13 : (StringFind(inputFileName, ".positions.csv") > 0 ? 10 : 0); if(columns == 0) { Print("Supported files: *.history.csv and .positions.csv"); return NULL; } Print("Reading csv-file ", inputFileName); uchar delimiter = (uchar)CSVDelimiter[0]; File f(inputFileName, FILE_READ|FILE_TXT|FILE_ANSI|FILE_SHARE_READ|FILE_SHARE_WRITE, delimiter); if(!f.isOpened()) { Alert("Can't read file " + inputFileName); return NULL; } int file = f.handle(); bool headerLine = true; IndexMap *data = new IndexMap(); string headers[]; uint count = 0; while(!FileIsEnding(file)) { string stLine = ""; string stParts[]; stLine = FileReadString(file); int nParts = StringSplit(stLine, delimiter, stParts); if(nParts != columns) { Print("File " + inputFileName + " contains " + (string)nParts + " columns (" + (string)(columns) + "+ required)"); Print("Line: ", stLine); return NULL; } if(headerLine) { headerLine = false; ArrayCopy(headers, stParts); continue; } IndexMap *row = new IndexMap(); for(int i = 0; i < nParts; i++) { row.setValue((string)i + "." + headers[i], stParts[i]); } data.add((string)count, row); ++count; } return data; } };