#property copyright "Paul Murfin"
#property link      ""

#define   MODEL "Trend Follower"

#define   STARTBAR      1
#define	 LONG          1
#define	 SHORT        -1
#define	 FLAT          0
#define   ALLLONG       2
#define   ALLSHORT     -2

#define	strLONG      "LONG"
#define	strSHORT     "SHORT"
#define	strFLAT      "FLAT"
#define  strALLLONG  "ALL LONG"
#define  strALLSHORT "ALL SHORT"

#define  REDNUM      16
#define  GREENNUM    12    
#define  BLUENUM     11
#define  ORANGENUM   13
#define  YELLOWNUM   14


extern   bool AlertOn = true;
extern   bool EmailOn = true;
extern   bool SnapShotOn = true;

double   RedMax;
double   RedMin;
int      RedTrend;
int      RedPeriods[REDNUM] = {125, 130, 135, 140, 145, 150, 155, 160, 165, 170, 175, 180, 185, 190, 195, 200};

double   GreenMax;
double   GreenMin;
int      GreenTrend;
int      GreenPeriods[GREENNUM] = {78, 82, 86, 90, 94, 98, 102, 106, 110, 114, 118, 122};

double   BlueMax;
double   BlueMin;
int      BlueTrend;
int      BluePeriods[BLUENUM] = {44, 47, 50, 53, 56, 59, 62, 65, 68, 71, 74};

double   OrangeMax;
double   OrangeMin;
int      OrangeTrend;
int      OrangePeriods[ORANGENUM] = {17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41};

double   YellowMax;
double   YellowMin;
int      YellowTrend;
int      YellowPeriods[YELLOWNUM] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
						
int	   SignalTrend;
int	   SlopeTrend;
int	   MACDTrend;
int	   LaguerreTrend;
int	   GuppyTrend;
int	   InvestorTrend;
int      TradingIndicator;

string	strTrends;

//FirstBarTime=StrToTime("00:05"); 


////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
////////////////////////////////////////////////////////

int init () {

	SignalTrend      = FLAT;
	SlopeTrend       = FLAT;
	MACDTrend        = FLAT;
	LaguerreTrend    = FLAT;
	InvestorTrend    = FLAT;
	GuppyTrend       = FLAT;
	TradingIndicator = FLAT;

	NewBar();
	CalculateIndicators(STARTBAR);
	DisplayComment();
	
	return (0);
}

////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
////////////////////////////////////////////////////////

int deinit () {

	return (0);
}

////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
////////////////////////////////////////////////////////

int start () {

	if (NewBar()) { 
		CalculateIndicators(STARTBAR);
		if (TradingIndicator == LONG) {
		    if (AlertOn)    Alert    (MODEL+" "+Symbol()+" "+Period()+"Min -  All Indicators Aligned - GO LONG");
		    if (EmailOn)    SendMail ("STF Long Alert "+Symbol(),    Symbol()+" "+Period()+"Min -  All Indicators Aligned - GO LONG");
          if (SnapShotOn) WindowScreenShot ("TrendFollower "+ Year()+"\\TF "+Month()+""+Day()+" "+Symbol()+" GO LONG @M"+Period()+" TIME=" +Hour()+ "-"+Minute()+".gif",800,600);



		} else if (TradingIndicator == SHORT) {
		    if (AlertOn) Alert    (MODEL+" "+Symbol()+" "+Period()+"Min -  All Indicators Aligned - GO SHORT");
		    if (EmailOn) SendMail ("STF Short Alert "+Symbol(),    Symbol()+" "+Period()+"Min -  All Indicators Aligned - GO SHORT");
          if (SnapShotOn) WindowScreenShot ("TrendFollower "+ Year()+"\\TF "+Month()+""+Day()+" "+Symbol()+" GO SHORT @M"+Period()+" TIME="+Hour()+"-"+Minute()+".gif",800,600);
		}
	}

	DisplayComment();
	
	return (0);

}

////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
////////////////////////////////////////////////////////

