#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 = false;

bool YellowAlert = false;
bool RedAlert = false;
bool YellowAlertDone = false;
bool RedAlertDone = false;

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	MACDTrend;
int	LaguerreTrend;
int	GuppyTrend;
int	InvestorTrend;
int   TradingIndicator;

string	strTrends;

//FirstBarTime=StrToTime("00:05"); 


////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
////////////////////////////////////////////////////////

int init () {

	SignalTrend = 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 (YellowAlertDone && !YellowAlert) YellowAlertDone = false;
		if (RedAlertDone && !RedAlert) RedAlertDone = false;
		if (YellowAlert && !YellowAlertDone) {
		    if (AlertOn) Alert("Yellow-Alert "+Symbol()+" "+Period()+"Min - "+GSD(InvestorTrend));
		    if (EmailOn) SendMail("Yellow-Alert "+Symbol()+" "+Period()+"Min - "+GSD(InvestorTrend),"Yellow-Alert");
		    YellowAlertDone = true;
		} else if (RedAlert && !RedAlertDone) {
		    if (AlertOn) Alert("Red-Alert "+Symbol()+" "+Period()+"Min - "+GSD(InvestorTrend));
		    if (EmailOn) SendMail("Red-Alert "+Symbol()+" "+Period()+"Min - "+GSD(InvestorTrend),"Red-Alert");
		    RedAlertDone = true;
		}
	}

	DisplayComment();
	
	return (0);

}

////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
////////////////////////////////////////////////////////

void CalculateIndicators (int BarNo) {

	double  Lag;
	double  LastLag;
	double  f1;
	double  s1;
	double  MACD0;
	double  MACD1;

	SignalTrend = FLAT;
	MACDTrend = FLAT;
	LaguerreTrend = FLAT;
	InvestorTrend = FLAT;
	GuppyTrend = FLAT;
	TradingIndicator = FLAT;
	YellowAlert = false;
	RedAlert = false;

//	Signal Direction

	f1 = iMA(NULL, 0, 4, 0, MODE_EMA, PRICE_CLOSE, 0);
	s1 = iMA(NULL, 0, 8, 0, MODE_EMA, PRICE_CLOSE, 0);

	if (f1 > s1) 
		SignalTrend = LONG;
	else if (f1 < s1) 
		SignalTrend = SHORT;
	
	
//	Laguerre

	Lag = iCustom(NULL,0,"Laguerre",0.66,9500,0,0);
	LastLag = iCustom(NULL,0,"Laguerre",0.66,9500,0,1);

	if ((Lag < 0.15) && (LastLag < 0.15) && (Lag > LastLag))
		LaguerreTrend = LONG;
	else if ((Lag > 0.75) && (LastLag > 0.75) && (Lag < LastLag))
		LaguerreTrend = SHORT;


//	MACD

	MACD0 = iMACD(NULL,0,5,35,5,PRICE_CLOSE,0,0);
	
	if ((MACD0 > -0.0005 && Lag < 0.05) || (MACD0 > -0.0003 && Lag < 0.1) || (MACD0 > -0.0001 && Lag < 0.15)) 
		MACDTrend = LONG;
   else if  ((MACD0 < 0.0005 && Lag > 0.95) || (MACD0 < 0.0003 && Lag > 0.85) || (MACD0 < 0.0001 && Lag > 0.75)) 
		MACDTrend = SHORT;
	else if (MACD0 > 0)
	   MACDTrend = LONG; 
	else if (MACD0 < 0)
	   MACDTrend = SHORT; 
	

//	Guppy

	CalculateGuppy(BarNo);

//	Trading Indicator

	if (LaguerreTrend == LONG && MACDTrend == LONG && InvestorTrend == LONG) YellowAlert = true;
	else if (LaguerreTrend == SHORT && MACDTrend == SHORT && InvestorTrend == SHORT) YellowAlert = true;

	if (SignalTrend == LONG && LaguerreTrend == FLAT && MACDTrend == LONG && GuppyTrend == LONG && YellowAlertDone == true) RedAlert = true;
	else if (SignalTrend == SHORT && LaguerreTrend == FLAT && MACDTrend == SHORT && GuppyTrend == SHORT && YellowAlertDone == true) RedAlert = true;
	

//	Display string

strTrends = "\nRed : "+GSD(RedTrend)+"  Green : "+GSD(GreenTrend)+ "  Blue : "+GSD(BlueTrend)+ "  Orange : "+GSD(OrangeTrend)+ "  Yellow : "+GSD(YellowTrend)+
"\n\nSignal : "+GSD(SignalTrend)+"  MACD : "+GSD(MACDTrend)+"  Laguerre : "+GSD(LaguerreTrend)+"  Investor : "+GSD(InvestorTrend)+"  Guppy : "+GSD(GuppyTrend)+"       TRADE : "+GSD(TradingIndicator);

   if (RedAlert == true) strTrends = strTrends + "\n\nRed-Alert";
   if (YellowAlert == true) strTrends = strTrends + "\n\nYellow-Alert";
  


}

////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
////////////////////////////////////////////////////////

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, 0);
      prev = iMA(NULL, 0, RedPeriods[i], 0, MODE_EMA, PRICE_CLOSE, BarNo);
      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, 0);
      prev = iMA(NULL, 0, GreenPeriods[i], 0, MODE_EMA, PRICE_CLOSE, BarNo);
      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, 0);
      prev = iMA(NULL, 0, BluePeriods[i], 0, MODE_EMA, PRICE_CLOSE, BarNo);
      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, 0);
      prev = iMA(NULL, 0, OrangePeriods[i], 0, MODE_EMA, PRICE_CLOSE, BarNo);
      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, 0);
      prev = iMA(NULL, 0, YellowPeriods[i], 0, MODE_EMA, PRICE_CLOSE, BarNo);
      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);
*/
		return (true);

}



void DisplayComment() {

   Comment(strTrends);
}