//+------------------------------------------------------------------+
//|                                                     EasyIndi.mq4 |
//|                                                  Thomas Langlois |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Thomas Langlois"
#property link      "http://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_width1  4
#property indicator_width2  4
#property indicator_maximum 1
#property indicator_minimum 0
#property indicator_color1 Lime
#property indicator_color2 Red

// Constant definitions
#define INDICATOR_NAME "EZYINDI"
#define INDICATOR_VERSION "1.0"

#define IND_TREND        "Trend"

#define IND_CCIMAS "CCIMAS"

#define MTFRSI_LONG_THRESH 70
#define MTFRSI_SHORT_THRESH 30

#define IND_NIAGG "Ni_Aggregated_1.01"

#define IND_GMTS "GMTS-Tape"

double sigLong[];
double sigShort[];

string indicatorName;
bool isOnInit;
int repaintBars;
int timeFrame;

double gdTREND_THRESH=0.33;


//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
//int OnInit()
int init()
  {
//--- indicator buffers mapping
   IndicatorBuffers(2);

   SetIndexStyle(0,DRAW_HISTOGRAM);
   SetIndexBuffer(0,sigLong);
   SetIndexStyle(1,DRAW_HISTOGRAM);
   SetIndexBuffer(1,sigShort);

// Null Label
  /* for(int i=0; i<(indicator_buffers+1); i++)
     {
      SetIndexLabel(i,NULL);
      SetIndexEmptyValue(i,0.0);
     }*/
//---
   indicatorName="EasyIndi";
   IndicatorShortName(indicatorName);
   isOnInit=true;
   
   //Check contract specifics
   double dLotSize = MarketInfo(Symbol(), MODE_LOTSIZE);
   if(dLotSize==10000) 
      gdTREND_THRESH = 0.0033;
      
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| 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[])
  {
//---
   
//--- return value of prev_calculated for next call
   return(rates_total);
  }*/

int start()
  {
   int i,iNewBars,iCountedBars;
   static datetime tCurBar=0;
   int resultEasyIndi;

// Get unprocessed bars
   iCountedBars=IndicatorCounted();
   if(iCountedBars < 0) return (-1);
   if(iCountedBars>0) iCountedBars--;

   timeFrame=(ENUM_TIMEFRAMES)Period();
   repaintBars=0;
// Set bars to redraw
   if(NewBars(timeFrame)>3)
      iNewBars=Bars-1;
   else
      iNewBars=Bars-iCountedBars;
   if(iNewBars<repaintBars)
      iNewBars=repaintBars;
//iNewBars=50;

//Update Tape Chart
   for(i=iNewBars;i>=0;i--)
     {
      // Calc Data
      ProcessEasyIndi(i,timeFrame,resultEasyIndi);
      
      if(i>=Bars)
         continue;
      if(resultEasyIndi==1) {
         sigLong[i]=1;
         sigShort[i]=0;
      }
      else if(resultEasyIndi==-1) {
         sigLong[i]=0;
         sigShort[i]=1;
      } else {
         sigLong[i]=0;
         sigShort[i]=0;
      }
     }

// Clear the init flag   
   if(isOnInit)
      isOnInit=False;

   return(0);
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
//---

  }
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
//---

  }
//+------------------------------------------------------------------+

//-----------------------------------------------------------------------------
// function: NewBars()
// Description: Return nr of new bars on a TF
//-----------------------------------------------------------------------------
int NewBars(int iPeriod)
  {
   static int iPrevSize=0;
   int iNewSize;
   int iNewBars;
   datetime tTimeArray[];

   ArrayCopySeries(tTimeArray,MODE_TIME,Symbol(),iPeriod);
   iNewSize=ArraySize(tTimeArray);
   iNewBars=iNewSize-iPrevSize;
   iPrevSize=iNewSize;
   return(iNewBars);
  }
