//+------------------------------------------------------------------+
//|                                 Intraday Intensity Open Form.mq4 |
//|                            Originally developed by : Mario Jemic |
//+------------------------------------------------------------------+
#property copyright ""
#property link      "www.forex-station.com"
#property indicator_separate_window
#property indicator_buffers 5
#property indicator_color1  clrDimGray
#property indicator_color2  clrLime
#property indicator_color3  clrLime
#property indicator_color4  clrRed
#property indicator_color5  clrRed
#property  indicator_width1  3
#property  indicator_width2  3
#property  indicator_width3  3
#property  indicator_width4  3
#property  indicator_width5  3
#property strict

//
//
//
//
//

extern ENUM_TIMEFRAMES  TimeFrame = PERIOD_CURRENT; // Time frame
extern ENUM_TIMEFRAMES mTimeFrame = PERIOD_H1;      // Time frame for "higher TF filtering"

extern bool       Interpolate     = true;           // Interpolate in multi time frame mode?
//
//
//

double val[],valUa[],valUb[],valDa[],valDb[],add[],trend[],mtrend[],count[];
string indicatorFileName;
bool returnBars;
#define _mtfCall(_timeframe,_buff,_ind) iCustom(NULL,_timeframe,indicatorFileName,PERIOD_CURRENT,PERIOD_CURRENT,_buff,_ind)

//------------------------------------------------------------------
//
//------------------------------------------------------------------
//
//
//
//
//

int init()
{
   IndicatorBuffers(9);

   SetIndexBuffer( 0,val);
   SetIndexBuffer( 1,valUa); 
   SetIndexBuffer( 2,valUb);
   SetIndexBuffer( 3,valDa);   
   SetIndexBuffer( 4,valDb);
   SetIndexBuffer( 5,add);  
   SetIndexBuffer( 6,trend);
   SetIndexBuffer( 7,mtrend);
   SetIndexBuffer( 8,count);
      indicatorFileName = WindowExpertName();
      TimeFrame         = MathMax(TimeFrame,_Period);
      mTimeFrame        = MathMax(mTimeFrame,_Period);  
   IndicatorShortName(timeFrameToString(TimeFrame)+"/"+timeFrameToString(mTimeFrame)+" Intraday Intensity Open Form");
   return(0);
}

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//
//
//
//
//

