//+------------------------------------------------------------------+
//|                                             CICRAlerter_cons.mq4 |
//|                                                      version 1.1 |
//|                                           Copyright © 2011, ride |
//|                                               yomajkel@gmail.com |
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+

#property copyright "Copyright © 2011, ride"
#property link      ""

#property indicator_chart_window

extern bool		ShowCurrentPairOnly  = true; //	Dispaly only chart Pair
extern string	PairsToTrade = "AUDCAD,AUDCHF,AUDNZD,AUDJPY,AUDUSD,CADCHF,CADJPY,CHFJPY,EURAUD,EURCAD,EURCHF,EURGBP,EURNZD,EURJPY,EURUSD,GBPCHF,GBPJPY,GBPUSD,NZDUSD,NZDJPY,USDCAD,USDCHF,USDJPY";
extern string	PeriodsToTrade = "H1,H4,D1,W1,MN"; // Time Frames to display are user defined
extern bool    DisplayNumbers = true;
extern double	DisplayStarts_X = 5;	//we positioning the object from the top right corner of window
extern double	DisplayStarts_Y = 15;
extern string	ada = "-----Auto Detect Above-----";
extern bool    AutoDetect = true;
extern string	as = "------Alerts Settings------";
extern bool    IntradayAlert = true;
extern bool    LongTermAlert = true;
extern int     AlertPeriod = 60; //in minutes
extern bool    EmailAlerts = false;
extern string	pdi="----Pair display inputs----";
extern bool    ModernDisplay = false;
extern int		FontSize=10;
extern color	FontColour=Yellow;
extern string	Font_Font = "Lucida Sans Unicode";

int      NumberOfIndexes = 8;
int      NumberOfPairs = 7;
int      NumberOfIndexSuffixes = 2;
string   IndexSuffixes[] = {"LFX", "LFXX"};
string   CurrencyIndexes[] = {"USD", "EUR", "GBP", "CHF", "JPY", "CAD", "AUD", "NZD"};
string   PairsForIndexes[8][7] = {
   "EURUSD", "GBPUSD", "AUDUSD", "NZDUSD", "USDCAD", "USDCHF", "USDJPY", //USD
   "EURUSD", "EURGBP", "EURJPY", "EURAUD", "EURCHF" ,"EURNZD", "EURCAD", //EUR
   "GBPUSD", "EURGBP", "GBPCHF", "GBPJPY", "GBPCAD", "GBPAUD", "GBPNZD", //GBP
   "USDCHF", "AUDCHF", "CHFJPY", "EURCHF", "GBPCHF", "CADCHF", "NZDCHF", //CHF
   "USDJPY", "EURJPY", "GBPJPY", "CADJPY", "CHFJPY", "NZDJPY", "AUDJPY", //JPY
   "USDCAD", "EURCAD", "GBPCAD", "AUDCAD", "CADJPY", "CADCHF" ,"NZDCAD", //CAD
   "AUDUSD" ,"AUDNZD", "AUDCAD", "AUDCHF", "AUDJPY", "EURAUD", "GBPAUD", //AUD
   "NZDUSD", "EURNZD", "GBPNZD", "NZDCAD", "AUDNZD", "NZDCHF", "NZDJPY" //NZD
};

double	ValueChange_1 = 2.5, ValueChange_2 = 4.75;

int	symbolCodeSUP=233,
		symbolCodeSDN=234,
		symbolCodeWUP=236,
		symbolCodeWDN=238,
		symbolCodeNoSignal=232;
color	colorCodeSUP=Blue,
		colorCodeSDN=Red,
		colorCodeWUP=DeepSkyBlue,
		colorCodeWDN=Magenta,
		colorCodeNoSignal=Gold;
//Background Colors;
color colorCodeBkTop = LimeGreen,
      colorCodeBkMid = Yellow,
      colorCodeBkNoBk = LightSteelBlue;
double RSILevel1 = 30, RSILevel2 = 50, RSILevel3 = 70;
      


//Pair extraction
int		NoOfPairs;				// Holds the number of pairs passed by the user via the inputs screen
int		NoOfPeriods;			// Holds the number of periods passed by the user via the inputs screen
string	TradePair[];			//Array to hold the pairs traded by the user
string	TradePeriod[];			//Array to hold the periods traded by the user
int		TradePeriodTF[];		//Array to hold the periods traded by the user
int		TradeTrendSymbol[][7];	//Array to hold the pairs trend symbol
color 	TradeTrendColor[][7];	//Array to hold the pairs trend color
color    TradeTrendThickColor[][7];
bool  	AlertSent[];

