Ваши вопросы по языку MQL4

Александр_Стручков

Интересующийся
Величины с плавающей точкой нельзя сравнивать на равенство, поскольку они хранятся округленными до ближайшей степени двойки. Попробуйте так
Код:
if (MathAbs(OrderStopLoss() - OrderOpenPrice()+SL*Point) < Point)
В stdlib есть функция CompareDoubles, можно ее использовать.

Спасибо! Для ордеров на покупку работает! :)

А с ордерами на продажу нет.. Там нужно учитывать спред, спред плавающий. Можно ли как-то узнать значение спреда в момент открытия ордера? Т.е. получить к.л. значение спреда из истории?

Родилась мысль создать массив для хранения определенных данных по каждому открытому ордеру. Например, тикет ордера, спред в этот момент. Далее начать поиск данных по тикету, а исходя из этого уже получить данные спреда в нужный нам момент. что думаете насчет этого?
 
Последнее редактирование:

qqmber

Почетный гражданин
А с ордерами на продажу нет.. Там нужно учитывать спред, спред плавающий. Можно ли как-то узнать значение спреда в момент открытия ордера? Т.е. получить к.л. значение спреда из истории?

Родилась мысль создать массив для хранения определенных данных по каждому открытому ордеру. Например, тикет ордера, спред в этот момент. Далее начать поиск данных по тикету, а исходя из этого уже получить данные спреда в нужный нам момент. что думаете насчет этого?

Думаю вот что.
Во-первых, при организации трала обычно нет смысла проверять, было ли уже изменение стопа. После первого изменения эта проверка ничего интересного не сообщит. Если только у вас не какой-то специальный случай, когда стоп подтягивается только один раз. Вместо этого вычисляйте, где положено находиться стопу в текущий тик, и если он далеко от этого места, дальше чем на спред, например, тогда только подтягивайте.
Во-вторых, вариантов тралов может быть много, но в большинстве случаев спред в момент открытия вам полезен как прошлогодний снег, а вот текущий можно брать в учет, особенно если трал ползет на расстоянии, сопоставимом со спредом.
В-третьих, хранить данные, описывающие прошлое состояние рынка - глобально плохая идея. Где вы будете их брать после перезапуска терминала при открытых позициях?
 

Александр_Стручков

Интересующийся
Думаю вот что.
Во-первых, при организации трала обычно нет смысла проверять, было ли уже изменение стопа. После первого изменения эта проверка ничего интересного не сообщит. Если только у вас не какой-то специальный случай, когда стоп подтягивается только один раз. Вместо этого вычисляйте, где положено находиться стопу в текущий тик, и если он далеко от этого места, дальше чем на спред, например, тогда только подтягивайте.
Во-вторых, вариантов тралов может быть много, но в большинстве случаев спред в момент открытия вам полезен как прошлогодний снег, а вот текущий можно брать в учет, особенно если трал ползет на расстоянии, сопоставимом со спредом.
В-третьих, хранить данные, описывающие прошлое состояние рынка - глобально плохая идея. Где вы будете их брать после перезапуска терминала при открытых позициях?

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

А проверка на изменение стоплосса нужна вот зачем:
Идея состоит в том, что тралл должен начать тащить стоплосс только после того, как цена пройдет определенный предел. Например 40 пунктов. Первое перемещение стоплосса идет сразу на 30-40 пунктов, а потом в след за ценой подтягивается по 1 пункту с каждым движением цены на новый максимум.

Дело в том, что если не делать проверку "изменялся ли стоплосс", то как еще оператору указать, что от этого типа трейлинга нужно переходить к другому типу? Т.е. пока стоплосс не изменялся, мы ждем пробития ценой уровня в эти 40 пунктов.

Однако если проверку не делать, то второй тип трала сразу же начнет тащить за собой стоплосс.

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

Хотя может я изобретаю велосипед и просто не знаком с какой-то полезной для меня в данный момент функцией..:D

А вопрос пока-что остается нерешенным..
 

mobidik

-----
Код:
MAX(a,b,c)=a<b?b<c?c:b:c<a?a:c;
MIN(a,b,c)=a>b?b>c?c:b:c>a?a:c;
:D

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

qqmber

Почетный гражданин

qqmber

