//+------------------------------------------------------------------+
//|                                   Meta COT Script Agregation.mq4 |
//|   Copyright © 2009, C-4 (Vasiliy Sokolov, Russia, St.-Petersburg,|
//|                                      2009), All Rights Reserved. |
//|                                                   vs-box@mail.ru |
//+------------------------------------------------------------------+

// Скрипт объединяет несколько отчетов и создает на их основе новый отчет включающий в себя сумму данных объединяемых отчетов.
// Например если имеются два отчета по позициям трейдеров на рынках S&P 500 и E-Mini S&P 500, то будет создан отчет включающий
// в себя совокупные данные по обоим рынкам.
// (совокупные - означает что каждая ячейка одного файла будет просуммирована с ячейкой другого файла)
//#property show_inputs
#property copyright "Copyright © 2009, C-4 (Vasiliy Sokolov, SPb), All Rights Reserved."
#property link      "vs-box@mail.ru"

#define EQU_NO           0
#define EQU_YES          1

#define DATA            1
#define OI              2
#define NONCOMM_LONG    3
#define NONCOMM_SHORT   4
#define SPREADING       5
#define OPERATORS_LONG  6
#define OPERATORS_SHORT 7
#define ALL_LONG        8
#define ALL_SHORT       9
#define NONREP_LONG     10
#define NONREP_SHORT    11

extern string s_list="AGREGATION.ini";

