//+------------------------------------------------------------------+
//|                              ALERTonOpenClose Indicator v1.1.mq4 |
//|                              mod. version of AlertCloseOrder.mq4 |
//|                               Copyright © 2010, Vladimir Hlystov |
//|                                         http://cmillion.narod.ru |
//+------------------------------------------------------------------+
//////////////////////////////////////////////////////////////////////
// !!! YOU MUST COMPILE THIS EA WITH THE BUILD 509 COMPILER, download the metaeditor for build 509 at http://www.forexfactory.com/showthread.php?t=470340 !!!
//////////////////////////////////////////////////////////////////////
//download source mod. version: http://www.forexfactory.com/showthread.php?p=7440130#post7440130
//download previous (original) version: http://www.forexfactory.com/showthread.php?p=7439381#post7439381
#property copyright "Copyright © 2010, Vladimir Hlystov // mod. fxdaytrader, http://ForexBaron.net"
#property link      "http://cmillion.narod.ru"
#property indicator_chart_window

extern bool FilterBySymbol      = FALSE;
extern bool FilterByMagicNumber = FALSE;
extern int  MagicNumber         = 0;//0:manual trades

extern bool ConsiderSwapCommissionAlso   = TRUE;
extern string uaslhi="allow slippage pips for sl/tp detection?";
extern bool UseAdvancedSLTPDetection = TRUE;
extern double SLTPbufferpips         = 3.0;
double pips2dbl;
int Multiplier;
extern bool IgnorePendingOrders    = TRUE;
extern bool AlertOnOpen            = TRUE;
extern bool AlertOnClose           = TRUE;
extern string amhi="alert methods: ";
extern bool PopupAlerts            = TRUE;
extern bool EmailAlerts            = FALSE;
extern bool PushNotificationAlerts = FALSE;
extern bool SoundAlerts            = FALSE;
extern string SoundFileNameClose   = "alert.wav";
extern string SoundFileNameOpen    = "alert2.wav";
extern bool ShowComment            = TRUE;
int Orders,orderstotal;

//+------------------------------------------------------------------+
int init() {
}

int deinit() {
 if (ShowComment) Comment("");
}

int start()
  {
   if (ShowComment) Comment("ALERTonOpenClose Indicator v1.1, © 2010, Vladimir Hlystov // mod. fxdaytrader *** http://ForexBaron.net"+"\n"+
        "ConsiderSwapCommissionAlso="+bool2txt(ConsiderSwapCommissionAlso)+", UseAdvancedSLTPDetection(pips="+DoubleToStr(SLTPbufferpips,2)+")="+bool2txt(UseAdvancedSLTPDetection)+"\n"+
        "AlertOnOpen="+bool2txt(AlertOnOpen)+", AlertOnClose="+bool2txt(AlertOnClose)+", PopupAlerts="+bool2txt(PopupAlerts)+", EmailAlerts="+bool2txt(EmailAlerts)+", PushNotificationAlerts="+bool2txt(PushNotificationAlerts)+", SoundAlerts="+bool2txt(SoundAlerts));
   
   CountOrders(Symbol(),MagicNumber);
   //replaced OrdersTotal() with orderstotal
   if (AlertOnClose) if (Orders>orderstotal) AlertOrderClose();
   if (AlertOnOpen)  if (Orders<orderstotal) AlertOrderOpen();
   Orders=orderstotal;
   return(0);
  }
//+------------------------------------------------------------------+
void AlertOrderClose() {
   string txt="not sl/tp";
   double OCP;
   int i=OrdersHistoryTotal()-1;
   if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==true)
   {                                     
      if (IgnorePendingOrders && OrderType()>OP_SELL) return;
      BrokerDigitAdjust(OrderSymbol());
      OCP=OrderClosePrice();
      if (!UseAdvancedSLTPDetection) {
       if (OCP==OrderStopLoss()  ) txt="SL";
       if (OCP==OrderTakeProfit()) txt="TP";
      }
      else if (UseAdvancedSLTPDetection) {
       if (OrderWasCloseAtPrice(OCP,OrderStopLoss())) txt="SL";
       if (OrderWasCloseAtPrice(OCP,OrderTakeProfit())) txt="TP";
      }
        double orderprofitpips = MathAbs(OrderOpenPrice()-OrderClosePrice())/pips2dbl;
        double orderprofit;
        if (ConsiderSwapCommissionAlso) orderprofit = OrderProfit()+OrderSwap()+OrderCommission();
         else if (!ConsiderSwapCommissionAlso) orderprofit = OrderProfit();
        doAlerts(ordertype2txt(OrderType())+" Order ticket "+OrderTicket()+", symbol: "+OrderSymbol()+", close in "+txt+" "+DoubleToStr(OCP,MarketInfo(OrderSymbol(),MODE_DIGITS))+" profit: "+DoubleToStr(orderprofit,2)+" "+AccountCurrency()+" (pips: "+DoubleToStr(orderprofitpips,2)+"), servertime: "+TimeToStr(OrderCloseTime()),SoundFileNameClose);
      //Alert("Order N "+OrderTicket()+", symbol: "+OrderSymbol()+", close in "+txt+" "+DoubleToStr(OCP,Digits)+" profit: ",DoubleToStr(OrderProfit()+OrderSwap()+OrderCommission(),2)+" "+AccountCurrency());
   }//if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==true)
}

