//+------------------------------------------------------------------+
//|               Nanningbob's BollingerBands auto trading robot.mq4 |
//|                                  Copyright © 2009, Steve Hopwood |
//|                              http://www.hopwood3.freeserve.co.uk |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2009, Steve Hopwood"
#property link      "http://www.hopwood3.freeserve.co.uk"
#include <WinUser32.mqh>
#include <stdlib.mqh>
#define  NL    "\n"
#define  up "Up"
#define  down "Down"
#define  none "None"


/*

----Trade direction module----
void ReadIndicatorValues()
void GetBB()
void GetSixths()
void GetStoch()
double GetStochMACD(int fast_ema_period, int slow_ema_period, int signal_period, int StochasticPeriod, int shift)
void GetTradeDirection()

This ea attempts to show a possible trading direction based on NanningBob's trade-direction finding rules:
Taking a potential sell:
- market must be above 

*/

extern string  gss="----Sixths inputs----";
extern int     BarCount=50;
extern bool    TradeZoneA=true;
extern bool    TradeZoneB=false;
extern string  smacd="----StochasticMacdSqualou inputs----";
extern int     FastEMA   =12;
extern int     SlowEMA   =26;
extern int     SignalSMA =9;
extern int     StochasticPeriod =120; //4 weeks of H4 bars = 4*5*24/4 = 120
extern string  mis="----Odds and ends----";
extern int     DisplayGapSize=30;



//6ths variable.
double         BottomGoldLine;//Bottom, gold line
double         BottomGreenLine;//Bottom, green line
double         MiddleWhiteLine;//Middle, white line
double         TopGreenLine;//Top, green line
double         TopGoldLine;//Top, gold line

//Stoch variables
double         StochWhite;
double         StochBlue;

//Macd
double         MacdVal;

//BB variables
double         BbUpper, BbLower;

//Trade direction
string         TradeDirection=none;

//Misc
string         Gap, ScreenMessage;

void DisplayUserFeedback()
{
   ScreenMessage = "";
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);
   //Code for time to bar-end display from Candle Time by Nick Bilak
   double i;
   int m,s,k;
   m=Time[0]+Period()*60-CurTime();
   i=m/60.0;
   s=m%60;
   m=(m-m%60)/60;
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, m + " minutes " + s + " seconds left to bar end", NL);

   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "BB Upper line: ", DoubleToStr(BbUpper, Digits), NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "BB Lower line: ", DoubleToStr(BbLower, Digits), NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Sixths: ", NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "    Top, gold line: ", DoubleToStr(TopGoldLine, Digits), NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "    Top, green line: ", DoubleToStr(TopGreenLine, Digits), NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "    Middle, white line: ", DoubleToStr(MiddleWhiteLine, Digits), NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "    Bottom, gold line: ", DoubleToStr(BottomGoldLine, Digits), NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "    Bottom, green line: ", DoubleToStr(BottomGreenLine, Digits), NL);
   if (TradeZoneA) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Trading zone A (above top gold line and below bottom gold line)", NL);
   if (TradeZoneB) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Trading zone B (above top green line and below bottom green line)", NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Stochastic white line: ", StochWhite, NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Stochastic blue line: ", StochBlue, NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Macd red line: ", DoubleToStr(MacdVal, 4), NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Trade direction: ", TradeDirection, NL);
   
   
   
      
      Comment(ScreenMessage);


}//void DisplayUserFeedback()


//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
{
//----
   Gap="";
   if (DisplayGapSize >0)
   {
      for (int cc=0; cc< DisplayGapSize; cc++)
      {
         Gap = StringConcatenate(Gap, " ");
      }   
   }//if (DisplayGapSize >0)
   
   
   start();
   
//----
   return(0);
}
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
{
//----
   Comment("");
//----
   return(0);
}

