//+------------------------------------------------------------------+
//|                                        mn Show Profit Alerts.mq5 |
//+------------------------------------------------------------------+
//download source: http://www.forexfactory.com/showthread.php?p=7403504#post7403504
//mod. fxdaytrader (thousands separator, zerocolor, calcswapcommissionalso, profitpips, alerts ...
#property copyright "Mn // mod. fxdaytrader"
#property link "http://ForexBaron.net"
#property indicator_plots 0
#property indicator_chart_window

#include <Trade\PositionInfo.mqh>

CPositionInfo  m_position;

input bool FilterBySymbol      = false;
input bool FilterByMagicNumber = false;
input int  MagicNumber         = 0;
//
input bool   CalcSwapCommissionAlso = true;//fxdaytrader
input string ThousandsSeparator = " ";
input string DecimalSeparator   = ",";
input ENUM_BASE_CORNER    mCorn = CORNER_RIGHT_LOWER;
input int    mtextSize = 18;
input int    mXDist = 306;
input int    mYDist = 99;
input color  ProfitColor = Blue, LossColor = Red, ZeroColor=SteelBlue;
input string mFont = "Arial";
input bool   ShowProfitPips       = true;
input color  PipsColor            = White;
input int    AddTomYDist          = 20;
input string PipsFont     = "Arial";
input int    PipsTextSize = 15;
double profitpips;
input string ahis = "******* ALERT SETTINGS:";
input bool   AlertAtProfitOf        = true;
input double AlertAtProfitAmount    = 1000.00;
input bool   AlertAtLossOf          = true;
input double AlertAtLossAmount      = 1000.00;
input int    AlertCandle            = 1;
input bool   PopupAlerts            = true;
input bool   EmailAlerts            = false;
input bool   PushNotificationAlerts = false;
input bool   SoundAlerts            = false;
input string SoundFileProfit        = "alert.wav";
input string SoundFileLoss          = "alert2.wav";
string SoundFileName;
int lastAlert=3;
int Multiplier;
double pips2dbl;
int mydist = mYDist;
double alertatlossammount=AlertAtLossAmount;
//+------------------------------------------------------------------+
   
int OnInit()
 {  
  if (ShowProfitPips) {
   ObjectCreate(0,"mShowProf1", OBJ_LABEL, 0, 0, 0, 0, 0);
   ObjectSetInteger(0,"mShowProf1", OBJPROP_CORNER, mCorn);
   ObjectSetInteger(0,"mShowProf1", OBJPROP_XDISTANCE, mXDist);
   ObjectSetInteger(0,"mShowProf1", OBJPROP_YDISTANCE, mydist);
   ObjectSetText("mShowProf1", " ", mtextSize, mFont, CLR_NONE);
  }
  
  if (ShowProfitPips) mydist+=AddTomYDist;
  ObjectCreate(0,"mShowProf", OBJ_LABEL, 0, 0, 0, 0, 0);
  ObjectSetInteger(0,"mShowProf", OBJPROP_CORNER, mCorn);
  ObjectSetInteger(0,"mShowProf", OBJPROP_XDISTANCE, mXDist);
  ObjectSetInteger(0,"mShowProf", OBJPROP_YDISTANCE, mydist);
  ObjectSetText("mShowProf", " ", mtextSize, mFont, CLR_NONE);
  
  alertatlossammount = MathAbs(alertatlossammount)*(-1);
  return(INIT_SUCCEEDED); 
 }
 
