Проблема с общим количеством открытых ордеров

 

Привет всем. Я перепробовал все советы, которые смог найти на этом форуме, но, похоже, ни один не работает. Кто-нибудь, пожалуйста, помогите. Я полагаю, что проблема заключается в моей функции OrderTotal. Я торгую 10 валютными парами, т.е. советник открыт на 10 графиках. Это простая стратегия хеджирования. Я хочу, чтобы советник открывал сделку (длинную или короткую) в зависимости от сигналов. Если сделка идет в мою сторону, я ставлю трейлингстоп или тейк-профит. Если же сделка идет против меня, я хочу, чтобы советник открыл сделку в противоположном направлении. Код, который я использую, вроде бы работает, но иногда он застревает, т.е. больше не открывает никаких сделок. Кроме того, когда на одной паре открыта одна или две сделки, он не хочет открывать сделки на других парах.

Вот мой код

int start()
{
     {
     if (OrdersTotal() == 0)
     if(Close[1]>Close[2])
         result=OrderSend(Symbol(), OP_BUY, 0.01, Ask, 3, Ask - StopLoss*0.0001, 0, "Original", magicNumber, 0, Blue);
         Print("Error setting Original order: ",GetLastError());
         }

  for(int i=OrdersTotal()-1; i>=0; i--) 
  {
      if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)==true)
      if (OrderSymbol()==Symbol())
      //Calculate the point value in case there are extra digits in the quotes
      if (MarketInfo(OrderSymbol(), MODE_POINT) == 0.00001) PointValue = 0.0001;
      else if (MarketInfo(OrderSymbol(), MODE_POINT) == 0.0001) PointValue = 0.01;
      else if (MarketInfo(OrderSymbol(), MODE_POINT) == 0.001) PointValue = 0.01;
      else PointValue = MarketInfo(OrderSymbol(), MODE_POINT);

//calculate new lotsize of hedge based on lotsize of current open trade*Multiplier
      double lots = NormalizeDouble(OrderLots() * Multiplier, 2); 
      
     if (OrderType() == OP_BUY) 
      {
        if (Bid - OrderOpenPrice() > NormalizeDouble(TrailingStart *PointValue,Digits))
         {
           if (OrderStopLoss() < Bid - NormalizeDouble(TrailingStop *PointValue,Digits))
            {
              if (OrderModify(OrderTicket(), OrderOpenPrice(), Bid - NormalizeDouble(TrailingStop *PointValue,Digits),
              OrderTakeProfit(), Blue)) 
              Print("Error setting Buy trailing stop: ",GetLastError()); 
              }
            }
            else if (OrderOpenPrice() > Bid + NormalizeDouble(Hedge*PointValue,Digits))
            if(OrdersTotal() == 1)
            result=OrderSend(Symbol(), OP_SELL, lots, Bid, 3,  Bid + Stoploss*PointValue, 0, "Hedge", 0, 0, Blue);
            Print("Error setting Sell Hedge: ", GetLastError());
          }
 
  1. Вам нужно фильтровать сделки.
          if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)==true)
          if (OrderSymbol()==Symbol())
          if (MarketInfo(OrderSymbol(), MODE_POINT) == 0.00001) PointValue = 0.0001;  // These
          else if (MarketInfo(OrderSymbol(), MODE_POINT) == 0.0001) PointValue = 0.01;// four
          else if (MarketInfo(OrderSymbol(), MODE_POINT) == 0.001) PointValue = 0.01; // lines
          else PointValue = MarketInfo(OrderSymbol(), MODE_POINT);                    // Execute only on Symbol orders.
    
          double lots = NormalizeDouble(OrderLots() * Multiplier, 2);  // This and below are always executed
          if (OrderType() == OP_BUY)                                   // Symbol is irrelevant.             
    
    С помощью скобок.
          if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)==true)
          if (OrderSymbol()==Symbol())
    {                                                                   // Rest of code executes only on Symbol orders.
          if (MarketInfo(OrderSymbol(), MODE_POINT) == 0.00001) PointValue = 0.0001;
          else if (MarketInfo(OrderSymbol(), MODE_POINT) == 0.0001) PointValue = 0.01;
          else if (MarketInfo(OrderSymbol(), MODE_POINT) == 0.001) PointValue = 0.01;
          else PointValue = MarketInfo(OrderSymbol(), MODE_POINT);
    
          double lots = NormalizeDouble(OrderLots() * Multiplier, 2); 
          
          if (OrderType() == OP_BUY) 
             :
    }

  2. На 4-х значном брокере, пункт = 0,0001.
          if (MarketInfo(OrderSymbol(), MODE_POINT) == 0.00001) PointValue = 0.0001;
          else if (MarketInfo(OrderSymbol(), MODE_POINT) == 0.0001) PointValue = 0.01;
          else if (MarketInfo(OrderSymbol(), MODE_POINT) == 0.001) PointValue = 0.01;
          else PointValue = MarketInfo(OrderSymbol(), MODE_POINT);
    
    Исправлено и упрощено.
    PointValue = MarketInfo(OrderSymbol(), MODE_POINT);
    if(MarketInfo(OrderSymbol(), MODE_DIGITS) % 2 = 1) PointValue *= 10;

  3. Поскольку все, что находится внутри скобок, является Symbol(), каждый MarketInfo можно заменить предопределенными переменными
  4. Не надо жестко кодировать числа.
    Проверьте ваши коды возвратаЧто такое функциональные коды возврата? Как их использовать? -MQL4 форум и распространенные ошибки в MQL4 программах и как их избежать - MQL4 Статьи
    result=OrderSend(Symbol(), OP_BUY, 0.01, Ask, 3, Ask - StopLoss*0.0001, 0, "Original", magicNumber, 0, Blue);
 