string	trend;
int		OldBars;
int WindowNo = 0;
//+------------------------------------------------------------------+
string objPrefix ;	// all objects drawn by this indicator will be prefixed with this
string buff_str ;	// all objects drawn by this indicator will be prefixed with this
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
{
//+------------------------------------------------------------------+ 
//----
	int i, j;
	objPrefix = WindowExpertName();
	
	setupDisplay();
	
   if (AutoDetect) {
      autoConfigure();
	} else if(!ShowCurrentPairOnly)	{
		//Extract the pairs traded by the user
		NoOfPairs = StringFindCount(PairsToTrade,",")+1;
		ArrayResize(TradePair, NoOfPairs);
		string AddChar = StringSubstr(Symbol(),6,4);
		StrPairToStringArray(PairsToTrade, TradePair, AddChar);
	} else {
		//Fill the array with only chart pair
		NoOfPairs = 1;
		ArrayResize(TradePair, NoOfPairs);
		TradePair[0] = Symbol();
	}
	
	NoOfPeriods = StringFindCount(PeriodsToTrade, ",")+1;
	
	ArrayResize(TradePeriod, NoOfPeriods);
	ArrayResize(TradePeriodTF, NoOfPeriods);
	StrToStringArray(PeriodsToTrade, TradePeriod);
	
	for(j=0; j<NoOfPeriods; j++)
	{
		TradePeriodTF[j] = StrToTF(TradePeriod[j]);	//this is for display Periods from topleft corner
		//TradePeriodTF[NoOfPeriods-j] = StrToTF(TradePeriod[j]);	//this is for display Periods from topright corner
	}
//----	
	ArrayResize(TradeTrendSymbol, NoOfPairs);
	ArrayInitialize(TradeTrendSymbol, symbolCodeNoSignal);		// Inizialize the array with symbolCodeNoSignal
	ArrayResize(TradeTrendColor, NoOfPairs);
	ArrayResize(TradeTrendThickColor, NoOfPairs);
	ArrayInitialize(TradeTrendColor, colorCodeNoSignal);		// Inizialize the array with colorCodeNoSignal
	ArrayInitialize(TradeTrendThickColor, LightSteelBlue);
//----
	return(0);
}// End init()

//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
{
//----
	Comment("");   
//+------------------------------------------------------------------+ 
	RemoveObjects(objPrefix);
//----
	return(0);
}// End deinit()

//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
{
   GetPairTrends(TradeTrendSymbol, TradeTrendColor, TradeTrendThickColor);
   PrintPairTrends();
   runAlerts();

}//End start()
//+------------------------------------------------------------------+

//-------------------------------------------------------------------+
// RemoveObjects                                                     |
//-------------------------------------------------------------------+
void RemoveObjects(string Pref)
{   
	int i;
	string objname = "";

	for (i = ObjectsTotal(); i >= 0; i--)
	{
		objname = ObjectName(i);
		if (StringFind(objname, Pref, 0) > -1) ObjectDelete(objname);
	}
	return(0);
} // End void RemoveObjects(string Pref)

//+------------------------------------------------------------------+
// StringFindCount                                                   |
//+------------------------------------------------------------------+
int StringFindCount(string str, string str2)
// Returns the number of occurrences of STR2 in STR
// Usage:   int x = StringFindCount("ABCDEFGHIJKABACABB","AB")   returns x = 3
{
  int c = 0;
  for (int i=0; i<StringLen(str); i++)
    if (StringSubstr(str,i,StringLen(str2)) == str2)  c++;
  return(c);
} // End int StringFindCount(string str, string str2)

//+------------------------------------------------------------------+
// StrPairToStringArray                                                  |
//+------------------------------------------------------------------+
void StrPairToStringArray(string str, string &a[], string p_suffix, string delim=",")
{
	int z1=-1, z2=0;
	for (int i=0; i<ArraySize(a); i++)
	{
		z2 = StringFind(str,delim,z1+1);
		a[i] = StringSubstr(str,z1+1,z2-z1-1) + p_suffix;
		if (z2 >= StringLen(str)-1)   break;
		z1 = z2;
	}
	return(0);
} // End void StrPairToStringArray(string str, string &a[], string p_suffix, string delim=",") 

