Скачать MetaTrader 5

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

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
traderEvgen
441
traderEvgen  

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

И вроде все работало правильно, на тестере точно правильно, но на счете была проблема.  Было открыто 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;
}
Yury Reshetov
13490
Yury Reshetov  
traderEvgen:

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

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

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

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

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

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

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

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

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

Yury Reshetov
13490
Yury Reshetov  
Andrey F. Zelinsky:

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

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

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

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

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

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

   return;
}
Andrey F. Zelinsky
33428
Andrey F. Zelinsky  
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 попыток открытия
Yury Reshetov
13490
Yury Reshetov  
Andrey F. Zelinsky:


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

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

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

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

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

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

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

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

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

traderEvgen
441
traderEvgen  
Yury Reshetov:


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

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

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

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

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

 

 

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

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