Почетный гражданин
qqmber, т.к. я только в начале пути, не могли бы Вы растолковать мне правую часть данного уравнения, как бы и понятно, но ранее подобную запись ни где не встречал, хочу услышать Ваш комментарий или где можно с этим ознакомиться, спс.
MQL, как и другие С-подобные языки, имеет сокращенный вариант оператора if
if(yesno) r=ок; else r=fail; можно короче записать
r=yesno ? ok : fail;
Эта форма часто используется, когда yesno, ok и fail короткие и ясные, для экономии, чтобы не писать к ним длинные if .. else.
Заодно широко встречается в "obfuscated C code" - синтаксически и алгоритмически правильных, но совершенно нечитаемых программах. Так пишут для скрытия алгоритма или для фана. Целые соревнования проводят даже, кто непонятнее код напишет :)
Так вот, ларчик просто открывается, тут три вложенных кратких оператора x?y:z

Код:
max = a<b ? (b<c ? c : b) : (c<a ? a : c);

Полный эквивалент 
if(a<b)
   if(b<c) max=c;
   else max=b;
else 
   if(c<a) max=a;
   else max=c;
Значок :D означает, что так писать не надо, но можно порадоваться, сколько интересного впереди у людей, начавших изучать программирование.
Ффууу :work-hard: теперь должно быть ясно.
 

mobidik

-----
Значок :D означает, что так писать не надо, но можно порадоваться, сколько интересного впереди у людей, начавших изучать программирование.
Ффууу :work-hard: теперь должно быть ясно.

Более чем, кратко и доходчиво.
Благодарю, жму руку!
 

tatianati

Активный участник
Перед этим циклом с модификацией отложек надо написать ещё один цикл с обнаружением сработавших. Если сработавшие есть, цикл с модификацией можно не выполнять.
Спасибо, но мне нужно чтобы не весь цикл не выполнялся а только модификация селл ордеров если селлимит стал рыночным, так же отдельно для бай.
Пытаюсь записать: - если нет открытой позиции можно передвигать,
соответственно если есть недолжен передвигать или ошибаюсь?
Вот так делаю для селл
PHP:
if(OrderType()==OP_SELLLIMIT)
{s_lm++; 
   if(high>0.2 && OrderOpenPrice()!=high && ExistPositions(NULL, OP_SELL, -1) <1) { // если нет селл--позиций, то переношу лимитник на новый уровень
               modify_limit_order(OP_SELLLIMIT, high);
        }

Вот так смотрю, есть ли позиции

PHP:
bool ExistPositions(string sy="", int op=-1, int mn=-1, datetime ot=0) {
  int i, k=OrdersTotal();
 
  if (sy=="0") sy=Symbol();
  for (i=0; i<k; i++) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
      if (OrderSymbol()==sy || sy=="") {
        if (OrderType()==OP_BUY || OrderType()==OP_SELL) {
          if (op<0 || OrderType()==op) {
            if (mn<0 || OrderMagicNumber()==mn) {
              if (ot<=OrderOpenTime()) return(True);
            }
          }
        }
      }
    }
  }
  return(False);
}
Не получается, помогите пожалуйста.
 

Александр_Стручков

Интересующийся
Спасибо, но мне нужно чтобы не весь цикл не выполнялся а только модификация селл ордеров если селлимит стал рыночным, так же отдельно для бай.
Пытаюсь записать: - если нет открытой позиции можно передвигать,
соответственно если есть недолжен передвигать или ошибаюсь?

В таком случае сделайте две bool переменных. Одну для sell ордеров, вторую для buy.

А потом задайте условие: если проверка, например, по sell ордерам показала результат true, то цикл модификации для этих ордеров не выполнять.

Аналогично сделать и для buy :)
 

tatianati

Активный участник
В таком случае сделайте две bool переменных. Одну для sell ордеров, вторую для buy.

А потом задайте условие: если проверка, например, по sell ордерам показала результат true, то цикл модификации для этих ордеров не выполнять.

Аналогично сделать и для buy :)
Покажите пожалуйста как это например должно выглядеть.
bool flag=false;
 
Последнее редактирование:

Александр_Стручков

Интересующийся
Покажите пожалуйста как это например должно выглядеть.
bool flag=false;

Только сейчас обратил внимание, что необходимая bool переменная у Вас уже имеется.
В таком случае я себе представляю это так:


PHP:
Сначала идет Ваш код проверки на наличие открытых позиций

bool ExistPositions(string sy="", int op=-1, int mn=-1, datetime ot=0) {
  int i, k=OrdersTotal();
 
  if (sy=="0") sy=Symbol();
  for (i=0; i<k; i++) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
      if (OrderSymbol()==sy || sy=="") {
        if (OrderType()==OP_BUY || OrderType()==OP_SELL) {
          if (op<0 || OrderType()==op) {
            if (mn<0 || OrderMagicNumber()==mn) {
              if (ot<=OrderOpenTime()) return(True);
            }
          }
        }
      }
    }
  }
  return(False);
}

