//+------------------------------------------------------------------+
//|                                                  Candle Size.mq4 |
//|                                                       Ryan Cap   |
//+------------------------------------------------------------------+
#property copyright "Ryan Cap"

// yeah like I care if you copy this.. haha.. feel free to sell it, make money, share it with your grand children etc... :p

#property indicator_chart_window#property indicator_buffers 1
#property indicator_plots 1
#property indicator_color1 Yellow
#property indicator_width1 3

input double __distance__ = 0.0010;//distance
double distance = __distance__;
input string __onOff__ = "on";//onOff
string onOff = __onOff__;

double v1[];
double val1;
int i;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
void OnInit()
  {
//---- indicators
   FDFE::SetIndexArrow(0,217);
   FDFE::SetIndexStyle(0,DRAW_ARROW,STYLE_SOLID,3);
   FDFE::SetIndexDrawBegin(0, i-1);
   FDFE::SetIndexBuffer(0, v1);
   FDFE::SetIndexLabel(0,"Candle bigger than Distance");
   
//----
   return;
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
void OnDeinit()
  {
//----
   
//----
   return;
  }
//+------------------------------------------------------------------+
//| 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[]
)
  {
   i = Bars;
   while(i >= 0)
     {   
       val1 = (High[i]-Low[i]);
       //----
       if(val1 > distance) {
           v1[i] = Low[i]-0.0005;
       }
       else{
           v1[i] = 0;
       }
       //----
       i--;
     }
   if(onOff == "on" && v1[0] != 0){
      Alert("Candle Bigger Than ",distance);
   }      
   return(0);
  }
   
   
//----
//+------------------------------------------------------------------+

//== fxDreema MQL4 to MQL5 Converter ==//

//-- Global Variables
int FXD_SELECTED_TYPE = 0;// Indicates what is selected by OrderSelect, 1 for trade, 2 for pending order, 3 for history trade
ulong FXD_SELECTED_TICKET = 0;// The ticket number selected by OrderSelect
int FXD_INDICATOR_COUNTED_MEMORY = 0;// Used as a memory for IndicatorCounted() function. It needs to be outside of the function, because when OnCalculate needs to be reset, this memory must be reset as well.

// Set the missing predefined variables, which are controlled by RefreshRates
int Bars     = Bars(_Symbol, PERIOD_CURRENT);
int Digits   = _Digits;
double Point = _Point;
double Ask, Bid, Close[], High[], Low[], Open[];
long Volume[];
datetime Time[];

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[])
{
	// In MQL4 the following arrays have AS_SERIES by default
	// Not only that, but they are unset from AS_SERIES on each OnCalculate,
	// so they must be set as series every time
	ArraySetAsSeries(time, true);
	ArraySetAsSeries(open, true);
	ArraySetAsSeries(high, true);
	ArraySetAsSeries(low, true);
	ArraySetAsSeries(close, true);
	ArraySetAsSeries(tick_volume, true);
	ArraySetAsSeries(volume, true);
	ArraySetAsSeries(spread, true);

	FDFE::RefreshRates();

	FDFE::_IndicatorProblem_(false);
	int output = __OnCalculate__(rates_total, prev_calculated, time, open, high, low, close, tick_volume, volume, spread);

	// Some custom indicators have 0 as a return value. In MQL4 this works, but not in MQL5
	if (output == 0) output = rates_total;

	if (FDFE::_IndicatorProblem_() == true)
	{
		// Returning 0 means that the next time prev_calculated will be 0,
		// which is the state for OnCalculate when all the calculations needs to be made.
		output = 0;
	}

	return output;
}



class FDFE
{
private:
	/**
	* _LastError is used to set custom errors that could be returned by the custom GetLastError method
	* The initial value should be -1 and everything >= 0 should be valid error code
	* When setting an error code in it, it should be the MQL5 value,
	* because then in GetLastError it will be converted to MQL4 value
	*/
	static int _LastError;
public:
	FDFE() {
		
	};
	
