Поиск magic номера в массиве

 

Здравствуйте!


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

В общем приближении задача такая:

Есть массив magic, есть открытые ордера по этим magic номерам, есть не открытые. Скрипт берет по очереди перебирает все ордера и сравнивает их magic номер с номерами из массива, если не находит, то открывает ордер с этим magic. Естественно проблема в том, что взяв ордер и сравнивая, программа находит одно совпадение, а на остальные не совпавшие открывает ордера и так далее по всем открытым ордерам.

Пробовал циклами и условиями, затем логическими функциями, чтобы передавали false или true в том или ином случае, и операторы break и continue... Понимаю, что как то можно это реализовать, а никак додумать не могу, уже голова кипит.

Помогите с идеями, подсказками, вариантами кода...

Вот один из вариантов, не правильно работающий, по естественным причинам...

void OnStart()
{
int ArrayMagicNumber[]={1,2,3};
int c=OrdersTotal();
for(int i=0; i<c; i++)
{
for(int j=0; j<ArraySize(ArrayMagicNumber); j++)
{
OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
if(OrderMagicNumber()==ArrayMagicNumber[j])
{
MessageBox("Открыт " +ArrayMagicNumber[j]);
}
else
{
if(Bid<1.3800)
OrderSend("EURUSD",OP_SELLLIMIT, 0.01, 1.3800, 3, 1.4000, 1.3600, "Open", ArrayMagicNumber[j], 0, clrNONE);
}
}
MessageBox(GetLastError());
i++;
}
}


 
alexhhl:

Здравствуйте!


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

В общем приближении задача такая:

Есть массив magic, есть открытые ордера по этим magic номерам, есть не открытые. Скрипт берет по очереди перебирает все ордера и сравнивает их magic номер с номерами из массива, если не находит, то открывает ордер с этим magic. Естественно проблема в том, что взяв ордер и сравнивая, программа находит одно совпадение, а на остальные не совпавшие открывает ордера и так далее по всем открытым ордерам.

Пробовал циклами и условиями, затем логическими функциями, чтобы передавали false или true в том или ином случае, и операторы break и continue... Понимаю, что как то можно это реализовать, а никак додумать не могу, уже голова кипит.

Помогите с идеями, подсказками, вариантами кода...

Вот один из вариантов, не правильно работающий, по естественным причинам...

void OnStart()
{
int ArrayMagicNumber[]={1,2,3};
int c=OrdersTotal();
for(int i=0; i<c; i++)
{
for(int j=0; j<ArraySize(ArrayMagicNumber); j++)
{
OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
if(OrderMagicNumber()==ArrayMagicNumber[j])
{
MessageBox("Открыт " +ArrayMagicNumber[j]);
}
else
{
if(Bid<1.3800)
OrderSend("EURUSD",OP_SELLLIMIT, 0.01, 1.3800, 3, 1.4000, 1.3600, "Open", ArrayMagicNumber[j], 0, clrNONE);
}
}
MessageBox(GetLastError());
i++;
}
}



Я-бы поменял местами циклы. Берёшь магик и ищешь его среди открытых ордеров... И после мессажа поставь прерывание цикла break

А else совсем не уместно, это и даёт открытие всех ордеров повторно.

 

Спасибо, помогла информация! Продвинулся)! Правда пришлось еще один цикл добавить, чтобы каждую цифру из массива, искать в другом массиве, и только после этого делать выводы). Рынок закрыт с ордерами не получается посмотреть, magic номера ордеров заменил еще одним массивом. Вот что в итоге получилось:

Массив Array2[] отличается от массива ArrayMagicNumber[] цифрой 3, ее отсутствие и пытаюсь найти. Скрипт находит все, которые совпадают. Теперь главный вопрос, как сделать, чтобы выводилось сообщение, что цифра 3 не найдена??? Помогите кто может, у кого мозг как компьютер, а то я с этими циклами ели как думаю...

void OnStart()
{
int ArrayMagicNumber[]={1,2,3,4,5};
int Array2[]={2,5,4,1};
int c=ArraySize(Array2);
for(int j=0; j<ArraySize(ArrayMagicNumber); j++)
{
for(int i=0; i<c; i++)
{
if(Array2[i]==ArrayMagicNumber[j])
{
MessageBox("Открыт выходим " +Array2[i]);
break;
}
for(int a=0; a<c; a++)
{
if(Array2[a]==ArrayMagicNumber[j])
{
MessageBox("Выходим открыт " +Array2[a]);
break;
}
}
}
MessageBox(GetLastError());
}
}


 
alexhhl:

Спасибо, помогла информация! Продвинулся)! Правда пришлось еще один цикл добавить, чтобы каждую цифру из массива, искать в другом массиве, и только после этого делать выводы). Рынок закрыт с ордерами не получается посмотреть, magic номера ордеров заменил еще одним массивом. Вот что в итоге получилось:

