MessageBox

建立并显示对话框并管理它,一个对话框包括信息和页眉,任意预定义标签和命令按钮的组合。

int  MessageBox(
   string  text,             // 信息文本
   string  caption=NULL,     // 对话框表头
   int     flags=0           // 对话框按键设置
   );

参量

text

[in]  文本,包括信息输出。

caption=NULL

[in]  可选文本出现在方框中,如果参量是空的,EA交易名称在方框中显示。

flags=0

[in]  可选项 标记 规定外观和信息框的行为,标签可与特殊标签组结合。

返回值

如果函数成功执行,返回值是 MessageBox() 返回代码中值的一个。

注释

该函数不可用于自定义指标,因为MessageBox()调用在等待用户响应时,会一直暂停执行线程。由于每个交易品种的所有指标都在一个线程中执行,因此暂停会造成无法操作该交易品种的所有时间周期的所有图表。

MessageBox()函数在策略测试中不工作。

示例:

//+------------------------------------------------------------------+
//| EA显示包含进一步工作请求的MessageBox窗口                             |
//| 当一系列未盈利交易达到指定数量时                                      |
//| 等待指定的柱形图数量并显示MessageBox                                 |
//| 请求继续工作。                                                      |
//| 为了进行检查,我们需要手动打开和关闭多个持仓                            |
//| 亏损,因为EA无法控制                                                |
//| 它自己的“持仓”(通过幻数)。                                           |
//+------------------------------------------------------------------+
 
//--- 输入参数
input uint InpMaxLossDeals      =  3;    // 最大亏损交易
input uint InpInactivityNumBars =  5;    // 不活动的柱形图数
 
//--- 全局变量
bool     ExtFirstStart=true;             // 第一启动标识
bool     ExtFlag=true;                   // 允许EA工作的标识
uint     ExtNumLoss;                     // 连续未盈利交易数
datetime ExtTimeLastLoss;                // 最后一笔亏损平仓的时间
 
//+------------------------------------------------------------------+
//| EA交易初始化函数                                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- 获得连续亏损交易的数量和最后一笔亏损平仓的时间
   ExtNumLoss=GetNumLosingTradesInRow(ExtTimeLastLoss);
 
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| EA交易去初始化函数                                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   Comment("");
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- 确定自该系列中最后一个收盘亏损持仓以来已经过多少柱形图
   int bars_remaining=iBarShift(Symbol(),PERIOD_CURRENT,ExtTimeLastLoss);
 
//--- 如果这是第一次启动
   if(ExtFirstStart)
     {
      //--- 如果在一系列未盈利持仓之后已经通过指定数量的柱形图,则设置EA操作标识
      if(bars_remaining>(int)InpInactivityNumBars)
         ExtFlag=true;
      ExtFirstStart=false;
     }
 
//--- 如果EA操作标识被禁用
   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(bars_remaining>(int)InpInactivityNumBars)
        {
         //--- 显示带有指定文本和窗口标题的MessageBox窗口
         //--- 请求窗口有两个“是(Yes)”/“否(No)”按键和一个带问号的图标。
         //--- 默认选择“是(Yes)”按键。
         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);
         //--- 如果来自MessageBox的返回代码是按下的“Yes”按键,则设置EA操作标识
         if(mb_id==IDYES)
           {
            ExtFlag=true;
            return;
           }
        }
      //--- EA操作标识被禁用,退出OnTick()
      return;
     }
 
//---  设置EA操作标识 - EA按照下面代码提供的方式工作
   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函数                                              |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransactiontrans,
                        const MqlTradeRequestrequest,
                        const MqlTradeResultresult)
  {
//--- 如果交易事务类型是向历史记录添加交易
   if(trans.type==TRADE_TRANSACTION_DEAL_ADD)
     {
      //--- 获得一个交易工单,并按工单从列表中选择一笔交易
      ulong deal_ticket=trans.deal;
      if(HistoryDealSelect(deal_ticket))
        {
         //--- 如果这是一个市场退出交易,得到连续亏损交易的数量和最后一次交易的时间
         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);
        }
     }
 
//--- 如果连续亏损的交易数量大于指定的值,则启用EA操作标识
   if(ExtNumLoss>=InpMaxLossDeals && ExtFlag)
     {
      //--- 显示包含指定文本和窗口标题的MessageBox窗口
      //--- 请求窗口有两个“是(Yes)”/“否(No)”按键和一个带感叹号的图标。
      //--- 默认情况下选择“否(No)”按键。
      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);
      //--- 如果来自MessageBox的返回代码是按下的“No”按键,,则禁用EA操作标识
      if(mb_id==IDNO)
         ExtFlag=false;
     }
  }
//+------------------------------------------------------------------+
//| 返回连续未盈利交易的数量                                             |
//| 以及最后一笔亏损平仓的时间                                           |
//+------------------------------------------------------------------+
uint GetNumLosingTradesInRow(datetime &time_last_deal)
  {
//--- 选择整个历史
   if(!HistorySelect(0,TimeCurrent()))
      return(0);
 
//--- 通过循环中的历史交易列表获得下一个交易工单
   uint res=0;
   uint total=HistoryDealsTotal();
   for(int i=(int)total-1i>=0i--)
     {
      ulong deal_ticket=HistoryDealGetTicket(i);
      if(deal_ticket>0)
        {
         //--- 如果交易不是为了退出持仓,那么继续下一笔交易
         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(!IsClosePositionWithLoss(deal_ticket))
            break;
         //--- 增加连续亏损交易的计数器
         res++;
         //--- 将最大交易时间写入变量(查找最后一个)
         datetime deal_time=(datetime)HistoryDealGetInteger(deal_ticket,DEAL_TIME);
         if(deal_time>time_last_deal)
            time_last_deal=deal_time;
        }
     }
 
//--- 返回连续亏损的数量
   return(res);
  }
//+------------------------------------------------------------------+
//| 返回亏损平仓标识                                                   |
//+------------------------------------------------------------------+
bool IsClosePositionWithLoss(const ulong deal_ticket)
  {
//--- 获取影响交易利润的属性值
   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(profit+comission+swap+fee<0);
  }