	/**
	* Refresh the data in the predefined variables and series arrays
	* In MQL5 this function should run on every tick or calculate
	*
	* Note that when Symbol or Timeframe is changed,
	* the global arrays (Ask, Bid...) are reset to size 0,
	* and also the static variables are reset to initial values.
	*/
	static bool RefreshRates()
	{
		static bool initialized = false;
		static double prevAsk   = 0.0;
		static double prevBid   = 0.0;
		static int prevBars     = 0;
		static MqlRates ratesArray[1];
	
		bool isDataUpdated = false;
	
		if (initialized == false)
		{
			::ArraySetAsSeries(::Close, true);
			::ArraySetAsSeries(::High, true);
			::ArraySetAsSeries(::Low, true);
			::ArraySetAsSeries(::Open, true);
			::ArraySetAsSeries(::Volume, true);
	
			initialized = true;
		}
	
		// For Bars below, if the symbol parameter is provided through a string variable, the function returns 0 immediately when the terminal is started
		::Bars = ::Bars(::_Symbol, PERIOD_CURRENT);
		::Ask  = ::SymbolInfoDouble(::_Symbol, SYMBOL_ASK);
		::Bid  = ::SymbolInfoDouble(::_Symbol, SYMBOL_BID);
	
		if ((::Bars > 0) && (::Bars > prevBars))
		{
			// Tried to resize these arrays below on every successful single result, but turns out that this is veeeery slow
			::ArrayResize(::Time, ::Bars);
			::ArrayResize(::Open, ::Bars);
			::ArrayResize(::High, ::Bars);
			::ArrayResize(::Low, ::Bars);
			::ArrayResize(::Close, ::Bars);
			::ArrayResize(::Volume, ::Bars);
	
			// Fill the missing data
			for (int i = prevBars; i < ::Bars; i++)
			{
				int success = ::CopyRates(::_Symbol, PERIOD_CURRENT, i, 1, ratesArray);
	
				if (success == 1)
				{
					::Time[i]   = ratesArray[0].time;
					::Open[i]   = ratesArray[0].open;
					::High[i]   = ratesArray[0].high;
					::Low[i]    = ratesArray[0].low;
					::Close[i]  = ratesArray[0].close;
					::Volume[i] = ratesArray[0].tick_volume;
				}
			}
		}
		else
		{
			// Update the current bar only
			int success = ::CopyRates(::_Symbol, PERIOD_CURRENT, 0, 1, ratesArray);
	
			if (success == 1)
			{
				::Time[0]   = ratesArray[0].time;
				::Open[0]   = ratesArray[0].open;
				::High[0]   = ratesArray[0].high;
				::Low[0]    = ratesArray[0].low;
				::Close[0]  = ratesArray[0].close;
				::Volume[0] = ratesArray[0].tick_volume;
			}
		}
	
		if (::Bars != prevBars || ::Ask != prevAsk || ::Bid != prevBid)
		{
			isDataUpdated = true;
		}
	
		prevBars = ::Bars;
		prevAsk  = ::Ask;
		prevBid  = ::Bid;
	
		return isDataUpdated;
	}
	
	static void SetIndexArrow(int index, int code)
	{
		::PlotIndexSetInteger(index, PLOT_ARROW, code);
	}
	
	/**
	* In MQL4 SetIndexBuffer makes the array as series and also fills it with as many elements as many bars they are, each element equals to EMPTY_VALUE.
	*
	* In MQL5 SetIndexBuffer does not make the array as series and that's why these overloads here exists.
	* The array is not resized and even if ArrayResize is applied, it appears as if its size is still 0. But magically the array appears resized in OnCalculate
	*/
	static bool SetIndexBuffer(int index, double &buffer[], ENUM_INDEXBUFFER_TYPE data_type)
	{
		bool success = ::SetIndexBuffer(index, buffer, data_type);
	
		if (success) {::ArraySetAsSeries(buffer, true);}
	
		return success;
	}
	static bool SetIndexBuffer(int index, double &buffer[])
	{
		return FDFE::SetIndexBuffer(index, buffer, INDICATOR_DATA);
	}
	
	static void SetIndexDrawBegin(int index, int begin)
	{
		::PlotIndexSetInteger(index, PLOT_DRAW_BEGIN, begin);
	}
	
	static void SetIndexLabel(int index, string text)
	{
		::PlotIndexSetString(index, PLOT_LABEL, text);
	}
	
	static void SetIndexStyle(int index, int type, int style = -1, int width = -1, color clr = clrNONE)
	{
		if (width > -1) ::PlotIndexSetInteger(index, PLOT_LINE_WIDTH, width);
	
		if (clr != clrNONE) ::PlotIndexSetInteger(index, PLOT_LINE_COLOR, clr);
	
		switch (type)
		{
			case 0: ::PlotIndexSetInteger(index, PLOT_DRAW_TYPE, DRAW_LINE); break;
			case 1: ::PlotIndexSetInteger(index, PLOT_DRAW_TYPE, DRAW_SECTION); break;
			case 2: ::PlotIndexSetInteger(index, PLOT_DRAW_TYPE, DRAW_HISTOGRAM); break;
			case 3: ::PlotIndexSetInteger(index, PLOT_DRAW_TYPE, DRAW_ARROW); break;
			case 4: ::PlotIndexSetInteger(index, PLOT_DRAW_TYPE, DRAW_ZIGZAG); break;
			case 12: ::PlotIndexSetInteger(index, PLOT_DRAW_TYPE, DRAW_NONE); break;
	
			default: ::PlotIndexSetInteger(index, PLOT_DRAW_TYPE, DRAW_LINE);
		}
	
		switch (style)
		{
			case 0: ::PlotIndexSetInteger(index, PLOT_LINE_STYLE, STYLE_SOLID); break;
			case 1: ::PlotIndexSetInteger(index, PLOT_LINE_STYLE, STYLE_DASH); break;
			case 2: ::PlotIndexSetInteger(index, PLOT_LINE_STYLE, STYLE_DOT); break;
			case 3: ::PlotIndexSetInteger(index, PLOT_LINE_STYLE, STYLE_DASHDOT); break;
			case 4: ::PlotIndexSetInteger(index, PLOT_LINE_STYLE, STYLE_DASHDOTDOT); break;
	
			default: ::PlotIndexSetInteger(index, PLOT_LINE_STYLE, STYLE_SOLID);
		}
	}
	
	/**
	* _IndicatorProblem() to get the state
	* _IndicatorProblem(true) or _IndicatorProblem(false) to set the state
	*/
	static bool _IndicatorProblem_(int setState = -1)
	{
		static bool memory = false;
	
		if (setState > -1) memory = setState;
		
		if (memory == 1) FXD_INDICATOR_COUNTED_MEMORY = 0; // Resets the IndicatorCount() function
	
		return memory;
	}
};
int FDFE::_LastError = -1;
bool ___RefreshRates___ = FDFE::RefreshRates();

//== fxDreema MQL4 to MQL5 Converter ==//