int start()
{
   int      h_list;                    // Дискриптор файла-списка (в нем находятся названия файлов-перечислений)
   //string   s_list;                    // Название файла-списка.
   
   int      h_enumeration;             // Дискриптор файла перечислений
   string   s_enumeration;             // Строка названия файла перечислений
   
   int      h_rezult;                  // Дискриптор файла-выхода
   string   s_rezult;                  // Название файла-выхода
   
   int      h_temp;                    // Врменный дескриптор конечных файлов (один на всех), используется для подсчета кол-ва файлов
   string   s_temp;                    // Врменная строка-название конечных файлов (одна на всех), используется для подсчета кол-ва файлов
   
   int      h_file[];                  // Массив постоянных дискрипторов конечных файлов.                   
   string   s_file[];                  // Массив названий конечных файлов
   
   datetime data[], data_all;
   int      oi[],             oi_all,
            noncomm_long[],   noncomm_long_all,
            noncomm_short[],  noncomm_short_all,
            spreading[],      spreading_all,
            operators_long[], operators_long_all,
            operators_short[],operators_short_all,
            all_long[],       all_long_all,
            all_short[],      all_short_all,
            nonrep_long[],    nonrep_long_all,
            nonrep_short[],   nonrep_short_all;
   
   int      str;                       // Содежрит количество конечных файлов
   int      n;                         // Содержит текущий номер конечного файла
   int      column;                    // Содежрит номер колонки
   int      frnz_str[];                // Содержит "замароженные" дискрипторы файлов*
   double   count;                     // Подсчитывает количество строк в каждом конечном файле
   string   tmp;                       // Содержит текстовую строку-ячейку полученную из конечного файла
         
   h_list=FileOpen(s_list,FILE_READ|FILE_CSV);                    // Открываем список файлов
   if(h_list==-1){Print("Список файлов не найден");return(0);}
   while(FileIsEnding(h_list)==false){                            // Читаем его построчно
      s_enumeration=FileReadString(h_list);                       // Каждая строка имя файла-перечислений
      Print("---------------<<",s_enumeration,">>---------------");
      h_enumeration=FileOpen(s_enumeration,FILE_READ|FILE_CSV);   // Пытаемся открыть файл-перечислений
      if(h_enumeration==-1){
         Print("Файл перечислений не найден ", s_enumeration);
         continue;                                                // Если файла-перечислений не сущесвует - то пропускаем его
      }
      
      s_rezult=StringConcatenate(ConvertName(s_enumeration),".csv");    
      h_rezult=FileOpen(s_rezult,FILE_WRITE|FILE_CSV);
      if(h_rezult==-1){
         Print("Не удалось создать результирующий файл: ", s_rezult,"; ", GetLastError());
         continue;
      }
      while(FileIsEnding(h_enumeration)==false){
         s_temp=FileReadString(h_enumeration);                    // Считываем построчно файл-перечислений, каждая строка - имя конечного файла
         h_temp=FileOpen(s_temp,FILE_READ|FILE_CSV);              // Пытаемся открыть конечный файл
         if(h_temp==-1)continue;        // Если конечный файл не сущесвует - то пропускаем его
         str++;                                                   // Иначе количество обрабатываемых файлов увеличиваем на 1.
         //Print("--> ",s_temp);
         while(FileIsEnding(h_temp)==false){
            tmp=FileReadString(h_temp);
            if(tmp!="")count++;
         }
         Print("--> ",s_temp," ",count/12);
         count=0;
         FileClose(h_temp);                                      // Закрываем конечный файл
      }//End While (подсчет файлов-перечислений)
      FileSeek(h_enumeration,0,SEEK_SET);
      
      ArrayResize(h_file,str);
      ArrayResize(s_file,str);
      ArrayResize(data,str);
      ArrayResize(oi,str);
      ArrayResize(noncomm_long,str);
      ArrayResize(noncomm_short,str);
      ArrayResize(spreading,str);
      ArrayResize(operators_long,str);
      ArrayResize(operators_short,str);
      ArrayResize(all_long,str);
      ArrayResize(all_short,str);
      ArrayResize(nonrep_long,str);
      ArrayResize(nonrep_short,str);
      ArrayResize(frnz_str,str);
      while(FileIsEnding(h_enumeration)==false){
         s_file[n]=FileReadString(h_enumeration);                    // Считываем построчно файл-перечислений, каждая строка - имя конечного файла
         //Print(str,"; ",s_file[n]);
         h_file[n]=FileOpen(s_file[n],FILE_READ|FILE_CSV);           // Пытаемся открыть конечный файл
         if(h_file[n]==-1){Print("Файл не найден");continue;}        // Если конечный файл не сущесвует - то пропускаем его
         n++;  
      }// End While(откырие файлов-перечислений)   
      //for(n=0;n<str;n++){
      //   Print(n,"; ",s_file[n]);
      //}
      // К текущему моменту имеем список конечных файлов (s_file[]) и их дискрипторов (h_file[]) содержащихся
      // в одном из файле перечислений. Теперь объединяем эти файлы в один:
      while(FileIsEnding(h_file[0])==false){                         // В качестве сигнала окончания файла служит конец первого файла (предплолагается, что фалы одинаковые)
         for(int i=0;i<str;i++){                                     // Читаем по колонке из каждого файла входящего в файл-перечислений.
            if(frnz_str[i]==1)continue;
            tmp=FileReadString(h_file[i]);
            switch (column){
               case DATA:            data[i]=StrToTime(tmp);
               case OI:              oi[i]=StrToInteger(tmp);
               case NONCOMM_LONG:    noncomm_long[i]=StrToInteger(tmp);
               case NONCOMM_SHORT:   noncomm_short[i]=StrToInteger(tmp);
               case SPREADING:       spreading[i]=StrToInteger(tmp);
               case OPERATORS_LONG:  operators_long[i]=StrToInteger(tmp);
               case OPERATORS_SHORT: operators_short[i]=StrToInteger(tmp);
               case ALL_LONG:        all_long[i]=StrToInteger(tmp);
               case ALL_SHORT:       all_short[i]=StrToInteger(tmp);
               case NONREP_LONG:     nonrep_long[i]=StrToInteger(tmp);
               case NONREP_SHORT:    nonrep_short[i]=StrToInteger(tmp);
            }
         }// End For()
         //Print(h_file[0], ";  ",s_file[0]);
         column++;
         if(FileIsLineEnding(h_file[0])==true||FileIsEnding(h_file[0])==true){  // Если строка закончилась - сравниваем даты строк всех файлов, если равны, то объединяем их
            column=0;
            if(tmp=="")continue;
            for(int k=0;k<str;k++){
               if(data[0]>data[k])
                  frnz_str[k]=1;
               if(data[0]<data[k])
                  frnz_str[0]=1;
               if(data[0]==data[k])frnz_str[k]=0;
               if(data[0]!=data[k]){
                  Print("Обнаружен Разрыв: ", TimeToStr(data[0],TIME_DATE),"; ",TimeToStr(data[k],TIME_DATE));
                  continue;
               }
            }
               
            for(k=0;k<str;k++){
               data_all=data[0];
               oi_all+=oi[k];
               noncomm_long_all+=noncomm_long[k];
               noncomm_short_all+=noncomm_short[k];
               spreading_all+=spreading[k];
               operators_long_all+=operators_long[k];
               operators_short_all+=operators_short[k];
               all_long_all+=all_long[k];
               all_short_all+=all_short[k];
               nonrep_long_all+=nonrep_long[k];
               nonrep_short_all+=nonrep_short[k];
            }
            FileWrite(h_rezult,ConvertName(s_enumeration),
                               TimeToStr(data_all,TIME_DATE),
                               oi_all,
                               noncomm_long_all,
                               noncomm_short_all,
                               spreading_all,
                               operators_long_all,
                               operators_short_all,
                               all_long_all,
                               all_short_all,
                               nonrep_long_all,
                               nonrep_short_all);
            //Print(TimeToStr(data_all,TIME_DATE),";  ",oi_all);
            data_all=0;
            oi_all=0;
            noncomm_long_all=0;
            noncomm_short_all=0;
            spreading_all=0;
            operators_long_all=0;
            operators_short_all=0;
            all_long_all=0;
            all_short_all=0;
            nonrep_long_all=0;
            nonrep_short_all=0;
         }
         
      }// End While(сумматор)
      
      // Обнуляем результаты
      FileClose(h_enumeration);
      FileClose(h_rezult);
      /*for(int j=0;j<str;j++){
         FileClose(h_file[j]);
         noncomm_long[j]=0;
         noncomm_short[j]=0;
         spreading[j]=0;
         operators_long[j]=0;
         operators_short[j]=0;
         all_long[j]=0;
         all_short[j]=0;
         nonrep_long[j]=0;
         nonrep_short[j]=0;
      }*/
      
      n=0;str=0;
   } //End While(список файлов перечислений)
   return 0;   
}// End Programm   

string ConvertName(string str)
{
   string str_cnv;
   int strlen=StringLen(str);
   int charter;
   for(int i=0;i<strlen-4;i++){
      charter=StringGetChar(str,i);
      str_cnv=StringConcatenate(str_cnv,CharToStr(charter));
   }
   return(str_cnv);
}

/*
--------------------
  * По некоторым инструментам данные могут публиковаться с временным разрывом более одной недели. Например швейцарский франк имеет временной разрыв с 2004.09.28
  по 2004.09.07. Т.е. отчеты за 2004.09.21 и 2004.09.14 отсутствуют, хотя они есть по другим инструментам. Программа сразу после информации 2004.09.28 считает 
  информацию за 2004.09.07 по швейцарскому франку, т.е. убежит впреред, по сравнению с другими иснтрументами. Что бы это обойти используется "замарозка", -
  чтение строк этого дискриптора прекращается до тех пор, пока колонка содержащая данные снова не становиться равна остальным.
*/