//+------------------------------------------------------------------+
//|                                                     strMeter.mq4 |
//|                                                          Flotsom |
//+------------------------------------------------------------------+
#property indicator_separate_window
#property indicator_buffers 8

#define X_BARSPACING		   22
#define Y_BARSPACING		   1
#define BAR_STR				"I"
#define BAR_ANGLE			   90
#define X_BASELINE0			0
#define X_BASELINE1			200
#define X_BASELINE2			500
#define X_CUROFF			   0
#define X_DIVOFF			   -5
#define Y_BASELINE0			70
#define Y_BASELINE1			70
#define Y_BASELINE2			85
#define Y_BASELINE3			135
#define Y_BASELINE4			138
#define FTSIZE_BAR			13
#define FTSIZE_CUR			7
#define FTSIZE_SYM			6
#define SCALE				   10000
#define PIXEL_SCALE			0.5
#define SUGCHT_HEIGHT		40
#define LINECHARTHEIGHT0	50
#define LINECHARTHEIGHT1	90

#define MAX					   50
#define MIN					   -50
//#property indicator_maximum	MAX
//#property indicator_minimum	MIN
//*/

extern bool    SessionStrength = true;
extern string  SS1            = "If True, starts as Session StartHour, up to";
extern string  SS2            = " MaxBars. Otherwise, uses LineChartBars.";
extern int     GMTOffset      = 0;
extern int     TokyoStartHour = 0;
extern int     LondonStartHour = 7;
extern int     NYStartHour    = 12;
extern string  BarNote        = "Add 1 to next three: 11, 61, 151, etc.";
extern int     MaxBars        = 151;
extern int		LineChartBars	= 151;
extern string  BarNote2       = "Uses DefaultBars if Start bar (Hour)";
extern string  BarNote3       = " > MaxBars";
extern int     DefaultBars    = 11;
extern int     LineWidth      = 1;
extern string	Currencies		= "USD,EUR,GBP,JPY,CHF,CAD,AUD,NZD";
extern string	CurrDisplay		= "1,1,1,1,1,1,1,1";
extern string	SymbolFixes		= "";									//for irregular Symbols
extern string	ShowSignal		= "AUDCAD,AUDCHF,AUDJPY,AUDNZD,AUDUSD,CADCHF,CADJPY,CHFJPY,EURAUD,EURCAD,EURCHF,EURGBP,EURJPY,EURNZD,EURUSD,GBPAUD,GBPCAD,GBPCHF,GBPJPY,GBPNZD,GBPUSD,NZDCAD,NZDCHF,NZDJPY,NZDUSD,USDCAD,USDCHF,USDJPY";
//extern string	ShowSignal		= "EURUSD,EURCHF,EURJPY,GBPUSD,USDCHF,GBPJPY,GBPCHF,AUDUSD";
extern int		TimeFrame		= 15;
extern int		StrengthBase	= 60;
extern int		RecentCHBase	= 10;
extern bool		ShowLineChart	= true;
extern bool		ShowBarChart	= false;
extern bool		UpdateOnTick	= true;
extern bool		AllowAlert		= false;
extern bool		AllowSound		= false;
extern int		MinimumAlertInterval	= 30;
extern int		LegendOffsetY	= 20;
extern int		MeterPosition	= 20;
extern color	BullColor		= Green;
extern color	BearColor		= Red;
extern color	Color0			= Green;
extern color	Color1			= White;
extern color	Color2			= Red;
extern color	Color3			= Yellow;
extern color	Color4			= Black;
extern color	Color5			= LightSalmon;
extern color	Color6			= Orange;
extern color	Color7			= Teal;
extern color	TextColor		= White;

int StartHour;

datetime	   gSymbolLastNotifyTime[];

double	   oLine0[],oLine1[],oLine2[],oLine3[],oLine4[],oLine5[],oLine6[],oLine7[];
double		gPairBuffer[],gPairLineBuffer[][8],gSymbolWeight[],gCurrencyWeight[];

string		gCurrencyArray[],gSymbolArray[];
string		gObjPrefix,gPrefix,gSuffix;

color		   gCurrencyColor[8];

bool		   gShow[],gShowSymbol[];

