Открыть противоположный ордер - страница 2

 

Вы не можете сделать это для настройки проскальзывания для 4/5-значных брокеров, это просто не имеет смысла.

Проскальзывание ДОЛЖНО быть int, т.е. целым числом, для 4-значного брокера проскальзывание в пунктах, поэтому Slippage = 3 означает 3 пункта, для 5-значного брокера проскальзывание в пунктах, поэтому Slippage = 3 означает 3 пункта или 0.Таким образом, для компенсации, для 5-значного брокера цифра проскальзывания должна быть умножена на десять, что дает 30 ... 30 пунктов = 3 пункта.

Так что этот код неправильный...

int init()
   {
   if (Digits ==3 || Digits ==5) pt = 10 * Point;
   else pt = Point;
   Slippage = Slippage * pt;    
   }
 

Попробуйте эту модифицированную версиюфункции OpenOppositeOrder(). ...

void OpenOppositeOrder() 
   {
   int Op;  
 
   for(int Counter = OrdersTotal()-1; Counter >= 0; Counter--)
      {
      if(OrderSelect(Counter,SELECT_BY_POS,MODE_TRADES))  // only continue if the OrderSelect() worked
         {
         if(OrderSymbol() == Symbol()&& OrderMagicNumber() == MagicNumber)
            {
            Op = OrderType();

            if(Op == OP_BUY && Bid < OrderOpenPrice())
               {      
               Ticket = OrderSend(Symbol(), OP_SELL, LotSize, Bid, Slippage, 0, 0, "Sell Order", MagicNumber, 0, Red);
               if(Ticket > 0) 
                  {
                  Print("Opposite Sell order placed # ", Ticket);
                  AddLimitsSell();
                  }
               else
                  {
                  Print("Order Send failed, error # ", GetLastError() );
                  }
               }
               
            if(Op == OP_SELL && Ask > OrderOpenPrice())
               {      
               Ticket = OrderSend(Symbol(), OP_BUY, LotSize, Ask, Slippage, 0, 0, "Buy Order", MagicNumber, 0, Green);
               if(Ticket > 0)
                  {
                  Print("Opposite Buy order placed # ", Ticket);
                  AddLimitsBuy();
                  }
               else
                  {  
                  Print("Order Send failed, error # ", GetLastError() );
                  }   
               }
            }
         }
      }
   }
 
RaptorUK:

Попробуйте эту модифицированную версию функции OpenOppositeOrder(). ...


Привет, RaptorUk,

Прежде всего, спасибо за помощь, оказанную до сих пор. Теперь советник начинает работать. Я сделал другие модификации о том, как закрыть все, если ордер имеет прибыль, и это нормально, но, как вы уже видели и предсказываете, для работы этой стратегии необходимо, чтобы ордер, который достигает прибыли, имел увеличенный размер лота, чтобы компенсировать предыдущие ордера. с учетом этого я ввел код, чтобы сделать это. Таким образом, я имею дело с путаницей здесь. Мне нужно подтвердить, был ли последний ордер прибыльным или нет, и я хочу использовать OrderProfit() для корректировки размера лота следующего ордера, но разве мне не нужно закрыть предыдущий ордер, чтобы получить эту информацию?

Вот код для открытия противоположного ордера, который работает нормально (спасибо вам), где я ввожу дополнительный код, чтобы узнать, есть ли прибыль у бывшего открытого ордера. Правильно ли я поступаю, чтобы получить эту информацию?

Спасибо

Луис

 void OpenOppositeOrder() 
 {
// LastOrder Loss Compensation 
   int Orders;
   Orders= OrdersTotal();
   if (Orders>0)
   {  
    for(i=0;i<Orders;i++)
   {
    OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
    if(OrderSymbol()==Symbol()&& OrderMagicNumber()== MagicNumber)
   {
    lastprofit = OrderProfit();
    lastlot = OrderLots();
   }
  }
 }
  mlots=0;
  if (lastprofit<0)mlots=NormalizeDouble(lastlot*Multiplier,Digits);
  else mlots=LotSize;
 
//+------------------------------------------------------------------+ 
//Open Opposite Order 
   int Op;  
 
   for(int Counter = OrdersTotal()-1; Counter >= 0; Counter--)
      {
      if(OrderSelect(Counter,SELECT_BY_POS,MODE_TRADES))  
         {
         if(OrderSymbol() == Symbol()&& OrderMagicNumber() == MagicNumber)
            {
            Op = OrderType();

            if(Op == OP_BUY && Bid < OrderOpenPrice())
               {  
               if(Martingale)ilots=mlots;else ilots=LotSize; 
               Ticket = OrderSend(Symbol(), OP_SELL, ilots, Bid, UseSlippage, 0, 0, "Sell Order", MagicNumber, 0, Red);
               if(Ticket > 0) 
                  {
                  Print("Opposite Sell order placed # ", Ticket);
                  AddLimitsSell();
                  }
               else
                  {
                  Print("Order Send failed, error # ", GetLastError() );
                  }
               }
               
            if(Op == OP_SELL && Ask > OrderOpenPrice())
               { 
               if(Martingale)ilots=mlots;else ilots=LotSize;
               Ticket = OrderSend(Symbol(), OP_BUY, ilots, Ask, UseSlippage, 0, 0, "Buy Order", MagicNumber, 0, Green);
               if(Ticket > 0)
                  {
                  Print("Opposite Buy order placed # ", Ticket);
                  AddLimitsBuy();
                  }
               else
                  {  
                  Print("Order Send failed, error # ", GetLastError() );
                  }   
               }
            }
         }
      }
   }
 