//+------------------------------------------------------------------+
// StrToStringArray                                                  |
//+------------------------------------------------------------------+
void StrToStringArray(string str, string &a[], string delim=",")
{
	int z1=-1, z2=0;
	for (int i=0; i<ArraySize(a); i++)
	{
		z2 = StringFind(str,delim,z1+1);
		a[i] = StringSubstr(str,z1+1,z2-z1-1);
		if (z2 >= StringLen(str)-1)   break;
		z1 = z2;
	}
	return(0);
} // End void StrToStringArray(string str, string &a[], string delim=",") 

//+------------------------------------------------------------------+
// StrToTF(string str)                                               |
//+------------------------------------------------------------------+
// Converts a timeframe string to its MT4-numeric value
// Usage:   int x=StrToTF("M15")   returns x=15
int StrToTF(string str)
{
  str = StringUpper(str);
  str = StringTrimLeft(str);
  str = StringTrimRight(str);
  
  if (str == "M1")   return(PERIOD_M1);
  if (str == "M5")   return(PERIOD_M5);
  if (str == "M15")  return(PERIOD_M15);
  if (str == "M30")  return(PERIOD_M30);
  if (str == "H1")   return(PERIOD_H1);
  if (str == "H4")   return(PERIOD_H4);
  if (str == "D1")   return(PERIOD_D1);
  if (str == "W1")   return(PERIOD_W1);
  if (str == "MN")   return(PERIOD_MN1);
  return(0);
}  

//+------------------------------------------------------------------+
// StringUpper(string str)                                           |
//+------------------------------------------------------------------+
// Converts any lowercase characters in a string to uppercase
// Usage:    string x=StringUpper("The Quick Brown Fox")  returns x = "THE QUICK BROWN FOX"
string StringUpper(string str)
{
  string outstr = "";
  string lower  = "abcdefghijklmnopqrstuvwxyz";
  string upper  = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  for(int i=0; i<StringLen(str); i++)  {
    int t1 = StringFind(lower,StringSubstr(str,i,1),0);
    if (t1 >=0)  
      outstr = outstr + StringSubstr(upper,t1,1);
    else
      outstr = outstr + StringSubstr(str,i,1);
  }
  return(outstr);
}  
//+------------------------------------------------------------------+
//| GetPairTrends                                                    |
//+------------------------------------------------------------------+
void GetPairTrends(int &trend_symbol[][], color &trend_color[][], color &trend_thick_color[][])
{
	int i, j;
	double c_val, p_val, delta_val;
	
	for(i=0; i<NoOfPairs; i++)
	{
		for(j=0; j<NoOfPeriods; j++)
		{
			trend_symbol[i][j] = symbolCodeNoSignal;
			trend_color[i][j] = colorCodeNoSignal;
			
			c_val = iRSI(TradePair[i], TradePeriodTF[j], 3, PRICE_CLOSE, 1);
			p_val = iRSI(TradePair[i], TradePeriodTF[j], 3, PRICE_CLOSE, 2);
			delta_val = MathAbs(c_val - p_val);
			
			if(c_val - p_val > 0)
			{
			   if (c_val < RSILevel1 && delta_val > ValueChange_1) {
			      trend_thick_color[i][j] = colorCodeBkTop;
			   } else if (c_val < RSILevel2 && delta_val > ValueChange_1) {
			      trend_thick_color[i][j] = colorCodeBkMid;
			   } else {
			      trend_thick_color[i][j] = colorCodeBkNoBk;
			   }
			   
				if(delta_val > ValueChange_2)
				{
					trend_symbol[i][j] = symbolCodeSUP;
					trend_color[i][j] = colorCodeSUP;
				} // End if(delta_val > ValueChange_2)
				if(delta_val > ValueChange_1 && delta_val < ValueChange_2)
				{
					trend_symbol[i][j] = symbolCodeWUP;
					trend_color[i][j] = colorCodeWUP;
				} // End if(delta_val > ValueChange_1 && delta_val < ValueChange_2)
			} // End if(c_val - p_val > 0)
			if(c_val - p_val < 0)
			{
			   if (c_val > RSILevel3 && delta_val > ValueChange_1) {
			      trend_thick_color[i][j] = colorCodeBkTop;
			   } else if (c_val > RSILevel2 && delta_val > ValueChange_1) {
			      trend_thick_color[i][j] = colorCodeBkMid;
			   } else {
			      trend_thick_color[i][j] = colorCodeBkNoBk;
			   }
			   
				if(delta_val > ValueChange_2)
				{
					trend_symbol[i][j] = symbolCodeSDN;
					trend_color[i][j] = colorCodeSDN;
				} // End if(delta_val > ValueChange_2)
				if(delta_val > ValueChange_1 && delta_val < ValueChange_2)
				{
					trend_symbol[i][j] = symbolCodeWDN;
					trend_color[i][j] = colorCodeWDN;
				} // End if(delta_val > ValueChange_1 && delta_val < ValueChange_2)
			} // End if(c_val - p_val > 0)
		} //End for(j=0; j<NoOfPeriods; j++)
	} //End for(i=0; i<NoOfPairs; i++)
	return(0);

}//End GetPairTrends(int &trend_symbol[][], color &trend_color[][])

