#property copyright "Copyright © 2008, Orest@ForexFactory"
#property link      ""

#include <WinUser32.mqh>


#property indicator_separate_window
#property indicator_buffers 4
#property indicator_color1 Yellow
#property indicator_width1 2
#property indicator_color2 DodgerBlue
#property indicator_width2 2
#property indicator_color3 Red
#property indicator_width3 2
#property indicator_color4 Green
#property indicator_width4 2

#property indicator_level1 0

#property indicator_minimum -2.0
#property indicator_maximum 2.0


extern string Alerts = "----- List of Alerts -----";

extern bool Popup_Alerts_On =true;
extern bool Audio_Alerts_On = false;
extern bool EMail_Alerts_On = false;

extern string Buy_currency_pairs = "----- List of Buy currency pairs -----";
extern string Buy_pair_1 = "USDJPY";
extern string Buy_pair_2 = "EURUSD";
extern string Buy_pair_3 = "EURCHF";
extern string Buy_pair_4 = "GBPJPY";
extern string Buy_pair_5 = "USDCAD";
extern string Buy_pair_6 = "CADJPY";
extern string Buy_pair_7 = "AUDUSD";

extern string Sell_currency_pairs = "----- List of Sell currency pairs -----";
extern string Sell_pair_1 = "EURJPY";
extern string Sell_pair_2 = "GBPUSD";
extern string Sell_pair_3 = "EURGBP";
extern string Sell_pair_4 = "GBPCHF";
extern string Sell_pair_5 = "CHFJPY";
extern string Sell_pair_6 = "USDCHF";
extern string Sell_pair_7 = "AUDJPY";

double GBPUSDm, EURGBPm, GBPJPYm, USDCHFm, NZDUSDm, AUDJPYm, EURJPYm;
double EURUSDm, USDJPYm, AUDUSDm, NZDJPYm, GBPCHFm, CHFJPYm, EURCHFm;

int blue, red;

double GBPUSDm_now,EURGBPm_now,GBPJPYm_now,USDCHFm_now,NZDUSDm_now,AUDJPYm_now,EURJPYm_now;
double EURUSDm_now,USDJPYm_now,AUDUSDm_now,NZDJPYm_now,GBPCHFm_now,CHFJPYm_now,EURCHFm_now;

double GBPUSDm_pips, EURGBPm_pips, GBPJPYm_pips, USDCHFm_pips, NZDUSDm_pips,
       AUDJPYm_pips, EURJPYm_pips;

double EURUSDm_pips, USDJPYm_pips,AUDUSDm_pips,NZDJPYm_pips,GBPCHFm_pips,
       CHFJPYm_pips,EURCHFm_pips;

double Signal_weekly[];
double Signal_daily[];
double Signal_4h[];
double Signal_1h[];

double iLast_Signal_weekly;
double iLast_Signal_daily;
double iLast_Signal_4h;
double iLast_Signal_1h;

bool DisplayLegend = true;
int Legend.X = 700;
int Legend.Y  = 0;

string objNames[0];
int array_count = 0;

int k;
string short_name;

bool bAlertSounded;

int init()
{
   SetIndexStyle(0, DRAW_HISTOGRAM);
   SetIndexBuffer(0, Signal_weekly);
   SetIndexStyle(1, DRAW_HISTOGRAM);
   SetIndexBuffer(1, Signal_daily);
   SetIndexStyle(2, DRAW_HISTOGRAM);
   SetIndexBuffer(2, Signal_4h);
   SetIndexStyle(3, DRAW_HISTOGRAM);
   SetIndexBuffer(3, Signal_1h);
   
   iLast_Signal_weekly = 0.0;
   iLast_Signal_daily  = 0.0;
   iLast_Signal_4h     = 0.0;
   iLast_Signal_1h     = 0.0;
   
   bAlertSounded = false;
   
   short_name="T101_Anchor_Signals_Orest_v1.01";
   IndicatorShortName(short_name);

   ArrayResize(objNames, 1000);
 
   return(0);
}

//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
  int items=ArrayRange(objNames,0)-1; //Print(items, " objects to delete");
  int i = 0;