int			gCurrencyCount,gSymbols;
int			gBarCount,gTimeFrame,gWindow,gXoffset,gYoffset;
int			gSymbolCurrencyLeft[],gSymbolCurrencyRight[];
int			gSymbolLastNotifyDirection[],gSymbolNotifyList[];

//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
int init()
{
   TokyoStartHour+=GMTOffset;
   LondonStartHour+=GMTOffset;
   NYStartHour+=GMTOffset;

	gBarCount=0;
	setPairs();
	gXoffset=MeterPosition;
	int id;
	id=newID();
	gObjPrefix=StringConcatenate(id,"_strM_");

	if(TimeFrame == 0)
	   gTimeFrame=Period();
	else
	   gTimeFrame=TimeFrame;

	IndicatorShortName("SMSession");
	
	SetIndexStyle(0,DRAW_LINE,STYLE_SOLID,2);
	SetIndexStyle(1,DRAW_LINE,STYLE_SOLID,2);
	SetIndexStyle(2,DRAW_LINE,STYLE_SOLID,1);
	SetIndexStyle(3,DRAW_LINE,STYLE_SOLID,1);
	SetIndexStyle(4,DRAW_LINE,STYLE_SOLID,LineWidth);
	SetIndexStyle(5,DRAW_LINE,STYLE_SOLID,LineWidth);
	SetIndexStyle(6,DRAW_LINE,STYLE_SOLID,1);
	SetIndexStyle(7,DRAW_LINE,STYLE_SOLID,LineWidth);
	return(0);
}

//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//deinitialization
int deinit()
{
	gWindow=WindowOnDropped();
	ObjectsDeleteAll(gWindow);
	return(0);
}

//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
int start()
{

   if(Hour() >= TokyoStartHour)
      StartHour = TokyoStartHour;
   if(Hour() >= LondonStartHour)
      StartHour = LondonStartHour;
   if(Hour() >= NYStartHour)
      StartHour = NYStartHour;
      
	if (!UpdateOnTick) 
	{
		if (gBarCount==iBars(Symbol(),gTimeFrame)) 
		   return(0);
		gBarCount=iBars(Symbol(),gTimeFrame);
	}

	gWindow=WindowOnDropped();

	if (gWindow==-1) 
	{
		Print("window error");
		return(0);
	}

	ObjectsDeleteAll(gWindow);
	drawLines();
	drawMeter();
	
	return(0);
}

