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

 

Привет всем

Извините, но я заговорил слишком рано. Хотя добавление RefreshRates(), кажется, изменило ситуацию, у меня все еще та же проблема. Иногда он открывает оба отложенных ордера, иногда только один из двух, а иногда ни один из них. Я все еще получаю ошибку 130, когда он не открывает ордер или оба, но нет ошибок, когда оба действительно открываются. Я также заметил, что на тех парах, где мои входы ниже MODE_STOPLEVEL, он никогда не открывает ордер и у меня всегда ошибка 130, несмотря на то, что программа корректирует мои входы в соответствии с запросом. Я печатаю значения и они корректируются, как ожидалось. Итак, я пытаюсь понять, почему мой OrderSend не работает.

На такой паре, как EURUSD, где stoplevel равен 5, он обычно отправляет оба ордера, но не всегда. Однако на такой паре, как EURAUD, где stoplevel равен 10, он никогда не отправляет ордер.

extern int TrailingStart=20;
extern int TrailingStop=5;

extern int Hedge=10;
extern double Multiplier=3;

extern int StopLossOriginal=11;

extern int StopLossHedge=9;

extern double Percentage=1;
extern double Lotsize=0.01;
extern double MyMaxlots=30;

extern datetime StartTime1 = D'2016.03.25 16:50';

