//+------------------------------------------------------------------+
//|                                                   candle-gap.mq4 |
//|                        Copyright 2021, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property indicator_separate_window
#property indicator_minimum    -1
#property indicator_maximum    1
#property indicator_buffers 2
#property indicator_plots   2

//plot bullish
#property indicator_type1   DRAW_HISTOGRAM
#property indicator_color1  clrLimeGreen
#property indicator_style1  STYLE_SOLID
#property indicator_width1  4

//plot bearish
#property indicator_type2   DRAW_HISTOGRAM
#property indicator_color2  clrRed
#property indicator_style2  STYLE_SOLID
#property indicator_width2  4

input double gap_height=0.000100;
input double bull_candle_body_ratio=0.48;
input double bear_candle_body_ratio=0.48;
input bool  bounds_bodies_ratio=true;
input double upper_bound_bodies_ratio=1.4;
input double lower_bound_bodies_ratio=0.7;
double bull_kickerBuffer[];
double bear_kickerBuffer[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
    IndicatorBuffers(2);
//--- indicator buffers mapping
   SetIndexBuffer(0,bull_kickerBuffer);
   SetIndexBuffer(1,bear_kickerBuffer);
   
   if((Digits==2&&gap_height<0.01)||(Digits==3&&gap_height<0.001)||(Digits==4&&gap_height<0.0001)||(Digits==5&&gap_height<0.00001))
     return(INIT_FAILED);
  
   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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 = IndicatorCounted();
   if(counted_bars < 0)  return(-1);
   if(counted_bars > 0)   counted_bars--;
   int limit = Bars - counted_bars;
   if(counted_bars==0) limit--;
    
    
    
    
   for(int i=limit;i>=0;i--)
   {
   
   if((close[i+1]>open[i+1])&&(close[i+2]<open[i+2])&&((open[i+1]-open[i+2])>gap_height)&&(close[i+1]-open[i+1]>=bull_candle_body_ratio*(high[i+1]-low[i+1]))&&(open[i+2]-close[i+2]>=bear_candle_body_ratio*(high[i+2]-low[i+2]))&&(bounds_bodies_ratio ? (( ((close[i+1]-open[i+1])/(open[i+2]-close[i+2]))>=lower_bound_bodies_ratio  )&&( (( close[i+1]-open[i+1] )/(open[i+2]-close[i+2]))<=upper_bound_bodies_ratio   )) :true))
   {
       if (!bounds_bodies_ratio)
      Comment("bull-----", TimeToString(time[i+1])); 
      else if(bounds_bodies_ratio)
       Comment("\nbull with bodies ratio-----", TimeToString(time[i+1]));
   
      bull_kickerBuffer[i+1]=+1.0;
     bear_kickerBuffer[i+1]=0.0;
   
   }
   else if((close[i+1]<open[i+1])&&(close[i+2]>open[i+2])&&((open[i+2]-open[i+1])>gap_height)&&(open[i+1]-close[i+1]>=bear_candle_body_ratio*(high[i+1]-low[i+1]))&&(close[i+2]-open[i+2]>=bull_candle_body_ratio*(high[i+2]-low[i+2]))&&(bounds_bodies_ratio ? (   (((open[i+1]-close[i+1])/(close[i+2]-open[i+2]))>=lower_bound_bodies_ratio )&&(((open[i+1]-close[i+1])/(close[i+2]-open[i+2]))<=upper_bound_bodies_ratio )) :true))
   {
      if(!bounds_bodies_ratio)
      Comment("bear-----",TimeToString(time[i+1]));
       if(bounds_bodies_ratio)
       Comment("\nbear with bodies ratio-----", TimeToString(time[i+1]));
      
     bull_kickerBuffer[i+1]=0.0;
     bear_kickerBuffer[i+1]=-1.0;
   }
   else
   {
     bull_kickerBuffer[i+1]=0.0;
     bear_kickerBuffer[i+1]=0.0;
   }
   
   
   
   }
   
   
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
