//+------------------------------------------------------------------+
//|Squalou and Steve's Trade Signals.mq4
//+------------------------------------------------------------------+
#property copyright "SQ&SteveHopwood"
#property link      ""

#property indicator_chart_window
#property indicator_buffers 3
#property indicator_color1 Blue
#property indicator_color2 Red
#property indicator_width1 3
#property indicator_width2 3

//

extern string  gss="----Sixths inputs----";
extern int     BarCount=50;
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 int     SMA6Period  =6;

//

double signalUP[];
double signalDN[];
double pendingSignal[];

#define  up "Up"
#define  down "Down"
#define  none "None"

//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;

//SMA(6) variables
string         SMA6direction;

//Trade direction
string         TradeDirection=none;


//+------------------------------------------------------------------+
int init()
{
   IndicatorBuffers(5);
   SetIndexBuffer(0,signalUP); SetIndexStyle(0,DRAW_ARROW); SetIndexArrow(0,233);
   SetIndexBuffer(1,signalDN); SetIndexStyle(1,DRAW_ARROW); SetIndexArrow(1,234);
   SetIndexBuffer(2,pendingSignal);//this is not plotted, just an indi buffer
   return(0);
}
int deinit() { return(0); }

//+------------------------------------------------------------------+
int start()
{
   int counted_bars=IndicatorCounted();
   int limit;
   int dir;
   
   if(counted_bars<0) return(-1);
   if(counted_bars>0) counted_bars--;
   limit=MathMin(Bars-counted_bars,Bars-1);

   for(int i=limit; i>=0; i--)
   {

      ReadIndicatorValues(i);
      dir = GetTradeDirection(i);

      // record current signal if any, else propagate last signal
      if (dir != -1) pendingSignal[i] = dir;
      else pendingSignal[i] = pendingSignal[i+1];

      signalUP[i] = EMPTY_VALUE;
      signalDN[i] = EMPTY_VALUE;

      // wait for the SMA(6) direction to agree with the last signal issuing the signal

      if (pendingSignal[i] == OP_BUY  && SMA6direction == up)   
      {
        signalUP[i] = Low[i] -200*Point;
        pendingSignal[i] = -1;//cancel pending signal
      }
      if (pendingSignal[i] == OP_SELL && SMA6direction == down)
      {
        signalDN[i] = High[i]+200*Point;
        pendingSignal[i] = -1;//cancel pending signal
      }
   }

   return(0);
}


void GetSixths(int shift)
{
   /*
   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 low   = Low[iLowest(NULL,0,MODE_LOW,BarCount,shift+1)];
   double value = High[iHighest(NULL,0,MODE_HIGH,BarCount,shift+1)] - low; //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+1*sixth, Digits);
   BottomGreenLine = NormalizeDouble(low+2*sixth, Digits);
   MiddleWhiteLine = NormalizeDouble(low+3*sixth, Digits);
   TopGreenLine    = NormalizeDouble(low+4*sixth, Digits);
   TopGoldLine     = NormalizeDouble(low+5*sixth, Digits);

}//End void GetSixths()



void GetStoch(int shift)
{
//double         StochWhite;
//double         StochRed;

   StochWhite = iStochastic(NULL, 0, 7, 3, 3, MODE_LWMA, 1, MODE_MAIN, shift);
   StochBlue = iStochastic(NULL, 0, 14, 3, 5, MODE_LWMA, 1, MODE_MAIN, shift);
   

}//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(int shift)
{
   //Reads BB figures into BbUpper, BbLower
   
   
   BbUpper = iBands(NULL, 0, 25, 2, 0, PRICE_CLOSE, MODE_UPPER, shift);
   BbLower = iBands(NULL, 0, 25, 2, 0, PRICE_CLOSE, MODE_LOWER, shift);
   
}//void GetBb()

string GetSMA6direction(int shift)
{
  if (iMA(NULL, 0,  SMA6Period, 0, MODE_SMA, PRICE_MEDIAN,shift) > iMA(NULL, 0,  6, 0, MODE_SMA, PRICE_MEDIAN,shift+1)) SMA6direction = up;
  else SMA6direction = down;
  return(SMA6direction);
}

void ReadIndicatorValues(int shift)
{

   GetBB(shift);
   GetSixths(shift);
   GetStoch(shift);
   MacdVal = GetStochMACD(FastEMA, SlowEMA, SignalSMA, StochasticPeriod , shift);
   GetSMA6direction(shift); 

}//End void ReadIndicatorValues()


int GetTradeDirection(int shift)
{
   TradeDirection = none;
   
   //Is market in the killing zone
   if (Open[shift] <= TopGreenLine && Open[shift] >= BottomGreenLine)
   {
      return(-1);// no signal
   }//if (Ask <= TopGreenLine && Ask >= BottomGreenLine Bid <= TopGreenLine && Bid >= BottomGreenLine)
   
   //Check for short direction trade setup
   if (Open[shift] > TopGreenLine)
   {
      if ( StochBlue >= 85
        && StochBlue >= StochWhite
        && MacdVal >= 85
        && BbUpper >= TopGreenLine)
      {
        TradeDirection = down;
        return(OP_SELL);
      }
   }//if (Ask > TopGoldLine)

   //Check for short direction trade setup
   if (Open[shift] < BottomGreenLine)
   {
      if ( StochBlue <= 15
        && StochBlue <= StochWhite
        && MacdVal <= 15
        && BbLower <= BottomGreenLine)
      {
        TradeDirection = up;
        return(OP_BUY);
      }
   }//if (Ask > TopGoldLine)

  return (-1);//no signal

}//End int GetTradeDirection()


//end