Массив Array2[] отличается от массива ArrayMagicNumber[] цифрой 3, ее отсутствие и пытаюсь найти. Скрипт находит все, которые совпадают. Теперь главный вопрос, как сделать, чтобы выводилось сообщение, что цифра 3 не найдена??? Помогите кто может, у кого мозг как компьютер, а то я с этими циклами ели как думаю...




void OnStart()
  {
   int ArrayMagicNumber[]={1,2,3,4,5};
   int Array2[];
   ArrayResize(Array2,ArraySize(ArrayMagicNumber));
   ArrayInitialize(Array2,0);

   for(int i=0;i<OrdersTotal();i++)
     {
      if(OrderSelect(i,SELECT_BY_POS))
        {
         for(int j=0; j<ArraySize(ArrayMagicNumber); j++)
           {
            if(OrderMagicNumber()==ArrayMagicNumber[j])
              {
               Array2[j]++;
               break;

              }
           }
        }
     }
     for (int i=0;i<ArraySize(Array2);i++) {
      if (Array2[i]==0) Alert(" Нет открытых позиций по магику ",ArrayMagicNumber[i]);
     }
     
  }
 
alexhhl:

Спасибо, помогла информация! Продвинулся)! Правда пришлось еще один цикл добавить, чтобы каждую цифру из массива, искать в другом массиве, и только после этого делать выводы). Рынок закрыт с ордерами не получается посмотреть, magic номера ордеров заменил еще одним массивом. Вот что в итоге получилось:

Массив Array2[] отличается от массива ArrayMagicNumber[] цифрой 3, ее отсутствие и пытаюсь найти. Скрипт находит все, которые совпадают. Теперь главный вопрос, как сделать, чтобы выводилось сообщение, что цифра 3 не найдена??? Помогите кто может, у кого мозг как компьютер, а то я с этими циклами ели как думаю...

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

Зачем тебе ещё один массив??? Перебираешь ордера и если магик равен проверяемому из массива ... или проверили все ордера но с таким магиком ордера нету...

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

 
Если предыдущий код обернуть условием совершать его только когда количество открытых ордеров меньше пяти, вообще не будет жрать машинное время.)
 
Спасибо большое! Все помогли)! В понедельник проверю, как,что работает). Еще попробую придумать как-нибудь еще...
 
alexhhl:

Здравствуйте!

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

В общем приближении задача такая:

Есть массив magic, есть открытые ордера по этим magic номерам, есть не открытые. Скрипт берет по очереди перебирает все ордера и сравнивает их magic номер с номерами из массива, если не находит, то открывает ордер с этим magic. Естественно проблема в том, что взяв ордер и сравнивая, программа находит одно совпадение, а на остальные не совпавшие открывает ордера и так далее по всем открытым ордерам.

Пробовал циклами и условиями, затем логическими функциями, чтобы передавали false или true в том или ином случае, и операторы break и continue... Понимаю, что как то можно это реализовать, а никак додумать не могу, уже голова кипит.

Помогите с идеями, подсказками, вариантами кода...

Вот один из вариантов, не правильно работающий, по естественным причинам...

Хороший вопрос. Первый совет - постарайтесь решать задачу по частям, а не всю сразу, целиком. Как решить ее по частям частично уже написано в Вашем вопросе. Но для начал избавимся от алогизмов:

Есть массив magic, есть открытые ордера по этим magic номерам, есть не открытые. Скрипт берет по очереди перебирает все ордера и сравнивает их magic номер с номерами из массива, если не находит, то открывает ордер с этим magic. Естественно проблема в том, что взяв ордер и сравнивая, программа находит одно совпадение, а на остальные не совпавшие открывает ордера и так далее по всем открытым ордерам.

Подумайте сами, если ордер открыт - то он уже принадлежит одному из маджику. Значит нужно перебирать не открытые ордера, а список magic'ов, ведь Вас интересуют отсутствующие ордера а не уже установленные! Итак, перебираем список маджиков:

///
/// Set SellLimit order by rulses.
///
void OnStart()
{
   int ArrayMagicNumber[]={1,2,3,4,5};
   int total = ArraySize(ArrayMagicNumber);
   for(int i = 0; i < total; i++)
   {
      //...
   }
}

Код весьма тривиален и практически идентичен Вашему. Теперь думаем, что нужно поместить внутрь цикла for. Очевидно там должно быть условие типа этого:

for(int i = 0; i < total; i++)
   {
      //Если ордер с текущим маджиком не установлен - установить его.
   }

Нет ничего проще чем написать нужное действие в виде обычного комментария. Теперь попытаемся наш комментарий сконвертировать в понятный для компилятора язык кодов. Очевидно что 'Если' это 'if'. А "...ордер с текущим маджиком не установлен..." - некое условие, которое будет очень просто выразить в виде функции PendingOrderNotFind, которая вернет true, если ордер с переданным ей маджиком не будет найден и false если она все-таки найдет его (Как будет работать эта функция - на текущем этапе не наша проблема).:

