//+------------------------------------------------------------------+
//|                                                       usdx histo |
//|                                                   usdx histo.mq4 |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "copyleft mladen"
#property link      "mladenfx@gmail.com"

#property indicator_separate_window
#property indicator_buffers 3
#property indicator_color1 Red
#property indicator_color2 DodgerBlue
#property indicator_color3 CLR_NONE
#property indicator_width1 2
#property indicator_width2 2
#property indicator_width3 1


//
//
//
//
//

extern int  SmoothPeriod = 4;
extern bool ShowHisto    = true;

//
//
//
//
//

double gbuffer[];
double rbuffer[];
double mbuffer[];
double wbuffer[];
string symbols[] = {"EURUSD","USDJPY","GBPUSD","USDCAD","USDSEK","USDCHF"};  
 double weights[] = {0.576,0.136,0.119,0.091,0.042,0.036};
 bool   divide[]  = {false,true,false,true,true,true};

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//
//
//
//
//

int init()
{
   IndicatorBuffers(4);
      SetIndexBuffer(0,rbuffer); SetIndexStyle(0,DRAW_HISTOGRAM);
      SetIndexBuffer(1,gbuffer); SetIndexStyle(1,DRAW_HISTOGRAM);
      SetIndexBuffer(2,mbuffer);
      SetIndexBuffer(3,wbuffer);
   IndicatorShortName("USDX ");
   return(0);
}

//
//
//
//
//

int start()
{
   int counted_bars=IndicatorCounted();
   int i,limit;
   
   if(counted_bars<0) return(-1);
   if(counted_bars>0) counted_bars--;
           limit=Bars-counted_bars;

   //
   //
   //
   //
   //
   
   
   for(i=limit; i>=0; i--)
   {
      double product = 0.00;
      bool   error   = false;
         
      //
      //
      //
      //
      //
       
      mbuffer[i] = EMPTY_VALUE;     
      wbuffer[i] = EMPTY_VALUE;     
           for (int k=0; k<6; k++)
            {
               double rateWeight = rateWeight(i,k,error);
                  if ( error ) break;
                  if ( product == 0.00)
                       product  = rateWeight;
                  else product *= rateWeight;                   
            }               
            if ( error ) continue;
 
      //
      //
      //
      //
      //
      
      wbuffer[i] = product*50.14348112;
      mbuffer[i] = smooth(i,SmoothPeriod);
      if (ShowHisto)
      {
         rbuffer[i] = rbuffer[i+1];
         gbuffer[i] = gbuffer[i+1];
            if (mbuffer[i] > mbuffer[i+1]) { gbuffer[i] = mbuffer[i]; rbuffer[i] = EMPTY_VALUE; }
            if (mbuffer[i] < mbuffer[i+1]) { rbuffer[i] = mbuffer[i]; gbuffer[i] = EMPTY_VALUE; }
      }            
   }            
   return(0);
}
  
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//
//
//
//

double rateWeight(int i, int k, bool& error)
{
   double price  = iClose(symbols[k],0,i);
   double weight = 0.00;
   
   if (price == 0) { error = true; return(0); }
   if (divide[k])
        weight = 1/price;
   else weight =   price;
   return(MathPow(weight,weights[k]));
}

//
//
//
//
//

#define Pi 3.141592653589793238462643

double smoothCoeffs[];
double smoothDivisor;   
bool   smoothInitialized = false;
int    smoothLength      = 0;

//
//
//
//
//

double smooth(int i, int length)
{
   //
   //
   //
   //
   //
   if (!smoothInitialized || length != smoothLength)
   {
      smoothInitialized = true;
      smoothLength      = MathMax(length,1);

         //
         //
         //
         //
         //
               
         ArrayResize(smoothCoeffs, smoothLength);
         smoothCoeffs[0] = 1;
         smoothDivisor   = 1;
         for (int k = 1; k < smoothLength; k++)
         {
            double temp = 1 << k / Pi;
               smoothCoeffs[k] = MathSin(temp) / temp;
               smoothDivisor  += smoothCoeffs[k];
         }   
   }

   //
   //
   //
   //
   //
   
   double sum = 0;
       for (int l = 0; l < smoothLength; l++) sum += wbuffer[l+i]*smoothCoeffs[l];
   return(sum/smoothDivisor);
}