//---- 
   //make sure to delete all objects created when unloading this indicator
   //this routine cycles thru the stored list of unique vertical line names 
   //and deletes the objects with that name
   for (i=items; i>=0;i--)
   {
      //all valid object names will have at least one character, so skip empty strings
      if(objNames[i] != "")
      {
         //Print("Deleted: ",objNames[i]);
         ObjectDelete(objNames[i]);
      }      
   }

    if (ObjectFind("_Legend1") != -1)
      ObjectDelete("_Legend1");

    if (ObjectFind("_Legend2") != -1)
      ObjectDelete("_Legend2");

    if (ObjectFind("_Legend3") != -1)
      ObjectDelete("_Legend3");

    if (ObjectFind("_Legend4") != -1)
      ObjectDelete("_Legend4");
   
//----
   return(0);
  }


int start()
{

int companion =WindowFind(short_name);

  int FontSz =7;
  int XDist = 0;
  XDist = Legend.X;
  int YDist = Legend.Y;
  
  if (DisplayLegend)
  {
    string name ="_Legend1";
 
    if (ObjectFind(name) == -1)
      ObjectCreate(name, OBJ_LABEL, companion, 0, 0);
 
    ObjectSet(name, OBJPROP_XDISTANCE, XDist);
    ObjectSet(name, OBJPROP_YDISTANCE, YDist);
    ObjectSetText(name, "nnn", FontSz, "Wingdings", indicator_color1);

    name = "_Legend2";

    if (ObjectFind(name) == -1)
      ObjectCreate(name, OBJ_LABEL, companion, 0, 0);
   
    ObjectSet(name, OBJPROP_XDISTANCE,XDist+25);
    ObjectSet(name, OBJPROP_YDISTANCE, YDist);
    ObjectSetText(name, "- Weekly", FontSz, "Arial",White);
    //------
 
    name ="_Legend3";
 
    if (ObjectFind(name) == -1)
      ObjectCreate(name, OBJ_LABEL, companion, 0, 0);
 
    ObjectSet(name, OBJPROP_XDISTANCE, XDist);
    ObjectSet(name, OBJPROP_YDISTANCE, YDist+10);
    ObjectSetText(name, "nnn", FontSz, "Wingdings", indicator_color2);

    name = "_Legend4";

    if (ObjectFind(name) == -1)
      ObjectCreate(name, OBJ_LABEL, companion, 0, 0);
   
    ObjectSet(name, OBJPROP_XDISTANCE,XDist+25);
    ObjectSet(name, OBJPROP_YDISTANCE, YDist+10);
    ObjectSetText(name, "- Daily", FontSz, "Arial",White);    
   
    name ="_Legend5";
 
    if (ObjectFind(name) == -1)
      ObjectCreate(name, OBJ_LABEL, companion, 0, 0);
 
    ObjectSet(name, OBJPROP_XDISTANCE, XDist);
    ObjectSet(name, OBJPROP_YDISTANCE, YDist+20);
    ObjectSetText(name, "nnn", FontSz, "Wingdings", indicator_color3);

    name = "_Legend6";

    if (ObjectFind(name) == -1)
      ObjectCreate(name, OBJ_LABEL, companion, 0, 0);
   
    ObjectSet(name, OBJPROP_XDISTANCE,XDist+25);
    ObjectSet(name, OBJPROP_YDISTANCE, YDist+20);
    ObjectSetText(name, "- 4 hours", FontSz, "Arial",White);       
   }

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;
//---- macd counted in the 1-st buffer

//=limit = 100;

  //initialize all elements of the array to empty string
   for (int i=ArrayRange(objNames,0); i>=0;i--)
   {
      objNames[i] = "";
   }

   for (k = 0; k<limit; k ++)
   {
      if((TimeDayOfWeek(Time[k])==1 && TimeHour(Time[k]) == 0 && TimeMinute(Time[k]) == 0))
      {
         if(ObjectFind(TimeToStr(Time[k]))==-1)
         {
            if(!ObjectCreate(TimeToStr(Time[k]), OBJ_VLINE, companion, Time[k], 0))
            {
               return(0);
            }else {

               //stores the unique name of each vertical line object as it is created so we can delete it when indicator is unloaded
               objNames[array_count] = TimeToStr(Time[k]);
               ObjectSet(TimeToStr(Time[k]), OBJPROP_STYLE, STYLE_DOT);
               ObjectSet(TimeToStr(Time[k]), OBJPROP_COLOR, DodgerBlue);
                
               //Print("Object created: ", objNames[array_count]); 
               
               //keep track of how many items are in the array
               array_count++;       
            }
         }
         else 
            {
            //Print("object ", TimeToStr(Time[pos]), " already exists!");
            } 
         }


      double result; 
      
      ////////////////////////
      run_statistics_longs(1,k);  
      run_statistics_shorts(1,k); 
      result = analyze_trades(1);

      Signal_weekly[k] = 0.0;
      if (result != 0 && iLast_Signal_weekly != result)
      {
         Signal_weekly[k] = result;
         iLast_Signal_weekly = result;
      }

      result = 0;
      // -----------------
      run_statistics_longs(2,k);  
      run_statistics_shorts(2,k); 
      result = analyze_trades(2);

      Signal_daily[k] = 0;
      if (result != 0 && iLast_Signal_daily != result)
      {
         Signal_daily[k] = result;
         iLast_Signal_daily = result;
      }

      result = 0;

      // -----------------
      run_statistics_longs(3,k);  
      run_statistics_shorts(3,k); 
      result = analyze_trades(3);

      Signal_4h[k] = 0;
      if (result != 0 && iLast_Signal_4h != result)
      {
         Signal_4h[k] = result;
         iLast_Signal_4h = result;
      }

      result = 0;
      // -----------------
      /*
      run_statistics_longs(4,k);  
      run_statistics_shorts(4,k); 
      result = analyze_trades(4);
      
      Signal_1h[k] = 0;
      if (result != 0 && iLast_Signal_1h != result)
      {
         Signal_1h[k] = result;
         iLast_Signal_1h = result;
      }
      */
   }

/*  ALERT CODE  */
/*--------------*/

      if ((Signal_weekly[0]!=0 || Signal_daily[0]!=0 || Signal_4h[0]!=0) && bAlertSounded == false)
      {
         string message;
         if (Signal_weekly[0]>0)
             message ="Buy Weekly Signal!";
         else if (Signal_weekly[0]<0)
            message ="Sell Weekly Signal!";
         else if (Signal_daily[0]>0)
            message ="Buy Daily Signal!";      
         else if (Signal_daily[0]<0)
            message ="Sell Daily Signal!";
         else if (Signal_4h[0]>0)
            message ="Buy 4h Signal!";
         else if (Signal_4h[0]<0)
            message ="Sell 4h Signal!";
 
     
         if (Popup_Alerts_On) {
              Alert(Symbol(), ", ", Period()," - ", message);

         }     
         if (Audio_Alerts_On == true)
              PlaySound("Alert.wav");
         if (EMail_Alerts_On == true)
             SendMail("Alert",message);
          bAlertSounded = true;
     }
     else
      bAlertSounded = false;

   return(0);
}

