//+------------------------------------------------------------------+
//|                                     QQE and MACD dual signal.mq4 |
//+------------------------------------------------------------------+
//#property copyright "Copyright © 2012, David Louisson"
//#property link      "http://www.forexfactory.com/hanover"

#property indicator_chart_window

#include <hanover --- function header.mqh>

#property  indicator_buffers 2
#property  indicator_color1  Red
#property  indicator_style1  STYLE_SOLID
#property  indicator_width1  2
#property  indicator_color2  Green
#property  indicator_style2  STYLE_SOLID
#property  indicator_width2  2

extern int        LookbackBars               = 500;
extern int        SpacingPips                = 20;
extern int        ArrowSize                  = 3;
extern int        UpArrowCode                = 233;
extern color      UpArrowColor               = Green;
extern int        DownArrowCode              = 234;
extern color      DownArrowColor             = Red;
extern string     MACD_parameters            = "12,26,9";
extern string     QQE_parameters             = "1,8,3";

string   RefreshPeriod = "H1";

string   ccy, IndiName;
int      dig, tf, tmf, vis, wno, RefreshEveryXMins, macp[3], qqep[3];
double   spr, pnt, tickval, bidp, askp, minlot, lswap, sswap, NewSL;
datetime prev_time;
bool     FirstTime;

double   ind_buffer0[], ind_buffer1[];

//+------------------------------------------------------------------+
int init()  {
//+------------------------------------------------------------------+
  IndiName = "QQE_MACD-" + GetHash("0");
  IndicatorShortName(IndiName);

  SetIndexBuffer(0,ind_buffer0);
  SetIndexStyle(0,DRAW_ARROW,STYLE_SOLID,ArrowSize,DownArrowColor);
  SetIndexArrow(0,DownArrowCode);     // 241 = up arrow; 242 = down arrow
  SetIndexDrawBegin(0,0);

  SetIndexBuffer(1,ind_buffer1);
  SetIndexStyle(1,DRAW_ARROW,STYLE_SOLID,ArrowSize,UpArrowColor);
  SetIndexArrow(1,UpArrowCode);     // 241 = up arrow; 242 = down arrow
  SetIndexDrawBegin(0,0);

  ccy     = Symbol();
  tmf     = Period();
  bidp    = MarketInfo(ccy,MODE_BID);
  askp    = MarketInfo(ccy,MODE_ASK);
  pnt     = MarketInfo(ccy,MODE_POINT);
  dig     = MarketInfo(ccy,MODE_DIGITS);
  spr     = MarketInfo(ccy,MODE_SPREAD);
  tickval = MarketInfo(ccy,MODE_TICKVALUE);
  minlot  = MarketInfo(ccy,MODE_MINLOT);
  lswap   = MarketInfo(ccy,MODE_SWAPLONG);
  sswap   = MarketInfo(ccy,MODE_SWAPSHORT);
  if (dig == 3 || dig == 5) {
    pnt     *= 10;
    spr     /= 10;
    tickval *= 10;
  }
  
  StrToIntegerArray(MACD_parameters,macp);
  StrToIntegerArray(QQE_parameters,qqep);
   
  RefreshEveryXMins = StrToTF(RefreshPeriod);
  prev_time = -9999;
  plot_obj();

  return(0);
}

//+------------------------------------------------------------------+
int deinit()  {
//+------------------------------------------------------------------+
  return(0);
}

//+------------------------------------------------------------------+
int start()  {
//+------------------------------------------------------------------+
  if (RefreshEveryXMins < 0)  {
    if (FirstTime)  {
      plot_obj();
    }
    FirstTime = false;      
    return(0);
  }  
  if (RefreshEveryXMins == 0) {
    plot_obj();    
  } else {
    if (prev_time != iTime(ccy,RefreshEveryXMins,0))  {
      plot_obj();
      prev_time = iTime(ccy,RefreshEveryXMins,0);
  } }      
  return(0);
}

//+------------------------------------------------------------------+
void plot_obj()   {
//+------------------------------------------------------------------+
  int curr_status = 0, prev_status = 0;
  for (int i=LookbackBars; i>0; i--)   {
    ind_buffer0[i] = EMPTY_VALUE;
    ind_buffer1[i] = EMPTY_VALUE;
    prev_status  = curr_status;

    // qqe = difference between indicator line value and signal line value; difference > 0 is bullish (indy line above signal line), vice versa is bearish....
    double qqe  = iCustom(Symbol(),Period(),"QQE ADV",qqep[0],qqep[1],qqep[2],0,i) 
                - iCustom(Symbol(),Period(),"QQE ADV",qqep[0],qqep[1],qqep[2],1,i);

    // macd = difference between indicator line value and signal line value; difference > 0 is bullish (indy line above signal line), vice versa is bearish....
    double macd = iCustom(Symbol(),Period(),"MACD_Platinum",macp[0],macp[1],macp[2],true,true,false,"alert.wav",false,false,false,1,1,0,0,0,0,0,0,0,0,0,4,i)
                - iCustom(Symbol(),Period(),"MACD_Platinum",macp[0],macp[1],macp[2],true,true,false,"alert.wav",false,false,false,1,1,0,0,0,0,0,0,0,0,0,5,i);

    // curr_status holds its value through successive data points (loop iterations), until both QQE and MACD switch their polarity....                 
    if (MathSign(qqe) + MathSign(macd) ==  2)   curr_status =  1;                                 // if both QQE and MACD are bullish, then overall status is bullish (+1)
    if (MathSign(qqe) + MathSign(macd) == -2)   curr_status = -1;                                 // if both QQE and MACD are bearish, then overall status is bearish (-1)
    if (curr_status > prev_status)              ind_buffer1[i] = Low[i]  - SpacingPips * pnt;     // status has changed to bullish, hence plot up-arrow below candle low
    if (curr_status < prev_status)              ind_buffer0[i] = High[i] + SpacingPips * pnt;     // status has changed to bearish, hence plot down-arrow above candle high
  }    
  return(0);
}

//+------------------------------------------------------------------+
#include <hanover --- extensible functions.mqh>