luisneves:


Привет, RaptorUk,

Прежде всего, спасибо за помощь, оказанную до сих пор. Теперь советник начинает работать. Я сделал другие модификации о том, как закрыть все, если ордер имеет прибыль, и это нормально, но, как вы уже видели и предсказываете, для работы этой стратегии необходимо, чтобы ордер, который достигает прибыли, имел увеличенный размер лота, чтобы компенсировать предыдущие ордера. С учетом этого я ввел код для этого. Итак, я имею дело с путаницей здесь. Мне нужно подтвердить, был ли последний ордер прибыльным или нет, и я хочу использовать OrderProfit() для корректировки размера лота следующего ордера, но разве мне не нужно закрыть предыдущий ордер, чтобы получить эту информацию?

Вот код для открытия противоположного ордера, который работает нормально (спасибо вам), где я ввожу дополнительный код, чтобы узнать, есть ли прибыль у бывшего открытого ордера. Правильно ли я поступаю, чтобы получить эту информацию?

Я подозреваю, что это вызовет у вас проблемы ...

mlots = NormalizeDouble(lastlot * Multiplier, Digits);

например, если результат был 1.12316734 лота, то ваша NormalizeDouble() на 5-значном номинале изменит его на1.12316, и это не будет соответствовать требованию шага лота . ... вам нужно использовать некоторые математические методы, чтобы ваш измененный размер лота был кратен шагу лота MarketInfo(Symbol(),MODE_LOTSTEP).

 
RaptorUK:

Я подозреваю, что это вызовет у вас проблемы. ...

например, если результат был 1.12316734 лота, то ваша NormalizeDouble() на 5-значном номинале изменит его на1.12316 и это не будет соответствовать требованию Lot Step . ... вам нужно использовать некоторые математические методы, чтобы ваш измененный размер лота был кратен шагу лота MarketInfo(Symbol(),MODE_LOTSTEP)


Привет, RaptorUK,

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

Теперь у меня возник другой вопрос (больше одного...)

Для открытия ордеров выше и ниже текущей цены я хочу использовать линию, где как только Ea начинает работать, я сравниваю цену с линией, которая все еще находится.

Возникает первая проблема: как я могу сравнить линию с разницей в цене?

Вот код, который у меня есть на данный момент. Как я могу задать имя для сравнения, потому что если я вставляю iHigh после priceline, это просто не работает.

Заранее спасибо за любую подсказку в этих вопросах.

Луис

priceline=iHigh(Symbol(),0,0);
 ObjectCreate("highline",OBJ_HLINE,0,0,Bid); 
 ObjectSet("highline",OBJPROP_COLOR,LimeGreen);
 ObjectSet("highline",OBJPROP_WIDTH,1);
 WindowRedraw();

Кажется, это вообще не работает (...)

if(Bid > priceline+Distance*pt)                      
                {       
// Open buy order

                            while(IsTradeContextBusy()) Sleep(10);
                                 RefreshRates();        
                       
             Ticket=OrderSend(Symbol(),OP_BUY,LotSize,Ask,UseSlippage,0,0,"Buy Order",MagicNumber,0,Green);
             if(Ticket>0)AddLimitsBuy();
            }

Я поместил сюда объект delete, потому что мне нужно, чтобы линия была удалена с закрытием всех ордеров. я прав?

void CloseAll()
      {
         int i,Op,Error;
         int Total=OrdersTotal();
     
         if(Total>0)
         {
         for(int pos=OrdersTotal()-1;pos>=0;pos--)
         if(OrderSelect(pos,SELECT_BY_POS)
         && OrderMagicNumber()==MagicNumber && OrderSymbol()==Symbol())
         {
         Op=OrderType();
         if(Op==OP_BUY)
         {
         OrderClose(OrderTicket(),OrderLots(),Bid, UseSlippage, Yellow);
         }
         if(Op==OP_SELL)
         {
         OrderClose(OrderTicket(),OrderLots(),Ask, UseSlippage, Yellow);
         }
         else
         {
         ObjectDelete("highline");
         }
        }
       }
      }
 
luisneves:

Кажется, это совсем не работает (...)

Я поставил здесь объект delete, потому что мне нужно, чтобы строка была удалена с закрытием всех ордеров. я прав?

Хорошо, я думаю, я понимаю, что вы хотите сделать, вы хотите проверить, где находится Bid по сравнению с вашей линией, для этого вам нужно получить позицию линии ... используйте ObjectGet() с именем объекта и индексом свойства объектаOBJPROP_TIME1 это вернет цену, по которой расположена линия.