/////////////////////////////////////////////////////

void run_statistics_longs(int week_back, int k)
{
int bars_back = 0;

GBPUSDm =0; EURGBPm =0; GBPJPYm=0; USDCHFm=0; NZDUSDm=0; AUDJPYm=0; EURJPYm=0;

GBPUSDm_now =0; EURGBPm_now = 0; GBPJPYm_now =0; USDCHFm_now =0; NZDUSDm_now = 0; AUDJPYm_now=0;EURJPYm_now=0;

GBPUSDm_pips = 0; EURGBPm_pips=0; GBPJPYm_pips = 0; USDCHFm_pips =0; NZDUSDm_pips=0;
AUDJPYm_pips = 0; EURJPYm_pips=0;


 if (week_back==1) // this week
      bars_back = GetWeekOpen(k);
 else if (week_back==2) // this day
      bars_back = GetDayOpen(k);
 else if (week_back==3) // 4 hours ago
      bars_back = Get4HoursAgo(k); 
else if (week_back==4) // hour ago
      bars_back = GetHourAgo(k);

if ((Time[k] - Time[bars_back]) <= 2*60*60 || bars_back==-1)
   return;

//if (week_back == 4)
//    Print(k+","+bars_back+","+(Time[k] - Time[bars_back]));
 
if (StringLen(Buy_pair_1)>0  && iOpen(Buy_pair_1, 0, bars_back)!=0)
{
   GBPUSDm      = iOpen(Buy_pair_1, 0, bars_back);
   GBPUSDm_now  = iOpen(Buy_pair_1, 0, k);
   GBPUSDm_pips = (GBPUSDm_now-GBPUSDm)/dPoint(Buy_pair_1);
}

if (StringLen(Buy_pair_2)>0 && iOpen(Buy_pair_2, 0, bars_back)!=0)
{
   EURGBPm= iOpen(Buy_pair_2, 0, bars_back);
   EURGBPm_now= iOpen(Buy_pair_2, 0, k);
   EURGBPm_pips = (EURGBPm_now-EURGBPm)/dPoint(Buy_pair_2);

}

if (StringLen(Buy_pair_3)>0 && iOpen(Buy_pair_3, 0, bars_back)!=0)
{
   GBPJPYm= iOpen(Buy_pair_3, 0, bars_back);
   GBPJPYm_now= iOpen(Buy_pair_3, 0, k);
   GBPJPYm_pips = (GBPJPYm_now-GBPJPYm)/dPoint(Buy_pair_3);
}

if (StringLen(Buy_pair_4)>0 && iOpen(Buy_pair_4, 0, bars_back)!=0)
{
   USDCHFm= iOpen(Buy_pair_4, 0, bars_back);
   USDCHFm_now= iOpen(Buy_pair_4, 0, k);
   USDCHFm_pips = (USDCHFm_now-USDCHFm)/dPoint(Buy_pair_4);
}

if (StringLen(Buy_pair_5)>0 && iOpen(Buy_pair_5, 0, bars_back)!=0)
{
   NZDUSDm= iOpen(Buy_pair_5, 0, bars_back);
   NZDUSDm_now= iOpen(Buy_pair_5, 0, k);
   NZDUSDm_pips = (NZDUSDm_now-NZDUSDm)/dPoint(Buy_pair_5);
}

if (StringLen(Buy_pair_6)>0 && iOpen(Buy_pair_6, 0, bars_back)!=0)
{
   AUDJPYm= iOpen(Buy_pair_6, 0, bars_back);
   AUDJPYm_now= iOpen(Buy_pair_6, 0, k);
   AUDJPYm_pips = (AUDJPYm_now-AUDJPYm)/dPoint(Buy_pair_6);
}

if (StringLen(Buy_pair_7)>0 && iOpen(Buy_pair_7, 0, bars_back)!=0)
{
   EURJPYm= iOpen(Buy_pair_7, 0, bars_back);
   EURJPYm_now= iOpen(Buy_pair_7, 0, k);
   EURJPYm_pips = (EURJPYm_now-EURJPYm)/dPoint(Buy_pair_7);
}

   return;
}