//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
void setPairs()
{
	int i,j,k,s;
	string current,workstr;
	
	workstr = normalizeStr(SymbolFixes,",");
	s=0;i=StringFind(workstr,",",s);

	if (i>0) 
	   gPrefix = StringSubstr(workstr,s,i-s);
	else 
	   gPrefix="";
	   
	s=i+1;i=StringFind(workstr,",",s);
	if (i>s) 
	   gSuffix = StringSubstr(workstr,s,i-s);
	else 
	   gSuffix="";

	workstr = normalizeStr(Currencies,",");
	s = 0;gCurrencyCount=0;
	i = StringFind(workstr,",",s);
	
	while (i > 0)
	{
		if (i-s>0) 
		{
			current = stringUpperCase(StringSubstr(workstr,s,i-s));
			gCurrencyCount++;
			ArrayResize(gCurrencyArray,gCurrencyCount);
			gCurrencyArray[gCurrencyCount-1]=current;
		}

		s = i + 1;
		i = StringFind(workstr,",",s);
	}
	
	ArrayResize(gSymbolArray,(gCurrencyCount-1)*gCurrencyCount/2);
	ArrayResize(gSymbolCurrencyLeft,(gCurrencyCount-1)*gCurrencyCount/2);
	ArrayResize(gSymbolCurrencyRight,(gCurrencyCount-1)*gCurrencyCount/2);
	ArrayResize(gPairBuffer,LineChartBars*gCurrencyCount);
	ArrayResize(gCurrencyWeight,gCurrencyCount);
	ArrayResize(gShow,gCurrencyCount);

	gSymbols=0;
	
	for (i=0;i<gCurrencyCount;i++) 
	{
		k=0;current="";
		for (j=0;j<gCurrencyCount;j++) 
		{
			if (i==j) 
			   continue;
			if (findNaddPair(i,j,i)) 
			{
			   k++;
			   current=current+"["+makeSymbol(i,j)+"]";
			   continue;
			}
			
			if (findNaddPair(j,i,i)) 
			{
			   k++;
			   current=current+"["+makeSymbol(j,i)+"]";
			   continue;
			}
			
		//	Print("No Symbol found for ",gCurrencyArray[i]," vs ",gCurrencyArray[j]," not found.");
		}

		if (k>0) 
		{
			Print (k," Symbols found for currency [",gCurrencyArray[i],"]:",current);
			continue;
		}

		Print ("No symbol found for currency [",gCurrencyArray[i],"], removed from list.");
		gCurrencyCount--;
		for (j=i;j<gCurrencyCount;j++) 
		   gCurrencyArray[j]=gCurrencyArray[j+1];
		   
		i--;
	}
	
	ArrayResize(gShowSymbol,gSymbols);
	ArrayResize(gSymbolWeight,gSymbols);
	ArrayResize(gSymbolLastNotifyDirection,gSymbols);
	ArrayResize(gSymbolLastNotifyTime,gSymbols);
	ArrayResize(gSymbolNotifyList,gSymbols);
	ArrayInitialize(gCurrencyWeight,0);
	ArrayInitialize(gSymbolLastNotifyDirection,0);
	ArrayInitialize(gSymbolLastNotifyTime,0);
	ArrayInitialize(gSymbolNotifyList,0);
	ArrayInitialize(gSymbolWeight,100);
	
	for (i=0;i<gSymbols;i++) 
	{
		gCurrencyWeight[gSymbolCurrencyLeft[i]]+=gSymbolWeight[i];
		gCurrencyWeight[gSymbolCurrencyRight[i]]+=gSymbolWeight[i];
		gSymbolWeight[i]*=SCALE;
		gShowSymbol[i]=false;
	}
	
	workstr = normalizeStr(ShowSignal,",");
	s = 0;i = StringFind(workstr,",",s);
	
	while (i > 0)
	{
		if (i-s>0) 
		{
			current = stringUpperCase(StringSubstr(workstr,s,i-s));
			k=lookupSymbol(StringConcatenate(gPrefix,current,gSuffix));
			if (k>=0) 
			{
				gShowSymbol[k]=true;
			}
		}
		
		s = i + 1;
		i = StringFind(workstr,",",s);
	}
	
	current="";
	
	for (i=0;i<gSymbols;i++) 
	   if (gShowSymbol[i]) 
	      current=StringConcatenate(current,"[",gSymbolArray[i],"]");

	Print("Show signal of ",current);
	Print("Symbols setting finished.");
	
	int lines;
	if (gCurrencyCount>8) 
	   lines=8;
	else 
	   lines=gCurrencyCount;
	   
	if (lines>0) {SetIndexBuffer(0,oLine0);gCurrencyColor[0]=Color0;}
	if (lines>1) {SetIndexBuffer(1,oLine1);gCurrencyColor[1]=Color1;}
	if (lines>2) {SetIndexBuffer(2,oLine2);gCurrencyColor[2]=Color2;}
	if (lines>3) {SetIndexBuffer(3,oLine3);gCurrencyColor[3]=Color3;}
	if (lines>4) {SetIndexBuffer(4,oLine4);gCurrencyColor[4]=Color4;}
	if (lines>5) {SetIndexBuffer(5,oLine5);gCurrencyColor[5]=Color5;}
	if (lines>6) {SetIndexBuffer(6,oLine6);gCurrencyColor[6]=Color6;}
	if (lines>7) {SetIndexBuffer(7,oLine7);gCurrencyColor[7]=Color7;}
	
	for (i=0;i<lines;i++) 
	   gShow[i]=true;
	   
	workstr = normalizeStr(CurrDisplay,",");
	j=0;
	s=0;
	i = StringFind(workstr,",",s);
	
	while (i>=0 && j<lines) 
	{
		k = StrToInteger(StringSubstr(workstr,s,i-s));
		
		if (k==0) 
		   gShow[j]=false;
		   
		j++;
		s = i + 1;
		i = StringFind(workstr,",",s);
	}
	
	for (i=0;i<lines;i++) 
	{
		SetIndexLabel(i,gCurrencyArray[i]);
		SetIndexStyle(i,DRAW_LINE,EMPTY,EMPTY,gCurrencyColor[i]);
	}
	
}

