#property indicator_separate_window
#property indicator_buffers 8
#property indicator_level1 0
#property indicator_color1 Green
#property indicator_color2 Aqua
#property indicator_color3 Blue
#property indicator_color4 Gray
#property indicator_color5 DarkOrange
#property indicator_color6 Purple
#property indicator_color7 Teal
#property indicator_color8 Red

double Buffer0[];
double Buffer1[];
double Buffer2[];
double Buffer3[];
double Buffer4[];
double Buffer5[];
double Buffer6[];
double Buffer7[];

extern int barLimit=2000;
extern string n1="Mode 0=show all, 1=show this pair only, 2=aggregate this pair";
extern int displayMode=2;
extern bool IgnoreWicks=true;
extern bool continuousMode=true;
extern int continuousModeHours=24;
extern string n2="Mode 0=show all, 1=show this pair only, 2=aggregate this pair";
extern bool ZeroCrossAlerts=true;

#define NONE 0
#define LONG 1
#define SHORT 2
#define WAIT 3
#define OK 4

int      secondInDay = 86400;
int      secondInHour = 3600;
int      secondInMinute = 60;
datetime AlertBar;

string Majors[]  = {"USD","EUR","GBP","JPY","CHF","CAD","NZD","AUD"};            

string Symbols[] = {"EURUSD", "GBPUSD", "USDJPY", "USDCHF", "USDCAD", "AUDUSD", "NZDUSD",
                    "EURGBP", "EURJPY", "EURCHF", "EURCAD", "EURAUD", "EURNZD",
                    "GBPJPY", "GBPCHF", "GBPCAD", "GBPAUD", "GBPNZD",
                    "AUDJPY", "AUDCHF", "AUDCAD", "AUDNZD",
                    "CHFJPY", "CADJPY", "NZDJPY",
                    "USDSGD"};          

  
int init()
{
   AlertBar = NULL;
   if (continuousModeHours*PERIOD_H1/Period() < 0) return;

   //,getCurrencyColor(Majors[0])
   
   SetIndexStyle(0, DRAW_LINE,0,1);
   SetIndexBuffer(0, Buffer0);
   SetIndexEmptyValue(0,EMPTY_VALUE);
   
   if (displayMode!=2)
      SetIndexLabel(0,Majors[0]);
   else
      SetIndexLabel(0,"Aggregate");
   
   if (displayMode!=2)
      SetIndexStyle(1, DRAW_LINE,0,1);
   else    
   {
      SetIndexStyle(1, DRAW_ARROW,0,1);
      SetIndexArrow(1, 233);
   }               
   SetIndexBuffer(1, Buffer1);
   SetIndexEmptyValue(1,EMPTY_VALUE);
   SetIndexLabel(1,Majors[1]);
   if (displayMode!=2)
      SetIndexStyle(2, DRAW_LINE,0,1);
   else   
   { 
      SetIndexStyle(2, DRAW_ARROW,0,1);
      SetIndexArrow(2, 234);
   }         
   SetIndexBuffer(2, Buffer2);
   SetIndexEmptyValue(2,EMPTY_VALUE);
   SetIndexLabel(2,Majors[2]);

   SetIndexStyle(3, DRAW_LINE,0,1);
   SetIndexBuffer(3, Buffer3);
   SetIndexEmptyValue(3,EMPTY_VALUE);
   SetIndexLabel(3,Majors[3]);

   SetIndexStyle(4, DRAW_LINE,0,1);
   SetIndexBuffer(4, Buffer4);
   SetIndexEmptyValue(4,EMPTY_VALUE);
   SetIndexLabel(4,Majors[4]);
   SetIndexStyle(5, DRAW_LINE,0,1);
   SetIndexBuffer(5, Buffer5);
   SetIndexEmptyValue(5,EMPTY_VALUE);
   SetIndexLabel(5,Majors[5]);
   SetIndexStyle(6, DRAW_LINE,0,1);
   SetIndexBuffer(6, Buffer6);
   SetIndexEmptyValue(6,EMPTY_VALUE);
   SetIndexLabel(6,Majors[6]);
   SetIndexStyle(7, DRAW_LINE,0,1);
   SetIndexBuffer(7, Buffer7);
   SetIndexEmptyValue(7,EMPTY_VALUE);
   SetIndexLabel(7,Majors[7]);
   return(0);
}

