MQL4、MQL5に関する初心者からの質問、アルゴリズムやコードに関するヘルプ、ディスカッションなど。 - ページ 755

 

こんにちは。何が悪いのかがわからない。

出来高が少ない注文と多い注文があり、テイクプロフィットが 異なる。数量の少ない注文を先に開き、次に数量の多い注文を開く。より大きな出来高の注文のTake Profitを見つける必要があります。

//MaxLotBuy() - функция находит ордер с наибольшим объемом (в Comment("") показывает правильные значения)
//buyTpL - в глобальных переменных
//---------------------------------------------
for(i = total-1; i >= 0; i--)
{
   if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
   {
      if(OrderSymbol() == Symbol() && OrderMagicNumber() == Magic)
      { 
         if(OrderType() == OP_BUY)
         { 
            if(OrderLots() == MaxLotBuy())
               buyTpL = OrderTakeProfit();
         }
      }
   }
} 

すべて正しいように見えますが、何らかの理由で、より少ない量の注文のテイクプロフィット値が得られます(それは最初に開かれました)。どうしたんですか?

追伸:total = OrdersTotal()

 
Youri Lazurenko:

こんにちは。何が悪いのかがわからない。

出来高が少ない注文と多い注文があり、テイクプロフィットが 異なる。数量の少ない注文を先に開き、次に数量の多い注文を開く。より大きな出来高の注文のTake Profitを見つける必要があります。

すべてが正しいように見えますが、何らかの理由で、小さい注文(最初に開かれた)でテイクプロフィットの値を得ることができます。どうしたんですか?

追伸:合計=OrdersTotal()です。

関数MaxLotBuy()には独自のオーダー検索が含まれているようで、この関数に戻ると別のオーダーが選択されているように見えるのです。ある注文のリバウンドのサイクル以外での注文のリバウンドを避ける。自分の言ったことが理解できない。 でも、本当なんです。

このような場合、ループの前に変数を宣言し、新しい値が前の値より大きいことを条件に、OrderLots()の値を代入した方がよいでしょう。

double orderLot = 0;
for(i = total-1; i >= 0; i--)
{
  if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
   {
      if(OrderSymbol() == Symbol() && OrderMagicNumber() == Magic)
      { 
         if(OrderType() == OP_BUY)
         { 
            if(OrderLots() > orderLot)
             {
              orderLot = OrderLots();
              buyTpL = OrderTakeProfit();
             }
         }
      }
   }
} 
 
Alexey Viktorov:

MaxLotBuy()関数は、独自の注文ループを持っているようで、この関数に戻るときに別の注文が選択されます。どのような注文ループの外側でも、注文をスルーするのは避けるべきでしょう。自分の言ったことが理解できない。 でも、本当なんです。

このような場合、ループの前に変数を宣言し、新しい値が前の値より大きいことを条件にOrderLots()の値を代入した方がよいでしょう。

ありがとうございます。はい、MaxLotBuy()は独自の注文の列挙を持っていますが、戻り値は最大のものです(コードをあげますね)

//  GetLots() - функция мани менеджмента
//------------------------
double MaxLotBuy()
{
   int    i;
   int    total  = OrdersTotal();
   double lot    = GetLots();
   
   if(CountBuy() == 0)
      lot = GetLots();
   
   if(CountBuy() >= 1)
   {   
      for(i = total-1; i >= 0; i--)
      {
         if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
         {
            if(OrderSymbol() == Symbol() && OrderMagicNumber() == Magic)
            {
               if(OrderType() == OP_BUY) 
               {
                  if(lot < OrderLots())
                     lot = OrderLots();
               }
            }
         }
      }
   }
   return(lot);
}

でも、あなたの考えは理解できました、ありがとう。これから試してみます。

 
Konstantin Nikitin:
それが正解なのでしょう。

ありがとうございます、その方がよさそうですね。

 
Konstantin Nikitin:
というのが正しいのではと思います。

ありがとうございます。気をつけなければならないのは、自分に向けて書くときだけではありません。

言葉ではそう書いてあるけれど。

ループの前に 変数を宣言する


 

