Как организовать работу советника одновременно с несколькими ордерами?

 
Я написала советник, который расотает с отложенными ордерами, и если ордер открылся остальные отложенные удаляются.  У меня возникла проблемма.  Ниже кусок кода который по какой-то причине не работает (вернее работает но не обращает внимания на if ) .  Может подскажите в чем проблема?

for(int i=0;i<=OrdersTotal();i++)
{

if(OrderSelect(i, SELECT_BY_POS)==true)

{
if(OrderSymbol()==Symbol())
{
t[i]=OrderTicket();
k[i]=OrderType();
l[i]=OrderLots();
Print("k[i] =",k[i]," l[i] =",l[i], " t[i] =",t[i]);
if(k[1] > OP_SELL && k[2] > OP_SELL) return(0); //если отлаженные
if((k[1]==OP_BUY || k[2]==OP_BUY) && l[1]==l[2]) //если один открылся на BUY
{
if(k[1]==OP_BUY) OrderDelete(t[2]);
if(k[2]==OP_BUY) OrderDelete(t[1]);
 
liza:
if(k[1] > OP_SELL && k[2] > OP_SELL) return(0); //если отлаженные

Если бы я был if-ом, я бы тоже не сработал ;)
 
komposter:
liza:
if(k[1] > OP_SELL && k[2] > OP_SELL) return(0); //если отлаженные

Если бы я был if-ом, я бы тоже не сработал ;)

А вот с отладкой у нас действительно проблемы
 
liza:
Я написала советник, который расотает с отложенными ордерами, и если ордер открылся остальные отложенные удаляются. У меня возникла проблемма. Ниже кусок кода который по какой-то причине не работает (вернее работает но не обращает внимания на if ) . Может подскажите в чем проблема?

for(int i=0;i<=OrdersTotal();i++)
{
if(OrderSelect(i, SELECT_BY_POS)==true)
{
if(OrderSymbol()==Symbol())
{
t[i]=OrderTicket();
k[i]=OrderType();
l[i]=OrderLots();
Print("k[i] =",k[i]," l[i] =",l[i], " t[i] =",t[i]);
if(k[1] > OP_SELL && k[2] > OP_SELL) return(0); //если отлаженные
if((k[1]==OP_BUY || k[2]==OP_BUY) && l[1]==l[2]) //если один открылся на BUY
{
if(k[1]==OP_BUY) OrderDelete(t[2]);
if(k[2]==OP_BUY) OrderDelete(t[1]);

В Вашей программе просматривается попытка реализации учёта ордеров (в массивах t[i], k[i] и l[i] ). Это правильное направление мысли. Однако, в такой реализации это годится только для одной конкретной программы. Через некоторое время Вы захотитте её усовершенствовать и Вам придётся всё переделывать. Гораздо эффективнее один раз сделать полноценную функцию учёта ордеров, а после использовать её во многих программах.

Посмотрите здесь Учебник по MQL4 Создание обычной программы Учёт ордеров и здесь Учёт ордеров в большой программе .

 
SK. писал (а):
liza:

Я написала советник, который расотает с отложенными ордерами, и если ордер открылся остальные отложенные удаляются. У меня возникла проблемма. Ниже кусок кода который по какой-то причине не работает (вернее работает но не обращает внимания на if ) . Может подскажите в чем проблема?



for(int i=0;i<=OrdersTotal();i++)

{

if(OrderSelect(i, SELECT_BY_POS)==true)

{

if(OrderSymbol()==Symbol())

{

t[i]=OrderTicket();

k[i]=OrderType();

l[i]=OrderLots();

Print("k[i] =",k[i]," l[i] =",l[i], " t[i] =",t[i]);

if(k[1] > OP_SELL && k[2] > OP_SELL) return(0); //если отлаженные

if((k[1]==OP_BUY || k[2]==OP_BUY) && l[1]==l[2]) //если один открылся на BUY

{

if(k[1]==OP_BUY) OrderDelete(t[2]);

if(k[2]==OP_BUY) OrderDelete(t[1]);




В Вашей программе просматривается попытка реализации учёта ордеров (в массивах t[i], k[i] и l[i] ). Это правильное направление мысли. Однако, в такой реализации это годится только для одной конкретной программы. Через некоторое время Вы захотитте её усовершенствовать и Вам придётся всё переделывать. Гораздо эффективнее один раз сделать полноценную функцию учёта ордеров, а после использовать её во многих программах.



Посмотрите здесь Учебник по MQL4 Создание обычной программы Учёт ордеров и здесь Учёт ордеров в большой программе .

 
Ув SK!
Конечно может это великолепно, но мне все-таки хотелось бы для начала сделать этот может быть и очень простой советник не используя отдельную функцию.  К тому же в описании нет того как потом использовать данные в start().  Могли бы Вы ответить конкретнее.
 
liza:
Ув SK!
Конечно может это великолепно, но мне все-таки хотелось бы для начала сделать этот может быть и очень простой советник не используя отдельную функцию. К тому же в описании нет того как потом использовать данные в start(). Могли бы Вы ответить конкретнее.


В данном случае, если я правильно понял, речь идет всего о нескольких ордерах, и ИМХО нет особой нужды заморачиваться тем о чем говорит SK (хотя говорит он безусловно правильно), если Вы не програмируете "про запас".

Если просто надо удалить оставшиеся отложки после срабатывания одной из них, сделайте два цикла перебора ордеров, первый подсчет OP_BUY и OP_SELL, второй перебор в случае нахождения сработавших ордеров на предмет поиска и удаления отложек... Примерно так...

  int actTotal=OrdersTotal();
  int BuyOrders=0;
  int SellOrders=0;
  int TotalOrders=0;
  for(int i=actTotal-1;i>=0;i--)
  {
    if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
    {
      if( OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
      {
         TotalOrders++;
         if(OrderType()==OP_BUY) BuyOrders++;
         if(OrderType()==OP_SELL) SellOrders++;
      }
    }
  }
  if ((BuyOrders!=0 || SellOrders!0) && BuyOrders+SellOrders!=TotalOrders)
  {
    // второй цикл перебора  ордеров на предмет нахождения и удаления отложек
  }
 
liza:
Ув SK!
Конечно может это великолепно, но мне все-таки хотелось бы для начала сделать этот может быть и очень простой советник не используя отдельную функцию. К тому же в описании нет того как потом использовать данные в start(). Могли бы Вы ответить конкретнее.


Ув. Лиза!

Трудно ответить на вопрос, который не очень-то понятен. Вы спрашиваете почему не работает, а представляете произвольный кусок, по которому трудно представить что и как должно работать по замыслу автора.

Чтобы работало, нужно чётко представлять: что и при каких обстоятельствах и как должно работать. Например, в массиве k[i] учитывается тип ордеров. Ниже в конструкции if(k[1] > OP_SELL && k[2] > OP_SELL) рассматриваются два элемента этого массива. Возникает вопрос: а что, отложенных ордеров может быть только 2? Их не предполагается 3 или 4?

А как советник будет реагировать, если вдруг будет только один отложенный ордер, а остальные - рыночные? Это значит, что один из двух элементов массива k[i] будет нулевым? И что тогда будет в конструкции if(k[1] > OP_SELL && k[2] > OP_SELL)? Как она отработает?

Ну, предположим, что 3 ордера. В какой последовательности эти ордера находятся в списке, из которого они считываются в массив k[i] ? Например, первый из трёх - рыночный, а два другие - отложенные. Как в этом случае отработает конструкция if(k[1] > OP_SELL && k[2] > OP_SELL)? А как в других случаях?

...

Если продолжать этот анализ в таком духе и дальше, то обязательно найдётся черта, ниже которой идти не будет смысла, т.к. станет самоочевидно, что без нормального учёта ордеров сколько-нибудь стоящую программу написать невозможно. Весь вопрос всодится к тому, сколько времени придётся потратить. Но результаты окупятся сторицей. Для начала можно посмотреть простую логику учёта в простых программах, например, здесь: Учебник по MQL4 Торговые операции Закрытие и удаление ордеров .

 
Скажите пожалуйста, почему последний if не работает?
Или как сравнить лоты независимо от типа ордера?
for(int i=actTotal-1;i>=0;i--)
{
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if( OrderSymbol()==Symbol())
{
l[i]=OrderLots();
TotalOrders++;
if(OrderType()==OP_BUY) BuyOrders++;
if(OrderType()==OP_SELL) SellOrders++;
if(OrderType()==OP_BUYSTOP) BuyStop++;
if(OrderType()==OP_SELLSTOP) SellStop++;
}
}
if(l[1]!=l[2]) return(0);
 
Вообще мне надо, если откроется один отложенный ордер,  удалить другой и на его место выставить отложенный ордер с измененным лотом.
 
liza:
Скажите пожалуйста, почему последний if не работает?
Или как сравнить лоты независимо от типа ордера?
for(int i=actTotal-1;i>=0;i--)
{
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if( OrderSymbol()==Symbol())
{
l[i]=OrderLots();
TotalOrders++;
if(OrderType()==OP_BUY) BuyOrders++;
if(OrderType()==OP_SELL) SellOrders++;
if(OrderType()==OP_BUYSTOP) BuyStop++;
if(OrderType()==OP_SELLSTOP) SellStop++;
}
}
if(l[1]!=l[2]) return(0);



Потому, что на момент окончания первой итерации значение l[1] сохраняется таким, каким оно было после инициализации массива (для случая 3 ордеров). Т.е., не успел ещё цикл for пройтись по всем ордерам, как тут же управление передаётся за пределы цикла. Если же у Вас всего два ордера, то инднксы у них (точно сказать нельзя, т.к. Вы не представили код, из которого было понятно какой размер массива I[]) должны быть соотв. 0 и 1, а не 1 и 2 (индексы массивов в MQL4 начинаются с 0).

Попутно:
1. В Вашем коде не хватает закрывающей фигурной скобки.
2. Для публикации кода на форуме пользуйтесь вставкой кода (кнопка MQL в верхней строке редактора).

Попробуйте услышать: функция (или блок) учёта ордеров - это не прихоть. Это просто способ корректного программирования. Если Вы сделаете всё правильно, то как раз учёт ордеров и получится.

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