extern int Pipmove=5;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int init()
//---
  {
   int TS=TrailingStart-TrailingStop;
   double stoplevel=(MarketInfo(Symbol(),MODE_STOPLEVEL))/10;
   if(StopLossOriginal<stoplevel || StopLossHedge<stoplevel || TS<stoplevel)
     {
      MessageBox("Please note: Your inputs for StopLossOriginal, StopLossHedge and/or"+
                 "\nTrailingStop are below the minimum levels required by your broker,"+
                 "\nand have been increased automatically to "+StringConcatenate(stoplevel)+" Pips");
     }
   return(0);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int deinit()
  {
   return(0);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int start()
  {
   int TS=TrailingStart-TrailingStop;
   Print("TS = ",TS);
   int sloss=StopLossOriginal-Pipmove;
   int stoplevel=(MarketInfo(Symbol(),MODE_STOPLEVEL))/10;
   Print("stoplevel = ",stoplevel);
     
   double Lots = NormalizeDouble(AccountEquity()*Percentage*Lotsize/100, 2),
          point=Point*10,
          Price=Pipmove*point,
          SL=(StopLossOriginal-Pipmove)*point,
          MinLots = MarketInfo(Symbol(),MODE_MINLOT),
          MaxLots = MarketInfo(Symbol(),MODE_MAXLOT),
          HedgeLots=NormalizeDouble(OrderLots()*Multiplier,2);
          
   if(sloss<=stoplevel) SL=stoplevel*point;
   Print("SL = ",SL);
   if(StopLossHedge<=stoplevel) StopLossHedge=stoplevel;
   Print("StopLossHedge = ",StopLossHedge);
   if(TS<=stoplevel) TrailingStart=(stoplevel+TrailingStop); 
   Print("TrailingStart = ",TrailingStart);     
          
   datetime time1=StartTime1-3300;      

   if(Lots>MaxLots) Lots=MaxLots;
   if(Lots<MinLots) Lots=MinLots;
   if(HedgeLots>MaxLots) HedgeLots=MaxLots;
   if(Lots>MaxLots || Lots<MinLots || HedgeLots>MaxLots)
     {
      MessageBox("Lotsize have been adjusted automatically");
     }

   int buy_ticket=0, sell_ticket=0, buystop_ticket=0, sellstop_ticket=0, total=0;
   for(int i= OrdersTotal()-1; i>= 0; i--)
      if(OrderSelect(i,SELECT_BY_POS) && OrderMagicNumber()==magic && OrderSymbol()==Symbol())
        {
         total++;
         if(OrderType()==OP_BUYSTOP) buystop_ticket=OrderTicket();
         if(OrderType()==OP_SELLSTOP) sellstop_ticket=OrderTicket();
         if(OrderType()==OP_BUY) buy_ticket=OrderTicket();
         if(OrderType()==OP_SELL) sell_ticket=OrderTicket();
        }

   if(total==0 && Time[0]==time1)
     {
      buy_ticket=OrderSend(Symbol(),OP_BUYSTOP,Lots,Ask+Price,30,0,0,"Pending",magic,0,Lime);
      OrderModify(OrderTicket(),OrderOpenPrice(),Ask-SL,OrderTakeProfit(),Yellow);
      Print("Buystop = ",GetLastError());
      Sleep(1000);
      RefreshRates();
      Sleep(1000);
      sell_ticket=OrderSend(Symbol(),OP_SELLSTOP,Lots,Bid-Price,30,0,0,"Pending",magic,0,Red);
      OrderModify(OrderTicket(),OrderOpenPrice(),Bid+SL,OrderTakeProfit(),Yellow);
      Print("Sellstop = ",GetLastError());
     }

Я также пробовал так, но это не имеет никакого значения:

buy_ticket=OrderSend(Symbol(),OP_BUYSTOP,Lots,Ask+Price,30,Ask-SL,0,"Pending",magic,0,Lime);
      RefreshRates();
sell_ticket=OrderSend(Symbol(),OP_SELLSTOP,Lots,Bid-Price,30,Bid+SL,0,"Pending",magic,0,Red);

И даже если я делаю так, это ничего не меняет:

if(total==0) // && (Time[0]==time1)
 

Спасибо всем за помощь. Я наконец-то заставил его работать. Единственный способ, которым я мог заставить его работать последовательно, это изменить его на этот:

 if(total==0)
     {
      buystop_ticket=OrderSend(Symbol(),OP_BUYSTOP,Lots,Ask+Price,30,Ask-SL,0,"Pending",magic,0,Lime);
      Print("buystop = ",GetLastError());
      RefreshRates();
     }
   if(total==1)
     {
      sellstop_ticket=OrderSend(Symbol(),OP_SELLSTOP,Lots,Bid-Price,30,Bid+SL,0,"Pending",magic,0,Red);
      Print("sellstop = ",GetLastError());
     }

Я также выяснил, что уровень Pipmove перед активацией отложенного ордера должен быть выше, чем stoplevel. Так что теперь все работает... Спасибо.

 
Trader3000:

Спасибо всем за помощь. Я наконец-то заставил его работать. Единственный способ, которым я мог заставить его работать последовательно, это изменить его на этот:

Я также выяснил, что уровень Pipmove перед активацией отложенного ордера должен быть выше, чем stoplevel. Так что теперь все работает... Спасибо.

Нет, это тоже не работает, потому что теперь он будет продолжать открывать sell_stop до тех пор, пока открыта одна сделка.
 
Простой ответ - не пытайтесь открывать отложенные ордера так близко к текущей цене. 5 пунктов - это обычно половина пункта
 
GumRai:
Простой ответ - не пытайтесь открывать отложенные ордера так близко к текущей цене. 5 пунктов - это обычно половина пункта.

Спасибо за ответ. Мой расчет на самом деле в пунктах, поэтому отложенные ордера находятся на расстоянии не менее 50 пунктов (5 пунктов от текущей цены), однако, похоже, что он работает, если я перемещаю его хотя бы на 1 пункт дальше от уровня стоплосса, который составляет 50 пунктов на EURUSD. Похоже, что теперь он открывает обе сделки, кроме первой, после того, как я перетаскиваю его на график. Но меня это пока устраивает. Мой код теперь выглядит следующим образом:

extern int TrailingStart=20;
extern int TrailingStop=5;
extern int Hedge=10;
extern double Multiplier=3;
extern int StopLossOriginal=11;
extern int StopLossHedge=9;
extern double Percentage=1;
extern double Lotsize=0.01;
extern double MyMaxlots=30;
extern datetime StartTime1 = D'2016.03.25 14:50';
extern int Pipmove=5;
int i,TS=TrailingStart-TrailingStop,stoplevel=(MarketInfo(Symbol(),MODE_STOPLEVEL))/10; //stoplevel has been converted from points to pips (/10)

int start()
  {
   double Lots = NormalizeDouble(AccountEquity()*Percentage*Lotsize/100, 2),
          point=Point*10,
          Price=Pipmove*point,
          SL=StopLossOriginal*point,
          MinLots = MarketInfo(Symbol(),MODE_MINLOT),
          MaxLots = MarketInfo(Symbol(),MODE_MAXLOT),
          HedgeLots=NormalizeDouble(OrderLots()*Multiplier,2);

   if(StopLossHedge<stoplevel) StopLossHedge=stoplevel;
   if(TS<stoplevel) TrailingStart=(stoplevel+TrailingStop);
   if(Pipmove<stoplevel+1) Pipmove=stoplevel+1;
   if(StopLossOriginal<=StopLossHedge) StopLossOriginal=StopLossHedge+1;

   datetime time1=StartTime1-300;

   int buy_ticket=0,sell_ticket=0,buystop_ticket=0,sellstop_ticket=0,total=0;
   for(i=OrdersTotal()-1; i>=0; i--)
      if(OrderSelect(i,SELECT_BY_POS) && OrderMagicNumber()==magic && OrderSymbol()==Symbol())
        {
         total++;
         if(OrderType()==OP_BUYSTOP) buystop_ticket=OrderTicket();
         if(OrderType()==OP_SELLSTOP) sellstop_ticket=OrderTicket();
         if(OrderType()==OP_BUY) buy_ticket=OrderTicket();
         if(OrderType()==OP_SELL) sell_ticket=OrderTicket();
        }

   if(total<1 && Time[0]==time1)
     {
      buystop_ticket=OrderSend(Symbol(),OP_BUYSTOP,Lots,Ask+Price,30,Ask-SL,0,"Pending",magic,0,Lime);
      RefreshRates();
      sellstop_ticket=OrderSend(Symbol(),OP_SELLSTOP,Lots,Bid-Price,30,Bid+SL,0,"Pending",magic,0,Red);
     }

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

if(OrderSelect(buy_ticket,SELECT_BY_TICKET) && OrderType()==OP_BUY)
     {
      if(Bid-OrderOpenPrice()>TrailingStart*point)
        {
         if(OrderStopLoss()<Bid-TrailingStop*point)
           {
            if(OrderModify(OrderTicket(),OrderOpenPrice(),Bid-TrailingStop*point,OrderTakeProfit(),Blue))
              {
               if(OrderSelect(sellstop_ticket,SELECT_BY_TICKET) && OrderType()==OP_SELLSTOP)
                 {
                  if(OrderDelete(sellstop_ticket,Orange))
                     return(0);
                 }
              }
           }
        }
      if(OrderOpenPrice()>Bid+Hedge*point && buy_ticket==1 && sell_ticket<=1)
            {
              sell_ticket=OrderSend(Symbol(),OP_SELL,HedgeLots,Bid,3,Bid+StopLossHedge*point,0,"Hedge",magic,0,Red);
            }  
        }
//Same for Sell

Или:


//Same up to here:
else if(total<=2 && OrderOpenPrice()>Bid+Hedge*point)
        {
         sell_ticket=OrderSend(Symbol(),OP_SELL,HedgeLots,Bid,3,Bid+StopLossHedge*point,0,"Hedge",magic,0,Red);
        }

Должен ли я использовать для этого отдельный цикл for? Спасибо.

 

Привет всем

Прошли недели попыток, а я все еще не достиг прогресса. Сейчас все работает, за исключением того, что при определенных условиях советник открывает более одной хеджевой сделки на исходной сделке. SL на исходной сделке составляет 11 пунктов, а SL на хеджевой сделке - 9 пунктов. Иногда хеджевая сделка останавливается на уровне 9 пунктов, в то время как оригинальная сделка все еще открыта. Тогда советник открывает вторую хеджевую сделку и даже третью и четвертую, в то время как оригинальная сделка все еще открыта. Я просто хочу ограничить количество хеджевых сделок до одной, и если она останавливается, просто подождать и посмотреть, что произойдет с оригинальной сделкой.

Вот такие результаты я получаю:

576 2015.01.15 11:39 buy stop 29 0.48 1.16786 1.16616 0.00000 0.00 4834.24

577 2015.01.15 11:39 sell stop 30 0.48 1.16642 1.16812 0.00000 0.00 4834.24

578 2015.01.15 11:39 sell 30 0.48 1.16642 1.16812 0.00000 0.00 4834.24

579 2015.01.15 11:39 удалить 29 0.48 1.16786 1.16616 0.00000 0.00 4834.24

580 2015.01.15 11:42 купить 31 1.44 1.16743 1.16653 0.00000 0.00 4834.24

581 2015.01.15 11:42 с/л 31 1.44 1.16653 1.16653 0.00000 -129.60 4704.64

582 2015.01.15 11:44 купить 32 1.44 1.16742 1.16652 0.00000 0.00 4704.64

583 2015.01.15 11:44 с/л 30 0.48 1.16812 1.16812 0.00000 -81.60 4623.04

584 2015.01.15 11:48 modify 32 1.44 1.16742 1.16893 0.00000 0.00 4623.04

Ордера buystop и sellstop (29 и 30) открываются как положено. Затем цена падает, и ордер sell (30) заполняется, а ордер buystop (29) удаляется. Затем цена снова поднимается, и срабатывает ордер hedge(martingale) (31) (3*lotsize). Затем цена снова падает и хедж (31) прекращается, но поскольку 30 все еще открыт, он вызывает другой хедж (32) и т.д. Как я могу предотвратить срабатывание ордера 32? Спасибо.


 

Привет всем. Уже больше месяца я пытаюсь решить эту проблему и начинаю думать, что это программно невозможно закодировать. Так что если кто-нибудь подтвердит это, я смогу успокоиться и двигаться дальше. Неужели нельзя установить глубокий уровень для количества хеджевых (мартингейловых) ордеров, как объяснено в сообщении выше? Спасибо.

Лучшее, что у меня есть на данный момент, это:

int start()
{
   int buy_ticket=0;
   int sell_ticket=0;
   int total=0;
   for(int i= OrdersTotal()-1; i>= 0; i--)
      if(OrderSelect(i,SELECT_BY_POS) && OrderSymbol()==Symbol())
     {
         total++;
         if(OrderType()==OP_BUY) buy_ticket=OrderTicket();
         if(OrderType()==OP_SELL) sell_ticket=OrderTicket();
        }
   /*if(total==1 && OrderSelect(buy_ticket,SELECT_BY_TICKET) && OrderType()==OP_BUY) <------- this blocked out code is irrelevant, but I want to put it here for completeness
     {
      if(Bid-OrderOpenPrice()>TrailingStart*point)
        {
         if(OrderStopLoss()<Bid-TrailingStop*point)
           {
            if(OrderModify(OrderTicket(),OrderOpenPrice(),Bid-TrailingStop *point,OrderTakeProfit(),Blue))
               return(0);
           }
        }*/
      else if(OrderOpenPrice()>Bid+Hedge*point)
        {
         sell_ticket=OrderSend(Symbol(),OP_SELL,HedgeLots,Bid,3,Bid+StopLossHedge*point,0,"Hedge",magic,0,Blue);
         return(0);
        }
     }
  }
 

Этого можно достичь разными способами.

Когда хедж открыт, создайте глобальную переменную клиентского терминала.

Дайте ей имя, включающее номер тикета основной сделки.

Дайте ей значение, которое будет служить флагом того, что для данного номера тикета была открыта хеджевая сделка, или, при необходимости, счетчик хеджа.

Проверьте GV перед открытием хеджа.


Хедж и основная сделка имеют разные размеры лота.

Перед открытием хеджа проверьте открытые ордера и историю, чтобы узнать, был ли открыт противоположный ордер с соответствующим размером лота с временем открытия ордера (OrderOpenTime()) более поздним, чем время открытия основной сделки.

 
GumRai:

Этого можно добиться разными способами.

При открытии хеджа создайте Глобальную переменную клиентского терминала.

Дайте ему имя, включающее номер тикета основной сделки.

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

Проверьте GV перед открытием хеджа.


Хедж и основная сделка имеют разные размеры лота.

Перед открытием хеджа проверьте открытые ордера и историю, чтобы узнать, был ли открыт противоположный ордер с соответствующим размером лота с OrderOpenTime() позже, чем время открытия основной сделки.

Большое спасибо, я рассмотрю эти варианты и сообщу вам.
 

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

//+------------------------------------------------------------------+
//|  Hedge                                                           |
//+------------------------------------------------------------------+
void Hedgetrade(){
int buy_hedge=0,sell_hedge=0,total=0;
double Pip=Point*10,HedgeLots=NormalizeDouble(OrderLots()*Multiplier,2),SLHedge=StopLossHedge*Pip;
   for(int i=OrdersTotal()-1; i>=0; i--){
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)&& OrderSymbol()==Symbol()){
      total++;
      int ticket=OrderTicket();
      Print("ticket = ",ticket);
     }          
         if(OrderType()==OP_BUY){
            if(buy_hedge==0 && sell_hedge==0 && OrderOpenPrice()>Bid+Hedge*Pip)
               GlobalVariableCheck(ticket);
               sell_hedge=OrderSend(Symbol(),OP_SELL,HedgeLots,Bid,3,Bid+SLHedge,0,"Hedge",0,0,Blue);
                  GlobalVariableSet(ticket,1);
                 }
         if(OrderType()==OP_SELL){
            if(sell_hedge==0 && buy_hedge==0 && OrderOpenPrice()<Ask-Hedge*Pip)
               GlobalVariableCheck(ticket);
               buy_hedge=OrderSend(Symbol(),OP_BUY,HedgeLots,Ask,3,Ask-SLHedge,0,"Hedge",0,0,Red);
                  GlobalVariableSet(ticket,1);
              }
            }
          }