みんな、ありがとうございます。ただ、元の位置にもリセットを追加しました。

   int    i;     
   int    total       = OrdersTotal();
   double orderLotBuy = GetLots();

   if(CountBuy() == 0)
      orderLotBuy = GetLots();

   for(i = total-1; i >= 0; i--)
   {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
      {
         if(OrderSymbol() == Symbol() && OrderMagicNumber() == Magic)
         { 
            if(OrderType() == OP_BUY)
            { 
               if(OrderLots() > orderLotBuy)
               {
                  buyTpL      = OrderTakeProfit();
                  orderLotBuy = OrderLots();
               }
            }
         }
      }
   } 
   
 
Youri Lazurenko:

みんな、ありがとうございます。ただ、元の位置にもリセットを追加しました。

まあ、そうなんですけどね。私の例は完全ではありません。今、訂正して、補足して、私の訂正があなたのメッセージと時間的に重なりました。
 
Alexey Viktorov:
まあ、そうなんですけどね。私の例は完全ではありません。今、訂正して、補足して、私の訂正があなたのメッセージと時間的に重なりました。

完成度が低いことは問題ではなく、重要なのは正しい考え、正しいアプローチです。皆さん、改めてありがとうございました。

 
Youri Lazurenko:

完成度が低いことは問題ではなく、重要なのは正しい考え、正しいアプローチです。あらためて、ありがとうございました。

すると、次のようになります。

   int    total       = OrdersTotal();
   double orderLotBuy = GetLots();

   if(CountBuy() > 0)
      for(i = total-1; i >= 0; i--)
      {
         if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
         {
            if(OrderSymbol() == Symbol() && OrderMagicNumber() == Magic)
            { 
               if(OrderType() == OP_BUY)
               { 
                  if(OrderLots() > orderLotBuy)
                  {
                     buyTpL      = OrderTakeProfit();
                     orderLotBuy = OrderLots();
                  }
               }
            }
         }
      } 
 
Konstantin Nikitin:

すると、次のようになります。

基本的に全てのコードは載せていませんが、一番ロットの大きい注文のテイクプロフィットを求める部分だけは載せています。要は、価格が反転したときに、より大きなロットの保留注文を 出すということです。うまくいくと、反対側の注文にストップロスが設定され、大きなロットの注文がテイクプロフィットで決済されると、ストップロスで利益がマイナスになった注文も決済されるようになります。ストップロスを設定した改造の全コードは次のようになります。

// sp            - величина спреда
// FirstOrderBuy - дабы избежать error1
//----------------------------------------------- 
     int i;
      
      int    total        = OrdersTotal();
      double orderLotBuy  = GetLots();     
   
      static int FirstOrderBuy  = 0;     

      if(CountBuy() < FirstOrderBuy)
         FirstOrderBuy = 0; 
         
      if(CountBuy() == 0)
         orderLotBuy = GetLots();
      
      if(CountSell() >= 1 && CountBuy() > FirstOrderBuy && MaxLotBuy() > MaxLotSell())
      {
         for(i = total-1; i >= 0; i--)
         {
            if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
            {
               if(OrderSymbol() == Symbol() && OrderMagicNumber() == Magic)
               { 
                  if(OrderType() == OP_BUY)
                  { 
                     if(OrderLots() > orderLotBuy)
                     {
                        buyTpL      = OrderTakeProfit();
                        orderLotBuy = OrderLots();
                     }
                  }
               }
            }
         } 
                        
         for(i = total-1; i >= 0; i--)
         {
            if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
            {
               if(OrderSymbol() == Symbol() && OrderMagicNumber() == Magic)
               { 
                  if(OrderType() == OP_SELL)  
                  {               
                     if(OrderStopLoss() == 0 || (OrderStopLoss() != 0 && OrderStopLoss() > OrderOpenPrice()))
                     {
                        slSell = NormalizeDouble(buyTpL + sp*point, Digits);
                        
                        OrderModifyX(OrderTicket(), OrderOpenPrice(), slSell, OrderTakeProfit(), 0, 0);
                     }
                  }    
               }
            }
         }
         FirstOrderBuy = CountBuy();
      }

追伸:テストの際、Expert Advisorに特定のケースでどのように動作するかを「説明」する必要があるニュアンスが非常に多くあります。