2016-09-25 13 views
0

エキスパートアドバイザーが開いたポジションがエキスパートによって指定された条件を満たしていない場合に通知を送信するMQL4コードを開発しようとしていますアドバイザーが遭遇した。エキスパートアドバイザーが取引ポジションをクローズしなかった場合の通知電子

これまで私がこれまで持っていたことは次のとおりです。
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()値を保持から利益を得ることができます。 1はこれを信じることが場合

は、コードの流れを遮断することはありません:

次は、提案されたMQL4コードのために悪い敵です。 MQL4コード実行環境は、イベントの外部ソース(The Market)によってトリガーされ、Sleep(60000)と呼ぶイベントベースであり、EuroTunnelの出口でレールをスリープ状態にするより悪いです。おい!

あなたのコードは、MQL4コードエコシステムの他の部分がマーケットイベントの流れと同期して息を切らないようにするために、反応しないこと、より悪いことに気付いています。より良い方法があります、どうすれば "ほとんど何も"、Sleep()より、私を信じてください。

効率ヒント:

避けるコード重複むしろDigits固有の書式を使用するが、それは実際の小数点以下の桁数、またはStringFormat()ビアパターンに設定変数を介してです。

コードのレイアウトが少し違っていて、構文エラーやカッコが紛れてしまうのを防ぐのに役立ちます。

OrderClose()で評価されているように、グローバルに一意の直接ポインタに似ているの数値を使用し、あとでコード内で再利用したいが、あらかじめ値をあらかじめ格納することをお勧めします。 OrderClose() - モーメント。

折りたたみと円柱ブロックが非常に便利になる(Geany、SciTe、JEdit、Notepad ++)MQL4コードエフォート用の別のIDEを楽しむことができます。
ここですぐにif(){}else if(){}コードブロックの非効率性を物理的に見ると、else部分には自然な形の{True|False} - 二重切断が複製されています。とにかく

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

の野生の世界を楽しむ - requote、または貿易コンテキストがビジー状態でありますまたは他の何か。

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 
} 
:近くの要求のいくつかの番号を送信しようとする - このような理由あなたはまた、あなたが、別の方法をTradeContextの問題などを解決しようとするかもしれ終値は

RefreshRates();

新鮮であることを確認する必要があり

+0

ところで、あなたは** ERROR:TradeContextBusy' **を最近受け取りましたか? – user3666197

+0

ダッシュボードでは、バーの始めに28 +記号を取引しています。私のクライアントが問題について話していたときに限ります。その後、私は上記と同様のsthにコードを変更しました - そして今はもちろん問題ありません –

+0

このようなハイスループットのシナリオに対するよりよい解決策があります。ループの中で{Try/Error/Sleep}というダムのシーケンスを外すことは、performace **の必要性を解決するものではありませんが、ブロックされた中央リソースに対して純粋な正気を提供するだけです。そのようなニーズに対する主な解決策は、衝突回避のためのものであり、(まだ)ろうプロセスの扉をより強くノックすることではありません。 – user3666197

関連する問題