// теперь проверяем значение ExistPositions и исходя из этого уже два варианта работы функции модификации ордеров:

if(OrderType()==OP_SELLLIMIT && ExistPositions=False) //(в условие добавляем проверку ExistPositions )
{s_lm++;  
   if(high>0.2 && OrderOpenPrice()!=high && ExistPositions(NULL, OP_SELL, -1) <1) 
   modify_limit_order(OP_SELLLIMIT, high); 
 }
Надеюсь, что я правильно понял задачу и, если что-то не так, профессионалы подправят :D
 

tatianati

Активный участник
Только сейчас обратил внимание, что необходимая bool переменная у Вас уже имеется.
В таком случае я себе представляю это так:


PHP:
Сначала идет Ваш код проверки на наличие открытых позиций

bool ExistPositions(string sy="", int op=-1, int mn=-1, datetime ot=0) {
  int i, k=OrdersTotal();
 
  if (sy=="0") sy=Symbol();
  for (i=0; i<k; i++) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
      if (OrderSymbol()==sy || sy=="") {
        if (OrderType()==OP_BUY || OrderType()==OP_SELL) {
          if (op<0 || OrderType()==op) {
            if (mn<0 || OrderMagicNumber()==mn) {
              if (ot<=OrderOpenTime()) return(True);
            }
          }
        }
      }
    }
  }
  return(False);
}

// теперь проверяем значение ExistPositions и исходя из этого уже два варианта работы функции модификации ордеров:

if(OrderType()==OP_SELLLIMIT && ExistPositions=False) //(в условие добавляем проверку ExistPositions )
{s_lm++;  
   if(high>0.2 && OrderOpenPrice()!=high && ExistPositions(NULL, OP_SELL, -1) <1) 
   modify_limit_order(OP_SELLLIMIT, high); 
 }
Надеюсь, что я правильно понял задачу и, если что-то не так, профессионалы подправят :D
Почему сначала идет код, код проверки на наличие открытых позиций вообще за пределами start то есть сейчас уже void OnTick()
 
Последнее редактирование:

Александр_Стручков

Интересующийся
Почему сначала идет код, код проверки на наличие открытых позиций вообще за пределами start то есть сейчас уже void OnTick() Компилятор ругается '&&' - l-value require '==' - l-value require

Блин.. пропустил один знак. Вот так правильно:

PHP:
if(OrderType()==OP_SELLLIMIT && ExistPositions==False) //
 
Последнее редактирование:

Александр_Стручков

Интересующийся
Всем доброго времени!

Написал код для выставления стоплосса у всех открытых ордеров. Для позиций на покупку выставляет идеально, а для позиций на продажу постоянно присутствует какая-то погрешность. Т.е. если нужно выставить стоплосс 100п., он выставляет то 95, то 97, то 101 и т.д. В чем может быть проблема? o_o

Код ниже
PHP:
extern int SL=100;      // StopLoss

void OnStart()
{RefreshRates();

bool mod;                                       //ей возвращается значение Ordermodify()
double take;                                    //TakeProfit рассчитанный
double stopl;                                   //StopLoss рассчитанны
int i=OrdersTotal();
bool ordslct;                                   //ей возвращается значение OrderSelect()
int  level;   //для хранения значения минимально допустимого значения стопа и тейка
for(i--;i>=0;i--) // Перебирает по очереди все открытые ордеры.
{ordslct=OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
level=MarketInfo(OrderSymbol(),MODE_STOPLEVEL);
 if (OrderType()==OP_BUY)
  {if (OrderStopLoss()==0)
      {if (SL>0&&SL<level) stopl=level;
      else {if (SL>level) stopl=OrderOpenPrice()-SL*Point;}};
   if (OrderStopLoss()==0) stopl=OrderStopLoss();
   mod=OrderModify(OrderTicket(),OrderOpenPrice(),stopl,OrderTakeProfit(),OrderExpiration(),clrNONE);// выставить стоплосс и тейкпрофит
  };

  if (OrderType()==OP_SELL)
  {if (OrderStopLoss()==0)
      {if (SL>0&&SL<level) stopl=level;
      else {if (SL>level) stopl=OrderOpenPrice()+SL*Point;}};
   if (OrderStopLoss()!=0) stopl=OrderStopLoss();
   mod=OrderModify(OrderTicket(),OrderOpenPrice(),stopl,OrderTakeProfit(),OrderExpiration(),clrNONE); //  выставить стоплосс и тейкпрофит
  };

};

}