int OnCalculate (const int       rates_total,
                 const int       prev_calculated,
                 const datetime& time[],
                 const double&   open[],
                 const double&   high[],
                 const double&   low[],
                 const double&   close[],
                 const long&     tick_volume[],
                 const long&     volume[],
                 const int&      spread[])
{  
   int counted_bars = prev_calculated;
      if(counted_bars < 0) return(-1);
      if(counted_bars > 0) counted_bars--;
      int limit=MathMax(MathMin(rates_total-counted_bars,rates_total-1),0); count[0] = limit;
      
         if (mTimeFrame!=_Period)
         {
 
            for (int i=limit;i>=0 && !_StopFlag; i--)
            {
               int y = iBarShift(NULL,mTimeFrame,time[i]);
               mtrend[i] = _mtfCall(mTimeFrame,6,y);
            }

         } 
      
         if (TimeFrame!=_Period)
         {
            limit = (int)MathMax(limit,MathMin(rates_total-1,_mtfCall(TimeFrame,8,0)*TimeFrame/_Period));
            if (trend[limit]== 1) CleanPoint(limit,valUa,valUb);
            if (trend[limit]==-1) CleanPoint(limit,valDa,valDb);
            for (int i=limit;i>=0 && !_StopFlag; i--)
            {
               int y = iBarShift(NULL,TimeFrame,time[i]);
                  val[i]   = _mtfCall(TimeFrame,0,y);
                  trend[i] = _mtfCall(TimeFrame,6,y);
                  valDa[i] = EMPTY_VALUE;
                  valDb[i] = EMPTY_VALUE;
                  valUa[i] = EMPTY_VALUE;
                  valUb[i] = EMPTY_VALUE;
                  if (!Interpolate || (i>0 && y==iBarShift(NULL,TimeFrame,time[i-1]))) continue;
                  
                  //
                  //
                  //
                  //
                  //
                  
                  #define _interpolate(buff) buff[i+k] = buff[i]+(buff[i+n]-buff[i])*k/n
                  int n,k; datetime itime = iTime(NULL,TimeFrame,y);
                     for(n = 1; (i+n)<rates_total && time[i+n] >= itime; n++) continue;	
                     for(k = 1; k<n && (i+n)<rates_total && (i+k)<rates_total; k++) 
                     {
                        _interpolate(val);
                     }                  
            }
            for (int i=limit;i>=0 && !_StopFlag; i--)
            {
                   if (mTimeFrame!=_Period)
                   {
                      if (trend[i] == 1 && mtrend[i] == 1) PlotPoint(i,valUa,valUb,val); 
                      if (trend[i] ==-1 && mtrend[i] ==-1) PlotPoint(i,valDa,valDb,val);                                                             
                   }
                   else
                   {
                      if (trend[i] == 1) PlotPoint(i,valUa,valUb,val); 
                      if (trend[i] ==-1) PlotPoint(i,valDa,valDb,val);
                   }                                                                                                                
                    
            }         
            return(rates_total);
         }    
   //
   //
   //
   //
   //
   int i;
   if (trend[limit]== 1) CleanPoint(limit,valUa,valUb);
   if (trend[limit]==-1) CleanPoint(limit,valDa,valDb); 

   for (i=limit; i >= 0; i--)
   {
	   if(i<rates_total-1)
	   {
	   if ((high[i]-low[i])!= 0)
	   {
   	      add[i]   = (2*close[i]-high[i]-low[i])/(high[i]-low[i])*tick_volume[i];
   		   val[i]   =  val[i+1] + add[i];
   		   trend[i] = (val[i]>val[i+1]) ? 1 : (val[i]<val[i+1]) ? -1 : 0;
	   }
	   }        
            //
            //
            //
            //
            //
            
                   
                   
                   valDa[i] = EMPTY_VALUE;
                   valDb[i] = EMPTY_VALUE;
                   valUa[i] = EMPTY_VALUE;
                   valUb[i] = EMPTY_VALUE;
         
                   //
                   //
                   //
                   //
                   //
                   if (mTimeFrame!=_Period)
                   {
                      if (trend[i] == 1 && mtrend[i] == 1) PlotPoint(i,valUa,valUb,val); 
                      if (trend[i] ==-1 && mtrend[i] ==-1) PlotPoint(i,valDa,valDb,val);                                                             
                   }
                   else
                   {
                      if (trend[i] == 1) PlotPoint(i,valUa,valUb,val); 
                      if (trend[i] ==-1) PlotPoint(i,valDa,valDb,val);
                   }                                                                                                                
                   

                   
                                     
   }
   return(rates_total);
}


//-------------------------------------------------------------------
//                                                                  
//-------------------------------------------------------------------
//
//
//
//
//

void CleanPoint(int i,double& first[],double& second[])
{
   if (i>=Bars-3) return;
   if ((second[i]  != EMPTY_VALUE) && (second[i+1] != EMPTY_VALUE))
        second[i+1] = EMPTY_VALUE;
   else
      if ((first[i] != EMPTY_VALUE) && (first[i+1] != EMPTY_VALUE) && (first[i+2] == EMPTY_VALUE))
          first[i+1] = EMPTY_VALUE;
}

void PlotPoint(int i,double& first[],double& second[],double& from[])
{
   if (i>=Bars-2) return;
   if (first[i+1] == EMPTY_VALUE)
      if (first[i+2] == EMPTY_VALUE) 
            { first[i]  = from[i]; first[i+1]  = from[i+1]; second[i] = EMPTY_VALUE; }
      else  { second[i] = from[i]; second[i+1] = from[i+1]; first[i]  = EMPTY_VALUE; }
   else     { first[i]  = from[i];                          second[i] = EMPTY_VALUE; }
}

string sTfTable[] = {"M1","M5","M15","M30","H1","H4","D1","W1","MN"};
int    iTfTable[] = {1,5,15,30,60,240,1440,10080,43200};

string timeFrameToString(int tf)
{
   for (int i=ArraySize(iTfTable)-1; i>=0; i--) 
         if (tf==iTfTable[i]) return(sTfTable[i]);
                              return("");
}