//+------------------------------------------------------------------+
//| PrintPairTrends                                                    |
//+------------------------------------------------------------------+
void PrintPairTrends()
{
	RemoveObjects(objPrefix);
	
	int i, j, x, y, rsiFontSize = FontSize;
	
	//Set Trade Pair
	for(i=0; i<NoOfPairs; i++)
	{
	   x = NoOfPeriods;
		if (NoOfPeriods > 5) x += 2;
		x *= FontSize * 2;
		
		y = yPosition(i);
		
		buff_str = StringConcatenate(objPrefix, TradePair[i]);
		ObjectDelete(buff_str);
		ObjectCreate(buff_str,OBJ_LABEL,WindowNo,0,0,0,0);
		ObjectSet(buff_str,OBJPROP_CORNER,1);
		ObjectSet(buff_str,OBJPROP_XDISTANCE,DisplayStarts_X + x);
		ObjectSet(buff_str,OBJPROP_YDISTANCE,DisplayStarts_Y + y);
		ObjectSetText(buff_str,TradePair[i],FontSize-2,Font_Font,FontColour);
		
	}
	//Set Trade Period
	for(j=0; j<NoOfPeriods; j++)
	{
		buff_str = StringConcatenate(objPrefix, TradePeriod[j]);
		ObjectDelete(buff_str);
		ObjectCreate(buff_str,OBJ_LABEL,WindowNo,0,0,0,0);
		ObjectSet(buff_str,OBJPROP_CORNER,1);
		x = NoOfPeriods - 1 - j;
		if (NoOfPeriods > 5 && j < NoOfPeriods - 5) x += 2;
		x *= FontSize * 2;
		ObjectSet(buff_str,OBJPROP_XDISTANCE,DisplayStarts_X + x);
		ObjectSet(buff_str,OBJPROP_YDISTANCE,DisplayStarts_Y);
		ObjectSetText(buff_str,TradePeriod[j],FontSize-2,Font_Font,FontColour);      
	}
	//Set Trade Trend
	for(i=0; i<NoOfPairs; i++)
	{
		for(j=0; j<NoOfPeriods; j++)
		{
		   x = NoOfPeriods - 1 - j;
	      if (NoOfPeriods > 5 && j < NoOfPeriods - 5) x += 2;
	      x *= FontSize * 2;
	      
	      y = yPosition(i);
	      
		   if (DisplayNumbers) {
		      if (TradeTrendThickColor[i][j] == colorCodeBkNoBk) rsiFontSize = FontSize - 2;
		      else rsiFontSize = FontSize - 1;
		   
		      buff_str = StringConcatenate(objPrefix, TradePair[i], TradePeriod[j], "_rsi_value");
			   ObjectDelete(buff_str);
			   ObjectCreate(buff_str,OBJ_LABEL,WindowNo,0,0,0,0);
 			   ObjectSet(buff_str,OBJPROP_CORNER,1);
            ObjectSet(buff_str, OBJPROP_XDISTANCE, DisplayStarts_X + x);
			   ObjectSet(buff_str, OBJPROP_YDISTANCE, DisplayStarts_Y + y + FontSize * 1.5);
			   ObjectSetText(buff_str, DoubleToStr(iRSI(TradePair[i], TradePeriodTF[j], 3, PRICE_CLOSE, 1), 0), rsiFontSize, "Arial", TradeTrendThickColor[i][j]);
			}
			
			//arrow
			buff_str = StringConcatenate(objPrefix, TradePair[i], TradePeriod[j]);
			ObjectDelete(buff_str);
			ObjectCreate(buff_str,OBJ_LABEL,WindowNo,0,0,0,0);
 			ObjectSet(buff_str,OBJPROP_CORNER,1);
			ObjectSet(buff_str,OBJPROP_XDISTANCE,DisplayStarts_X + x);
			ObjectSet(buff_str,OBJPROP_YDISTANCE,DisplayStarts_Y + y);
			ObjectSetText(buff_str,CharToStr(TradeTrendSymbol[i][j]),FontSize,"Wingdings",TradeTrendColor[i][j]);
		}
	}
//----
	return(0);

}//End PrintPairTrends()