void CalculateIndicators (int BarNo) {

	double  up;
	double  dn;
	double  L0;
	double  L1;
	double  f1;
	double  f2;
	double  s1;
	double  s2;
	double  MACD0;
	double  MACD1;

	SignalTrend      = FLAT;
	SlopeTrend       = FLAT;
	MACDTrend        = FLAT;
	LaguerreTrend    = FLAT;
	InvestorTrend    = FLAT;
	GuppyTrend       = FLAT;
	TradingIndicator = FLAT;

//	Signal Direction

	f1 = iMA(NULL, 0, 4, 0, MODE_EMA, PRICE_CLOSE, BarNo);
	s1 = iMA(NULL, 0, 8, 0, MODE_EMA, PRICE_CLOSE, BarNo);
	f2 = iMA(NULL, 0, 4, 0, MODE_EMA, PRICE_CLOSE, BarNo+1);
	s2 = iMA(NULL, 0, 8, 0, MODE_EMA, PRICE_CLOSE, BarNo+1);

	     if (f1 > s1 && f2 < s2) 
		      SignalTrend = LONG;
	else if (f1 < s1 && f2 > s2) 
		      SignalTrend = SHORT;
	
	if (SignalTrend == FLAT) {

	f1 = iMA(NULL, 0, 4, 0, MODE_EMA, PRICE_CLOSE, BarNo+1);
	s1 = iMA(NULL, 0, 8, 0, MODE_EMA, PRICE_CLOSE, BarNo+1);
	f2 = iMA(NULL, 0, 4, 0, MODE_EMA, PRICE_CLOSE, BarNo+2);
	s2 = iMA(NULL, 0, 8, 0, MODE_EMA, PRICE_CLOSE, BarNo+2);

	     if (f1 > s1 && f2 < s2) 
		      SignalTrend = LONG;
	else if (f1 < s1 && f2 > s2) 
		      SignalTrend = SHORT;
	}

//	Slope Direction

	up = iCustom(NULL,0,"Slope Direction Line",80,3,0,BarNo);
	dn = iCustom(NULL,0,"Slope Direction Line",80,3,1,BarNo);

	     if (up == EMPTY_VALUE && dn != EMPTY_VALUE) 
		      SlopeTrend = SHORT;
   else if (dn == EMPTY_VALUE && up != EMPTY_VALUE) 
		      SlopeTrend = LONG;


//	MACD

	MACD0 = iMACD(NULL,0,5,35,5,PRICE_CLOSE,0,BarNo);
	
	     if (MACD0 > 0) 
		      MACDTrend = LONG;
   else if (MACD0 < 0) 
		      MACDTrend = SHORT;
	

//	Laguerre

	L0 = iCustom(NULL,0,"Laguerre",0.66,9500,0,BarNo);
	L1 = iCustom(NULL,0,"Laguerre",0.66,9500,0,BarNo+1);

	     if (L0 > 0.15 && L1 < 0.15) 
		      LaguerreTrend = LONG;
	else if (L0 < 0.75 && L1 > 0.75)  
		      LaguerreTrend = SHORT;
	

	if (LaguerreTrend == FLAT) {

	L0 = iCustom(NULL,0,"Laguerre",0.66,9500,0,BarNo+1);
	L1 = iCustom(NULL,0,"Laguerre",0.66,9500,0,BarNo+2);

	     if (L0 > 0.15 && L1 < 0.15) 
		      LaguerreTrend = LONG;
	else if (L0 < 0.75 && L1 > 0.75)  
		      LaguerreTrend = SHORT;
	}


//	Guppy

	CalculateGuppy(BarNo);

//	Trading Indicator

	if (SignalTrend == LONG && LaguerreTrend == LONG && MACDTrend == LONG && GuppyTrend == LONG) TradingIndicator = LONG;
	else if (SignalTrend == SHORT && LaguerreTrend == SHORT && MACDTrend == SHORT && GuppyTrend == SHORT) TradingIndicator = SHORT;

//	Display string

strTrends = "\nRed : "+GSD(RedTrend)+"  Green : "+GSD(GreenTrend)+ "  Blue : "+GSD(BlueTrend)+ "  Orange : "+GSD(OrangeTrend)+ "  Yellow : "+GSD(YellowTrend)+
"\n\nSignal : "+GSD(SignalTrend)+"  Slope : "+GSD(SlopeTrend)+"  MACD : "+GSD(MACDTrend)+"  Laguerre : "+GSD(LaguerreTrend)+"  Guppy : "+GSD(GuppyTrend)+"       TRADE : "+GSD(TradingIndicator);




}

////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
////////////////////////////////////////////////////////