1. Большое спасибо за помощь. Я добавил скобки, как было предложено, но советник по-прежнему открывает сделку только на одной валютной паре. Он не открывает сделку ни на одном из других графиков, даже если условие покупки было выполнено. Я застрял на этом в течение нескольких недель, не могли бы вы взглянуть еще раз.

2. РЕДАКТИРОВАТЬ: больше не требуется

3. Мой код теперь выглядит следующим образом

int start()
{
  {
    if (OrdersTotal() == 0)
    if(Close[1]>Close[2])
         result=OrderSend(Symbol(), OP_BUY, 0.01, Ask, 3, Ask - StopLoss*Point*10, 0, "Original", magicNumber, 0, Blue);
         Print("Error setting Original order: ",GetLastError());
  }       

  for(int i=OrdersTotal()-1; i>=0; i--) 
    {
      //calculate new lotsize of hedge based on lotsize of current open trade*Multiplier
      double lots = NormalizeDouble(OrderLots() * Multiplier, 2);
      if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)==true)
      if (OrderSymbol()==Symbol())
    { 
     if (OrderType() == OP_BUY) 
       {
        if (Bid - OrderOpenPrice() > NormalizeDouble(TrailingStart *Point*10,Digits))
         {
           if (OrderStopLoss() < Bid - NormalizeDouble(TrailingStop *Point*10,Digits))
           {
              if (OrderModify(OrderTicket(), OrderOpenPrice(), Bid - NormalizeDouble(TrailingStop *Point*10,Digits),
              OrderTakeProfit(), Blue)) 
              Print("Error setting Buy trailing stop: ",GetLastError()); 
           }
         }
            else if (OrderOpenPrice() > Bid + NormalizeDouble(Hedge*Point*10,Digits))
            if(OrdersTotal() == 1)
            result=OrderSend(Symbol(), OP_SELL, lots, Bid, 3,  Bid + Stoploss*Point*10, 0, "Hedge", 0, 0, Blue);
            Print("Error setting Sell Hedge: ", GetLastError());
       }
 
    if (OrdersTotal() == 0)
    if(Close[1]>Close[2])
         result=OrderSend(Symbol(), OP_BUY, 0.01, Ask, 3, Ask - StopLoss*PointValue, 0, "Original", magicNumber, 0, Blue);
         Print("Error setting Original order: ",GetLastError());
Если ордер открыт на любой паре, он не будет открывать другой ордер, пока OrdersTotal()==0 снова не будет открыт
 
GumRai:
Если ордер открыт на любой паре, он не будет открывать другой ордер, пока OrdersTotal()==0 снова

Спасибо за помощь. Мне нужно ограничить первый первоначальный ордер только одной сделкой. Я не хочу, чтобы советник продолжал открывать ордера, когда условие покупки выполнено. Поэтому я добавил Orderstotal, чтобы ограничить это. Этот код, однако, кажется, мешает коду здесь.

else if (OrderOpenPrice() > Bid + NormalizeDouble(Hedge*Point*10,Digits))
            if(OrdersTotal() == 1) //<----------
            result=OrderSend(Symbol(), OP_SELL, lots, Bid, 3,  Bid + Stoploss*Point*10, 0, "Hedge", 0, 0, Blue);
            Print("Error setting Sell Hedge: ", GetLastError());

Здесь я хочу, чтобы советник открывал только один хедж на каждую открытую сделку, поэтому OrderTotal ==1.

Так как же тогда лучше всего ограничить количество сделок, т.е. одна оригинальная сделка и одна сделка хеджирования? Спасибо.

 
Trader3000: Так как же тогда лучше всего ограничить количество сделок, т.е. одна оригинальная сделка и одна хеджевая?
  1. Итак, подсчитайте количество ордеров, открытых на текущем графике. OrdersTotal возвращает количество ордеров, открытых на всех графиках.
  2. Отсутствие фильтрации по магическому числу делает советник несовместимым со всеми остальными (включая себя на других ТФ) и ручной торговлей Symbol Doesn't equal Ordersymbol when another currency is added to another seperate chart . - Форум MQL4
 

Большое спасибо всем за помощь. Я решил проблему, и теперь советник открывает сделку на всех графиках при выполнении условия покупки, однако ничего ниже этого не работает. Советник не вызывает функции Trailingstop или Hedge. Кто-нибудь, пожалуйста, посмотрите и сообщите мне, что я сделал не так, потому что я не могу это понять.

int start()
{ 
   double Lots = NormalizeDouble(AccountEquity()*Percentage*Lotsize/100, 2);
   double lots = NormalizeDouble(OrderLots() * Multiplier, 2);
   total=0;
   for(i = OrdersTotal()-1; i >= 0 ; i--)
   if ( OrderSelect(i, SELECT_BY_POS)                
    &&  OrderMagicNumber()  == magicNumber            
    &&  OrderSymbol()       == Symbol())
    {             
      total++;
    }
    {
    if(total==0 )
    if(Close[1]>Close[2])
    {
         result=OrderSend(Symbol(), OP_BUY, Lots, Ask, 3, Ask - StopLoss*Point*10, 0, "Original", magicNumber, 0, Blue);
         Print("Error setting Original order: ",GetLastError());     
    }
    
     if (OrderType() == OP_BUY) 
       {
        if (Bid - OrderOpenPrice() > NormalizeDouble(TrailingStart *Point*10,Digits))
         {
           if (OrderStopLoss() < Bid - NormalizeDouble(TrailingStop *Point*10,Digits))
           {
              if (OrderModify(OrderTicket(), OrderOpenPrice(), Bid - NormalizeDouble(TrailingStop *Point*10,Digits),
              OrderTakeProfit(), Blue)) 
              Print("Error setting Buy trailing stop: ",GetLastError()); 
           }
         }
 else if (OrderOpenPrice() > Bid + NormalizeDouble(Hedge*Point*10,Digits))
            if(total == 1)
            result=OrderSend(Symbol(), OP_SELL, lots, Bid, 3,  Bid + Stoploss*Point*10, 0, "Hedge", magicNumber, 0, Blue);
            Print("Error setting Sell Hedge: ", GetLastError());
       }
 
   double Lots = NormalizeDouble(AccountEquity()*Percentage*Lotsize/100, 2);
   double lots = NormalizeDouble(OrderLots() * Multiplier, 2);

Я не знаю, что именно вы делаете, но советую вам избегать именования двух переменных, единственным отличием которых является заглавная буква. Их легко спутать, особенно когда другие, читающие ваш код, вполне могут принять соглашение о том, что переменные, начинающиеся с заглавной буквы, являются Globalscope.

Заказ не был выбран, поэтому OrderLots() может быть чем угодно.


    
     if (OrderType() == OP_BUY) 

Это будет использовать значения из последнего заказа, выбранного в предыдущем цикле, это может быть неправильное магическое число или символ.

 

Спасибо за ответ. Я пытаюсь сделать так, чтобы советник открывал первую оригинальную сделку, где размер лота составляет процент от моего капитала. Если сделка идет против

я, советник должен открыть один хедж в противоположном направлении, но здесь размер лота должен быть в 3 раза больше первоначального размера лота (OrderLots). Несмотря на то, что кажется, будто не выбран ни один ордер, это не так.

я поместил лоты непосредственно в функцию OrderSend, но ни трейлингстоп, ни трелингстоп не влияют на работу.

то хедж срабатывает в нужный момент. Оба варианта отлично работали до того, как я добавил следующее

total=0;
   for(i = OrdersTotal()-1; i >= 0 ; i--)
   if ( OrderSelect(i, SELECT_BY_POS)                
    &&  OrderMagicNumber()  == magicNumber            
    &&  OrderSymbol()       == Symbol())
    {             
      total++;
    }

int start()
{ 
   double Lots = NormalizeDouble(AccountEquity()*Percentage*Lotsize/100, 2);
   
   total=0;
   for(i = OrdersTotal()-1; i >= 0 ; i--)
   if ( OrderSelect(i, SELECT_BY_POS)                
    &&  OrderMagicNumber()  == magicNumber            
    &&  OrderSymbol()       == Symbol())
    {             
      total++;
    }
    {
    if(total==0 )
    if(Close[1]>Close[2])
         result=OrderSend(Symbol(), OP_BUY, Lots, Ask, 3, Ask - StopLoss*Point*10, 0, "Original", magicNumber, 0, Blue);
         Print("Error setting Original order: ",GetLastError());     
    }
    {
     if (OrderType() == OP_BUY) 
       {
        if (Bid - OrderOpenPrice() > NormalizeDouble(TrailingStart *Point*10,Digits))
         {
           if (OrderStopLoss() < Bid - NormalizeDouble(TrailingStop *Point*10,Digits))
           {
              if (OrderModify(OrderTicket(), OrderOpenPrice(), Bid - NormalizeDouble(TrailingStop *Point*10,Digits),
              OrderTakeProfit(), Blue)) 
              Print("Error setting Buy trailing stop: ",GetLastError()); 
           }
         }
            else if (OrderOpenPrice() > Bid + NormalizeDouble(Hedge*Point*10,Digits))
            if(total == 1)
            result=OrderSend(Symbol(), OP_SELL, NormalizeDouble(OrderLots() * Multiplier, 2), Bid, 3,  Bid + Stoploss*Point*10, 0, "Hedge", magicNumber, 0, Blue);
            Print("Error setting Sell Hedge: ", GetLastError());
       }

Я считаю, что мои скобки {} не в тех местах.

 
Я уже сказал вам во второй части моего предыдущего сообщения.
 

Большое спасибо за помощь. Я делаю успехи. Теперь у меня все работает так, как должно работать, за исключением того, что советник игнорирует условие для открытия хеджевой сделки. Иногда (но не всегда) он открывает хеджевую сделку, даже если условия не были выполнены. Также не всегда срабатывает TrailingStop. Я думаю, что где-то не хватает скобок {}. Мой код сейчас выглядит так. Кто-нибудь, пожалуйста, посмотрите. Спасибо.

int start()
{ 
   total=0;
   for(i = OrdersTotal()-1; i >= 0 ; i--)
   if ( OrderSelect(i, SELECT_BY_POS)                
    &&  OrderMagicNumber()  == magicNumber            
    &&  OrderSymbol()       == Symbol())
    {             
      total++;
    }
    {
    if(total==0 )
    if(Close[1]>Close[2])
    {
         result=OrderSend(Symbol(), OP_BUY, 0.01, Ask, 3, Ask - StopLoss*Point*10, 0, "Original", magicNumber, 0, Blue);
         Print("Error setting Original order: ",GetLastError());     
    }
     if (OrderType() == OP_BUY) 
       {
        if (Bid - OrderOpenPrice() > NormalizeDouble(TrailingStart *Point*10,Digits))
         {
           if (OrderStopLoss() < Bid - NormalizeDouble(TrailingStop *Point*10,Digits))
           {
              if (OrderModify(OrderTicket(), OrderOpenPrice(), Bid - NormalizeDouble(TrailingStop *Point*10,Digits),
              OrderTakeProfit(), Blue)) 
              Print("Error setting Buy trailing stop: ",GetLastError()); 
           }
         }
            else if (OrderOpenPrice() > Bid + NormalizeDouble(Hedge*Point*10,Digits)) //<------- THIS IS BEING IGNORED SOMETIMES (I THINK)
            if(total == 1)
            {
            result=OrderSend(Symbol(), OP_SELL, NormalizeDouble(OrderLots() * Multiplier, 2), Bid, 3,  Bid + Stoploss*Point*10, 0, "Hedge", magicNumber, 0, Blue);
            Print("Error setting Sell Hedge: ", GetLastError());
            }
       }
      // else if (OrderType() == OP_SELL)
      // ... 

GumRai:

This would use the values from the last order selected in the previous loop, it may not be the correct magic number or symbol.


Я пытался исправить это, изменив скобки. Это лучший способ, или мне нужно дублировать и добавлять функцию OrderSelect каждый раз перед OrderSend? Спасибо.