//-----------------------------------------------+ 
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
   color mTextCol;
   double mProf = 0;
   profitpips=0.0;
   for(int i = 0; i < PositionsTotal(); i++)
     {
     string symbol = PositionGetSymbol(i);
     long   magic  = m_position.Magic();
     int    type   = m_position.Type();
      if(PositionSelect(symbol) == false) break;
      //if(OrderSymbol() == Symbol() && OrderType() < 2)
      if(FilterBySymbol&&symbol!=_Symbol) continue;
      if(FilterByMagicNumber&&magic!=MagicNumber) continue;
      if (type == POSITION_TYPE_BUY ||type == POSITION_TYPE_SELL)
        {
          if (!CalcSwapCommissionAlso) mProf = mProf + m_position.Profit();
           else if (CalcSwapCommissionAlso) mProf = mProf + m_position.Profit() + 
                                                            m_position.Swap() + 
                                                            m_position.Commission();
           
          if (ShowProfitPips) {
           BrokerDigitAdjust(symbol);
           if (type==POSITION_TYPE_BUY) profitpips=profitpips+((SymbolInfoDouble(symbol,SYMBOL_BID)-m_position.PriceOpen())/pips2dbl);
           if (type==POSITION_TYPE_SELL) profitpips=profitpips+((m_position.PriceOpen()-SymbolInfoDouble(symbol,SYMBOL_ASK))/pips2dbl);
          }//if (ShowPips) {
        }
     }

   //mProf = -159651.62;//testing
   if(mProf < 0.00) { mTextCol = LossColor; SoundFileName = SoundFileLoss; }
    else if (mProf > 0.00) { mTextCol = ProfitColor; SoundFileName = SoundFileProfit; }
     else mTextCol = ZeroColor;
   //fxdaytrader
    string smProf = DoubleToString(mProf,2);
    smProf = (string)StringReplace(smProf,".",DecimalSeparator);
    if (mProf>0.00) {
      if (lastAlert!=1) if (AlertAtProfitOf&&mProf>=AlertAtProfitAmount) { lastAlert=1; doAlerts("Profit >= "+DoubleToString(AlertAtProfitAmount,2)+" (current profit: "+DoubleToString(mProf,2)+") "+AccountInfoString(ACCOUNT_CURRENCY),SoundFileName); }
     if (mProf>=1000.00&&mProf<10000.00) smProf = StringInsert(smProf,1,ThousandsSeparator);
     if (mProf>=10000.00&&mProf<100000.00) smProf = StringInsert(smProf,2,ThousandsSeparator);
     if (mProf>=100000.00&&mProf<1000000.00) smProf = StringInsert(smProf,3,ThousandsSeparator);
     if (mProf>=1000000.00&&mProf<10000000.00) { smProf = StringInsert(smProf,1,ThousandsSeparator); smProf = StringInsert(smProf,5,ThousandsSeparator); }
     if (mProf>=10000000.00) { smProf = StringInsert(smProf,2,ThousandsSeparator); smProf = StringInsert(smProf,6,ThousandsSeparator); }
    }//if (mProf>0.00) {
    else if (mProf<0.00) {
      if (lastAlert!=2) if (AlertAtLossOf&&mProf<=alertatlossammount) { lastAlert=2; doAlerts("Profit <= "+DoubleToString(alertatlossammount,2)+" (current loss: "+DoubleToString(mProf,2)+") "+AccountInfoString(ACCOUNT_CURRENCY),SoundFileName); }
     if (MathAbs(mProf)>=1000.00&&MathAbs(mProf)<10000.00) smProf = StringInsert(smProf,2,ThousandsSeparator);
     if (MathAbs(mProf)>=10000.00&&MathAbs(mProf)<100000.00) smProf = StringInsert(smProf,3,ThousandsSeparator);
     if (MathAbs(mProf)>=100000.00&&MathAbs(mProf)<1000000.00) smProf = StringInsert(smProf,4,ThousandsSeparator);
     if (MathAbs(mProf)>=1000000.00&&MathAbs(mProf)<10000000.00) { smProf = StringInsert(smProf,2,ThousandsSeparator); smProf = StringInsert(smProf,6,ThousandsSeparator); }
     if (MathAbs(mProf)>=10000000.00) { smProf = StringInsert(smProf,3,ThousandsSeparator); smProf = StringInsert(smProf,7,ThousandsSeparator); }
    }//else if (mProf<0.00) {
   //end fxdaytrader

   //ObjectSetText("mShowProf", DoubleToString(mProf, 2), mtextSize, mFont, mTextCol);
   ObjectSetText("mShowProf", smProf+" "+AccountInfoString(ACCOUNT_CURRENCY), mtextSize, mFont, mTextCol);//fxdaytrader
   if(mProf == 0) 
     //ObjectSetText("mShowProf", " ", mtextSize, mFont, CLR_NONE);
     ObjectSetText("mShowProf", "0" +" "+AccountInfoString(ACCOUNT_CURRENCY), mtextSize, mFont, mTextCol);//fxdaytrader
     
   if (ShowProfitPips) ObjectSetText("mShowProf1","(Profit Pips: "+DoubleToString(profitpips,2)+")", PipsTextSize, PipsFont, PipsColor);//fxdaytrader

  return(rates_total);
 }
 
