//+------------------------------------------------------------------+
//|                                              Meta COT cotlib.mq4 |
//|   Copyright © 2011, C-4 (Vasiliy Sokolov, Russia, St.-Petersburg,|
//|                                      2011), All Rights Reserved. |
//|                                                   vs-box@mail.ru |
//|                                         last changes:  14.03.2011|
//+------------------------------------------------------------------+
#property copyright "Copyright © 2011, C-4 (Vasiliy Sokolov, SPb), All Rights Reserved."
#property link      "vs-box@mail.ru"

// Возможные значения параметра "type" функции get_data()
#define OI                    0
#define NONCOMM_LONG          1
#define NONCOMM_SHORT         2
#define OPERATORS_LONG        3
#define OPERATORS_SHORT       4
#define NONREP_LONG           5
#define NONREP_SHORT          6
#define NET_NONCOMM           7
#define NET_OPERATORS         8
#define NET_NONREP            9
#define OI_NONCOMM_LONG       10
#define OI_NONCOMM_SHORT      11
#define OI_OPERATORS_LONG     12
#define OI_OPERATORS_SHORT    13
#define OI_NONREP_LONG        14
#define OI_NONREP_SHORT       15
#define WILLCO_NONCOMM        16
#define WILLCO_OPERATORS      17
#define WILLCO_NONREP         18
#define INDEX_OI              19
#define INDEX_NONCOMM         20
#define INDEX_OPERATORS       21
#define INDEX_NONREP          22
#define MOVEMENT_NONCOMM      23
#define MOVEMENT_OPERATORS    24
#define MOVEMENT_NONREP       25
#define MOVEMENT_OI           26
#define OI_NET_NONCOMM        27
#define OI_NET_OPERATORS      28
#define OI_NET_NONREP         29


extern bool   load_cot_file=false;
extern string cot_file="COT - U.S. DOLLAR CONCATENATE.csv";
extern string settings="settings.ini";
string name;
bool error=false;
int column;
bool DrawData=true;
bool LoadData=true;


//***************************************************************************************************************
//                                     ТАБЛИЦА ДАННЫХ COT
int n_str;                    //содержит кол-во строк

// Массив содержит дату
datetime realize_data[];
// Массивы содержат обсолютные позиции 
double open_interest[];       // Открытый интерес
double noncomm_long[];        // Длинные позиции некоммерческих трейдеров
double noncomm_short[];       // Короткие позиции некоммерческих трейдеров
double noncomm_spread[];      // Покрытие некоммерческих трейдеров
double operators_long[];      // Длинные позиции некоммерческих трейдеров (операторов)
double operators_short[];     // Короткие позиции некоммерческих трейдеров (операторов)
double nonrep_long[];         // Длинные позиции неподотчетных трейдеров (публики)
double nonrep_short[];        // Короткие опзиции неподотчетных трейдеров (публики)

// Массивы содержат результат деления обсолютной длинной и короткой позиции каждой из трех групп трейдеров на открытый интерес
double oi_noncomm_long[];     // Открытый интерес / Длинные позиции некоммерческих трейдеров
double oi_noncomm_short[];    // Открытый интерес / Короткие позиции некоммерческих трейдеров
double oi_operators_long[];   // Открытый интерес / Длинные позиции некоммерческих трейдеров (операторов)
double oi_operators_short[];  // Открытый интерес / Короткие позиции некоммерческих трейдеров (операторов)
double oi_nonrep_long[];      // Открытый интерес / Длинные позиции неподотчетных трейдеров (публики)
double oi_nonrep_short[];     // Открытый интерес / Короткие опзиции неподотчетных трейдеров (публики)

//Массивы содержат результат деления чистой позиции каждой из трех групп трейдеров на открытый интерес
//используется для построения индекса WILLCO
double oi_net_noncomm[];
double oi_net_operators[];
double oi_net_nonrep[];

