MQL4 - automated forex trading   /  

Форум

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

К списку тем  | 1 2 Авторизуйтесь или зарегистрируйтесь, чтобы создать новую тему

avatar
274
liza 12.02.2008 16:59 
Я написала советник, который расотает с отложенными ордерами, и если ордер открылся остальные отложенные удаляются.  У меня возникла проблемма.  Ниже кусок кода который по какой-то причине не работает (вернее работает но не обращает внимания на 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]);

article

Статистический отчет №4

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


avatar
13989
komposter 12.02.2008 17:20 
liza писал (а):
if(k[1] > OP_SELL && k[2] > OP_SELL) return(0); //если отлаженные

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

avatar
605
space_cowboy 12.02.2008 17:46 
komposter писал (а):
liza писал (а):
if(k[1] > OP_SELL && k[2] > OP_SELL) return(0); //если отлаженные

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

А вот с отладкой у нас действительно проблемы

avatar
4818
SK. 12.02.2008 18:33 
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 Создание обычной программы Учёт ордеров и здесь Учёт ордеров в большой программе .


avatar
274
liza 13.02.2008 00:12 
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 Создание обычной программы Учёт ордеров и здесь Учёт ордеров в большой программе .




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

avatar
2873
Figar0 13.02.2008 00:48 
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)
  {
    // второй цикл перебора  ордеров на предмет нахождения и удаления отложек
  }

avatar
4818
SK. 13.02.2008 02:42 
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 Торговые операции Закрытие и удаление ордеров .


avatar
274
liza 13.02.2008 12:57 
Скажите пожалуйста, почему последний 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);



avatar
274
liza 13.02.2008 13:16 
Вообще мне надо, если откроется один отложенный ордер,  удалить другой и на его место выставить отложенный ордер с измененным лотом.

avatar
4818
SK. 13.02.2008 13:58 
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 в верхней строке редактора).

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

К списку тем   | 1 2  

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