То работает идеально, то косячит со стоплоссами для sell ордеров.. Уже мозг сломал, не могу врубиться..
 
Последнее редактирование:

volodymyr67

Гуру форума
Всем приет !

подскажите пожалоста как этот индикатор прописать сюда чтоб по стрелкам торговал
double UpArr(int bar){ return( iCustom(NULL, timeframe, "12_G", gi_76, gi_80, gi_84, gi_88, 4, bar ) ); }
double DnArr(int bar){ return( iCustom(NULL, timeframe, "12_G", gi_76, gi_80, gi_84, gi_88, 5, bar ) ); }
 

Вложения

  • Rubicon+Indicator.mq4
    29,3 КБ · Просмотры: 22
  • Rubicon+Indicator.ex4
    22,7 КБ · Просмотры: 17

qqmber

Почетный гражданин
Написал код для выставления стоплосса у всех открытых ордеров.
Не сильно вникая в логику, вижу, что
if (OrderStopLoss()==0) stopl=OrderStopLoss();
if (OrderStopLoss()!=0) stopl=OrderStopLoss();
для buy и sell.
Кроме того, пара советов.
Конструкция for(i--;i>=0;i--) хотя и формально правильная, но шибко нетрадиционная. Обычно пишут for(i=OrdersTotal()-1;i>=0;i--) так чтобы i нигде вне цикла не использовалось. Помогает избежать ошибок, когда циклов больше чем один.
Точку с запятой после блока {} ставить не надо.
 

tatianati

Активный участник
Только сейчас обратил внимание, что необходимая bool переменная у Вас уже имеется.
В таком случае я себе представляю это так:


PHP:
Сначала идет Ваш код проверки на наличие открытых позиций

bool ExistPositions(string sy="", int op=-1, int mn=-1, datetime ot=0) {
  int i, k=OrdersTotal();
 
  if (sy=="0") sy=Symbol();
  for (i=0; i<k; i++) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
      if (OrderSymbol()==sy || sy=="") {
        if (OrderType()==OP_BUY || OrderType()==OP_SELL) {
          if (op<0 || OrderType()==op) {
            if (mn<0 || OrderMagicNumber()==mn) {
              if (ot<=OrderOpenTime()) return(True);
            }
          }
        }
      }
    }
  }
  return(False);
}

// теперь проверяем значение ExistPositions и исходя из этого уже два варианта работы функции модификации ордеров:

if(OrderType()==OP_SELLLIMIT && ExistPositions=False) //(в условие добавляем проверку ExistPositions )
{s_lm++;  
   if(high>0.2 && OrderOpenPrice()!=high && ExistPositions(NULL, OP_SELL, -1) <1) 
   modify_limit_order(OP_SELLLIMIT, high); 
 }
Надеюсь, что я правильно понял задачу и, если что-то не так, профессионалы подправят :D
Профессионалы посмотрели и видимо решили что всё правильно(или не посмотрели).
Однако не работает как нужно. Сделала по Вашей рекомендации вот так
PHP:
for(i=OrdersTotal()-1; i>=0; i--) 
     {OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
      if(OrderSymbol()==Symbol() && OrderMagicNumber()==magic ) 
        {//пересчитываем количество ордеров:
         if(OrderType()==OP_BUY)      {op_b++; }  
         if(OrderType()==OP_SELL)     {op_s++; }  
         if(OrderType()==OP_BUYLIMIT && ExistPositions == False) 
           {b_lm++; 
            if(low>0.2 && OrderOpenPrice()!=low &&  
            ExistPositions(NULL, OP_BUY, magic) <1) {// если нет бай--позиций, то переношу лимитник на новый уровень
               modify_limit_order(OP_BUYLIMIT, low);
               Sleep(1000*10);
              }
           }
         if(OrderType()==OP_SELLLIMIT && ExistPositions == False)
           {s_lm++; 
            if(high>0.2 && OrderOpenPrice()!=high && 
            ExistPositions(NULL, OP_SELL, magic) <1) { // если нет селл--позиций, то переношу лимитник на новый уровень
               modify_limit_order(OP_SELLLIMIT, high);
               Sleep(1000*10);
              }
           }
        }
     }
что неправильно?
 
Последнее редактирование:

Дмитрий 2010

Интересующийся
Добрый день. Скажите пожалуйста существуел ли функция чтобы присоединяла определённый скрипт при работе советника. Пример if(a+b>5 && Script125==0){Присоединяем скрипт;Script125=1;}.
 
Верх