MessageBox

It creates and shows a message box and manages it. A message box contains a message and header, any combination of predefined signs and command buttons.

int  MessageBox(
   string  text,             // message text
   string  caption=NULL,     // box header
   int     flags=0           // defines set of buttons in the box
   );

Parameters

text

[in]  Text, containing message to output.

caption=NULL

[in]  Optional text to be displayed in the box header. If the parameter is empty, Expert Advisor name is shown in the box header.

flags=0

[in]  Optional flags defining appearance and behavior of a message box. Flags can be a combination of a special group of flags.

Return Value

If the function is successfully performed, the returned value is one of values of MessageBox() return codes.

Note

The function cannot be used in custom indicators since calling MessageBox() suspends the thread of execution for the whole time while waiting for the user's response. Since all indicators for each symbol are executed in a single thread, such suspension makes the operation of all charts on all timeframes for this symbol impossible.

MessageBox() function does not work in the Strategy Tester.

Example:

//+------------------------------------------------------------------+
//| The EA displays MessageBox window with a request for further work|
//| upon reaching specified number of series of unprofitable trades  |
//| Wait for the specified number of bars and display MessageBox     |
//| with a request to continue work.                                 |
//| To check, we need to manually open and close several positions   |
//| with a loss, since the EA does not control                       |
//| its own "positions" by magic number for simplicity.              |
//+------------------------------------------------------------------+
 
//--- input parameters
input uint InpMaxLossDeals      =  3;    // Max Loss deals
input uint InpInactivityNumBars =  5;    // Number of bars of advisor inactivity
 
//--- global variables
bool     ExtFirstStart=true;             // First launch flag
bool     ExtFlag=true;                   // Flag for allowing the EA to work
uint     ExtNumLoss;                     // Number of consecutive unprofitable trades
datetime ExtTimeLastLoss;                // Time of the last trade to close a losing position
 
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- get the number of losing trades in a row and the time of the last trade to close the position
   ExtNumLoss=GetNumLosingTradesInRow(ExtTimeLastLoss);
 
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   Comment("");
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- determine how many bars have passed since the last closed losing position in the series
   int bars_remaining=iBarShift(Symbol(),PERIOD_CURRENT,ExtTimeLastLoss);
 
//--- if this is the first launch
   if(ExtFirstStart)
     {
      //--- If a specified number of bars have already passed after a series of unprofitable positions, set the EA operation flag
      if(bars_remaining>(int)InpInactivityNumBars)
         ExtFlag=true;
      ExtFirstStart=false;
     }
 
//--- if the EA operation flag is disabled
   if(!ExtFlag)
     {
      Comment(StringFormat("The advisor is stopped for %d bars. Num Loss positions: %u, Time last loss: %s",
                          (InpInactivityNumBars-bars_remaining),ExtNumLoss,TimeToString(ExtTimeLastLoss,TIME_DATE|TIME_MINUTES|TIME_SECONDS)));
      //--- if a specified number of bars have passed after a series of unprofitable positions
      if(bars_remaining>(int)InpInactivityNumBars)
        {
         //--- display MessageBox window with the specified text and window title
         //--- the request window has two Yes/No buttons and an icon with a question mark.
         //--- the Yes button is selected by default.
         string mb_text="The specified number of bars of EA inactivity have passed.\n Continue its work?";
         string mb_caption="Please note";
         int    mb_id=MessageBox(mb_text,mb_caption,MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON1);
         //--- if the return code from MessageBox is the Yes button pressed, set the EA operation flag
         if(mb_id==IDYES)
           {
            ExtFlag=true;
            return;
           }
        }
      //--- the EA operation flag is disabled, exit OnTick()
      return;
     }
 
//---  the EA operation flag is set - the EA works as provided by the code below
   Comment(StringFormat("The advisor is working. Num Loss positions: %u, Time last loss: %s, Elapsed Bars: %d",
           ExtNumLoss,TimeToString(ExtTimeLastLoss,TIME_DATE|TIME_MINUTES|TIME_SECONDS),bars_remaining));
  }