void run_statistics_shorts(int week_back, int k)
{

int bars_back = 0;

EURUSDm=0; USDJPYm=0; AUDUSDm=0; NZDJPYm=0; GBPCHFm=0; CHFJPYm=0; EURCHFm=0;
EURUSDm_now=0;USDJPYm_now=0;AUDUSDm_now=0;NZDJPYm_now=0;GBPCHFm_now=0;CHFJPYm_now=0;EURCHFm_now=0;

EURUSDm_pips=0; USDJPYm_pips=0;AUDUSDm_pips=0;NZDJPYm_pips=0; GBPCHFm_pips=0;
CHFJPYm_pips=0;EURCHFm_pips=0;

 if (week_back==1) // this week
      bars_back = GetWeekOpen(k);
 else if (week_back==2) // this day
      bars_back = GetDayOpen(k);
 else if (week_back==3) // 4 hours ago
      bars_back = Get4HoursAgo(k); 
 else if (week_back==4) // hour ago
      bars_back = GetHourAgo(k);


if ((Time[k] - Time[bars_back]) <= 2*60*60 || bars_back==-1)
   return;

if (StringLen(Sell_pair_1)>0 && iOpen(Sell_pair_1, 0, bars_back)!=0)
{
   EURUSDm      = iOpen(Sell_pair_1, 0, bars_back);
   EURUSDm_now  = iOpen(Sell_pair_1, 0, k);
   EURUSDm_pips = (EURUSDm-EURUSDm_now)/dPoint(Sell_pair_1);
}

if (StringLen(Sell_pair_2)>0 && iOpen(Sell_pair_2, 0, bars_back)!=0)
{
   USDJPYm= iOpen(Sell_pair_2, 0, bars_back);
   USDJPYm_now= iOpen(Sell_pair_2, 0, k);
   USDJPYm_pips = (USDJPYm-USDJPYm_now)/dPoint(Sell_pair_2);
}

if (StringLen(Sell_pair_3)>0 && iOpen(Sell_pair_3, 0, bars_back)!=0)
{
   AUDUSDm= iOpen(Sell_pair_3, 0, bars_back);
   AUDUSDm_now= iOpen(Sell_pair_3, 0, k);
   AUDUSDm_pips = (AUDUSDm-AUDUSDm_now)/dPoint(Sell_pair_3);
}

if (StringLen(Sell_pair_4)>0 && iOpen(Sell_pair_4, 0, bars_back)!=0)
{
   NZDJPYm= iOpen(Sell_pair_4, 0, bars_back);
   NZDJPYm_now= iOpen(Sell_pair_4, 0, k);
   NZDJPYm_pips = (NZDJPYm-NZDJPYm_now)/dPoint(Sell_pair_4);
}

if (StringLen(Sell_pair_5)>0 && iOpen(Sell_pair_5, 0, bars_back)!=0)
{
   GBPCHFm= iOpen(Sell_pair_5, 0, bars_back);
   GBPCHFm_now= iOpen(Sell_pair_5, 0, k);
   GBPCHFm_pips = (GBPCHFm-GBPCHFm_now)/dPoint(Sell_pair_5);
}

if (StringLen(Sell_pair_6)>0 && iOpen(Sell_pair_6, 0, bars_back)!=0)
{
   CHFJPYm= iOpen(Sell_pair_6, 0, bars_back);
   CHFJPYm_now= iOpen(Sell_pair_6, 0, k);
   CHFJPYm_pips = (CHFJPYm-CHFJPYm_now)/dPoint(Sell_pair_6);

}

if (StringLen(Sell_pair_7)>0 && iOpen(Sell_pair_7, 0, bars_back)!=0)
{
   EURCHFm= iOpen(Sell_pair_7, 0, bars_back);
   EURCHFm_now= iOpen(Sell_pair_7, 0, k);
   EURCHFm_pips = (EURCHFm-EURCHFm_now)/dPoint(Sell_pair_7);
}
   return;
}


