Одновременное открытие двух позиций

 

Написал функцию открытия одновременно двух ордеров.

И вроде все работало правильно, на тестере точно правильно, но на счете была проблема.  Было открыто 4 позиции одновременно вместо 2.

Может кто знает почему ? Может будут советы как переделать ?

 

void OrdersWorker::OrderSendX(int cmd, double stoploss, double takeprofit1, double takeprofit2, string comment)
{
   int count = 0;
   double price = 0;
   ticket1 = -1;
   ticket2 = -1;
    
   while(true)
   {
      if(cmd == OP_BUY)  price = Ask;
      if(cmd == OP_SELL) price = Bid;
      
      if(ticket1 == -1 )
         ticket1 = OrderSend(Symbol(), cmd, lot, price, 3, stoploss, takeprofit1, comment + "_1", magicNumber, 0, Red);
      
      if(ticket1<0)
      {
          Print("OrderSend1 завершилась с ошибкой #",GetLastError());
      }

      Sleep (100);
      RefreshRates();
      
      if(cmd == OP_BUY)  price = Ask;
      if(cmd == OP_SELL) price = Bid;
      
      if(ticket2 == -1 )
         ticket2 = OrderSend(Symbol(), cmd, lot, price, 3, stoploss, takeprofit2, comment + "_2", magicNumber, 0, Green);
        
      if(ticket2<0)
      {
          Print("OrderSend2 завершилась с ошибкой #",GetLastError());
      }
  

      if(ticket1==-1 || ticket2==-1)
      {  
         count++;
         Sleep(2000);
         RefreshRates();
      }
      if ((ticket1!=-1 && ticket2!=-1) || count>5)
      {
         return;
      }
   }

   return;
}
 
traderEvgen:

И вроде все работало правильно, на тестере точно правильно, но на счете была проблема.  Было открыто 4 позиции одновременно вместо 2.

Может кто знает почему ? Может будут советы как переделать ?

Потому что в функции нет никакой обработки ошибок (есть только вывод сообщений в журнал) и за пределы функции тоже ничего не передаётся на предмет: открылись позы или нет.

А поскольку приведённая Вами функция - это всего лишь огрызок от бизнес-логики, а та часть которая её вызывает осталась за кадром, то остаётся лишь гадать, чего Вы там ещё нахимичили.

Однако, поскольку алгоритм вызывающий функцию никоим образом не может контролировать ситуацию при наличии ошибок, то неудивительно, что  невозможно добиться адекватности принятия решений за пределами этой функции.
 
Yury Reshetov:

Потому что в функции нет никакой обработки ошибок ...

Справедливости ради, в приведенной функции ЕСТЬ блок обработки ошибок. Вот его начало:

if(ticket1==-1 || ticket2==-1) { ... }

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

 
Andrey F. Zelinsky:

Справедливости ради, в приведенной функции ЕСТЬ блок обработки ошибок. Вот его начало:

if(ticket1==-1 || ticket2==-1) { ... }

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

Другой вопрос: а толку? Ведь что по условию этого блока, что без него (что в лоб, что по лбу).

Он ведь ничего не обрабатывает и ничего никуда не передаёт, а всего лишь выходит из функции точно также, как он выходит из неё независимо от этого блока (абсолютно бестолковый кусок кода):

...
if ((ticket1!=-1 && ticket2!=-1) || count>5)
      {
         return;
      }
   }

   return;
}
 
Yury Reshetov:

Другой вопрос: а толку? Ведь что по условию этого блока, что без него (что в лоб, что по лбу).

Он ведь ничего не обрабатывает и ничего никуда не передаёт, а всего лишь выходит из функции точно также, как он выходит из неё независимо от этого блока (абсолютно бестолковый кусок кода):

не надо наговаривать на автора -- всё у него предельно осмысленно: 

   int count = 0;
   ticket1 = -1;
   ticket2 = -1;

   while(true)
   {
      if(ticket1 == -1 )
         ticket1 = OrderSend(...);
      
      if(ticket2 == -1 )
         ticket2 = OrderSend(...);

      if(ticket1==-1 || ticket2==-1)
      {  
         count++;
      }
      if ((ticket1!=-1 && ticket2!=-1) || count>5)
      {
         return;
      }
   }
-- выход, когда открыт И бай И селл -- или испробовано 5 попыток открытия
 
Andrey F. Zelinsky:


-- выход, когда открыт И бай И селл -- или испробовано 5 попыток открытия

Угу. И судя по тому, что ticket1 и ticket2 - не являются локальными для этой функции, то скорее всего дополнительная обработка событий открытых/неоткрытых позиций находится за её пределами.

И косяки должны быть тоже за этими пределами.

Ведь с помощью этой функции невозможно открыть одновременно две встречные позы, т.к. направление позы передаётся единожды в аргументе функции cmd и нигде в пределах функции не меняется.

 
Когда сам не можешь найти ошибку, она находится не там, где ищешь. Поэтому нет смысла показывать этот код, в нем все нормально. Ошибка должна быть в другом месте.
 
Yury Reshetov:

Ведь с помощью этой функции невозможно открыть одновременно две встречные позы, т.к. направление позы передаётся единожды в аргументе функции cmd и нигде в пределах функции не меняется.

в этом коде только эта ошибка
 
Andrey F. Zelinsky:
в этом коде только эта ошибка

Сложно сказать, поскольку в приведённом огрызке всей бизнес логики не видно и остаётся только гадать, где находится косяк?

Ведь теоретически можно вызвать эту функцию дважды: один раз для покупки, а второй для продажи. Но у  топикстатера почему-то открываются четыре позы вместо двух. Т.е. эта функция где-то снаружи вызывается четырежды.

 
Yury Reshetov:


Ведь с помощью этой функции невозможно открыть одновременно две встречные позы, т.к. направление позы передаётся единожды в аргументе функции cmd и нигде в пределах функции не меняется.

Это не для открытия встречный позиций. Это для открытия двух позиций в одном направления только с разными стопами. Вызов происходит один раз. 

OrderSendX(OP_BUYSL, TP1, TP2, "main");

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

Может совет дадите, как-бы Вы написали функцию для такой задачи. 

 

 

4 позиции в терминале открылось с промежутком в несколько секунд, а Вызов этой функции принципе возможен раз в 15 минут. Так что дело только в этой функции, остальное проверил 
 
Dmitry Fedoseev:
Когда сам не можешь найти ошибку, она находится не там, где ищешь. Поэтому нет смысла показывать этот код, в нем все нормально. Ошибка должна быть в другом месте.

4 позиции в терминале открылось с промежутком в несколько секунд, а вызов этой функции принципе возможен раз в 15 минут. Так что дело только в этой функции, остальное проверил 
Причина обращения: