当EA交易无法关闭交易头寸时发送电子邮件通知

时间:2016-09-25 10:42:22

标签: mql4 metatrader4 mt4

我正在尝试开发一段MQL4代码,当Expert Advisor打开的职位在满足EA交易指定的条件时无法关闭/清算时,会向您发送通知。

以下是我到目前为止的情况。
当成功平仓时ClosePosition()返回true,当EA未能平仓时返回falseelse 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而不是compile files('libs/lucene-6.2.0/queryparser/lucene-queryparser-6.2.0.jar') compile files('libs/lucene-6.2.0/demo/lucene-demo-6.2.0.jar') compile files('libs/lucene-6.2.0/core/lucene-core-6.2.0.jar') compile files('libs/lucene-6.2.0/analysis/common/lucene-analyzers-common-6.2.0.jar')

2 个答案:

答案 0 :(得分:0)

不,抱歉。代码很难被证实是正确的。

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

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

您可能会受益于相当保留搜索OrderTicket()然后直接db.POOL后的唯一SELECT_BY_TICKET值,这对{ MODE_TRADES | MODE_HISTORY } db.POOL部分Sleep( 60000 )部分中的所有order_state / order_relative_position更改都很有效

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

如果有人相信这一点,永远不会阻止代码的流动。 MQL4代码执行环境是基于事件的,由外部事件源(市场)触发,调用Sleep()比在EuroTunnel退出时在轨道上休眠更糟糕。 OUCH !!

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

效率提示:

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

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

更喜欢使用全球唯一的,与指针类似的OrderClose()数字,如OrderClose()中所评估,而是预先存储它的值,因为您希望稍后在代码中重复使用它,但是没有从if(){}else if(){}时刻获得它。

可以享受另一个用于MQL4代码工作的IDE,其中折叠和柱状块变得非常方便(Geany,SciTe,JEdit,Notepad ++)。在这里,您很快就会在{True|False}代码中查看效率低下的情况-blocks,其中else部分重复了自然的共同//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() ) ); } } } } - 二分法。

enter image description here

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

cellForRowAtIndexPath

答案 1 :(得分: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
}