// Массивы содержат чистые позиции коммерческих трейдеров, операторов и не подотчетной публики
double net_noncomm[];         // Чистые позиции некоммерческих трейдеров
double net_operators[];       // Чистые позиции коммерческих трейдеров
double net_nonrep[];          // Чистые позиции неподотчетных трейдеров

// Массивы содержат индекс чистых позиций каждой из трех групп
double index_oi[];            // Индекс открытого интереса
double index_ncomm[];         // Индекс некоммерческих трейдеров
double index_operators[];     // Индекс коммерческих трейдеров (операторов)
double index_nonrep[];        // Инддекс неподотчетных трейдеров (публики)

// Массивы содержат стохастический осцилятор высчитанный из отношения открытого интереса к чистой позииции каждой из трех групп
// Stohastic(OI/NET_POSITION)
double willco_ncomm[];        // 
double willco_operators[];    //
double willco_nonrep[];       //

//MOVEMENT INDEX
double movement_oi[];
double movement_ncomm[];
double movement_operators[];
double movement_nonrep[];
//***********************************************************************************************************************************

//
bool init_data()
{
   string data;
   int handle_cotfile;
   int str;
   //settings_load();
   settings_load();
   handle_cotfile=FileOpen(cot_file,FILE_READ|FILE_CSV);
   //handle_cotfile=FileOpen("COT - U.S. DOLLAR CONCATENATE.csv",FILE_READ|FILE_CSV);
   if(handle_cotfile==-1){
      Print("Не удалось загрузить файл. Дальнейшее продолжение невозможно ", cot_file);
      Print(GetLastError());
      return(false);
   }
   while(FileIsEnding(handle_cotfile)==false){
      data=FileReadString(handle_cotfile);
      if(FileIsLineEnding(handle_cotfile)&&data!="")str++;
   }
   ArrayResize(realize_data,str);
   
   ArrayResize(open_interest,str);
   ArrayResize(noncomm_long,str);
   ArrayResize(noncomm_short,str);
   ArrayResize(noncomm_spread,str);
   ArrayResize(operators_long,str);
   ArrayResize(operators_short,str);
   ArrayResize(nonrep_long,str);
   ArrayResize(nonrep_short,str);
   
   ArrayResize(oi_noncomm_long,str);
   ArrayResize(oi_noncomm_short,str);
   ArrayResize(oi_operators_long,str);
   ArrayResize(oi_operators_short,str);
   ArrayResize(oi_nonrep_long,str);
   ArrayResize(oi_nonrep_short,str);
   
   ArrayResize(oi_net_noncomm,str);
   ArrayResize(oi_net_operators,str);
   ArrayResize(oi_net_nonrep,str);
   
   ArrayResize(net_noncomm,str);
   ArrayResize(net_operators,str);
   ArrayResize(net_nonrep,str);
   
   ArrayResize(index_oi,str);
   ArrayResize(index_ncomm,str);
   ArrayResize(index_operators,str);
   ArrayResize(index_nonrep,str);
   
   ArrayResize(willco_ncomm,str);
   ArrayResize(willco_operators,str);
   ArrayResize(willco_nonrep,str);
   
   ArrayResize(movement_oi,str);
   ArrayResize(movement_ncomm,str);
   ArrayResize(movement_operators,str);
   ArrayResize(movement_nonrep,str);
   
   FileClose(handle_cotfile);
   return(true);
}

/*void settings_load()
{
   int h_set, _column;
   string set, sname;
   if(load_cot_file==true)return;
   h_set=FileOpen(settings,FILE_READ|FILE_CSV,";");
   //FileOpen("\Temp\Cot_file.txt",FILE_WRITE,FILE_CSV);
   if(h_set==-1)return;
   while(FileIsEnding(h_set)==false){
      set=FileReadString(h_set);
      _column++;
      if(set==Symbol()&&_column!=1){cot_file=sname;return;}
      if(_column==2&&set!="")name=set;             // Вторая колонка - желаемое название индикатора
      if(FileIsLineEnding(h_set)==true)_column=0;
      if(_column==1)sname=set;
      
   }
   FileClose(h_set);
}*/

