ループと注文のクローズまたは削除 - ページ 5

 
Eleni Anna Branou:

</> ボタンでコードを挿入してください。


申し訳ありません... これは適切な形式です...

OrdersTotal()が正しくない...

私は、OrdersTotal()を使用 するループコード列が正しい結果を与えないことに驚いています(2つの異なるブローカーで観察されました)。

私は、Linux Ubuntu-MATE 16.04 デスクトップで、WINE 3.0を実行しているMT4バージョン1090を使用しています。

以下は、私が使用しているものです...

これがそれです。

for(int cc = 0; cc < OrdersTotal(); cc++)
{
      if (!OrderSelect(cc, SELECT_BY_POS, MODE_TRADES) ) continue;
      if (OrderSymbol() != Symbol() ) continue;
      if (OrderType() > 1) continue;    //--ignore pending trades

      OpenTradecnt++;    //--counts up for every live position of that symbol that exists
      Print("count of the open trades of this symbol is: ", OpenTradecnt);

2つのブローカーで、OrdersTotal()の値がMT4ブローカーの「取引」タブに表示されるものと常に一致しないことに気づきました。 最初は、ブローカーがOrdersTotal()を正しく機能させない原因になっていると思いました。 2番目のブローカーで気づいたとき、MT4に内部「問題」があるか、私のコードが間違っているか、MT4とサーバーが正しく同期する際の問題ではないかと考えはじめました......。

このフォーラムスレッドを読んだ後、私はfor..loopを読み取るように変更することで、より良い結果を得ることができるのだろうか。

for(int cc = OrdersTotal() - 1; cc >= 0; cc--)
{
      if (!OrderSelect(cc, SELECT_BY_POS, MODE_TRADES) ) continue;
      if (OrderSymbol() != Symbol() ) continue;
      if (OrderType() > 1) continue;    //--ignore pending trades

      OpenTradecnt++;    //--counts up for every live position of that symbol that exists
      Print("count of the open trades of this symbol is: ", OpenTradecnt);
または、OnTick()イベント中にOrdersTotal()が適切に同期されるようにするフラグやコードの行はありますか?

この件に関して何か説明があれば、とても助かります!よろしくお願いします。

 
Simon Gniadkowski:

Expert Advisor Builderのようなゴミのせいもあってか、これは私がよく目にするエラーの一つです。 だから、私はそれが将来の参考のためにリンクすることができますので、それは主題に専用のスレッドのための時間だと思った。

問題点

簡単な例を見てみましょう。私たちはEAのすべてのオープンオーダーをクローズする関数が欲しいのですが、たくさんの例がありますが、一から作ってみましょう。

このループの中で、注文を選択するコード、それが正しいシンボルとマジックナンバーであることをチェックするコード、そして最後に注文をクローズするコードを記述することになります。

このコードは悪いです .. . 使わないで ください .. . 次の章でその理由を説明します ... ...

説明

上記のコードを通して作業してみましょう ... ... 一行ずつ、注文ごとに ... ...

次のような注文があるとします。これらはすべてEAと同じマジックナンバーとシンボルを持っているので、コードはこれらすべてをクローズするようにします。

ポジション チケット番号
0111
1222
2333
3444
4555

ループの1回目。

PositionIndexの初期値は0なので、ポジション0のチケット番号111のオーダーが選択され、このオーダーは正常に削除され、残りのオーダーは以下のようにポジションが変更されます。

ポジション チケット番号
0222
1333
2444
3555

ループの2回目。

ここで、PositionIndexの 値は1なので、ポジション1のチケット番号333のオーダーが選択 され、 このオーダーは 正常に 削除され、残りのオーダーは 以下の ようにポジションが変更 されます

ポジション チケット番号
0222
1444
2555

ループの3回目。

ここで PositionIndexの値は 2なので、ポジション2のチケット番号555のオーダーが選択 され、 このオーダーは 正常に 削除され、残りのオーダーは 次の ようにポジションを変更 します。

ポジション チケット番号
0222
1444

ループの4回目の実行。

、PositionIndexの値は3です OrderSelect()はポジション3のオーダーを選択しようとして失敗 し、continueはループ内の次の値までコードを実行します ... .


ループの5回目と最後の実行

PositionIndexの値は4です OrderSelect()はポジション4でオーダーを選択しようとし、 失敗し、continueはループ内の次の値にコードの実行を取ります ... ループは終了しました


現在、チケット222と444の2つの注文が残っており、これらはクローズされるべきでしたが、されていません ... 次に、この問題を解決する方法を説明します。

解決方法

次のコードは、未決済注文を決済したり、保留中の 注文を削除する場合の正しい方法です ... ...

重要な違いは、ループが (TotalNumberOfOrders - 1 ) から 0 までデクリメントする ことです。

もう一度、上記のコードで作業してみましょう ... 行ごとに、注文ごとに ...

先ほどと同じ注文があります。

ポジション チケット番号
0111
1222
2333
3444
4555

ループの 1 回目。

PositionIndexの初期値はTotalNumberOfOrders -1で、5 - 1 = 4と なるので、 ポジション4のチケット番号555のオーダーが選択され、このオーダーは正常に削除され、残りのオーダーは以下のようにポジションが変更 されます。

ポジション チケット番号
0111
1222
2333
3444

ループの2回目。

ここで、PositionIndexの 値は3なので、ポジション3のチケット番号444のオーダーが選択 され、 このオーダーは 正常に 削除され、残りのオーダーは 以下の ようにポジションが変更 されます

ポジション チケット番号
0111
1222
2333

3回目のループを実行します。

ここで PositionIndexの値は 2なので、ポジション2のチケット番号333のオーダーが選択 され、 このオーダーは 正常に 削除され、残りのオーダーは 以下の ようにポジションが変更 されます。

ポジション チケット番号
0111
1222

ループを4回実行。

ここで 、PositionIndexの値は 1なので、ポジション1のチケット番号222のオーダーが選択 され、 このオーダーは 正常に 削除され、残りのオーダーは 以下の ようにポジションが変更 されます

ポジション チケット番号
0111

ループの5回目、最後の実行です。

今、 PositionIndexの 値は 0です だから、位置0の注文が選択されます、チケット番号111、 この注文は 正常に 削除されます、値0はループのための最後の有効な値 です... ループは終了しています。

一致する注文をすべて削除することに成功しました ... ...

このスレッドにリンクしています。 ループと注文のクローズまたは削除

ありがとうございました!とてもわかりやすい説明です。
 
こんにちは、コーダーの皆さん。
このスレッドで注文の選択について読みました。確かに、私は正しいことをしたと思うコードがありますが、選択された注文のOpenPriceを読むことができないので、選択は私には機能 しません。他のものはすべてうまくいくのですが、提供されたコードのその部分だけがうまくいきません。理由はよくわかりません。
コード全体では、注文が送信された直後にOrderOpenPriceを呼び出す必要があるセクションが4つあります...OrderSend はうまく機能しますが、OrderSelect は必要な結果を得ることができません。あなたが助けることができる場合、コードの1つのセクションを参照してください。
ありがとうございました。
 if(Protection_Step_One==1)
        {
        while(Protective_Order<0)
          {
          RefreshRates();
          Protective_Order=OrderSend(Symbol(),OP_SELL,Protective_Lots,NormalizeDouble(MarketInfo(Symbol(),MODE_BID),MarketInfo(Symbol(),MODE_DIGITS)),3,0,0,"Intermediary",MN_Sell_Intermediary_Protection,0,Cyan);
          }
  //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Addition for Clamp       
          for (int i=OrdersTotal()-1; i>=0; i--)
            {if(OrderSelect(i,SELECT_BY_POS, MODE_TRADES)==true)
               {if (OrderMagicNumber()==MN_Sell_Intermediary_Protection)
                  { RefreshRates();
                  Intermediary_OpenPrice_Sell= OrderOpenPrice();
                  }
                }
             }   
               //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>..
        if(Protective_Order!=-1)
          { 
          Protection_Step_One=0;
          RealTime_Drawing=2;
          Protective_Mode_Activated=1;
          Protective_Order=-2;
          Defcon=2;

 

親愛なるSimon Gniadkowskiに 感謝します。

あなたの投稿は、私の時間を本当に救ってくれました。

 
Gelson Kasonia:
void OnStart()
{
     int Protective_Order=OrderSend(_Symbol,ORDER_TYPE_BUY,0.01,Ask,3,0,0,"Intermediary");
     if(Protective_Order<0)
          return;
     if(!OrderSelect(Protective_Order,SELECT_BY_TICKET, MODE_TRADES))
          return;
     Print(Protective_Order, " OrderOpenPrice: ", OrderOpenPrice());
}
 

これは、成行注文を閉じるために私が提案するコードです。

int MagicNo=1234;
int Slippage=10;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void CloseOrdersBackward()
  {
   for(int i=OrdersTotal()-1; i>=0 && !IsStopped(); i--)
     {
      if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
        {
         Print("Order Select failed, order index: ",i," Error: ",GetLastError());
         continue;
        }

      if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNo && OrderType()<=OP_SELL)
        {
         if(!OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),Slippage))

            Print("Order Close failed, order ticket: ",OrderTicket()," Error: ",GetLastError());
        }
     }
  }

そして、もしforwardループが使われるなら、これが正しい方法だと思います(アメリカのブローカーのFIFOルールに準拠するため)。

int MagicNo=1234;
int Slippage=10;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void CloseOrdersForward()
  {
   for(int i=0; i<OrdersTotal() && !IsStopped(); i++)
     {
      if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
        {
         Print("Order Select failed, order index: ",i," Error: ",GetLastError());
         continue;
        }

      if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNo && OrderType()<=OP_SELL)
        {
         if(OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),Slippage))
           {
            i--;
           }
         else
           {
            Print("Order Close failed, order ticket: ",OrderTicket()," Error: ",GetLastError());
           }
        }
     }
  }

フォワードループの中で

  1. ORDERTOTAL() 関数は、ループの反復ごとに未決済注文の残数を更新するために for ループ内で使用され、インデックスが配列の範囲 外にならないようにします。
  2. インデックス i は、注文が決済されるたびにデクリメントされ、一部の注文をスキップしないようにします。
 
amrali: インデックスiは注文が終了するごとにデクリメントさ れ、一部の注文をスキップしないようにします。
複数の注文がある場合(1つのEA複数のチャート、複数のEA、手動取引、)現在の操作(クローズ、削除、修正)が完了するのを待っている間に、他の注文に対する他のいくつもの 操作が同時に起こり、ポジションインデックスが変更された可能性があります。
  1. FIFOでない(米国のブローカー)(または EAがシンボルごとに1つの注文しか出さない)場合は、単純に ポジションループでカウントダウン すれば、注文を見逃すことはない。常にカウントダウンする習慣を身につけましょう。
    ループと注文のクローズまたは削除 - MQL4プログラミングフォーラム
    FIFO(米国のブローカー)で シンボルごとに複数の注文を処理する場合、最も早い注文を見つけ、それを決済し、操作が成功 したら、残りのすべてのポジションを再処理する必要が あります。
    FIFOルールによるCloseOrders - Strategy Tester - MQL4プログラミングフォーラム - ページ 2 #16

  2. そして、それ以前のポジションが削除された場合に備えて、OrderSelectを チェックします。
    関数の戻り値とは何ですか?どのように使用するのですか?- MQL4プログラミングフォーラム
    MQL4プログラムにおける一般的なエラーとその回避方法 - MQL4 Articles
  3. そして、複数の注文を処理する可能性がある場合、次の注文/サーバーコールで定義済み変数(Bid/Ask)または(方向に依存しないように)OrderClosePrice()を使用したい場合は、サーバーコール後にRefreshRates() を呼び出す必要が あります。
 

これがどれだけ私を助けてくれたかわかるでしょう。私が取り組んでいたコードだけでなく、私の理解全体に対してです。今では完璧に動作し、様々な方法で実装することができるようになりました。

この情報には本当に感謝しています。