//+------------------------------------------------------------------+
//|                                                InterestRates.mq4 |
//|                                    Copyright © 2009, Fibollinger |
//|                                        http://moneyunleashed.com |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2009, Fibollinger"
#property link      "http://moneyunleashed.com"

#property indicator_separate_window
#property indicator_buffers 3
#property indicator_color1 Blue
#property indicator_color2 Green
#property indicator_color3 Red
#property indicator_width3 1

//---- input parameters
extern string  FileExtention = "txt";
extern int     Delimiter = 9;


//---- buffers
double ExtMapBuffer1[];
double ExtMapBuffer2[];
double ExtMapBuffer3[];

datetime ComDate[];
double ComRate[];
datetime NoncomDate[];
double NoncomRate[];
datetime NonrepDate[];
double NonrepRate[];
datetime MaxComDate[];
double MaxComRate[];
datetime MinComDate[];
double MinComRate[];
datetime MaxNoncomDate[];
double MaxNoncomRate[];
datetime MinNoncomDate[];
double MinNoncomRate[];
datetime MaxNonrepDate[];
double MaxNonrepRate[];
datetime MinNonrepDate[];
double MinNonrepRate[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
{
   //---- indicators
   SetIndexStyle(0, DRAW_LINE, 0, 1, Green);
   SetIndexBuffer(0, ExtMapBuffer1);
   SetIndexStyle(1, DRAW_LINE, 0, 1, Red);
   SetIndexBuffer(1, ExtMapBuffer2);
   SetIndexStyle(2, DRAW_LINE, 0, 1, Blue);
   SetIndexBuffer(2, ExtMapBuffer3);
   
   string commercial = "commercial";
   string noncommercial = "noncommercial";
   string nonreporting = "nonreporting";
   string maxcom = "maxcom";
   string mincom = "mincom";
   string maxnoncom = "maxnoncom";
   string minnoncom = "minnoncom";
   string maxnonrep = "maxnonrep";
   string minnonrep = "minnonrep";

   //---- read file
  if (ReadSeriesFromFile(StringConcatenate(commercial, ".", FileExtention), Delimiter, ComDate, ComRate) < 0)
   {
      return(Terminate());
   }

   if (ReadSeriesFromFile(StringConcatenate(noncommercial, ".", FileExtention), Delimiter, NoncomDate, NoncomRate) < 0)
   {
      return(Terminate());
   }
   
   if (ReadSeriesFromFile(StringConcatenate(nonreporting, ".", FileExtention), Delimiter, NonrepDate, NonrepRate) < 0)
   {
      return(Terminate());
   }
   
   if (ReadSeriesFromFile(StringConcatenate(maxcom, ".", FileExtention), Delimiter, MaxComDate, MaxComRate) < 0)
   {
      return(Terminate());
   }
   
   if (ReadSeriesFromFile(StringConcatenate(mincom, ".", FileExtention), Delimiter, MinComDate, MinComRate) < 0)
   {
      return(Terminate());
   }
   
   if (ReadSeriesFromFile(StringConcatenate(maxnoncom, ".", FileExtention), Delimiter, MaxNoncomDate, MaxNoncomRate) < 0)
   {
      return(Terminate());
   }
   
   if (ReadSeriesFromFile(StringConcatenate(minnoncom, ".", FileExtention), Delimiter, MinNoncomDate, MinNoncomRate) < 0)
   {
      return(Terminate());
   }
   
   if (ReadSeriesFromFile(StringConcatenate(maxnonrep, ".", FileExtention), Delimiter, MaxNonrepDate, MaxNonrepRate) < 0)
   {
      return(Terminate());
   }
   
   if (ReadSeriesFromFile(StringConcatenate(minnonrep, ".", FileExtention), Delimiter, MinNonrepDate, MinNonrepRate) < 0)
   {
      return(Terminate());
   }
   

   //----
   return(0);
}

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
{
   int Counted_bars = IndicatorCounted();
   int i;
   
   i = Bars - Counted_bars - 1;
   while(i >= 0)
   {
      int iCom = ArrayBsearchCorrect(ComDate, Time[i]);
      int iNoncom = ArrayBsearchCorrect(NoncomDate, Time[i]);
      int iNonrep = ArrayBsearchCorrect(NonrepDate, Time[i]);
      int iMaxCom = ArrayBsearchCorrect(MaxComDate, Time[i]);
      int iMinCom = ArrayBsearchCorrect(MinComDate, Time[i]);
      int iMaxNoncom = ArrayBsearchCorrect(MaxNoncomDate, Time[i]);
      int iMinNoncom = ArrayBsearchCorrect(MinNoncomDate, Time[i]);   
      int iMaxNonrep = ArrayBsearchCorrect(MaxNonrepDate, Time[i]);      
      int iMinNonrep = ArrayBsearchCorrect(MinNonrepDate, Time[i]); 
      
      if(MaxComRate[iMaxCom]-MinComRate[iMinCom]==0)
      {
      ExtMapBuffer1[i] = 50;
      }else
      {
      ExtMapBuffer1[i] = ((ComRate[iCom]-MinComRate[iMinCom])/(MaxComRate[iMaxCom]-MinComRate[iMinCom]))*100;
      }
      
      if(MaxNoncomRate[iMaxNoncom]-MinNoncomRate[iMinNoncom]==0)
      {
      ExtMapBuffer2[i] = 50;
      }else
      {
      ExtMapBuffer2[i] = ((NoncomRate[iNoncom]-MinNoncomRate[iMinNoncom])/(MaxNoncomRate[iMaxNoncom]-MinNoncomRate[iMinNoncom]))*100;
      }
      
      if(MaxNonrepRate[iMaxNonrep]-MinNonrepRate[iMinNonrep]==0)
      {
      ExtMapBuffer3[i] = 50;
      }else
      {
     ExtMapBuffer3[i] = ((NonrepRate[iNonrep]-MinNonrepRate[iMinNonrep])/(MaxNonrepRate[iMaxNonrep]-MinNonrepRate[iMinNonrep]))*100;
      }   
      i--;
   }
  
   //----
   return(0);
}
//+------------------------------------------------------------------+

int ReadSeriesFromFile(string filename, int delimiter, datetime &keys[], double &values[])
{
   int h = FileOpen(filename, FILE_CSV || FILE_READ, delimiter);
   if (h < 1) 
   {
      Print("File ", filename, " not found, the last error is ", GetLastError());
      return(-1);
   }
   Print("File ", filename, " open.");

   int i = 0;
   while (!FileIsEnding(h))
   {
      string s = StringTrimRight(FileReadString(h));
      if (s == "")
      {
         continue;   // ignore blank lines
      }
      datetime date = StrToTime(s);
      
      // value = FileReadNumber(h);
      s = FileReadString(h);
      double value = StrToDouble(s);
 
      // Print(TimeToStr(date, TIME_DATE), ": ", value, "%");

      ArrayResize(keys, i + 1);
      keys[i] = date;
      ArrayResize(values, i + 1);
      values[i] = value;
      i++;
   }

   FileClose(h);
   SortDictionary(keys, values);
   
   return(i);
}

void SortDictionary(datetime &keys[], double &values[], int sortDirection = MODE_ASCEND)
{
   datetime keyCopy[];
   double valueCopy[];
   ArrayCopy(keyCopy, keys);
   ArrayCopy(valueCopy, values);
   ArraySort(keys, WHOLE_ARRAY, 0, sortDirection);

   for (int i = 0; i < MathMin(ArraySize(keys), ArraySize(values)); i++)
   {
      //Print(i, ": ", TimeToStr(keys[i], TIME_DATE), " ci=", ArrayBsearch(keyCopy, keys[i]), " cv=", valueCopy[ArrayBsearch(keyCopy, keys[i])]);
      //values[i] = valueCopy[ArrayBsearch(keyCopy, keys[i])];
      values[ArrayBsearch(keys, keyCopy[i])] = valueCopy[i];
   }
}

int ArrayBsearchCorrect(datetime array[], datetime value, int count = WHOLE_ARRAY, int start = 0, int direction = MODE_ASCEND)
{
   int i = ArrayBsearch(array, value, count, start, direction);
   if (value < array[i])
   {
      i = -1;
   }
   return (i);
}

int Terminate()
{
   int err = 1; 
   Print("Self-terminating with divide by zero");
   err /= 0;
   return (err);
}