// На сегодняшний день, единственный брокер в России, который поддерживает практически все инструменты
// попадающие в отчет трейдеров является Broco Company. Поэтому поддержка брокера включена в проект.
// Это означает, что вам не надо будет выбирать название инструмента, из сотни файлов, все будет сделано
// автоматически!!!
void settings_load()
{
   int h_set, _column;
   string set, sname;
   if(load_cot_file==true)return;
   h_set=FileOpen(settings,FILE_READ|FILE_CSV,";");
   //FileOpen("\Temp\Cot_file.txt",FILE_WRITE,FILE_CSV);
   if(h_set==-1)return;
   while(FileIsEnding(h_set)==false){
      set=FileReadString(h_set);
      _column++;
      if(_column==1&&set!="")sname=set;
      if(_column==2&&set!="")name=set;             // Вторая колонка - желаемое название индикатора
      if(_column>2&&set!=""&&StringFind(Symbol(),set)==0){cot_file=sname;return;}
      if(FileIsLineEnding(h_set)==true)_column=0;
   }
}

void load_data()
{
   //datetime data_realize;
   int handle_cotfile;
   string data;
   handle_cotfile=FileOpen(cot_file,FILE_READ|FILE_CSV, ";");
   Print("Файл найден");
   while(FileIsEnding(handle_cotfile)==false){
      data=FileReadString(handle_cotfile);
      column++;
      if(FileIsLineEnding(handle_cotfile)==true||FileIsEnding(handle_cotfile)==true){//column=12 - обнуляет раньше времени
        if(column==12)
           nonrep_short[n_str]=StrToDouble(data);
        column=0;
        if(data!="")n_str++;
      }
      else{
         switch(column){
            case 2:
               realize_data[n_str]=StrToTime(data);
               break;
            case 3:
               open_interest[n_str]=StrToDouble(data);
               //Print(open_interest[n_str]);
               break;
            case 4:
               noncomm_long[n_str]=StrToDouble(data);
               break;
            case 5:
               noncomm_short[n_str]=StrToDouble(data);
               break;          
            case 6:
               noncomm_spread[n_str]=StrToDouble(data);
               break;
            case 7:
               operators_long[n_str]=StrToDouble(data);
               break;
            case 8:
               operators_short[n_str]=StrToDouble(data);
               break;
            case 11:
               nonrep_long[n_str]=StrToDouble(data);
               break;
         }
      } 
   }
   FileClose(handle_cotfile);
   Print("Файл загружен");
}

void count_data()
{
   int    max,
          min;
   double delta;
   
   for(int i=0;i<n_str;i++){
      index_oi[i]=EMPTY_VALUE;
      index_ncomm[i]=EMPTY_VALUE;
      index_operators[i]=EMPTY_VALUE;
      index_nonrep[i]=EMPTY_VALUE;
      willco_ncomm[i]=EMPTY_VALUE;
      willco_operators[i]=EMPTY_VALUE;
      willco_nonrep[i]=EMPTY_VALUE;
      movement_ncomm[i]=EMPTY_VALUE;
      movement_operators[i]=EMPTY_VALUE;
      movement_nonrep[i]=EMPTY_VALUE;
   }
   for(i=0;i<n_str;i++){
      if(open_interest[i]==0){
         oi_noncomm_long[i]=0;
         oi_noncomm_short[i]=0;
         oi_operators_long[i]=0;
         oi_operators_short[i]=0;
         oi_nonrep_long[i]=0;
         oi_nonrep_short[i]=0;
      }
      else{
         oi_noncomm_long[i]=noncomm_long[i]/open_interest[i];
         oi_noncomm_short[i]=noncomm_short[i]/open_interest[i];
         oi_operators_long[i]=operators_long[i]/open_interest[i];
         oi_operators_short[i]=operators_short[i]/open_interest[i];
         oi_nonrep_long[i]=nonrep_long[i]/open_interest[i];
         oi_nonrep_short[i]=nonrep_short[i]/open_interest[i];
      }
      
      net_noncomm[i]=noncomm_long[i]-noncomm_short[i];
      net_operators[i]=operators_long[i]-operators_short[i];
      net_nonrep[i]=nonrep_long[i]-nonrep_short[i];
      
      if(open_interest[i]==0){
         oi_net_noncomm[i]=0;
         oi_net_operators[i]=0;
         oi_net_nonrep[i]=0;
      }
      else{
         oi_net_noncomm[i]=net_noncomm[i]/open_interest[i];
         oi_net_operators[i]=net_operators[i]/open_interest[i];
         oi_net_nonrep[i]=net_nonrep[i]/open_interest[i];
      }  
   }
   
   for(i=0;i<n_str-period;i++){  
      
      max=ArrayMaximum(open_interest,period,i);
      min=ArrayMinimum(open_interest,period,i);
      delta=open_interest[max]-open_interest[min];
      if(delta==0)delta=1;
      index_oi[i]=(open_interest[i]-open_interest[min])/delta*100;
      
      max=ArrayMaximum(net_noncomm,period,i);
      min=ArrayMinimum(net_noncomm,period,i);
      delta=net_noncomm[max]-net_noncomm[min];
      if(delta==0)delta=1;
      index_ncomm[i]=(net_noncomm[i]-net_noncomm[min])/delta*100;
      
      max=ArrayMaximum(net_operators,period,i);
      min=ArrayMinimum(net_operators,period,i);
      delta=net_operators[max]-net_operators[min];
      if(delta==0)delta=1;
      index_operators[i]=(net_operators[i]-net_operators[min])/delta*100;
      
      max=ArrayMaximum(net_nonrep,period,i);
      min=ArrayMinimum(net_nonrep,period,i);
      delta=net_nonrep[max]-net_nonrep[min];
      if(delta==0)delta=1;
      index_nonrep[i]=(net_nonrep[i]-net_nonrep[min])/delta*100;
      
      max=ArrayMaximum(oi_net_noncomm,period,i);
      min=ArrayMinimum(oi_net_noncomm,period,i);
      delta=oi_net_noncomm[max]-oi_net_noncomm[min];
      if(delta==0)delta=1;
      willco_ncomm[i]=(oi_net_noncomm[i]-oi_net_noncomm[min])/delta*100;
      
      max=ArrayMaximum(oi_net_operators,period,i);
      min=ArrayMinimum(oi_net_operators,period,i);
      delta=oi_net_operators[max]-oi_net_operators[min];
      if(delta==0)delta=1;
      willco_operators[i]=(oi_net_operators[i]-oi_net_operators[min])/delta*100;
      
      max=ArrayMaximum(oi_net_nonrep,period,i);
      min=ArrayMinimum(oi_net_nonrep,period,i);
      delta=oi_net_nonrep[max]-oi_net_nonrep[min];
      if(delta==0)delta=1;
      willco_nonrep[i]=(oi_net_nonrep[i]-oi_net_nonrep[min])/delta*100;
   }
   for(i=0;i<n_str-period-movement_index;i++){
      movement_oi[i]=index_oi[i]-index_oi[i+movement_index];
      movement_ncomm[i]=index_ncomm[i]-index_ncomm[i+movement_index];
      movement_operators[i]=index_operators[i]-index_operators[i+movement_index];
      movement_nonrep[i]=index_nonrep[i]-index_nonrep[i+movement_index];
   }
}

// Возвращает одно из значений COT таблицы определенное переменной "type" для бара "bar"
double get_data(int type, int bar)
{
   //double data;
   int i_data=get_cot(bar);
   if(i_data==EMPTY_VALUE)return(EMPTY_VALUE);
   switch (type){
      case OI:
         return(open_interest[i_data]);
      case NONCOMM_LONG:
         //return(noncomm_long[i_data]+noncomm_spread[i_data]);
         return(noncomm_long[i_data]);
      case NONCOMM_SHORT:
         //return(noncomm_short[i_data]+noncomm_spread[i_data]);
         return(noncomm_short[i_data]);
      case OPERATORS_LONG:
         return(operators_long[i_data]);
      case OPERATORS_SHORT:
         return(operators_short[i_data]);
      case NONREP_LONG:
         return(nonrep_long[i_data]);
      case NONREP_SHORT:
         return(nonrep_short[i_data]);
      case NET_NONCOMM:
         return(net_noncomm[i_data]);
      case NET_OPERATORS:
         return(net_operators[i_data]);
      case NET_NONREP:
         return(net_nonrep[i_data]);
      case INDEX_OI:
         return(index_oi[i_data]);
      case INDEX_NONCOMM:
         return(index_ncomm[i_data]);
      case INDEX_OPERATORS:
         return(index_operators[i_data]);
      case INDEX_NONREP:
         return(index_nonrep[i_data]);
      case OI_NONCOMM_LONG:
         return(oi_noncomm_long[i_data]);
      case OI_NONCOMM_SHORT:
         return(oi_noncomm_short[i_data]);
      case OI_OPERATORS_LONG:
         return(oi_operators_long[i_data]);
      case OI_OPERATORS_SHORT:
         return(oi_operators_short[i_data]);
      case OI_NONREP_LONG:
         return(oi_nonrep_long[i_data]);
      case OI_NONREP_SHORT:
         return(oi_nonrep_short[i_data]);
      case WILLCO_NONCOMM:
         return(willco_ncomm[i_data]);
      case WILLCO_OPERATORS:
         return(willco_operators[i_data]);
      case WILLCO_NONREP:
         return(willco_nonrep[i_data]);
      case OI_NET_NONCOMM:
         return(oi_net_nonrep[i_data]);
      case OI_NET_OPERATORS:
         return(oi_net_operators[i_data]);
      case OI_NET_NONREP:
         return(oi_net_nonrep[i_data]);
      case MOVEMENT_NONCOMM:
         return(movement_ncomm[i_data]);
      case MOVEMENT_OPERATORS:
         return(movement_operators[i_data]);
      case MOVEMENT_NONREP:
         return(movement_nonrep[i_data]);
      case MOVEMENT_OI:
         return(movement_oi[i_data]);
   }
   return(EMPTY_VALUE);
}

//Возвращает номер ячейке в массиве, в котором эти данные хранятся, возвращает значение EMPTY_VALUE, если не удалось найти бар
int get_cot(int i)
{
   datetime tbar=iTime(Symbol(),0,i);
   for(int k=0;k<n_str;k++){
      //Возвращаем данные недельной давности, для эмулирования отсрочки публикации
      //if(realize_data[k]+518400<tbar)return(k);
      if(realize_data[k]<tbar)return(k);
   }
   return(EMPTY_VALUE);
}

// Возвращает бар для которого известно последнее значение COT данных
int get_lastdata()
{
   return(iBarShift(Symbol(),0,realize_data[n_str-1],false));
}

// Возвращает строку без расширения и первых 6 символов (было "COT - FileName.csv" стало "FileName")
string str_trim(string fname)
{
   int strlen=StringLen(fname)-1;
   int charter;
   string str;
   for(int i=strlen;i>0;i--){
      charter=StringGetChar(fname,i);
      if(charter=='.'){
         for(int b=6;b<i;b++)//поменять на b=0 если не требуется удалять первые 6 символов
            str=str+CharToStr(StringGetChar(fname,b));
         return(str);
      }
   }
   return(fname);
}