//+------------------------------------------------------------------+
int newID()
{
	int id;
	if(!GlobalVariableCheck("id")) 
	{
		id=0;
	} 
	else 
	   id=1+GlobalVariableGet("id");
	   
	GlobalVariableSet("id",id);
	
	return(id);
}

//+------------------------------------------------------------------+
//Draw Begin
void drawLines()
{
	int i,j,bm;
	double k,b,max,min,upper,lower;
	if(SessionStrength)
	{
   	int StartBar = iBarShift(Symbol(),0,iTime(Symbol(),PERIOD_H1,Hour()-StartHour))+1;
   	
   	if(StartBar < MaxBars)
      	LineChartBars = StartBar;
      else
      	LineChartBars = DefaultBars;
   }

//Print("LineChartBars=",LineChartBars);
//	calc(0,LineChartBars-1,StrengthBase,LineChartBars);
	calc(0,LineChartBars,LineChartBars-1,LineChartBars);
	lower=MIN;
	
	if (!ShowLineChart) 
	   return;
	   
	if (ShowBarChart) 
	   upper=(LINECHARTHEIGHT0*MAX+(100-LINECHARTHEIGHT0)*MIN)/100;
	else 
	   upper=(LINECHARTHEIGHT1*MAX+(100-LINECHARTHEIGHT1)*MIN)/100;
	   
	max=0;
	min=0;
	
	for (i=0;i<gCurrencyCount;i++) 
	{
		bm=i*LineChartBars;
		
		for (j=0;j<LineChartBars;j++) 
		{
			if (gPairBuffer[bm+j]>max) 
			   max=gPairBuffer[bm+j];
			   
			if (gPairBuffer[bm+j]<min) 
			   min=gPairBuffer[bm+j];
		} 
	}
	
	if (max-min==0) 
	   return;
	
	k=(upper-lower)/(max-min);
	b=lower-min*k;//*/
//	k=1;b=0;
	
	for (i=0;i<gCurrencyCount && i<8;i++) 
	{
		if (!gShow[i]) 
		   continue;
		   
		bm=i*LineChartBars;
		
		for (j=0;j<LineChartBars;j++) 
		{
			switch (i) 
			{
   			case 0:oLine0[j]=k*gPairBuffer[bm+j]+b;break;
   			case 1:oLine1[j]=k*gPairBuffer[bm+j]+b;break;
   			case 2:oLine2[j]=k*gPairBuffer[bm+j]+b;break;
   			case 3:oLine3[j]=k*gPairBuffer[bm+j]+b;break;
   			case 4:oLine4[j]=k*gPairBuffer[bm+j]+b;break;
   			case 5:oLine5[j]=k*gPairBuffer[bm+j]+b;break;
   			case 6:oLine6[j]=k*gPairBuffer[bm+j]+b;break;
   			case 7:oLine7[j]=k*gPairBuffer[bm+j]+b;break;
			}
		}
		
		SetIndexDrawBegin(i,Bars-LineChartBars);
	}
	
	int WindowNum = WindowFind("SMSession");
   DrawLine("Zero line Session", OBJ_HLINE, Silver, k*gPairBuffer[7*LineChartBars+LineChartBars-1]+b, WindowNum);

	drawLegend();
}

//+------------------------------------------------------------------+
void drawLegend()
{
	int i,y;
	string name;

	y=FTSIZE_CUR*2;
	
	if (ShowBarChart) 
	   y+=LegendOffsetY+Y_BASELINE0+100*PIXEL_SCALE;

	for (i=0;i<gCurrencyCount;i++) 
	{
		name=StringConcatenate(gObjPrefix,i,"_LEGT");
//		drawLabel(name,i*X_BARSPACING+X_BASELINE0+X_CUROFF,y,gCurrencyArray[i],TextColor,0,FTSIZE_CUR);
		drawLabel(name,i*X_BARSPACING+X_BASELINE0+X_CUROFF,y,gCurrencyArray[i],gCurrencyColor[i],0,FTSIZE_CUR);
		
		if (!gShow[i] || i>=8) 
		   continue;
		
		name=StringConcatenate(gObjPrefix,i,"_LEGL");
		drawLabel(name,i*X_BARSPACING+X_BASELINE0+X_CUROFF,y+3," ___",gCurrencyColor[i],0,FTSIZE_CUR);
	}
}

