//+------------------------------------------------------------------+
//|                                  Copyright © 2011, by talliy |
//|                                        mr.taliy@mail.ru      |
//| http://forum.tradelikeapro.ru/index.php?topic=3219.45
//+------------------------------------------------------------------+
#property copyright "Copyright © 2011, by talliy"
#property link      "mr.taliy@mail.ru"

#property indicator_chart_window

#property indicator_buffers 2

#define MR_NONE 0
#define MR_LONG 1
#define MR_SHORT 2
#define MR_RANGE 3
#define MR_CTLONG 4
#define MR_CTSHORT 5
#define MR_NOTAPPLICABLE 6

#define DFT_MARKETREAD 3

#define TLE_MODEOPEN 1
#define TLE_MODECLOSE 9

#define OPEN_BUY 1
#define OPEN_SELL 2
#define OPEN_BUYSTOP 3
#define OPEN_BUYLIMIT 4
#define OPEN_SELLSTOP 5
#define OPEN_SELLLIMIT 6

#define CLOSE_ORDER 9

#define DFT_RETURN -1

extern int MarketRead;
extern int TLEMode;
extern int BasketType;
extern string totalpair;
extern string totalpairs;

// User Definitions for other indicators etc.

double CB_Action[];
double CB_Price[];
string Pair[];
string Pairs[];
string Pair1[];
string Pairs1[];
datetime LastAlert;
datetime LastBar;
int b,s,bb,ss,b1,s1,bb1,ss1;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//----
   IndicatorBuffers(2);
   SetIndexBuffer(0,CB_Action);
   SetIndexBuffer(1,CB_Price);
   IndicatorDigits(Digits);
   b=0;s=0;bb=0;ss=0;b1=0;s1=0;bb1=0;ss1=0;
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
//----

   // Reset any close request on subsequent entry
   if (CB_Action[0] == CLOSE_ORDER)
      {
      CB_Action[0] = DFT_RETURN;
      // If an order cannot be opened on the same bar one is closed - comment out this line 
      LastBar = 0;
      }

   // Do nothing if the market read is NONE
   if (MarketRead == MR_NONE) return(0);
      
   // If the mode is not open or close - do nothing
   if (TLEMode != TLE_MODEOPEN && TLEMode != TLE_MODECLOSE) return(0);
   
   // Perform the trade logic
   if (TLEMode == TLE_MODEOPEN) Check_For_Open();
   if (TLEMode == TLE_MODECLOSE) Check_For_Close();
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Check for open of new trade                                      |
//+------------------------------------------------------------------+
int Check_For_Open()
  {
//----
int razmer;
int razmers;
int razmerm;
double procs,procb;
bool rem = false;
bool rems = false;
SplitString(totalpair, ",", Pair, rem);


razmer=ArraySize(Pair);

double HA10[];
double HA11[];
double HA01[];
double HA010[];
double HA02[];
double UT[];
double UT1[];
ArrayResize( HA10, razmer) ;
ArrayResize( HA11, razmer) ;
ArrayResize( HA01, razmer) ;
ArrayResize( HA010, razmer) ;
ArrayResize( HA02, razmer) ;
ArrayResize( UT, razmer) ;
ArrayResize( UT1, razmer) ;

/*ArrayInitialize( HA10, 0) ;
ArrayInitialize( HA11, 0) ;
ArrayInitialize( HA01, 0) ;
ArrayInitialize( HA010, 0) ;
ArrayInitialize( HA02, 0) ;
ArrayInitialize( HA020, 0) ;
ArrayInitialize( VQz20, 0) ;*/
if (totalpairs!=""){
SplitString(totalpairs, ",", Pairs, rems);
razmers=ArraySize(Pairs);
razmerm=razmer+razmers;
double HA10s[];
double HA11s[];
double HA01s[];
double HA010s[];
double HA02s[];
double UTs[];
double UT1s[];
ArrayResize( HA10s, razmers) ;
ArrayResize( HA11s, razmers) ;
ArrayResize( HA01s, razmers) ;
ArrayResize( HA010s, razmers) ;
ArrayResize( HA02s, razmers) ;
ArrayResize( UTs, razmers) ;
ArrayResize( UT1s, razmers) ;

/*ArrayInitialize( HA10s, 0) ;
ArrayInitialize( HA11s, 0) ;
ArrayInitialize( HA01s, 0) ;
ArrayInitialize( HA010s, 0) ;
ArrayInitialize( HA02s, 0) ;
ArrayInitialize( HA020s, 0) ;
ArrayInitialize( VQz20s, 0) ;*/}
   
   // Decide if the routine is to be run every tick
   // if so, comment out the next if statement
   if (Time[0] == LastBar) return(0);  // Once per bar 
   
   LastBar = Time[0];
   
   if (Time[0] == LastAlert) return(0);

   // Reset the communication buffers
   CB_Action[0] = DFT_RETURN;
   CB_Price[0] = DFT_RETURN;
   
   // Set the default market read if the market read is not applicable
   if (MarketRead == MR_NOTAPPLICABLE) MarketRead = DFT_MARKETREAD;
   
/*

the rest of the code in this routine is the user defined code for the TLE

*/
  // get variables for HAMA 
  //double HAsignal = iCustom(NULL,TimeFrames,Indy1,"",MaMetods,MaPeriods,Steps,6,1);
  //double HAtrend = iCustom(NULL,TimeFramet,Indy1,"",MaMetodt,MaPeriodt,Stept,6,1);
bool lb_Long, lb_Short;
 
 if (totalpairs!=""){
  for (int i=0; i<razmer; i++)
  {
      //double HA00=iCustom(NULL, 0, "HP_DIFF",38,1,0);
      HA10[i]=iCustom(Pair[i], 30, "HP_DIFF",60,1,1);
      HA11[i]=iCustom(Pair[i], 30, "HP_DIFF",60,1,2);
      //double HA20=iCustom(NULL, 0, "SSRC",3,21,2.0,6,0,1);
      HA01[i]=iCustom(Pair[i], 30,  "HP_DIFF MTF",60,60,1,1);
      HA010[i]=iCustom(Pair[i], 30, "HP_DIFF MTF",60,60,1,2);
      UT[i]=iCustom(Pair[i], 30, "ULTRA_TREND",678999942,1,1500,8,3,30,0,1);
      UT1[i]=iCustom(Pair[i], 30, "ULTRA_TREND",678999942,1,1500,8,3,30,1,1);
      }
   // Set up the allowable bands based on the direction
  
  for (int ii=0;ii<razmer;ii++){
   if (( HA10[ii] ==-1&& HA11[ii]==-1) && (HA01[ii]==-1&&HA010[ii]==-1) && UT[ii] >UT1[ii]){b++;}                           
      
                            
  if (( HA10[ii] ==1&& HA11[ii]==1) && (HA01[ii]==1&&HA010[ii]==1)&& UT1[ii]>UT[ii]) {s++; }
                        
      }      
 for (int q=0; q<razmers; q++)
  {
      HA10s[q]=iCustom(Pairs[q], 30, "HP_DIFF",60,1,1);
      HA11s[q]=iCustom(Pairs[q], 30, "HP_DIFF",60,1,2);
      //double HA20=iCustom(NULL, 0, "SSRC",3,21,2.0,6,0,1);
      HA01s[q]=iCustom(Pairs[q], 30,  "HP_DIFF MTF",60,60,1,1);
      HA010s[q]=iCustom(Pairs[q], 30, "HP_DIFF MTF",60,60,1,2);
      UTs[q]=iCustom(Pairs[q], 30, "ULTRA_TREND",678999942,1,1500,8,3,30,0,1);
      UT1s[q]=iCustom(Pairs[q], 30, "ULTRA_TREND",678999942,1,1500,8,3,30,1,1);
      }
      for (int iq=0;iq<razmer;iq++){
  if (( HA10s[iq] ==-1&& HA11s[iq]==-1) && (HA01s[iq]==-1&&HA010s[iq]==-1) && UTs[iq] >UT1s[iq]){b1++;}                           
      
                            
  if (( HA10s[iq] ==1&& HA11s[iq]==1) && (HA01s[iq]==1&&HA010s[iq]==1)&& UT1s[iq]>UTs[iq]) {s1++; }
                        
      } 
      
  procb = (b+s1)*100/razmerm;
  procs = (s+b1)*100/razmerm;
  }
  else
  {
   for (int x=0; x<razmer; x++)
  {
      //double HA00=iCustom(NULL, 0, "HP_DIFF",38,1,0);
      HA10[x]=iCustom(Pair[x], 30, "HP_DIFF",60,1,1);
      HA11[x]=iCustom(Pair[x], 30, "HP_DIFF",60,1,2);
      //double HA20=iCustom(NULL, 0, "SSRC",3,21,2.0,6,0,1);
      HA01[x]=iCustom(Pair[x], 30,  "HP_DIFF MTF",60,60,1,1);
      HA010[x]=iCustom(Pair[x], 30, "HP_DIFF MTF",60,60,1,2);
      UT[x]=iCustom(Pair[x], 30, "ULTRA_TREND",678999942,1,1500,8,3,30,0,1);
      UT1[x]=iCustom(Pair[x], 30, "ULTRA_TREND",678999942,1,1500,8,3,30,1,1);
      }
   // Set up the allowable bands based on the direction
 
  for (int ix=0;ix<razmer;ix++){
  if (( HA10[ix] ==-1&& HA11[ix]==-1) && (HA01[ix]==-1&&HA010[ix]==-1) && UT[ix] >UT1[ix]){b++;}                           
      
                            
  if (( HA10[ix] ==1&& HA11[ix]==1) && (HA01[ix]==1&&HA010[ix]==1)&& UT1[ix]>UT[ix]) {s++; }
                         
      }      
   procb = (b)*100/razmer;
  procs = (s)*100/razmer;
  }
  if (procb>=75.0){lb_Long = true;}
  if (procs>=75.0){lb_Short = true;}
  if (lb_Long == true||lb_Short == true){b=0;s=0;b1=0;s1=0;}
   // Send any alerts necessary
   if (lb_Short)
      {
      Alert("Possible SHORT opportunity at ",DoubleToStr(Close[0], Digits),TimeToStr(Time[0],TIME_DATE|TIME_MINUTES));
      LastAlert = Time[0];
      CB_Action[0] = OPEN_SELL;
      CB_Price[0] = 0;
      }
   
   if (lb_Long )
      {
      Alert("Possible LONG opportunity at ",DoubleToStr(Close[0], Digits),TimeToStr(Time[0],TIME_DATE|TIME_MINUTES));
      LastAlert = Time[0];
      CB_Action[0] = OPEN_BUY;
      CB_Price[0] = 0;
      }
      
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Check for close of a trade                                       |
//+------------------------------------------------------------------+
int Check_For_Close()
  {
double procss,procbb;
double AHA10[];
double AHA11[];
double AHA01[];
double AHA010[];
double AHA02[];
double AUT[];
double AUT1[];
int razmer1;
int razmers1;
int razmerm1;

bool remo=false;
   SplitString(totalpair, ",", Pair1, remo);
   razmer1=ArraySize(Pair1);
   razmerm1=razmer1;
ArrayResize( AHA10, razmer1) ;
ArrayResize( AHA11, razmer1) ;
ArrayResize( AHA01, razmer1) ;
ArrayResize( AHA010, razmer1) ;
ArrayResize( AHA02, razmer1) ;
ArrayResize( AUT, razmer1) ;
ArrayResize( AUT1, razmer1) ;

/*ArrayInitialize( AHA10, 0) ;
ArrayInitialize( AHA11, 0) ;
ArrayInitialize( AHA01, 0) ;
ArrayInitialize( AHA010, 0) ;
ArrayInitialize( AHA02, 0) ;
ArrayInitialize( AHA020, 0) ;
ArrayInitialize( AVQz20, 0) ;*/

if (totalpairs!=""){

bool remos=false;
SplitString(totalpairs, ",", Pairs1, remos);
razmers1=ArraySize(Pairs1);
razmerm1=razmer1+razmers1;
double AHA10s[];
double AHA11s[];
double AHA01s[];
double AHA010s[];
double AHA02s[];
double AUTs[];
double AUT1s[];

ArrayResize( AHA10s, razmers1) ;
ArrayResize( AHA11s, razmers1) ;
ArrayResize( AHA01s, razmers1) ;
ArrayResize( AHA010s, razmers1) ;
ArrayResize( AHA02s, razmers1) ;
ArrayResize( AUTs, razmers1) ;
ArrayResize( AUT1s, razmers1) ;

/*ArrayInitialize( AHA10s, 0) ;
ArrayInitialize( AHA11s, 0) ;
ArrayInitialize( AHA01s, 0) ;
ArrayInitialize( AHA010s, 0) ;
ArrayInitialize( AHA02s, 0) ;
ArrayInitialize( AHA020s, 0) ;
ArrayInitialize( AVQz20s, 0) ;*/}
   
   if (BasketType != OPEN_BUY && BasketType != OPEN_SELL) return(0);
   
   // Decide if the routine is to be run every tick
   // if so, comment out the next if statement
   if (Time[0] == LastBar) return(0);  // Once per bar 
   
   LastBar = Time[0];

 //  if (Time[0] == LastAlert) return(0);

   // Reset the communication buffers
   CB_Action[0] = DFT_RETURN; //-1


// the rest of the code in this routine is the user defined code for the TLE

if (totalpairs!=""){
  for (int i=0; i<razmer1; i++)
  {
      //double HA00=iCustom(NULL, 0, "HP_DIFF",38,1,0);
      AHA10[i]=iCustom(Pair1[i], 30, "HP_DIFF",60,1,1);
      AHA11[i]=iCustom(Pair1[i], 30, "HP_DIFF",60,1,2);
      //double HA20=iCustom(NULL, 0, "SSRC",3,21,2.0,6,0,1);
      AHA01[i]=iCustom(Pair1[i], 30,  "HP_DIFF MTF",60,60,1,1);
      AHA010[i]=iCustom(Pair1[i], 30, "HP_DIFF MTF",60,60,1,2);
      AUT[i]=iCustom(Pair1[i], 30, "ULTRA_TREND",678999942,1,1500,8,3,30,0,1);
      AUT1[i]=iCustom(Pair1[i], 30, "ULTRA_TREND",678999942,1,1500,8,3,30,1,1);
      }
   // Set up the allowable bands based on the direction
  
  for (int ii=0;ii<razmer1;ii++){
   if (( AHA10[ii] ==-1&& AHA11[ii]==-1) && (AHA01[ii]==-1&&AHA010[ii]==-1) && AUT[ii] >AUT1[ii]){bb++;}                           
      
                            
  if (( AHA10[ii] ==1&& AHA11[ii]==1) && (AHA01[ii]==1&&AHA010[ii]==1)&& AUT1[ii]>AUT[ii]) {ss++; }
                        
      }      
 for (int q=0; q<razmers1; q++)
  {
      AHA10s[q]=iCustom(Pairs1[q], 30, "HP_DIFF",60,1,1);
      AHA11s[q]=iCustom(Pairs1[q], 30, "HP_DIFF",60,1,2);
      //double HA20=iCustom(NULL, 0, "SSRC",3,21,2.0,6,0,1);
      AHA01s[q]=iCustom(Pairs1[q], 30,  "HP_DIFF MTF",60,60,1,1);
      AHA010s[q]=iCustom(Pairs1[q], 30, "HP_DIFF MTF",60,60,1,2);
      AUTs[q]=iCustom(Pairs1[q], 30, "ULTRA_TREND",678999942,1,1500,8,3,30,0,1);
      AUT1s[q]=iCustom(Pairs1[q], 30, "ULTRA_TREND",678999942,1,1500,8,3,30,1,1);
      }
      for (int iq=0;iq<razmers1;iq++){
  if (( AHA10s[iq] ==-1&& AHA11s[iq]==-1) && (AHA01s[iq]==-1&&AHA010s[iq]==-1) && AUTs[iq] >AUT1s[iq]){bb1++;}                           
      
                            
  if (( AHA10s[iq] ==1&& AHA11s[iq]==1) && (AHA01s[iq]==1&&AHA010s[iq]==1)&& AUT1s[iq]>AUTs[iq]) {ss1++; }
                        
      } 
      
  procbb = (bb+ss1)*100/razmerm1;
  procss = (ss+bb1)*100/razmerm1;
  }
  else
  {
   for (int x=0; x<razmer1; x++)
  {
      //double HA00=iCustom(NULL, 0, "HP_DIFF",38,1,0);
      AHA10[x]=iCustom(Pair1[x], 30, "HP_DIFF",60,1,1);
      AHA11[x]=iCustom(Pair1[x], 30, "HP_DIFF",60,1,2);
      //double HA20=iCustom(NULL, 0, "SSRC",3,21,2.0,6,0,1);
      AHA01[x]=iCustom(Pair1[x], 30,  "HP_DIFF MTF",60,60,1,1);
      AHA010[x]=iCustom(Pair1[x], 30, "HP_DIFF MTF",60,60,1,2);
      AUT[x]=iCustom(Pair1[x], 30, "ULTRA_TREND",678999942,1,1500,8,3,30,0,1);
      AUT1[x]=iCustom(Pair1[x], 30, "ULTRA_TREND",678999942,1,1500,8,3,30,1,1);
      }
   // Set up the allowable bands based on the direction
 
  for (int ix=0;ix<razmer1;ix++){
  if (( AHA10[ix] ==-1&& AHA11[ix]==-1) && (AHA01[ix]==-1&&AHA010[ix]==-1) && AUT[ix] >AUT1[ix]){bb++;}                           
      
                            
  if (( AHA10[ix] ==1&& AHA11[ix]==1) && (AHA01[ix]==1&&AHA010[ix]==1)&& AUT1[ix]>AUT[ix]) {ss++; }
                         
      }      
 procbb = (bb)*100/razmerm1;
  procss = (ss)*100/razmerm1;
  }

    
   if (BasketType==OPEN_BUY  && procss>=75.0 ) 
      {
      Alert("close of long at ",DoubleToStr(Close[0], Digits),TimeToStr(Time[0],TIME_DATE|TIME_MINUTES));
      LastAlert = Time[0];
      CB_Action[0] = CLOSE_ORDER;
      }
      
   // If the basket is a sell and we previous closed below the lower
   
   if (BasketType==OPEN_SELL && procbb>=75.0)  
         {
      Alert("close of short at ",DoubleToStr(Close[0], Digits),TimeToStr(Time[0],TIME_DATE|TIME_MINUTES));
      LastAlert = Time[0];
      CB_Action[0] = CLOSE_ORDER;
      }
      if(CB_Action[0] == CLOSE_ORDER){bb=0;ss=0;bb1=0;ss1=0;}
     
   // We don't want to send any actions UNLESS the market read is range
   //if (MarketRead != MR_RANGE)
      //CB_Action[0] = DFT_RETURN;
      
//----
   return(0);
  }
//+------------------------------------------------------------------+
int SplitString(string s, string sep, string& parts[], bool removeEmpty = false)
{
	int count = 0;
	int sepLen = StringLen(sep);

	string part;
	while (true)
	{
		int p = StringFind(s, sep);
		if (p >= 0)
		{
			if (p == 0)
				part = "";
			else
				part = StringSubstr(s, 0, p);

			if (!removeEmpty || (Trim(part) != ""))
			{
				count++;
				ArrayResize(parts, count);
				parts[count - 1] = part;
			}

			s = StringSubstr(s, p + sepLen);
		}
		else
		{
			// Последний кусок
			if (!removeEmpty || (Trim(s) != ""))
			{
				count++;
				ArrayResize(parts, count);
				parts[count - 1] = s;
			}

			break;
		}		
	}
	
	// удалить последнюю пустую строку
	if ((count > 0) && (parts[count - 1] == ""))
	{
		count--;
		ArrayResize(parts, count);
	}
	
	return(count);
}
string Trim(string s, int char = 0)
{
	if (char == 0)
		return(StringTrimLeft(StringTrimRight(s)));
	else
		return(TrimLeft(TrimRight(s, char), char));
}
string TrimLeft(string s, int char = 0)
{
	if (char == 0)
	{	
		s = StringTrimLeft(s);
	}
	else
	{
		int len = StringLen(s);
		
		// слева
		int cut = 0;

		for (int i = 0; i < len; i++)
		{
			if (StringGetChar(s, i) == char)
				cut++;
			else
				break;
		}
		
		if (cut > 0)
		{
			if (cut > len - 1)
				s = "";
			else
				s = StringSubstr(s, cut);
		}
	}
	return(s);
}

// Убирает указанные символы в конце строки
string TrimRight(string s, int char = 0)
{
	if (char == 0)
	{	
		s = StringTrimRight(s);
	}
	else
	{
		int len = StringLen(s);
		
		// справа
		int cut = len;

		for (int i = len - 1; i >= 0; i--)
		{
			if (StringGetChar(s, i) == char)
				cut--;
			else
				break;
		}
		
		if (cut != len)
		{
			if (cut == 0)
				s = "";
			else
				s = StringSubstr(s, 0, cut);
		}		
	}
	return(s);
}