void AlertOrderOpen() {
   string txt="not sl/tp";
   double OCP;
   int i=OrdersTotal()-1;
   if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true)
   {                                     
     if (IgnorePendingOrders && OrderType()>OP_SELL) return;
     doAlerts(ordertype2txt(OrderType())+" Order ticket "+OrderTicket()+", symbol: "+OrderSymbol()+", was opened at "+DoubleToStr(OrderOpenPrice(),MarketInfo(OrderSymbol(),MODE_DIGITS))+", servertime: "+TimeToStr(OrderOpenTime()),SoundFileNameOpen);
   }//if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==true)
}
//+------------------------------------------------------------------+

void doAlerts(string msg,string SoundFile) {
        msg="ALERTonClose mod.: "+msg;
 string emailsubject="MT4 alert on acc. "+AccountNumber()+", "+WindowExpertName()+" - Alert on "+Symbol()+", period "+TFtoStr(Period());
  if (PopupAlerts) Alert(msg);
  if (EmailAlerts) SendMail(emailsubject,msg);
  if (PushNotificationAlerts) SendNotification(msg);
  if (SoundAlerts) PlaySound(SoundFile);
}//void doAlerts(string msg,string SoundFile) {

string TFtoStr(int period) {
 if (period==0) period=Period();
 switch(period) {
  case 1     : return("M1");  break;
  case 5     : return("M5");  break;
  case 15    : return("M15"); break;
  case 30    : return("M30"); break;
  case 60    : return("H1");  break;
  case 240   : return("H4");  break;
  case 1440  : return("D1");  break;
  case 10080 : return("W1");  break;
  case 43200 : return("MN1"); break;
  default    : return(DoubleToStr(period,0));
 }
 return("UNKNOWN");
}//string TFtoStr(int period) {

string ordertype2txt(int type) {
 if (type==OP_BUY)  return("BUY");
 if (type==OP_SELL) return("SELL");
 if (type==OP_BUYSTOP) return("BUYSTOP");
 if (type==OP_SELLSTOP) return("SELLSTOP");
 if (type==OP_BUYLIMIT) return("BUYLIMIT");
 if (type==OP_SELLLIMIT) return("SELLLIMIT");
 return("UNKNOWN");
}

void BrokerDigitAdjust(string symbol) {
 Multiplier = 1;
 if (MarketInfo(symbol,MODE_DIGITS) == 3 || MarketInfo(symbol,MODE_DIGITS) == 5) Multiplier = 10;
 if (MarketInfo(symbol,MODE_DIGITS) == 6) Multiplier = 100;   
 if (MarketInfo(symbol,MODE_DIGITS) == 7) Multiplier = 1000;
 pips2dbl = Multiplier*MarketInfo(symbol,MODE_POINT);
}

bool OrderWasCloseAtPrice(double closeprice,double sltpprice) {
 if (MathAbs(closeprice-sltpprice)>(SLTPbufferpips*pips2dbl)) return(false);
 return(true);
}

string bool2txt(int lbool) {
 if (lbool==true) return("yes");
 if (lbool==false) return("no");
 return("%");
}


void CountOrders(string symbol,int magicnumber) {
 orderstotal=0;
 for (int cnt=OrdersTotal()-1; cnt>=0; cnt--) {
  if (!OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES)) continue;
  if (FilterBySymbol && OrderSymbol()!=symbol) continue;
  if (FilterByMagicNumber && OrderMagicNumber()!=magicnumber) continue;
  if (IgnorePendingOrders && OrderType()>OP_SELL) continue;
  if (OrderType()>OP_SELLSTOP) continue;//no funding/withdrawel operations
   {
    orderstotal++;
   }
  }
}