//+------------------------------------------------------------------+
void drawLabel(string name, int x, int y, 
				string text, color clr, double angle=BAR_ANGLE,
				int fontsize=FTSIZE_BAR, string font="Arial")
{
//	ObjectDelete(name);
	ObjectCreate(name,OBJ_LABEL,gWindow,0,0);
	ObjectSetText(name,text,fontsize,font,clr);
	ObjectSet(name,OBJPROP_XDISTANCE,x+gXoffset);
	ObjectSet(name,OBJPROP_YDISTANCE,y+gYoffset);
	ObjectSet(name,OBJPROP_ANGLE,angle);
}

//+------------------------------------------------------------------+
void drawMeter()
{
	int i,j,k;
	double value,level,max,min;
	int sdir[],rdir[];
	
	ArrayResize(sdir,gCurrencyCount);
	ArrayResize(rdir,gCurrencyCount);
	ArrayInitialize(sdir,0);
	ArrayInitialize(rdir,0);

	calc(0,0,StrengthBase,1);

	max=0;min=0;
	
	for (i=0;i<gCurrencyCount;i++) 
	{
		value=gPairBuffer[i];
		
		if (value>0) 
		{
			sdir[i]=1;
			
			if (value>max) 
			   max=value;
		}
		else if (value<0) 
		{
			sdir[i]=-1;
			
			if (value<min) 
			   min=value;
		}
	}

	if (ShowBarChart) 
	{
		k=0;
		
		for (i=0;i<gCurrencyCount;i++) 
		{
			if (!gShow[i]) 
			   continue;
			   
			value=gPairBuffer[i];
			
			if (value>0) 
			   level=MathRound(100*value/max);
			else 
			   level=-MathRound(100*value/min);
			   
			drawBars(0,k,level);
			k++;
		}
	}

	calc(0,0,RecentCHBase,1);

	max=0;min=0;
	
	for (i=0;i<gCurrencyCount;i++) 
	{
		value=gPairBuffer[i];
		
		if (value>0) 
		{
			rdir[i]=1;
			
			if (value>max) 
			   max=value;
		}
		else if (value<0) 
		{
			rdir[i]=-1;
			
			if (value<min) 
			   min=value;
		}
	}

	if (ShowBarChart) 
	{
		k=0;
		
		for (i=0;i<gCurrencyCount;i++) 
		{
			if (!gShow[i]) 
			   continue;
			   
			value=gPairBuffer[i];
			
			if (value>0) 
			   level=MathRound(100*value/max);
			else 
			   level=-MathRound(100*value/min);
			   
			drawBars(1,k,level);
			k++;
		}
		
		drawTexts();
	}

	string sym,name;
//	color clr;
	int symidx;
	k=0;
	
	for (i=0;i<gCurrencyCount;i++) 
	{
		if (!gShow[i]) 
		   continue;
		   
		if (sdir[i]!=rdir[i]) 
		   continue;
		   
		for (j=i+1;j<gCurrencyCount;j++) 
		{
			if (!gShow[j]) 
			   continue;
			   
			if (sdir[j]!=rdir[j]) 
			   continue;
			   
			if (sdir[i]==sdir[j]) 
			   continue;
			   
			sym=makeSymbol(i,j);
			symidx=lookupSymbol(sym);
			
			if (symidx<0) 
			{
				sym=makeSymbol(j,i);
				symidx=lookupSymbol(sym);
				
				if (symidx<0) 
				   continue;
				   
				if (sdir[i]>0) 
				   level=-SUGCHT_HEIGHT;
				else 
				   level=SUGCHT_HEIGHT;
			}
			else
			{
   			if (sdir[i]>0) 
   			   level=SUGCHT_HEIGHT;
   			else 
   			   level=-SUGCHT_HEIGHT;
         }
         			
			if (!gShowSymbol[symidx]) 
			   continue;
			   
			if (ShowBarChart) 
			{
				drawBars(2,k*2,level);
				name=StringConcatenate(gObjPrefix,"_",k,"_DIV");
				drawLabel(name,k*2*X_BARSPACING+X_BASELINE2+X_DIVOFF,Y_BASELINE0,sym,TextColor,0,FTSIZE_SYM);
//				drawLabel(name,k*2*X_BARSPACING+X_BASELINE2+X_DIVOFF,Y_BASELINE0,sym,gCurrencyColor[i],0,FTSIZE_SYM);
			}
			
			gSymbolNotifyList[symidx]=level;
			k++;
		}
	}

	if (AllowAlert || AllowSound) 
	   doNotify();
}