for(int i = 0; i < total; i++)
{
   if(PendingOrderNotFind(...))
      ...
}

Теперь осталось всего несколько штрихов. Первое - выяснить текущий маджик, второе - передать его функции OrderNotFind, третье - установить ордер, в случае если OrderNotFind вернет false, т.е. не найдет ордер. Для последнего действия тоже подойдет функция, назовем ее InstallPendingOrder(). Вот что у меня получилось:

///
/// Set SellLimit order by rulses.
///
void OnStart()
{
   int ArrayMagicNumber[]={1,2,3,4,5};
   int total = ArraySize(ArrayMagicNumber);
   for(int i = 0; i < total; i++)
   {
      int magic = ArrayMagicNumber[i];
      if(PendingOrderNotFind(magic))
         InstallPendingOrder(magic);
   }
}
///
/// Return true if pending order with magic 'magic' not find, if find - return false.
///
bool PendingOrderNotFind(int magic)
{
   return true;
}
///
/// Install pending order with magic 'magic'.
///
void InstallPendingOrder(int magic)
{
   ;
}

Обратите внимание, что тела функций PendingOrderNotFind и InstallPendingOrder пустые. Однако код работает и компилятор никаких ошибок не видит. Этого мы и добиваемся - что бы на каждом этапе написания - мы имели полностью работоспособное приложение. Далее осталось лишь заполнить тела функций, и получить код в целом:

///
/// Set SellLimit order by rulses.
///
void OnStart()
{
   int ArrayMagicNumber[]={1,2,3,4,5};
   int total = ArraySize(ArrayMagicNumber);
   for(int i = 0; i < total; i++)
   {
      int magic = ArrayMagicNumber[i];
      if(PendingOrderNotFind(magic))
         InstallPendingOrder(magic);
   }
}

///
/// Return true if pending order with magic 'magic' not find, if find - return false.
///
bool PendingOrderNotFind(int magic)
{
   // Нет активного ордера - возвращаем ложь.
   if(!OrderSelect(magic, SELECT_BY_TICKET, MODE_TRADES))return false;
   //Если ордер не отложенный (Buy или Sell) - возвращаем ложь.
   if(OrderType() == ORDER_TYPE_BUY ||
      OrderType() == ORDER_TYPE_SELL)
      return false;
   return true;
}
///
/// Install pending order with magic 'magic'.
///
void InstallPendingOrder(int magic)
{
   if(Bid<1.3800)
      OrderSend(Symbol(), OP_SELLLIMIT, 0.01, 1.3800, 3, 1.4000, 1.3600, "Open", magic, 0, clrNONE);
}

Надеюсь код в функции OnStart() получился настолько очевидным, что вопросов что он делает не возникнет даже у самого зеленого новичка и даже если мы уберем реализации функций которые он задействует:

///
/// Set SellLimit order by rulses.
///
void OnStart()
{
   int ArrayMagicNumber[]={1,2,3,4,5};
   int total = ArraySize(ArrayMagicNumber);
   //Перебираем маджики из списка маджиков.
   for(int i = 0; i < total; i++)
   {
      int magic = ArrayMagicNumber[i]; //Получаем текущий маджик.
      if(PendingOrderNotFind(magic))   //Если отложенный ордер с текущим маджиком не найден...
         InstallPendingOrder(magic);   //...устанавливаем новый отложенный ордер.
   }
}
Сам капитан очевидность позавидовал бы функции OnStart. Но этого и надо добиваться в каждом, даже самом маленьком сегменте программы.
 
Спасибо за урок С-4. Немного позже посмотрю внимательнее,как и что работает. Не знал о существовании таких встроенных функций как OrderNotFound и InstallPendingOrder..Хотя в основном по справке самого mql обучаюсь.. Главное, чтобы не получалось так,когда скрипт берет первый magic и сравнивает с первым, вторым, третьим и т.д. ордерами, не открывал ордера с этим magic по всем ордерам кроме одного,который уже открыт.. В общем, позже посмотрю, как работает. Спасибо, за совет, огромное!
 
Так этих функций и нет в мкл4. Я их написал специально, чтобы упростить логику программы.
 

C-4:

Обратите внимание, что тела функций PendingOrderNotFind и InstallPendingOrder пустые. Однако код работает и компилятор никаких ошибок не видит. Этого мы и добиваемся - что бы на каждом этапе написания - мы имели полностью работоспособное приложение. Далее осталось лишь заполнить тела функций, и получить код в целом:

Что-то здесь не так:
if(!OrderSelect(magic, SELECT_BY_TICKET, MODE_TRADES))return false;

Надо бы заменить на что-то другое.

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