//+------------------------------------------------------------------+
//| TradeTransaction function                                        |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransactiontrans,
                        const MqlTradeRequestrequest,
                        const MqlTradeResultresult)
  {
//--- if the transaction type is adding a transaction to history
   if(trans.type==TRADE_TRANSACTION_DEAL_ADD)
     {
      //--- get a deal ticket and select a deal from the list by ticket
      ulong deal_ticket=trans.deal;
      if(HistoryDealSelect(deal_ticket))
        {
         //--- if this is a market exit trade, get the number of losing trades in a row and the time of the last trade
         ENUM_DEAL_ENTRY entry=(ENUM_DEAL_ENTRY)HistoryDealGetInteger(deal_ticket,DEAL_ENTRY);
         if(entry==DEAL_ENTRY_OUT || entry==DEAL_ENTRY_INOUT || entry==DEAL_ENTRY_OUT_BY)
            ExtNumLoss=GetNumLosingTradesInRow(ExtTimeLastLoss);
        }
     }
 
//--- if the number of losing trades in a row is greater than the specified value and the EA operation flag is enabled
   if(ExtNumLoss>=InpMaxLossDeals && ExtFlag)
     {
      //--- display MessageBox window with the specified text and window title
      //--- the request window has two Yes/No buttons and an icon with an exclamation mark.
      //--- the No button is selected by default.
      string mb_text="The number of losing trades has reached the specified maximum. The advisor is stopped.\n Continue its work?";
      string mb_caption="Attention!";
      int    mb_id=MessageBox(mb_text,mb_caption,MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON2);
      //--- if the return code from MessageBox is the No button pressed, disable the EA operation flag
      if(mb_id==IDNO)
         ExtFlag=false;
     }
  }
//+------------------------------------------------------------------+
//| Return the number of consecutive unprofitable trades             |
//| and the time of the last trade to close a losing position        |
//+------------------------------------------------------------------+
uint GetNumLosingTradesInRow(datetime &time_last_deal)
  {
//--- select the entire history
   if(!HistorySelect(0,TimeCurrent()))
      return(0);
 
//--- get the next trade ticket by the list of historical deals in a loop
   uint res=0;
   uint total=HistoryDealsTotal();
   for(int i=(int)total-1i>=0i--)
     {
      ulong deal_ticket=HistoryDealGetTicket(i);
      if(deal_ticket>0)
        {
         //--- if the deal is not for exiting the position, move on to the next one
         ENUM_DEAL_ENTRY entry=(ENUM_DEAL_ENTRY)HistoryDealGetInteger(deal_ticket,DEAL_ENTRY);
         if(entry!=DEAL_ENTRY_OUT && entry!=DEAL_ENTRY_OUT_BY && entry!=DEAL_ENTRY_INOUT)
            continue;
         //--- if the result of closing a position has a profit, interrupt the loop
         if(!IsClosePositionWithLoss(deal_ticket))
            break;
         //--- increase the counter of consecutive loss-making trades
         res++;
         //--- write the maximum trade time into a variable (looking for the last one)
         datetime deal_time=(datetime)HistoryDealGetInteger(deal_ticket,DEAL_TIME);
         if(deal_time>time_last_deal)
            time_last_deal=deal_time;
        }
     }
 
//--- return the number of consecutive losses
   return(res);
  }
//+------------------------------------------------------------------+
//| Return the flag of closing a position with a loss                |
//+------------------------------------------------------------------+
bool IsClosePositionWithLoss(const ulong deal_ticket)
  {
//--- get the values of the properties affecting profit from the trade
   double profit=HistoryDealGetDouble(deal_ticket,DEAL_PROFIT);
   double comission=HistoryDealGetDouble(deal_ticket,DEAL_COMMISSION);
   double swap=HistoryDealGetDouble(deal_ticket,DEAL_SWAP);
   double fee=HistoryDealGetDouble(deal_ticket,DEAL_FEE);
 
//--- return the flag indicating that the total value of the received properties is negative
   return(profit+comission+swap+fee<0);
  }