0

我正在尝试开发一段 MQL4 代码,当智能交易系统指定的条件得到满足时,当智能交易系统开立的头寸未能关闭/清算时,它会向您发送通知。

这是我到目前为止所拥有的。平仓成功时返回,
EA平仓失败时返回。这是开始的地方。ClosePosition()truefalseelse if (ClosePosition == false)

//Order Close//
              string sym  =  Symbol();
              int ordersTotal = OrdersTotal();
              for(int PosSel = ordersTotal-1; PosSel>=0; PosSel--)
                 {
                 if(OrderSelect(PosSel,SELECT_BY_POS,MODE_TRADES))
                 if(OrderTicket() > 0)
                 if(OrderMagicNumber() == Period())
                 if(OrderSymbol() == Symbol())
                 if(TimeCurrent() >=(OrderOpenTime() + 60 * Period())) 
                    {                  
                    ClosePosition = OrderClose(OrderTicket(),8,MarketInfo(sym,MODE_BID) + MarketInfo(sym,MODE_SPREAD) * MarketInfo(sym,MODE_POINT),300,clrNONE);
                       if(ClosePosition == true)
                       {
                       Sleep(60000);
                       int PosSelHist = OrdersHistoryTotal()-1;
                       bool reshist = OrderSelect(PosSelHist,SELECT_BY_POS,MODE_HISTORY);
                          if(reshist == true && Digits == 5)
                          {
                          double ClosingPrice = OrderClosePrice();
                          double OpeningPrice = OrderOpenPrice();
                          double Profit       = OrderProfit();
                          int    Ticket       = OrderTicket();
                          SendMail("Trade Notification Email (TNE)","Order# "+DoubleToStr(Ticket,0)+" has been closed on the account "+AccountName()+
                          "\n"+
                          "\nThe order exit price for this trade is "+DoubleToStr(ClosingPrice,5)+"with a profit/loss of"+DoubleToStr(Profit,2)+
                          "\n"+
                          "\nThe spread charge for this position is £"+DoubleToStr((spread*tickvalue)*LotSize,2)+
                          "\n"+

                          "\n-----------------------------------------------------------------------"+
                          "\n"+

                          SendNotification("Ticket # "+IntegerToString(Ticket,10)+"has closed with a profit/loss of "+DoubleToStr(Profit,2));
                          }
                          else if(reshist == true && Digits == 3)
                          {
                          double ClosingPrice = OrderClosePrice();
                          double OpeningPrice = OrderOpenPrice();
                          double Profit       = OrderProfit();
                          int    Ticket       = OrderTicket();
                          SendMail("Trade Notification Email (TNE)","Order# "+DoubleToStr(Ticket,0)+" has been placed on the account "+AccountName()+
                          "\n"+
                          "\nThe order entry price for this trade is "+DoubleToStr(ClosingPrice,3)+"with a profit/loss of"+DoubleToStr(Profit,2)+
                          "\n"+
                          "\nThe spread charge for this position is £"+DoubleToStr((spread*tickvalue)*LotSize,2)+
                          "\n"+

                          "\n-----------------------------------------------------------------------"+

                          SendNotification("Ticket # "+IntegerToString(Ticket,10)+" has closed with a profit/loss of "+DoubleToStr(Profit,2));
                          }
                       }
                       else if(ClosePosition == false)
                       {
                       int failedClosePosition = OrdersTotal()-1;
                       bool fail = OrderSelect(failedClosePosition,SELECT_BY_POS,MODE_HISTORY);       
                       if(fail == true)
                          {
                          SendNotification("Order Number #"+IntegerToString(OrderTicket(),10)+" has failed to close. Please refer to error code "+IntegerToString(GetLastError()));
                          }
                       }
                    }
                 }

首先,这是获得预期结果的正确方法,其次;这是为 的替代编码的正确方法ClosePosition == true,还是会是一个if而不是一个else if

4

2 回答 2

0

您可能会尝试平仓但由于一些常规问题而失败 - 重新报价,或交易环境繁忙或其他。因此,您必须确保收盘价是新鲜的

RefreshRates();

您也可以尝试解决 TradeContext 问题和其他替代方式 - 尝试发送一些关闭请求:

int ATTEMPTS;                                      // declare on a global scope
int OnInit(){                                      // initialise
   ATTEMPTS = IsTesting() ? 1 : 100;               // ternary-op =boolA?valB:valC
   //---
   return(INIT_SUCCEEDED);
}

void Order_Close(){
   int ticket = GetTicketNumberToClose();         // put all checks here
   TradeClose(ticket);
}

void TradeClose(int ticket){                      // change to bool
                                                  // returning T/F if you need

   while(IsTradeContextBusy()) Sleep(5);          // a blocking-loop

   int current_attempt = 0, err=-1;

   while(current_attempt < ATTEMPTS){

      RefreshRates();                             // get fresh prices from Market

      if (!OrderClose(ticket,OrderLots(),OrderClosePrice(),5)){
         err = GetLastError();
         current_attempt++;
      }else return;
   }
   Print( __LINE__,
         "failed to close ticket#", ticket,
         " at price", DoubleToStr( OrderClosePrice(), Digits ),
         ". err#", err
         );                                     // send notification
                                                // instead of Print() if you need
}
于 2016-09-26T15:33:25.907 回答
0

不,对不起。代码很难被确认是正确的。

当然,可以修复一些语法错误。

大部分处理是重复的,这可能有效,但很难长期维护,被认为是一种糟糕的软件工程实践/习惯。

您可能会受益于在搜索然后直接搜索后保留唯一OrderTicket()值,这对于.db.POOLSELECT_BY_TICKET{ MODE_TRADES | MODE_HISTORY }db.POOL

接下来是提议的 MQL4 代码的更大敌人:

如果有人可能相信这一点,请永远不要阻止代码的流动。MQL4 代码执行环境是基于事件的,由外部事件源 (The Market) 触发,调用Sleep( 60000 )比在 EuroTunnel 出口处睡觉更糟糕。哎哟!!

您的代码无法做出反应,更糟糕的是,无法让 MQL4 代码生态系统的其他部分与市场事件流同步呼吸。相信我,肯定有更好的方法,如何“几乎什么都不做” Sleep()

效率提示:

避免代码重复,而是使用Digits特定格式,无论是通过设置为实际小数位数的变量,还是通过StringFormat()模式。

可能会享受一些不同的代码布局,这将帮助您避免语法错误、遗漏括号等。

更喜欢使用全局唯一的、类似直接指针的OrderTicket()数字,OrderClose()因为您希望在稍后的代码中重新使用它,但不能从OrderClose()-moment 中随时获得它,而是预先存储它的值。

可以享受另一个用于 MQL4 代码工作的 IDE,其中折叠和柱状块变得非常方便(Geany、SciTe、JEdit、Notepad++)。
在这里,您很快就会看到if(){}else if(){}代码块中的低效率,其中自然的相互{True|False}二分法在部分中被复制else

在此处输入图像描述

无论如何,享受 MQL4 的狂野世界

//Order Close//

string sym         =  Symbol();
int    ordersTotal = OrdersTotal();
for (  int PosSel  = ordersTotal - 1;                                   // loopVar .SET
           PosSel >= 0;                                                 // loopVar .PRE-condition
           PosSel--                                                     // loopVar .DEC at loop-end
           )
{      
       if (                          OrderSelect( PosSel, SELECT_BY_POS, MODE_TRADES ) )
             if (                    OrderTicket()      >  0 )
                   if (              OrderMagicNumber() == Period() )
                         if (        OrderSymbol()      == Symbol() )
                               if (  OrderOpenTime()    <= TimeCurrent() - ( 60 * Period() ) )
                               {                  
                                     ClosePosition = OrderClose( OrderTicket(),
                                                                 8,
                                                                 MarketInfo( sym, MODE_BID    )
                                                               + MarketInfo( sym, MODE_SPREAD )
                                                               * MarketInfo( sym, MODE_POINT  ),
                                                                 300,
                                                                 clrNONE
                                                                 );
                                     if (       ClosePosition == true )
                                     {  // ===================||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||====================
                                           Sleep( 60000 );  //|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| BLOCKS EA-EXECUTION
                                        // ===================||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||====================

                                           int  PosSelHist = OrdersHistoryTotal() - 1;
                                           bool    reshist = OrderSelect( PosSelHist, SELECT_BY_POS, MODE_HISTORY );
                                           if (  reshist == true
                                              && Digits  == 5
                                                 )
                                           {
                                                 double ClosingPrice = OrderClosePrice();
                                                 double OpeningPrice = OrderOpenPrice();
                                                 double Profit       = OrderProfit();
                                                 int    Ticket       = OrderTicket();

                                                 SendMail(   "Trade Notification Email (TNE)",
                                                             "Order# "                                  + DoubleToStr( Ticket,       0 )
                                                         +   " has been closed on the account "         + AccountName()
                                                         + "\n"
                                                         + "\nThe order exit price for this trade is "  + DoubleToStr( ClosingPrice, 5 )
                                                         +   "with a profit/loss of"                    + DoubleToStr( Profit,       2 )
                                                         + "\n"
                                                         + "\nThe spread charge for this position is £" + DoubleToStr( ( spread
                                                                                                                       * tickvalue
                                                                                                                         )
                                                                                                                         * LotSize,  2 )
                                                         + "\n"
                                                         + "\n-----------------------------------------------------------------------"
                                                         + "\n"
                                                         + SendNotification( "Ticket # "
                                                                           + IntegerToString( Ticket, 10 )
                                                                           + "has closed with a profit/loss of "
                                                                           + DoubleToStr( Profit, 2 )
                                                                             )
                                                           );
                                                 }
                                           else if (  reshist == true
                                                   && Digits  == 3
                                                      )
                                                {     
                                                      double ClosingPrice = OrderClosePrice();
                                                      double OpeningPrice = OrderOpenPrice();
                                                      double Profit       = OrderProfit();
                                                      int    Ticket       = OrderTicket();

                                                      SendMail(   "Trade Notification Email (TNE)",
                                                                  "Order# "                                  + DoubleToStr( Ticket,       0 )
                                                              +   " has been placed on the account "         + AccountName()
                                                              + "\n"
                                                              + "\nThe order entry price for this trade is " + DoubleToStr( ClosingPrice, 3 )
                                                              +   "with a profit/loss of"                    + DoubleToStr( Profit,       2 )
                                                              + "\n"
                                                              + "\nThe spread charge for this position is £" + DoubleToStr( ( spread
                                                                                                                            * tickvalue
                                                                                                                              )
                                                                                                                              * LotSize,  2 )
                                                              +  "\n"
                                                              +  "\n-----------------------------------------------------------------------"
                                                              +  SendNotification( "Ticket # "
                                                                                 + IntegerToString( Ticket, 10 )
                                                                                 + " has closed with a profit/loss of "
                                                                                 + DoubleToStr( Profit, 2 )
                                                                                   )
                                                                 );
                                                      }
                                           }
                                     else if (  ClosePosition == false )
                                          {     
                                                int   failedClosePosition = OrdersTotal() - 1;
                                                bool  fail                = OrderSelect( failedClosePosition, SELECT_BY_POS, MODE_HISTORY );
                                                if (  fail == true )
                                                {     
                                                      SendNotification( "Order Number #"
                                                                      + IntegerToString( OrderTicket(), 10 )
                                                                      + " has failed to close. Please refer to error code "
                                                                      + IntegerToString( GetLastError() )
                                                                        );
                                                      }
                                                }
                                     }
       }
于 2016-09-26T11:40:05.517 回答