Fragen von Neueinsteigern zu MQL4 und MQL5, Hilfe und Diskussion über Algorithmen und Codes - Seite 755

 

Hallo. Ich kann nicht herausfinden, was falsch ist.

Es gibt zwei Aufträge mit kleinerem und größerem Volumen und unterschiedlichen Gewinnmitnahmen. Der Auftrag mit dem kleineren Volumen wird zuerst eröffnet, dann der Auftrag mit dem größeren Volumen. Wir müssen einen Take Profit für den Auftrag mit dem größeren Volumen finden.

//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();
         }
      }
   }
} 

Alles scheint korrekt zu sein, aber aus irgendeinem Grund erhalten wir Take-Profit-Werte für die Order mit einem geringeren Volumen (sie wurde zuerst eröffnet). Was ist los?

P.S. gesamt = AufträgeSumme()

 
Youri Lazurenko:

Hallo. Ich kann nicht herausfinden, was falsch ist.

Es gibt zwei Aufträge mit kleinerem und größerem Volumen und unterschiedlichen Gewinnmitnahmen. Der Auftrag mit dem kleineren Volumen wird zuerst eröffnet, dann der Auftrag mit dem größeren Volumen. Wir müssen einen Take Profit für den Auftrag mit dem größeren Volumen finden.

Alles scheint korrekt zu sein, aber aus irgendeinem Grund erhalten wir Take-Profit-Werte mit einem kleineren Auftrag (er wurde zuerst eröffnet). Was ist los?

P.S. Gesamt = AufträgeSumme()

Es scheint, dass die Funktion MaxLotBuy() ihre eigene Auftragssuche enthält und ein anderer Auftrag ausgewählt zu sein scheint, wenn wir zu dieser Funktion zurückkehren. Vermeiden Sie Auftragsrücksprünge außerhalb eines Auftragsrücksprungzyklus. Ich verstehe nicht, was ich gesagt habe. Aber es ist wahr.

In dieser Situation ist es besser, vor der Schleife eine Variable zu deklarieren und ihr den Wert von OrderLots() zuzuweisen, vorausgesetzt, der neue Wert ist größer als der vorherige.

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:

Die Funktion MaxLotBuy() scheint eine eigene Bestellschleife zu haben und bei der Rückkehr zu dieser Funktion wird eine andere Bestellung ausgewählt. Sie sollten es vermeiden, den Auftrag außerhalb einer Auftragsschleife zu bearbeiten. Ich verstehe nicht, was ich gesagt habe. Aber es ist wahr.

In dieser Situation ist es besser, vor der Schleife eine Variable zu deklarieren und ihr den Wert von OrderLots() zuzuweisen, vorausgesetzt, der neue Wert ist größer als der vorherige.

Ich danke Ihnen. Ja,MaxLotBuy() hat eine eigene Aufzählung von Aufträgen, aber der Rückgabewert ist der maximale Wert (ich gebe Ihnen den Code).

//  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);
}

Aber ich habe Ihre Idee verstanden, danke. Ich werde es jetzt versuchen.

 
Konstantin Nikitin:
Das ist wahrscheinlich der richtige Weg.

Danke, das scheint besser zu sein.

 
Konstantin Nikitin:
Ich denke, das Richtige wäre, wenn

Ich danke Ihnen. Nicht nur, wenn Sie an sich selbst schreiben, müssen Sie vorsichtig sein.

Obwohl es genau das ist, was es in Worten sagt.

eine Variable vor der Schleife deklarieren


 

Vielen Dank, Leute, es funktioniert, wie es sollte. Ich habe die ursprüngliche Position ebenfalls zurückgesetzt.

   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:

Vielen Dank, Leute, es funktioniert, wie es sollte. Ich habe die ursprüngliche Position ebenfalls zurückgesetzt.

Nun, ja. Mein Beispiel ist nicht vollständig. Ich habe sie soeben korrigiert und ergänzt, und meine Korrektur stimmte rechtzeitig mit Ihrer Nachricht überein.
 
Alexey Viktorov:
Nun, ja. Mein Beispiel ist nicht vollständig. Ich habe sie soeben korrigiert und ergänzt, und meine Korrektur stimmte rechtzeitig mit Ihrer Nachricht überein.

Es spielt keine Rolle, dass sie nicht vollständig ist, was zählt, ist die richtige Idee, der richtige Ansatz. Ich danke Ihnen allen nochmals.

 
Youri Lazurenko:

Es spielt keine Rolle, dass sie nicht vollständig ist, was zählt, ist die richtige Idee, der richtige Ansatz. Ich danke Ihnen allen noch einmal.

Dann geht es so

   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:

Dann sieht es so aus

Im Grunde habe ich nicht den gesamten Code gepostet, sondern nur einen Teil der Ermittlung des Take-Profits der Order mit dem höchsten Lot. Das Ganze funktioniert folgendermaßen: Wenn sich der Kurs umkehrt, wird ein schwebender Auftrag mit einem größeren Lot erteilt. Wenn es funktioniert, wird ein Stop-Loss für den entgegengesetzten Auftrag gesetzt, so dass, wenn der Auftrag mit dem großen Lot bei Take Profit geschlossen wird, der Auftrag mit dem negativen Gewinn bei Stop-Loss ebenfalls geschlossen wird. Der vollständige Code der Änderung mit dem Setzen eines Stop-Loss sieht wie folgt aus

// 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();
      }

P.S. Beim Testen gibt es so viele Nuancen, die dem Expert Advisor "erklärt" werden müssen, wie er sich in bestimmten Fällen verhalten soll.