int CalculateGuppy (int BarNo) {

   int      i;
   double   curr;
   double   prev;
   int      count;
     
   RedTrend      = FLAT;
   RedMin        =    0;
   RedMax        =    0;
   GreenTrend    = FLAT;
   GreenMin      =    0;
   GreenMax      =    0;
   BlueTrend     = FLAT;
   BlueMin       =    0;
   BlueMax       =    0;
   OrangeTrend   = FLAT;
   OrangeMin     =    0;
   OrangeMax     =    0;
   YellowTrend   = FLAT;
   YellowMin     =    0;
   YellowMax     =    0;
   InvestorTrend = FLAT;
   GuppyTrend    = FLAT;

   // Red Trends

   count = 0;   
   for (i=0;i<REDNUM;i++) {
      curr = iMA(NULL, 0, RedPeriods[i], 0, MODE_EMA, PRICE_CLOSE, BarNo);
      prev = iMA(NULL, 0, RedPeriods[i], 0, MODE_EMA, PRICE_CLOSE, BarNo+1);
      if (RedMax == 0 || curr > RedMax) RedMax = curr;
      if (RedMin == 0 || curr < RedMin) RedMin = curr;
      if (curr > prev) count++;
      else if (curr < prev) count--;
   }
   if (count == REDNUM) RedTrend = ALLLONG;
   else if (count == -REDNUM) RedTrend = ALLSHORT;
   else RedTrend = FLAT;
   
   // Green Trends

   count = 0;   
   for (i=0;i<GREENNUM;i++) {
      curr = iMA(NULL, 0, GreenPeriods[i], 0, MODE_EMA, PRICE_CLOSE, BarNo);
      prev = iMA(NULL, 0, GreenPeriods[i], 0, MODE_EMA, PRICE_CLOSE, BarNo+1);
      if (GreenMax == 0 || curr > GreenMax) GreenMax = curr;
      if (GreenMin == 0 || curr < GreenMin) GreenMin = curr;
      if (curr > prev) count++;
      else if (curr < prev) count--;
   }
   if (count == GREENNUM) GreenTrend = ALLLONG;
   else if (count == -GREENNUM) GreenTrend = ALLSHORT;
   else GreenTrend = FLAT;
   
  // Blue Trends

   count = 0;   
   for (i=0;i<BLUENUM;i++) {
      curr = iMA(NULL, 0, BluePeriods[i], 0, MODE_EMA, PRICE_CLOSE, BarNo);
      prev = iMA(NULL, 0, BluePeriods[i], 0, MODE_EMA, PRICE_CLOSE, BarNo+1);
      if (BlueMax == 0 || curr > BlueMax) BlueMax = curr;
      if (BlueMin == 0 || curr < BlueMin) BlueMin = curr;
      if (curr > prev) count++;
      else if (curr < prev) count--;
   }
   if (count == BLUENUM) BlueTrend = ALLLONG;
   else if (count == -BLUENUM) BlueTrend = ALLSHORT;
   else BlueTrend = FLAT;
 
// Orange Trends

   count = 0;   
   for (i=0;i<ORANGENUM;i++) {
      curr = iMA(NULL, 0, OrangePeriods[i], 0, MODE_EMA, PRICE_CLOSE, BarNo);
      prev = iMA(NULL, 0, OrangePeriods[i], 0, MODE_EMA, PRICE_CLOSE, BarNo+1);
      if (OrangeMax == 0 || curr > OrangeMax) OrangeMax = curr;
      if (OrangeMin == 0 || curr < OrangeMin) OrangeMin = curr;
      if (curr > prev) count++;
      else if (curr < prev) count--;
   }
   if (count == ORANGENUM) OrangeTrend = ALLLONG;
   else if (count == -ORANGENUM) OrangeTrend = ALLSHORT;
   else OrangeTrend = FLAT;
    
// Yellow Trends

   count = 0;   
   for (i=0;i<YELLOWNUM;i++) {
      curr = iMA(NULL, 0, YellowPeriods[i], 0, MODE_EMA, PRICE_CLOSE, BarNo);
      prev = iMA(NULL, 0, YellowPeriods[i], 0, MODE_EMA, PRICE_CLOSE, BarNo+1);
      if (YellowMax == 0 || curr > YellowMax) YellowMax = curr;
      if (YellowMin == 0 || curr < YellowMin) YellowMin = curr;
      if (curr > prev) count++;
      else if (curr < prev) count--;
   }
   if (count == YELLOWNUM) YellowTrend = ALLLONG;
   else if (count == -YELLOWNUM) YellowTrend = ALLSHORT;
   else YellowTrend = FLAT;    
      
// InvestorTrend

     if (RedTrend == ALLLONG &&  GreenTrend == ALLLONG && RedMax < GreenMin) InvestorTrend = LONG;
     else if (RedTrend == ALLSHORT && GreenTrend == ALLSHORT && RedMin > GreenMax) InvestorTrend = SHORT;
     else InvestorTrend = FLAT;

// Guppy Trend
 
     if (YellowTrend == ALLLONG && OrangeTrend == ALLLONG && BlueTrend == ALLLONG && InvestorTrend == LONG) GuppyTrend = LONG;
     else if (YellowTrend == ALLSHORT && OrangeTrend == ALLSHORT && BlueTrend == ALLSHORT && InvestorTrend == SHORT) GuppyTrend = SHORT;
     else GuppyTrend = FLAT;
    
	
}


////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
////////////////////////////////////////////////////////

string GSD(int D) {

	switch (D) {
		case LONG : return (strLONG);
		case SHORT : return (strSHORT);
		case ALLLONG : return (strALLLONG);
		case ALLSHORT : return (strALLSHORT);
	}
	return (strFLAT);

}

////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
////////////////////////////////////////////////////////

bool NewBar() {

	static datetime LastTime = 0;

	if (Time[0] != LastTime) {
		LastTime = Time[0];		
		return (true);
	} else
		return (false);
}



void DisplayComment() {

   Comment(strTrends);
}