double analyze_trades(int week_back)
{

blue=0; red=0;                                                                                  

   color  PairsColor[14];              
   double PLArray[14];

   PLArray[0]=GBPUSDm_pips;
   PLArray[1]=EURGBPm_pips;
   PLArray[2]=GBPJPYm_pips;
   PLArray[3]=USDCHFm_pips;
   PLArray[4]=NZDUSDm_pips;
   PLArray[5]=AUDJPYm_pips;
   PLArray[6]=EURJPYm_pips;
   
   PLArray[7]=  EURUSDm_pips;
   PLArray[8]=  USDJPYm_pips;
   PLArray[9]=  AUDUSDm_pips;
   PLArray[10]= NZDJPYm_pips;
   PLArray[11]= GBPCHFm_pips;
   PLArray[12]= CHFJPYm_pips;
   PLArray[13]= EURCHFm_pips;

   PairsColor[0] = Green;
   PairsColor[1] = Green;
   PairsColor[2] = Green;
   PairsColor[3] = Green;
   PairsColor[4] = Green;
   PairsColor[5] = Green;
   PairsColor[6] = Green;

   PairsColor[7] = Red;
   PairsColor[8] = Red;
   PairsColor[9] = Red;
   PairsColor[10]= Red;
   PairsColor[11]= Red;
   PairsColor[12]= Red;
   PairsColor[13]= Red;

   int plarr_size = ArraySize(PLArray);
   
   double temp_var;
   color temp_color;
   
   for(int i=0;i < plarr_size;i++) //Hold the first element
	{
		for(int j=i+1;j<plarr_size;j++) //Hold the next element from the first element
		{
			if(PLArray[i] < PLArray[j])	//comparing first and next element
			{
				temp_var = PLArray[j];	
				PLArray[j] = PLArray[i];
				PLArray[i] = temp_var;
				
   			temp_color  = PairsColor[j];	
				PairsColor[j] = PairsColor[i];
				PairsColor[i] = temp_color;
			}
		}
	}

// here is check if 7 straight buys/sells

   bool all_straight_buy  = false;
   bool all_straight_sell = false; 

   int blue_pos=0, blue_neg=0, red_pos=0, red_neg=0;
   
   for(i=0;i<=13;i++)
    { 
      if(PairsColor[i] == Green) 
       {
         blue = blue + PLArray[i];
         if (PLArray[i]>=0)
             blue_pos++;
         else
             blue_neg++;
         
         if (i>0)
         {
           if (PairsColor[0]==Green && PairsColor[i-1] == Green)
              all_straight_buy = true;
           else
              all_straight_buy = false;
         }   
       }
       
      if(PairsColor[i] == Red) 
       {
         red = red + PLArray[i];
         if (PLArray[i]>=0)
             red_pos++;
         else
             red_neg++;

         if (i>0)
         {
           if (PairsColor[0]==Red && PairsColor[i-1] == Red)
              all_straight_sell = true;
           else
              all_straight_sell = false;
         }   
       }
    }

  int trend = 0;
  all_straight_sell = false;
  all_straight_buy = false;


   if ((blue_pos > blue_neg && blue>0 && PairsColor[13] == Green) || (red_neg > red_pos && red < 0 && PairsColor[0] == Red))
       all_straight_sell = true;
   else if ((blue_neg > blue_pos && blue<0 && PairsColor[0] == Green) || (red_pos > red_neg && red > 0 && PairsColor[13] == Red))    
       all_straight_buy = true;

   if (all_straight_buy)
      trend = 2;  //"Long (all straight)" 
   else if (all_straight_sell)
      trend = -2;  //"SHORT (all straight)" 
   //else if (red > 0 && blue < 0)
   //   trend = -1;  //"SHORT (Strong)"
  // else if (blue > 0 && red < 0)
   //   trend = 1;   //"LONG (Strong)"
      
 if (week_back==1) // this week
      return(trend);
 else if (week_back==2) // this day
      return(0.7*trend);
 else if (week_back==3) // 4 hours ago
      return(0.5*trend); 
 else if (week_back==4) // hour ago
      return(0.25*trend);
}