void runAlerts() {
   static int AllowIntradayAlert = 0;
   static int AllowLongTermAlert = 0;
   
   if ((!IntradayAlert && !LongTermAlert) || (TimeCurrent() <= AllowIntradayAlert && TimeCurrent() <= AllowLongTermAlert)) {
      return;
   }
   
   int timestamp = TimeCurrent() + AlertPeriod;
   int downArrows, upArrows;
   bool h4Yellow, dYellow, h4Up, h4Down, dUp, dDown;
   string msg;
   
   for(int i = 0; i < NoOfPairs; i++) {
      downArrows = 0; upArrows = 0;
      h4Yellow = false; dYellow = false; h4Up = false; h4Down = false; dUp = false; dDown = false;
      for (int j = 0; j < NoOfPeriods; j++) {
         if (TradePeriodTF[j] != PERIOD_H4 && TradePeriodTF[j] != PERIOD_D1 && TradePeriodTF[j] != PERIOD_W1 && TradePeriodTF[j] != PERIOD_MN1) continue;
         
         if (TradeTrendSymbol[i][j] == symbolCodeSUP) upArrows++;
         if (TradeTrendSymbol[i][j] == symbolCodeSDN) downArrows++;
         
         if (TradePeriodTF[j] == PERIOD_H4) {
            h4Yellow = TradeTrendThickColor[i][j] == colorCodeBkMid;
            if (TradeTrendSymbol[i][j] == symbolCodeSUP) h4Up = true;
            else if (TradeTrendSymbol[i][j] == symbolCodeSDN) h4Down = true;
         }
         if (TradePeriodTF[j] == PERIOD_D1) {
            dYellow = TradeTrendThickColor[i][j] == colorCodeBkMid;
            if (TradeTrendSymbol[i][j] == symbolCodeSUP) dUp = true;
            else if (TradeTrendSymbol[i][j] == symbolCodeSDN) dDown = true;
         }
      }
      
      if (IntradayAlert && TimeCurrent() > AllowIntradayAlert && h4Yellow && dYellow && ((h4Up && dUp) || (h4Down && dDown))) {
         msg = TradePair[i] + " - H4 and D1 reading yellow and point the same direction - possible intraday setup";
         Alert(msg);
         if (EmailAlerts) SendMail(Symbol() + " CICR Intraday Alert", msg);
         AllowIntradayAlert  = timestamp;
      }
   
      if (LongTermAlert && TimeCurrent() > AllowLongTermAlert && (upArrows == 4 || downArrows == 4)) {
         msg = TradePair[i] + " - all 4 arrows (H4 - MN)  point the same direction";
         Alert(msg);
         if (EmailAlerts) SendMail(Symbol() + " CICR Long Term Alert", msg);
         AllowLongTermAlert = timestamp;
      }
   }
}

void autoConfigure() {
   for (int i = 0; i < NumberOfIndexes; i++) {
      for (int n = 0; n < NumberOfIndexSuffixes; n++) {
         string symbol;
         if (Symbol() == (CurrencyIndexes[i] + IndexSuffixes[n]) || Symbol() == (IndexSuffixes[n] + CurrencyIndexes[i])) {
            configureForIndex(i);
            return;
         }
      }
   }

   configureForPair();
}

void configureForIndex(int index) {
   PeriodsToTrade = "H1,H4,D1,W1,MN";
   DisplayNumbers = false;
   NoOfPairs = NumberOfIndexes;
   ArrayResize(TradePair, NoOfPairs);
   TradePair[0] = Symbol();
   //ArrayCopy(TradePair, PairsForIndexes, 1, index * NumberOfPairs, NumberOfPairs);
   for (int i = 0; i < NumberOfPairs; i++) TradePair[i + 1] = PairsForIndexes[index][i];
}

void configureForPair() {
   PeriodsToTrade = "M15,M30,H1,H4,D1,W1,MN";
   NoOfPairs = 1;
   TradePair[0] = Symbol();
}

void setupDisplay() {
   if (!ModernDisplay) return;
   
   FontColour = White;
   colorCodeSUP = Lime;
	colorCodeWUP = Orange;
	colorCodeNoSignal = Yellow;
}

int yPosition(int i) {
   int y = (i + 1) * 2;
   if (DisplayNumbers) y += i * 2;
   return(FontSize * y);
   //return(FontSize * ((i + 1) * 1.5 + i * 2.5));
}