void GetSixths()
{
   /*
   These are declared in the general section and count the lines from the bottom upwards
   double         BottomGoldLine;//Bottom, gold line
   double         BottomGreenLine;//Bottom, green line
   double         MiddleWhiteLine;//Middle, white line
   double         TopGreenLine;//Top, green line
   double         TopGoldLine;//Top, gold line

   */

   //double value = WindowPriceMax(0)-WindowPriceMin(0);      //value top of the chart - value buttem
   double value = High[iHighest(NULL,0,MODE_HIGH,BarCount,1)] - Low[iLowest(NULL,0,MODE_LOW,BarCount,1)];      //value top of the chart - value bottom
   double sixth = value/6;
   double valueS = (value*(MathPow(10,Digits)));
   double sixthS = (sixth*(MathPow(10,Digits)));
   
   BottomGoldLine = NormalizeDouble(Low[iLowest(NULL,0,MODE_LOW,BarCount,1)]+sixth, Digits);
   BottomGreenLine = NormalizeDouble(Low[iLowest(NULL,0,MODE_LOW,BarCount,1)]+sixth+sixth, Digits);
   MiddleWhiteLine = NormalizeDouble(Low[iLowest(NULL,0,MODE_LOW,BarCount,1)]+sixth+sixth+sixth, Digits);
   TopGreenLine = NormalizeDouble(Low[iLowest(NULL,0,MODE_LOW,BarCount,1)]+sixth+sixth+sixth+sixth, Digits);
   TopGoldLine = NormalizeDouble(Low[iLowest(NULL,0,MODE_LOW,BarCount,1)]+sixth+sixth+sixth+sixth+sixth, Digits);



}//End void GetSixths()



void GetStoch()
{

   StochWhite = iStochastic(NULL, 0, 7, 3, 3, MODE_LWMA, 1, MODE_MAIN, 0);
   StochBlue = iStochastic(NULL, 0, 14, 3, 5, MODE_LWMA, 1, MODE_MAIN, 0);
   

}//void GetStoch();

double GetStochMACD(int fast_ema_period, int slow_ema_period, int signal_period, int StochasticPeriod, int shift)
{
  // get macd signal line
  double macdSignal;
  int j;
  // get highest/lowest of macdSignal over StochasticPeriod
  double ll = 100000, hh = -100000, dif;
  for(j=shift; j<shift+StochasticPeriod; j++)
  {
    macdSignal = iMACD(NULL,0,fast_ema_period, slow_ema_period, signal_period, PRICE_CLOSE,MODE_SIGNAL,j);
    hh = MathMax(hh,macdSignal);
    ll = MathMin(ll,macdSignal);
  }

  // normalize to 0..100

  dif = hh-ll;
  if (dif==0) return (0);
  else return (100 * (iMACD(NULL,0,fast_ema_period, slow_ema_period, signal_period, PRICE_CLOSE,MODE_SIGNAL,shift)-ll)/dif); 
}//End double GetStochMACD(int fast_ema_period, int slow_ema_period, int signal_period, int StochasticPeriod, int shift)

void GetBB()
{
   //Reads BB figures into BbUpper, BbLower
   
   
   BbUpper = iBands(NULL, 0, 25, 2, 0, PRICE_CLOSE, MODE_UPPER, 0);
   BbLower = iBands(NULL, 0, 25, 2, 0, PRICE_CLOSE, MODE_LOWER, 0);
   
}//void GetBb()


void ReadIndicatorValues()
{

   GetBB();
   GetSixths();
   GetStoch();
   MacdVal = GetStochMACD(FastEMA, SlowEMA, SignalSMA, StochasticPeriod , 0);

}//End void ReadIndicatorValues()


void GetTradeDirection()
{
   
   //Is market in the killing zone
   if (Ask <= TopGreenLine && Ask >= BottomGreenLine && Bid <= TopGreenLine && Bid >= BottomGreenLine)
   {
      TradeDirection = none;
      return;
   }//if (Ask <= TopGreenLine && Ask >= BottomGreenLine Bid <= TopGreenLine && Bid >= BottomGreenLine)
   
   ReadIndicatorValues();

   if (TradeZoneA) double target = TopGoldLine;
   if (TradeZoneB) target = TopGreenLine;
   
   
   //Check for short direction trade setup
   if (Ask > target)
   {
      TradeDirection = down;
      if (StochBlue < 85) TradeDirection = none;
      if (StochWhite > StochBlue) TradeDirection = none;
      if (MacdVal < 85) TradeDirection = none;
      if (BbUpper < TopGreenLine) TradeDirection = none;  
   }//if (Ask > target)

   if (TradeZoneA) target = BottomGoldLine;
   if (TradeZoneB) target = BottomGreenLine;

   //Check for short direction trade setup
   if (Bid < target)
   {
      TradeDirection = up;
      if (StochBlue > 15 ) TradeDirection = none;
      if (StochWhite < StochBlue) TradeDirection = none;
      if (MacdVal > 15 ) TradeDirection = none;
      if (BbLower > BottomGreenLine) TradeDirection = none;
   }//if (Bid < target)



}//End void GetTradeDirection()


//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
{
//----


   GetTradeDirection();
   
   
   DisplayUserFeedback();
   
//----
   return(0);
}
//+------------------------------------------------------------------+