int deinit()
{
   return(0);
}
     
int start()
{  
   int limit;
   int counted_bars=IndicatorCounted();
   //---- check for possible errors
   if(counted_bars<0) return(-1);
   //---- last counted bar will be recounted
   if(counted_bars>0) counted_bars--;

   limit=Bars-counted_bars;
   if (barLimit!=0 && limit>barLimit) limit=barLimit;
   
   for(int x = limit; x >= 0; x--) 
   {
      double aggregate1, aggregate2;
      for(int c=0; c<ArraySize(Majors); c++)
      {
         if (displayMode==2 && (Majors[c] == StringSubstr(Symbol(), 0, 3) || Majors[c] == StringSubstr(Symbol(), 3, 3)) )
         {
            if (Majors[c] == StringSubstr(Symbol(), 0, 3))
               aggregate1=getStrength(Majors[c], x);
            else
               aggregate2=getStrength(Majors[c], x);
               
         }
         else if (displayMode==0 || (Majors[c] == StringSubstr(Symbol(), 0, 3) || Majors[c] == StringSubstr(Symbol(), 3, 3)) )
         {
            switch(c)
            {
               case 0: Buffer0[x] = getStrength(Majors[c], x); break;
               case 1: Buffer1[x] = getStrength(Majors[c], x); break;
               case 2: Buffer2[x] = getStrength(Majors[c], x); break;
               case 3: Buffer3[x] = getStrength(Majors[c], x); break;
               case 4: Buffer4[x] = getStrength(Majors[c], x); break;
               case 5: Buffer5[x] = getStrength(Majors[c], x); break;
               case 6: Buffer6[x] = getStrength(Majors[c], x); break;
               case 7: Buffer7[x] = getStrength(Majors[c], x); break;                                                                                    
            }   
         }
      }
      if (displayMode==2)
         Buffer0[x] = aggregate1-aggregate2;
         
      if (ZeroCrossAlerts && displayMode==2 && x>0)
      {
         if (Buffer0[x] >0 && Buffer0[x+1] <=0)
         {
            Buffer1[x]=-10;
         }   
         else if (Buffer0[x] <0 && Buffer0[x+1] >=0)
         {
            Buffer2[x]=10;
         }   

        if (AlertBar != Time[0] && x==0)
        {
            AlertBar = Time[0];
            int Type=NONE;
            if (Buffer0[1] >0 && Buffer0[2] <=0)
            {
               Type=LONG;
            }   
            else if (Buffer0[1] <0 && Buffer0[2] >=0)
            {
               Type=SHORT;
            }       
            if (Type!=NONE)
               Alert("Powerline: " + TimeToStr(Time[0],TIME_MINUTES) + " " + Symbol() + " " +  getTypeString(Type));
         }   
      }
   }
   return(0);
}