double dPoint(string sym)
{
  double _Point = MarketInfo(sym, MODE_POINT);
  if (StringFind(sym, "JPY")>=0)
      _Point=0.01;
  
  if (_Point==0) _Point=0.0001; 
  
  return (_Point);
}

int GetWeekOpen(int shift)
{
   for (int i = shift; i < Bars; i++)
   {        
      if (TimeDayOfWeek(Time[i]) < TimeDayOfWeek(Time[i+1]))
         return(i);
   }
   return(-1);
}

int GetDayOpen(int shift)
{
      string    dailyCloseTime = "00:00";
 
      for (int i = shift; i < Bars; i++)
      {
         string candleDateString = TimeToStr(Time[i], TIME_DATE);
         datetime closeTime = StrToTime(candleDateString + " " + dailyCloseTime);
      
         if (closeTime < Time[shift] && closeTime >= Time[i])
            return(i);
      }   
   return(-1);
}

int GetHourAgo(int shift)
{
   for (int i = shift; i < Bars; i++)
   {        
      if ((Time[shift] - Time[i]) >= 60*60)
      return(i);
   }
 
   return(-1);
}

int Get4HoursAgo(int shift)
{
   for (int i = shift; i < Bars; i++)
   {        
      if ((Time[shift] - Time[i]) >= 4*60*60)
      return(i);
   }
 
   return(-1);
}