Ваш вызов ObjectDelete() выглядит нормально. Мне особенно не нравится использование ObjectsDeleteAll(), я считаю его ленивым и опасным ... или, по крайней мере, неудобным для других.

 
RaptorUK:

Хорошо, я думаю, я понимаю, что вы хотите сделать, вы хотите проверить, где находится Bid по сравнению с вашей линией, для этого вам нужно получить позицию линии ... используйте ObjectGet() с именем объекта и индексом свойства объектаOBJPROP_TIME1 это вернет цену, на которой находится линия.

Ваш вызов ObjectDelete() выглядит нормально.


Привет, RaptorUK,

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

Заранее благодарю за любую помощь

Луис

int GoToClose()
 {
  int pos;  
 {
  for(int Profit=OrdersTotal()-1;pos>=0;pos--)
  if(OrderSelect(Profit,SELECT_BY_POS)
  && OrderMagicNumber()==MagicNumber && OrderSymbol()==Symbol()
  && OrderProfit()+OrderSwap()+OrderCommission()>0||OrdersTotal()> MaxOrders)CloseAll();  
 }
}
//+---------------------------------------------------------------------------+  
      void CloseAll()
      {
         int Op,Error;
                    
         for(int pos=OrdersTotal()-1;pos>=0;pos--)
         if(OrderSelect(pos,SELECT_BY_POS)
         && OrderMagicNumber()==MagicNumber && OrderSymbol()==Symbol())
         {
         Op=OrderType();
         if(Op==OP_BUY)
         {
         RefreshRates();
         OrderClose(OrderTicket(),OrderLots(),Bid, UseSlippage, Yellow);
         }
         if(Op==OP_SELL)
         {
         RefreshRates();
         OrderClose(OrderTicket(),OrderLots(),Ask, UseSlippage, Yellow);
         }
         if(Op==OP_SELLSTOP||OP_BUYSTOP||OP_SELLLIMIT||OP_BUYLIMIT)
         {
         RefreshRates();
         OrderDelete(OrderTicket());
         }
         else Print("Error opening BUY Stop Order : ",GetLastError());         
         }
        }             
 
luisneves:


Привет, RaptorUK,

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

Вы должны понять, как работают выражения ... вы не можете сделать это ....

if(Op == OP_SELLSTOP || OP_BUYSTOP || OP_SELLLIMIT || OP_BUYLIMIT)

это похожая ситуация, но не совсем та же самая:https://www.mql5.com/en/forum/141790


Что является результатом ...

WhatValue = (5  || 4  ||  3  ||  2 );

||- это оператор Bolean, поэтому работает только с bools. ...


в результате получается результирующее значение bool. ...

( Op == OP_SELLSTOP )

. . . если вы хотите использовать побитовый оператор для ваших значений, то вы можете использовать это. . . . . .

int WhatValue = (5  | 4  |  3  |  2 );

... но это не то, что вы пытаетесь сделать.

 
RaptorUK:

Вам нужно понять, как работают выражения ... вы не можете этого сделать ... .

это похожая ситуация, но не совсем такая же:https://www.mql5.com/en/forum/141790


Что является результатом ...

||- это оператор Bolean, поэтому работает только с bools. ...


в результате получается значение bool. ...

. . . если вы хотите использовать побитовый оператор для ваших значений, то вы можете использовать это. . . . . .

... но это не то, что вы пытаетесь сделать.


Привет, RaptorUK,

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

void CloseAll()
      {
         int Op,Error;
                    
         for(int pos=OrdersTotal()-1;pos>=0;pos--)
         if(OrderSelect(pos,SELECT_BY_POS)
         && OrderMagicNumber()==MagicNumber && OrderSymbol()==Symbol())
         {
         Op=OrderType();
         if(Op==OP_BUY)
         {
         RefreshRates();
         OrderClose(OrderTicket(),OrderLots(),Bid, UseSlippage, Yellow);
         }
         if(Op==OP_SELL)
         {
         RefreshRates();
         OrderClose(OrderTicket(),OrderLots(),Ask, UseSlippage, Yellow);
         }
         if(Op==OP_SELLSTOP)
         {
         RefreshRates();
         OrderDelete(OrderTicket());
         }
         if(Op==OP_BUYSTOP)
         {
         RefreshRates();
         OrderDelete(OrderTicket());
         }
         else Print("Error opening BUY Stop Order : ",GetLastError());         
         }
        }        
 
luisneves:


Привет, RaptorUK,

Понятно, но теперь я изменил код, и отложенный ордер все еще там...

Это может быть, если она имеет Magic Number, отличный отMagicNumber, или она для символа, отличного от символа, на котором работает советник, или если это OP_SELLLIMIT или OP_BUYLIMIT . . Также необходимо проверить возвращаемые значения из вызовов OrderDelete() и OrderClose()....

Зачем вам нужно вызывать RefreshRates()? Я не имею в виду избавиться от них, но вы можете объяснить, почему вы вызываете RefreshRates() там, где вы находитесь?


Что такое возвращаемые значения функции? Как их использовать?

Причина обращения: