新人对MQL4和MQL5的任何问题,对算法和代码的帮助和讨论 - 页 755

 

你好。我搞不清楚哪里出了问题。

有两笔订单,成交量较小和较大,获利 不同。交易量较小的订单首先被打开,然后是交易量较大的订单。我们需要为成交量较大的订单找到一个止盈点。

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

一切似乎都是正确的,但由于某些原因,我们得到了成交量较小的订单的获利值(它是先开的)。有什么问题吗?

P.S. total = OrdersTotal()

 
Youri Lazurenko:

你好。我搞不清楚哪里出了问题。

有两笔订单,成交量较小和较大,获利 不同。交易量较小的订单首先被打开,然后是交易量较大的订单。我们需要为成交量较大的订单找到一个止盈点。

一切似乎都是正确的,但由于某些原因,我们在一个较小的订单中得到了获利值(它先被打开)。有什么问题吗?

P.S. Total = 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();
      }

P.S. 在测试过程中,有许多细微差别需要向专家顾问 "解释",说明它在某些情况下应该如何表现。

原因: