2016-09-25 10 views
0

MQL4 코드를 개발하려고합니다. Expert Advisor가 열어 준 포지션이 전문가가 지정한 조건에 따라 종결/청산에 실패했을 때 통보합니다 고문이 만났습니다.Expert Advisor가 거래 포지션을 닫지 못했을 때 전자 메일로 통보

여기까지 제가 지금까지 있습니다.
ClosePosition()은 위치가 성공적으로 닫히면 true을 반환하고 EA가 위치를 닫지 못하면 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())); 
          } 
         } 
        } 
       } 

else if (ClosePosition == false) 차기,이 원하는 결과를 얻기에 올바른 방법이며, 둘째 곳이다; ClosePosition == true에 대한 대안을 코딩하는 올바른 방법입니까 아니면 else if 대신 if일까요?

+1

'if','else if' 또는'else'만이 작동합니다. 가장 정확한 것은'else' 일 것입니다. –

답변

0

아니요, 죄송합니다. 이 코드는 올바른 것으로 확인하기가 어렵습니다.

확실히 몇 가지 구문 오류가 수정 될 수 있습니다.

처리의 큰 부분이 복제되어 작동 할 수는 있지만 장기간 실행하기가 어렵고 소프트웨어 엔지니어링 관행/습관이 좋지 않은 것으로 간주됩니다.

당신은 오히려 db.POOL{ MODE_TRADES | MODE_HISTORY } 부분의 양쪽에있는 모든 order_state/order_relative_position 변화에 대한 강력한이다 db.POOL 후 바로 SELECT_BY_TICKET를 검색 한 번 독특한 OrderTicket() 값을 유지하는 혜택을 누릴 수 있습니다. 하나는 믿을 수있는 경우

은, 코드의 흐름을 차단하지 :

다음은 제안 된 MQL4 코드에 대한 나쁜 적이다. MQL4 코드 실행 환경은 외부 이벤트 소스 (The Market)에 의해 트리거 된 이벤트 기반이며 Sleep(60000) 호출은 EuroTunnel의 출구에서 레일에서 잠을자는 것보다 나쁩니다. 아야!!

귀하의 코드는 시장 이벤트의 흐름과 동기화되어 MQL4 코드 생태계 호흡의 다른 부분이 호흡하지 못하도록 반응 할 수 없으며 더욱 악화 될 수 있습니다. 더 나은 방법, 확실한 방법은, "거의 아무것도", Sleep()보다, 나를 믿어.

효율성 팁 :

않도록 코드 중복 오히려는 Digits - 특정 서식을 사용하는 소수 자릿수의 실제 숫자 변수 세트를 통해 그것을, 또는 StringFormat() 패턴을 통해.

구문 오류를 피할 수 있도록 코드 레이아웃이 약간 다를 수 있습니다. 누락 된 괄호 등.

OrderClose()으로 평가 된 전체적으로 고유 한 직접 포인터 비슷하게 OrderTicket() 숫자를 사용하고 나중에 코드에서 다시 사용하기를 원하지만 나중에 값을 미리 저장하는 것이 바람직합니다. OrderClose() -moment.

MQL4 코드 작업을위한 또 다른 IDE (축소 형 및 원주 형 블록이 매우 편리함) (Geany, SciTe, JEdit, Notepad ++)를 즐길 수 있습니다.
여기서 if(){}else if(){} 코드 블록의 비효율은 곧 else 부분에서 자연스러운 상호 {True|False}- 절편이 중복 된 부분을 물리적으로 보게됩니다.requote를, 또는 무역 컨텍스트가 사용 중입니다 -

enter image description here

어쨌든, 때문에 정기적 인 문제로 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()) 
                     ); 
                 } 
               } 
            } 
     } 
0

당신이 당신의 위치를 ​​닫으려고하지만 실패 할 수의 야생 세계를 즐길 수 또는 다른 어떤 것.

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 
} 
닫기 요청의 일부 번호를 보내려고 - 당신이 확실 종가을해야합니다 같은 이유로 도

RefreshRates();

당신이 TradeContext 문제 등, 다른 방법을 해결하려고 할 수 있습니다 신선

+0

안녕하십니까, 최근에 말하면, ** ERROR : TradeContextBusy **를 받나요? – user3666197

+0

대시 보드는 술집이 시작될 때 28 개 이상의 기호를 거래합니다. 한 번만 제 의뢰인이 문제에 대해 말한 것입니다. 그 후 위 코드와 비슷한 sth 코드로 바뀌 었습니다. 물론 이제는 아무런 문제가 없습니다. –

+0

이러한 높은 처리량 시나리오에는 더 나은 솔루션이 있습니다. 루프에서 {Try/Error/Sleep}의 벙어리 시퀀스를 셸링하면 ** performace **의 필요성을 해결하지 못하고 차단 된 중앙 리소스에 순진한 정당성을 제공합니다. 정당한 충돌 회피는 그러한 요구에 대한 주된 해결책이지, 여전히 (여전히) 청각 장애인 과정의 문을 두드리는 것이 아닙니다. – user3666197