double getStrength(string major, int shift) 
{
   if ((Bars-(continuousModeHours*PERIOD_H1/Period()))<shift) return(EMPTY_VALUE);
   
   int index;
   double HiLo;
   double ld_28;
   double returnValue = 0;
    
   int cnt = 0;
   for (int i = 0; i < ArraySize(Symbols); i++) 
   {
      index = 0;

      if (symbolExists(Symbols[i]))
      {
         if (major == StringSubstr(Symbols[i], 0, 3) || major == StringSubstr(Symbols[i], 3, 3)) 
         {
            int count;
            if (continuousMode)
            {
               count = continuousModeHours*PERIOD_H1/Period();
            }
            else
            {
               int tShift = iBarShift(Symbol(), PERIOD_D1, iTime(Symbol(),Period(),shift),false);
               count = iBarShift(Symbol(), Period(), iTime(Symbol(),PERIOD_D1,tShift),true)-shift;
//               Alert(shift + " " + (count-shift) + " " + TimeToStr(iTime(Symbol(),Period(),shift),TIME_DATE) + " " + TimeToStr(iTime(Symbol(),Period(),shift),TIME_MINUTES) + " " + TimeToStr(iTime(Symbol(),PERIOD_D1,tShift),TIME_DATE) + " " + TimeToStr(iTime(Symbol(),PERIOD_D1,tShift),TIME_MINUTES));
            }

            double high;
            double low;         

            if (IgnoreWicks)
            {
               high = GreaterOfTheTwo(iHigh(Symbols[i],Period(),iHighest(Symbols[i],Period(),MODE_CLOSE,count,shift)), iHigh(Symbols[i],Period(),iHighest(Symbols[i],Period(),MODE_OPEN,count,shift)));
               low = LesserOfTheTwo(iLow(Symbols[i],Period(),iLowest(Symbols[i],Period(),MODE_CLOSE,count,shift)), iLow(Symbols[i],Period(),iLowest(Symbols[i],Period(),MODE_OPEN,count,shift)));         
            }
            else
            {
               high = iHigh(Symbols[i],Period(),iHighest(Symbols[i],Period(),MODE_HIGH,count,shift));
               low = iLow(Symbols[i],Period(),iLowest(Symbols[i],Period(),MODE_LOW,count,shift));         
            }

            HiLo = (high - low) * MarketInfo(Symbols[i], MODE_POINT);
            if (HiLo != 0.0) 
            {
            
               double close =iClose(Symbols[i],Period(),shift);
               if (close < low) close =low;
               ld_28 = 100.0 * ((iClose(Symbols[i],Period(),shift) - low) / HiLo * MarketInfo(Symbols[i], MODE_POINT));
               /*
               if (ld_28 >=  0.0) index = 1;
               if (ld_28 > 10.0) index = 2;
               if (ld_28 > 25.0) index = 3;
               if (ld_28 > 40.0) index = 4;
               if (ld_28 > 50.0) index = 5;
               if (ld_28 > 60.0) index = 6;
               if (ld_28 > 75.0) index = 7;
               if (ld_28 > 90.0) index = 8;
               if (ld_28 > 97.0) index = 9;
               */
               cnt++;
               //if (major == StringSubstr(Symbols[i], 3, 3)) index = 9 - index;
               if (major == StringSubstr(Symbols[i], 3, 3)) ld_28=100-ld_28;
               //returnValue += index;
               returnValue += ld_28;
            }
         }
      }
   }
   returnValue /= cnt;
   return (returnValue);  
}
int getCurrencyColor(string bufferSymbol)
{
   return(CLR_NONE);
   if (bufferSymbol == "USD")
      return (Green);
   if (bufferSymbol == "EUR")
      return (Aqua);
   if (bufferSymbol == "CHF")
      return (Blue);
   if (bufferSymbol == "JPY")
      return (Gray);
   if (bufferSymbol == "AUD")
      return (DarkOrange);
   if (bufferSymbol == "CAD")
      return (Purple);
   if (bufferSymbol == "NZD")
      return (Teal);
   if (bufferSymbol == "GBP")
      return (Red);
}
bool symbolExists(string symbol)
{
   //return(true);
   double bid=MarketInfo(symbol,MODE_BID);
   return(!(GetLastError()==4106)); // ERR_UNKNOWN_SYMBOL
}


//--------------------------------------------------------------------------------------
double LesserOfTheTwo(double first, double second)
//--------------------------------------------------------------------------------------
{
   if (first <= second)
      return(first);
   else
      return(second);   
}

//--------------------------------------------------------------------------------------
double GreaterOfTheTwo(double first, double second)
//--------------------------------------------------------------------------------------
{
   if (first >= second)
      return(first);
   else
      return(second);   
}
string getTypeString(int Type)
{
   if (Type==LONG)
      return("LONG");
   else if (Type==SHORT)   
      return("SHORT");   
   else if (Type==NONE)   
      return("NONE");   
   else if (Type==WAIT)   
      return("WAIT");   
   else if (Type==OK)   
      return("OK");   
}