//+------------------------------------------------------------------+
void drawTexts()
{
	int i,j;
	string name;

	j=0;
	
	for (i=0;i<gCurrencyCount;i++) 
	{
		if (!gShow[i]) 
		   continue;
		   
		name=StringConcatenate(gObjPrefix,0,"_",i,"_SYM");
//		drawLabel(name,j*X_BARSPACING+X_BASELINE0+X_CUROFF,Y_BASELINE0,gCurrencyArray[i],TextColor,0,FTSIZE_CUR);
		drawLabel(name,j*X_BARSPACING+X_BASELINE0+X_CUROFF,Y_BASELINE0,gCurrencyArray[i],gCurrencyColor[i],0,FTSIZE_CUR);
		name=StringConcatenate(gObjPrefix,1,"_",i,"_SYM");
//		drawLabel(name,j*X_BARSPACING+X_BASELINE1+X_CUROFF,Y_BASELINE0,gCurrencyArray[i],TextColor,0,FTSIZE_CUR);
		drawLabel(name,j*X_BARSPACING+X_BASELINE1+X_CUROFF,Y_BASELINE0,gCurrencyArray[i],gCurrencyColor[i],0,FTSIZE_CUR);
		j++;
	}
}

//+------------------------------------------------------------------+
void drawBars(int section,int isym,double level)
{
	int i,x,y0,ystep,yend,b;
	static int offsetX[]={X_BASELINE0,X_BASELINE1,X_BASELINE2};
	string name;
	color clr;

	x=offsetX[section]+isym*X_BARSPACING;
	
	if (level>0) 
	{
		b=MathRound(level*PIXEL_SCALE);
		yend=Y_BASELINE1-b;
		y0=Y_BASELINE1;
		ystep=-Y_BARSPACING;
		clr=BullColor;
	}
	else 
	{
		b=MathRound(-level*PIXEL_SCALE);
		yend=Y_BASELINE2+b;
		y0=Y_BASELINE2;
		ystep=Y_BARSPACING;
		clr=BearColor;
	}
	
	b=b/Y_BARSPACING;
	
	for (i=0;i<b;i++) 
	{
		name=StringConcatenate(gObjPrefix,section,"_",isym,"_",i);
		drawLabel(name,x,y0+i*ystep,BAR_STR,clr);
	}
	
	return;
}

//+------------------------------------------------------------------+
//| Strength calc Begin
void calc(int start,int end,int bars_back, int pairbufferlength)
{
	int i,j,l,r;
	double ratio,base;
	double weight[];
	
	ArrayResize(weight,gCurrencyCount); //gCurrencyCount = 8
	
	for (i=0;i<gCurrencyCount;i++) 
	   weight[i]=gCurrencyWeight[i];
	
	ArrayInitialize(gPairBuffer,0);
	
	for (i=0;i<gSymbols;i++) 
	{
		l=gSymbolCurrencyLeft[i];
		r=gSymbolCurrencyRight[i];
		l*=pairbufferlength;
		r*=pairbufferlength;
		
		for (j=0;j<pairbufferlength;j++) 
		{
//			base=iOpen(gSymbolArray[i],gTimeFrame,j+bars_back);
//			base=iOpen(gSymbolArray[i],gTimeFrame,bars_back);
			base=iClose(gSymbolArray[i],gTimeFrame,bars_back);
		
			if (base==0) 
			   continue;
			   
			ratio=iClose(gSymbolArray[i],gTimeFrame,j)/base;
			gPairBuffer[l+j]+=gSymbolWeight[i]*ratio;
			gPairBuffer[r+j]+=gSymbolWeight[i]/ratio;
		}
	}
	
	for (i=0;i<gCurrencyCount;i++)  //gCurrencyCount = 8
	{
		l=i*pairbufferlength;
		
		for (j=0;j<pairbufferlength;j++) 
		{
			if (weight[i]==0) 
			   continue;
			   
			gPairBuffer[l+j]/=weight[i];
			gPairBuffer[l+j]-=SCALE;
//			gPairBuffer[l+j]-=50;
		}
	}

}

//| Strength calc End

//+-------------------------------------------------------------------------------------------+

void DrawLine(string ZeroLine, int LineType, color LineColor, double LinePrice, int WinNum)
   {
      if(ObjectFind(ZeroLine) != 0)
      {
         ObjectCreate(ZeroLine, LineType, WinNum, Time[0], LinePrice);
         ObjectSet(ZeroLine, OBJPROP_STYLE, STYLE_DOT);
         ObjectSet(ZeroLine, OBJPROP_COLOR, LineColor);
      }
      else
      {
         ObjectMove(ZeroLine, 0, Time[0], LinePrice);
      }
   }

//+------------------------------------------------------------------+
void doNotify()
{
	int i,j;
	datetime dt;
	string alstr="Suggested pairs:";

	dt=TimeCurrent();
	j=0;
	
	for (i=0;i<gSymbols;i++) 
	{
		if (gSymbolNotifyList[i]==0) 
		   continue;
		   
		if (gSymbolNotifyList[i]!=gSymbolLastNotifyDirection[i] || dt-gSymbolLastNotifyTime[i]>MinimumAlertInterval) 
		{
			j++;
			gSymbolLastNotifyDirection[i]=gSymbolNotifyList[i];
			alstr=StringConcatenate(alstr,"[",gSymbolArray[i],"]");
		}
		
		gSymbolLastNotifyTime[i]=dt;
	}
	
	if (j==0) 
	   return;
	   
	if (AllowAlert) 
	   Alert(alstr);
	   
	if (AllowSound) 
	   PlaySound("alert.wav");
}

//+------------------------------------------------------------------+
bool findNaddPair(int left,int right,int c)
{
	string sym=makeSymbol(left,right);
	int s=lookupSymbol(sym);

	if (s<0) 
	{
		if (testSym(sym)) 
		{
			gSymbolArray[gSymbols]=sym;
			gSymbolCurrencyLeft[gSymbols]=left;
			gSymbolCurrencyRight[gSymbols]=right;
			gSymbols++;
		} 
		else 
		   return(false);
	}
	
//	Print("Symbol [",sym,"] found for currency [",gCurrencyArray[c],"].");
	return (true);
}

//+------------------------------------------------------------------+
string makeSymbol(int left, int right)
{
	return (StringConcatenate(gPrefix,gCurrencyArray[left],gCurrencyArray[right],gSuffix));
}

//+------------------------------------------------------------------+
int lookupSymbol(string sym)
{
	for (int i=0;i<gSymbols;i++)
		if (gSymbolArray[i]==sym) 
		   return (i);
		   
//	int error=GetLastError();
//	if (error!=0) Print("Error ",error," occured looking up Symbol [",sym,"], i=",i,"|gSymbols=",gSymbols);
	return (-1);
}

//+------------------------------------------------------------------+
bool testSym(string sym)
{
	GetLastError();
	
	if (iBars(sym,gTimeFrame)>0) 
	   return (true);
	   
	int error=GetLastError();
	if (4066==error) 
	{
		Print("Waiting for data of [",sym,"].");
		return (true);
	}
	
//	if (error!=0) Print("Error ",error," occured testing Symbol [",sym,"]");
	return (false);
}

//+------------------------------------------------------------------+
string normalizeStr(string s,string div)
{
	string workstr = StringTrimLeft(StringTrimRight(s));
	
	if (StringSubstr(workstr,StringLen(workstr),1) != div)
		workstr = StringConcatenate(workstr,div);

	return (workstr);
}

//+------------------------------------------------------------------+
string stringUpperCase(string str)
{
	string s=str;
	int chr;
	int length=StringLen(str)-1;
   
	while(length>=0) 
	{
		chr=StringGetChar(s,length);
		
		if((chr>96 && chr<123) || (chr>223 && chr<256))
			s=StringSetChar(s,length,chr-32);
		else if(chr>-33 && chr<0)
			s=StringSetChar(s,length,chr+224);
		length--;
	}
	
	return(s);
} 