//+------------------------------------------------------------------+
//|                                                 Price Action.mq4 |
//|                                                  Jason Normandin |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "Jason Normandin"
#property link      ""

#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 Blue
#property indicator_color2 Blue

extern	int		AtrPeriod				= 20;

extern 	double	PinBarHeightPercent		= 0.5;
extern 	double	PinBarNoseHeightPercent	= 0.6;
extern 	int		PinBarLookback			= 3;

double dBearPinBarBuffer[];
double dBullPinBarBuffer[];

double dATR1;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init() {

	SetIndexBuffer(0, dBearPinBarBuffer);
	SetIndexStyle (0, DRAW_ARROW);
	SetIndexArrow (0, 161);
	SetIndexBuffer(1, dBullPinBarBuffer);
	SetIndexStyle (1, DRAW_ARROW);
	SetIndexArrow (1, 161);

	return(0);
}


//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit() {

	return(0);
}


//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start() {

	// Get ATR
	dATR1 = iATR(NULL,0,AtrPeriod,1);

	// Number of bars already processed.
	int		iBarsCalced = IndicatorCounted();
	
	// Always reprocess the last completed bar
	if (iBarsCalced > 0) iBarsCalced -= 1;
	
	// Iterate through bars checking for patterns
	for (int i=Bars-iBarsCalced-1;i>=0;i--) {
	
		// Only check current bar if timeframe is >= 15min and less than 3min left in bar
		if (i == 0 && (Period() < PERIOD_M15 || getSecondsLeftInBar() > 180)) continue;
		
		if (checkBearishPinbar(i)) continue;
		if (checkBullishPinbar(i)) continue;

	}
	
	return(0);
}



// Bar height must be >= % of ATR
// Nose height must be >= % of Bar
// Nose must be higher than previous # of bar highs
bool checkBearishPinbar(int i) {

	double	dBarHeight	= High[i] - Low[i] + Point;
	double	dNoseHeight = High[i] - MathMax(Open[i],Close[i]);
	
	if (dBarHeight > dATR1 * PinBarHeightPercent
			&& dNoseHeight > dBarHeight * PinBarNoseHeightPercent
			&& iHighest(NULL,0,MODE_HIGH,PinBarLookback+1,i) == i) {
		dBearPinBarBuffer[i] = High[i];
		return(true);
	}
	else {
		dBearPinBarBuffer[i] = EMPTY_VALUE;
		return(false);
	}
}

// Bar height must be >= % of ATR
// Nose height must be >= % of Bar
// Nose must be lower than previous # of bar lows
bool checkBullishPinbar(int i) {

	double	dBarHeight	= High[i] - Low[i] + Point;
	double	dNoseHeight = MathMin(Open[i],Close[i]) - Low[i];
	
	if (dBarHeight > dATR1 * PinBarHeightPercent
			&& dNoseHeight > dBarHeight * PinBarNoseHeightPercent
			&& iLowest(NULL,0,MODE_LOW,PinBarLookback+1,i) == i) {
		dBullPinBarBuffer[i] = Low[i];
		return(true);
	}
	else {
		dBullPinBarBuffer[i] = EMPTY_VALUE;
		return(false);
	}
}

int getSecondsLeftInBar(int period=0) {
	
	datetime dtSecondsLeft  = iTime(NULL,period,0) - TimeCurrent();
	if (dtSecondsLeft < 0) dtSecondsLeft = 0;
			
	return(dtSecondsLeft);
	
}