Скачать MetaTrader 5

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

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Как подобрать необходимый сигнал и быстро подписаться на него
traderEvgen
412
traderEvgen 2016.10.28 20:40 

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

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

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

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

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

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

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

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

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

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

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

Yury Reshetov
13459
Yury Reshetov 2016.10.29 16:10  
Andrey F. Zelinsky:

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

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

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

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

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

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

   return;
}
Andrey F. Zelinsky
31295
Andrey F. Zelinsky 2016.10.29 16:28  
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
13459
Yury Reshetov 2016.10.29 16:49  
Andrey F. Zelinsky:


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

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

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

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

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

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

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

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

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

traderEvgen
412
traderEvgen 2016.10.30 13:05  
Yury Reshetov:


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

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

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

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

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

 

 

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

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