//-----------------------------------------------------------------------------
// function: ProcessTVI()
// Description: Calc TVI data and update matrix
//-----------------------------------------------------------------------------
int ProcessEasyIndi(int iNewBars,int iTF,int& result)
  {
   int i=iNewBars;
   
   //Trend
   double trendValue1,trendValue2;
   int trendRes=0;
   
   trendValue1=iCustom(Symbol(),iTF,IND_TREND,0,0,0,20,2,13,5000,0,i);
   trendValue2=iCustom(Symbol(),iTF,IND_TREND,0,0,0,20,2,13,5000,1,i);

   if(trendValue1==EMPTY_VALUE || trendValue2==EMPTY_VALUE)
      trendRes=0;
   else if(trendValue1>=gdTREND_THRESH)
      trendRes=1;
   else if(trendValue2>=gdTREND_THRESH)
      trendRes=-1;
   else
      trendRes=0;

   //CCI63, MA21, MA7
   double dCCIValue, dMA7, dMA21;
   int iCCIMASRes=0;
   
   dCCIValue=iCustom(Symbol(),iTF,IND_CCIMAS,63,7,21,0,i);
   dMA7=iCustom(Symbol(),iTF,IND_CCIMAS,63,7,21,1,i);
   dMA21=iCustom(Symbol(),iTF,IND_CCIMAS,63,7,21,2,i);
   
   if(dCCIValue==EMPTY_VALUE || dMA7==EMPTY_VALUE || dMA21==EMPTY_VALUE)
      iCCIMASRes=0;
   else if(dCCIValue>dMA7 && dMA7>dMA21)
      iCCIMASRes=1;
   else if(dCCIValue<dMA7 && dMA7<dMA21)
      iCCIMASRes=-1;
   else
      iCCIMASRes=0;
         
   //RSI H1 vs D1
   double dH1RSIValue, dD1RSIValue;
   int iMTFRSIRes=0;       
 
   dH1RSIValue=iRSI(Symbol(),60,5,0,i);
   int Shift = iBarShift (Symbol(), 1440, Time [i], False);
   dD1RSIValue=iRSI(Symbol(),1440,5,0,Shift);
         
   if(dH1RSIValue==EMPTY_VALUE || dD1RSIValue==EMPTY_VALUE)
      iMTFRSIRes=0;
   else if(dH1RSIValue>dD1RSIValue && dH1RSIValue>MTFRSI_LONG_THRESH)
      iMTFRSIRes=1;
   else if(dH1RSIValue<dD1RSIValue && dH1RSIValue<MTFRSI_SHORT_THRESH)
      iMTFRSIRes=-1;
   else
      iMTFRSIRes=0;
   
   //Ni Aggregated
   double dNIAGGUp, dNIAGGFlat, dNIAGGDown;
   int iNIAGGRes=0;
   
   dNIAGGUp=iCustom(Symbol(),iTF,IND_NIAGG,"--",7,14,21,33,false,false,false,0,i);
   dNIAGGFlat=iCustom(Symbol(),iTF,IND_NIAGG,"--",7,14,21,33,false,false,false,1,i);
   dNIAGGDown=iCustom(Symbol(),iTF,IND_NIAGG,"--",7,14,21,33,false,false,false,2,i);
   
   if(dNIAGGUp==EMPTY_VALUE && dNIAGGFlat==EMPTY_VALUE && dNIAGGDown==EMPTY_VALUE)
      iNIAGGRes=0;
   else if(dNIAGGUp==1 && dNIAGGFlat==EMPTY_VALUE && dNIAGGDown==EMPTY_VALUE)
      iNIAGGRes=1;
   else if(dNIAGGDown==1 && dNIAGGFlat==EMPTY_VALUE && dNIAGGUp==EMPTY_VALUE)
      iNIAGGRes=-1;
   else
      iNIAGGRes=0;   
      
   
   //GMTS Tape
   double dGMTSUp, dGMTSDown;
   int iGMTSRes=0;
   
   dGMTSUp=iCustom(Symbol(),iTF,IND_GMTS,"—",PERIOD_CURRENT,0,"—",False,clrDimGray,clrRoyalBlue,clrFireBrick,"—",12,12,5,"—",20,"—",8,0.618,5000,"T3 ","—",10,"—",False,False,True,True,"",False,"","—",30,clrDarkGray,0,i);
   dGMTSDown=iCustom(Symbol(),iTF,IND_GMTS,"—",PERIOD_CURRENT,0,"—",False,clrDimGray,clrRoyalBlue,clrFireBrick,"—",12,12,5,"—",20,"—",8,0.618,5000,"T3 ","—",10,"—",False,False,True,True,"",False,"","—",30,clrDarkGray,1,i);
   
   if(dGMTSUp==EMPTY_VALUE || dGMTSDown==EMPTY_VALUE)
      iGMTSRes=0;
   else if(dGMTSUp==1 && dGMTSDown==0)
      iGMTSRes=1;
   else if(dGMTSDown==1 && dGMTSUp==0)
      iGMTSRes=-1;
   else
      iGMTSRes=0;   
      
      
   //result=iGMTSRes;
   
   //Final result
   if(trendRes==1 && iCCIMASRes==1 && iMTFRSIRes==1 && iNIAGGRes==1 && iGMTSRes==1)
      result=1;
   else if(trendRes==-1 && iCCIMASRes==-1 && iMTFRSIRes==-1 && iNIAGGRes==-1 && iGMTSRes==-1)
      result=-1;
   else   
      result=0;
   
   return(0);
  }
//+------------------------------------------------------------------+