//-----------------------------------------------+
void OnDeinit(const int reason)
 {
  ObjectDelete(0,"mShowProf");
  if (ShowProfitPips) ObjectDelete(0,"mShowProf1");
  ChartRedraw(0);
 }

//-----------------------------------------------+

//String functions by Hanover, http://www.forexfactory.com/showthread.php?t=165557
//+------------------------------------------------------------------+
string StringInsert(string str1, int pos, string str2)   {
//+------------------------------------------------------------------+
// Creates a result where str2 is inserted into str1, at pos in str1, e.g.
// StringInsert("0123456789",5,"XY") returns "01234XY56789"

  string outstr = StringSubstr(str1,0,pos) + str2 + StringSubstr(str1,pos);
  return(outstr);
} 

//+------------------------------------------------------------------+
string StringRep(string str, string str1, string str2)  {
//+------------------------------------------------------------------+
// Usage: replaces every occurrence of str1 with str2 in str
  string outstr = "";
  for (int i=0; i<StringLen(str); i++)   {
    if (StringSubstr(str,i,StringLen(str1)) == str1)  {
      outstr = outstr + str2;
      i += StringLen(str1) - 1;
    }
    else
      outstr = outstr + StringSubstr(str,i,1);
  }
  return(outstr);
}

void doAlerts(string msg,string SoundFile) {
        msg="Show Profit -> Alert on "+Symbol()+", period "+TFtoStr(PERIOD_CURRENT)+": "+msg;
 string emailsubject="MT4 alert on acc. "+AccountInfoString(ACCOUNT_NAME)+", "+MQLInfoString(MQL_PROGRAM_NAME)+" - Alert on "+Symbol()+", period "+TFtoStr(PERIOD_CURRENT);
  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(ENUM_TIMEFRAMES period){
   if(period == PERIOD_CURRENT)  period   = (ENUM_TIMEFRAMES) _Period;
   string   period_xxx  = EnumToString(period);                // PERIOD_XXX
   return StringSubstr(period_xxx, 7);                         // XXX
}
//+------------------------------------------------------------------+//string TFtoStr(int period) {

void BrokerDigitAdjust(string symbol) {
 Multiplier = 1;
 long digits = SymbolInfoInteger(symbol,SYMBOL_DIGITS);
 double point  = SymbolInfoDouble(symbol,SYMBOL_POINT);
 if (digits == 3 || digits == 5) Multiplier = 10;
 if (digits == 6) Multiplier = 100;   
 if (digits == 7) Multiplier = 1000;
 pips2dbl = Multiplier*point;
 //Slippage*=Multiplier;
}
bool ObjectSetText(string name,
                       string text,
                       int font_size,
                       string font="",
                       color text_color=CLR_NONE)
  {
   int tmpObjType=(int)ObjectGetInteger(0,name,OBJPROP_TYPE);
   if(tmpObjType!=OBJ_LABEL && tmpObjType!=OBJ_TEXT) return(false);
   if(StringLen(text)>0 && font_size>0)
     {
      if(ObjectSetString(0,name,OBJPROP_TEXT,text)==true
         && ObjectSetInteger(0,name,OBJPROP_FONTSIZE,font_size)==true)
        {
         if((StringLen(font)>0)
            && ObjectSetString(0,name,OBJPROP_FONT,font)==false)
            return(false);;
         return(true);
        }
      return(false);
     }
   return(false);
  }