Изучаем язык программирования MQL4

AlexeyVik

Программист mql4 mql5
Привет, Алексей!
Эта ветка для тех кто первый раз укусил справочник. Мой вариант всё же проще им читать.
Привет, я не заострял внимание на тернарном операторе, я хотел сказать что i+3 на мой взгляд выглядет неприемлемо в конкретном примере лично для меня.
А по Вашему коду: только та свеча, с которой начинаем поиск.
А может это у меня зашел ум за разум. Помогите, пожалуйста, с кодами разобраться.
В моём примере не только с какого бара начать, но и количество баров для поиска. Соответственно сумма этих значений будет баром на котором надо завершить цикл.
 

Defort

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

gravity

Местный знаток
Возможно глупый вопрос) Но я всё же задам
Код:
if(OrderType()<2 && OrderMagicNumber() == Magic)
Подправил тут немного советник, изначально не было проверки на магик и условие выглядело так:
Код:
if(OrderType()==OP_BUY || OrderType()==OP_SELL)

Я ничего не напутал, он не будет захватывать и бай лимиты, со значением =2 или всё же будет?



Подумал, похоже всё же будет. Хотел чтоб по компактнее было)
Код:
if(OrderType()<2 && OrderType()!=2 && OrderMagicNumber() == Magic)
или
Код:
if(OrderType()==OP_BUY || OrderType()==OP_SELL && OrderMagicNumber() == Magic)

Так ведь правильно?
 

Вложения

  • Screenshot_1.jpg
    Screenshot_1.jpg
    22,6 КБ · Просмотры: 4
Последнее редактирование:

vladradon

Программист
Подумал, похоже всё же будет.
if(OrderType()<2 - будет только 0 и 1 пропускать. Если было бы if(OrderType()<=2 - пропускал бы и 2.
if((OrderType()==OP_BUY || OrderType()==OP_SELL) && OrderMagicNumber() == Magic) - комбинацию ИЛИ отделяем скобками.
 

MERFY

Местный житель
Добрый вечер!

Подскажите, пожалуйста, правильно ли я реализовываю код по сдвигу индикаторе вперед на Shift часов?

Код:
for(int i=limit; i>=0; i--)
   {
     int y = iBarShift(NULL,timeFrame,Time[i]) + Shift; 
      int beg = iBarShift(NULL,_Period,iTime(NULL,timeFrame,y-1)) +Shift;    //iBarShift(NULL,PERIOD_D1,Time[0]) + 1;    // yesterday
    
     //int y = iBarShift(NULL,timeFrame,Time[i]);
     double x=0.0,
            h = iHigh(NULL,timeFrame,beg),
            l = iLow(NULL,timeFrame,beg),
            o = iOpen(NULL,timeFrame,beg),
            c = iClose(NULL,timeFrame,beg);
     if     (c<o)  x=(h+l+c+l)/2;
     else if(c>o)  x=(h+l+c+h)/2;
     else if(c==o) x=(h+l)/2;
 

vladradon

Программист
Подскажите, пожалуйста, правильно ли я реализовываю код по сдвигу индикаторе вперед на Shift часов?
Привет. Вообще-то ты шифтом откатываешь назад. Нулевой бар - текущий и если плюсуешь к нему, то уходишь в историю, а не в вперед.)))
 

MERFY

Местный житель
Привет. Вообще-то ты шифтом откатываешь назад. Нулевой бар - текущий и если плюсуешь к нему, то уходишь в историю, а не в вперед.)))
Возможно я неправильно выразился, я имел в виду, что не хочу видеть на текущем баре перерисовку, а чтобы на текущем баре отображалось значение диапазона хода от предыдущего бара.

Еще хочу сделать сдвиг по GMT для D1, но не понимаю как ((
 

vladradon

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

Еще хочу сделать сдвиг по GMT для D1, но не понимаю как ((
Это не так просто, как хотелось бы... Не факт, что придется изменить только один цикл.))) Возможно придется переделать весь код и не факт, что будет положительный рез...
 

gravity

Местный знаток
Приветствую!

1) Обрезал историю показаний индикатора сделав такую замену в коде -

Screenshot_2.jpg

Хотел узнать, больше ничего менять не надо?)

Код:
//+------------------------------------------------------------------+
//|                                                     Soho_VIX.mq4 |
//|                            Copyright © 2007, Matthew Ebersviller |
//|                                                                  |
//+------------------------------------------------------------------+

/**********************************************************************
* This is a Synthetic VIX indicator as described in the December 2007 *
* issue of "Active Trader" magazine.  The indicator is also named the *
* "Williams VIX Fix" since Larry Williams is credited with the        *
* formula's discovery.                                                *
*                                                                     *
* This indicator was coded by Matthew Ebersviller.
and modified by sohocool the 07/01/2011                 *
**********************************************************************/


#property copyright "Copyright © 2007, Matthew Ebersviller"
#property link      ""

#property indicator_separate_window
#property indicator_buffers 1
#property indicator_color1 DodgerBlue
#property indicator_width1 1

extern int VIX_Period = 22;
extern int MaxBars    = 500;

double VixBuffer[];


int init() {
   string short_name;
   IndicatorBuffers(1);
   SetIndexStyle(0,DRAW_LINE);
   SetIndexBuffer(0,VixBuffer);
   //SetIndexBuffer(1,TempBuffer);
   short_name="SOHO_VIX("+VIX_Period+")";
   IndicatorShortName(short_name);
   SetIndexLabel(0,short_name);

   SetIndexDrawBegin(0,Bars-MaxBars); //SetIndexDrawBegin(0,VIX_Period);

   return(0);
}

int deinit()
  {
   return(0);
  }

int start()
  {
   int i, counted_bars=IndicatorCounted();

   if(Bars<=VIX_Period) return(0);

   if(counted_bars<1) {
      for(i=1;i<=VIX_Period;i++) {
         VixBuffer[Bars-i]=0.0;
      }
   }

   int limit=Bars-counted_bars;
   if (counted_bars>0) limit++;
   for(i=0; i<limit; i++)
      VixBuffer[i]=VIX(i);
 
   return(0);
  }
//+------------------------------------------------------------------+

double VIX(int shift) {
  double highClose, vix;
  highClose = High[iHighest(NULL,0,MODE_CLOSE,VIX_Period,shift)];
  vix = -100 *(highClose - Low[shift]) / highClose ;
  return (vix);
}

2) Или лучше так, и есть ли существенная разница между этими способами?

Screenshot_3.jpg

Код:
//+------------------------------------------------------------------+
//|                                                     Soho_VIX.mq4 |
//|                            Copyright © 2007, Matthew Ebersviller |
//|                                                                  |
//+------------------------------------------------------------------+

/**********************************************************************
* This is a Synthetic VIX indicator as described in the December 2007 *
* issue of "Active Trader" magazine.  The indicator is also named the *
* "Williams VIX Fix" since Larry Williams is credited with the        *
* formula's discovery.                                                *
*                                                                     *
* This indicator was coded by Matthew Ebersviller.
and modified by sohocool the 07/01/2011                 *
**********************************************************************/


#property copyright "Copyright © 2007, Matthew Ebersviller"
#property link      ""

#property indicator_separate_window
#property indicator_buffers 1
#property indicator_color1 DodgerBlue
#property indicator_width1 1

extern int VIX_Period = 22;
extern int MaxBars    = 500;

double VixBuffer[];


int init() {
   string short_name;
   IndicatorBuffers(1);
   SetIndexStyle(0,DRAW_LINE);
   SetIndexBuffer(0,VixBuffer);
   //SetIndexBuffer(1,TempBuffer);
   short_name="SOHO_VIX("+VIX_Period+")";
   IndicatorShortName(short_name);
   SetIndexLabel(0,short_name);

   SetIndexDrawBegin(0,VIX_Period);// SetIndexDrawBegin(0,Bars-MaxBars); //SetIndexDrawBegin(0,VIX_Period);

   return(0);
}

int deinit()
  {
   return(0);
  }

int start()
  {
   int i, counted_bars=IndicatorCounted();

   if(Bars<=VIX_Period) return(0);

   if(counted_bars<1) {
      for(i=1;i<=VIX_Period;i++) {
         VixBuffer[Bars-i]=0.0;
      }
   }

   int limit=Bars-counted_bars;
      if (limit > MaxBars)
   {
      limit = MaxBars;
   }
   if (counted_bars>0) limit++;
   for(i=0; i<limit; i++)
      VixBuffer[i]=VIX(i);
 
   return(0);
  }
//+------------------------------------------------------------------+

double VIX(int shift) {
  double highClose, vix;
  highClose = High[iHighest(NULL,0,MODE_CLOSE,VIX_Period,shift)];
  vix = -100 *(highClose - Low[shift]) / highClose ;
  return (vix);
}

А то хотел попробовать сделать, но не до конца понимаю, правильно ли.

3) Ещё и так можно оказывается -

Screenshot_1.jpg

Код:
//+------------------------------------------------------------------+
//|                                                     Soho_VIX.mq4 |
//|                            Copyright © 2007, Matthew Ebersviller |
//|                                                                  |
//+------------------------------------------------------------------+

/**********************************************************************
* This is a Synthetic VIX indicator as described in the December 2007 *
* issue of "Active Trader" magazine.  The indicator is also named the *
* "Williams VIX Fix" since Larry Williams is credited with the        *
* formula's discovery.                                                *
*                                                                     *
* This indicator was coded by Matthew Ebersviller. 
and modified by sohocool the 07/01/2011                 *
**********************************************************************/


#property copyright "Copyright © 2007, Matthew Ebersviller"
#property link      ""

#property indicator_separate_window
#property indicator_buffers 1
#property indicator_color1 DodgerBlue
#property indicator_width1 1

extern int VIX_Period = 22;
extern int MaxBars    = 500;

double VixBuffer[];


int init() {
   string short_name;
   IndicatorBuffers(1);
   SetIndexStyle(0,DRAW_LINE);
   SetIndexBuffer(0,VixBuffer);
   //SetIndexBuffer(1,TempBuffer);
   short_name="SOHO_VIX("+VIX_Period+")";
   IndicatorShortName(short_name);
   SetIndexLabel(0,short_name);

   SetIndexDrawBegin(0,VIX_Period);// SetIndexDrawBegin(0,Bars-MaxBars); //SetIndexDrawBegin(0,VIX_Period);

   return(0);
}

int deinit()
  {
   return(0);
  }

int start()
  {
   int i, counted_bars=IndicatorCounted();

   if(Bars<=VIX_Period) return(0);

   if(counted_bars<1) {
      for(i=1;i<=VIX_Period;i++) {
         VixBuffer[Bars-i]=0.0;
      }
   }

   int limit=Bars-counted_bars;
      if (limit > MaxBars)
   {
      limit = MaxBars;
   }
   if (counted_bars>0) limit++;
   for(i=0; i<limit; i++)
      VixBuffer[i]=VIX(i);
    
   return(0);
  }
//+------------------------------------------------------------------+

double VIX(int shift) {
  double highClose, vix;
  highClose = High[iHighest(NULL,0,MODE_CLOSE,VIX_Period,shift)];
  vix = -100 *(highClose - Low[shift]) / highClose ;
  return (vix);
}
 
Последнее редактирование:

gravity

Местный знаток
И снова я)

Нашёл код индикатора сессий из этой сборки. Код не исходник, так скажем.
Где-то ошибка в условии

Screenshot_1.jpg

Не смог сам разобраться.
Рисует вертикальные линии вне зависимости от настроек.
И не удаляет их при деинициализации.

Warning - каким нашёл
No good - подправил простые ошибки и предупреждения
 

Вложения

  • Brilliant Session Levels(warning).mq4
    30,6 КБ · Просмотры: 15
  • Brilliant Session Levels(not good).mq4
    61,2 КБ · Просмотры: 12

mobidik

-----
1) Обрезал историю показаний индикатора сделав такую замену в коде -

Screenshot_2.jpg
Справка по этому вопросу дает полный ответ:
"SetIndexDrawBegin() - Устанавливает порядковый номер бара от начала данных, с которого должна начинаться отрисовка указанной линии индикатора."

2) Или лучше так, и есть ли существенная разница между этими способами?
А в этом случае: если номер бара больше за максимальное значение заданной истории - то расчет индикатора не производим. На счет разницы, думаю, что ответ очевиден.
3) Ещё и так можно оказывается
Если период индикатора, который задан переменной VIX_Period, больше за установленное значение в параметре MaxBars (History) - расчет индикатора не производится, по причине не хватки баров для расчета. Далее, если выполняется условие: if(counted_bars<1) - значит это самый первый запуск индикатора - подсчитанных баров нет, counted_bars = 0 - производится инициализация баров от значения History до History-VIX_Period.
А вот далее.., почва для размышлений: в переменную counted_bars после первого прохода по коду, будет установлено значение равное Bars() - отсюда вопрос: чему будет равен limit в следующих случаях:
1) limit = Bars-countedbars;
2) limit = History-countedbars;
А далее, по Вашему примеру, смотрим ответ на 2п. и смотрим код под споллером, находим отличия.
 

mobidik

-----
И снова я)

Нашёл код индикатора сессий из этой сборки. Код не исходник, так скажем.
Где-то ошибка в условии

Screenshot_1.jpg


Не смог сам разобраться.
Рисует вертикальные линии вне зависимости от настроек.
И не удаляет их при деинициализации.
А на основании чего Вы именно так расставили скобки?
Ответ: так захотелось...
А следовало сперва ознакомится с этим: Приоритеты и порядок операций - Операции и выражения - Основы языка - Справочник MQL4 -https://docs.mql4.com/ru/basis/operations/rules
 
Последнее редактирование модератором:

gravity

Местный знаток
А на основании чего Вы именно так расставили скобки?
Ответ: так захотелось...
А следовало сперва ознакомится с этим: Приоритеты и порядок операций - Операции и выражения - Основы языка - Справочник MQL4 -https://docs.mql4.com/ru/basis/operations/rules
Да, спасибо, я так понял, что раньше || считался приоритетнее, а сейчас &&.
Расставил так скобки, потому что раньше что-то такое попадалось и такая расстановка помогла убрать ошибку) и почему-то подсознательно "или" казалось важнее "и")
да и предупреждение пропало)

Сделал расстановку скобок как положено, действительно заработало.
Осталась только проблема с удалениями объектов при деинициализации, думаю справлюсь. Если нет, напишу)

Спасибо ещё раз за разъяснение!
 

gravity

Местный знаток
Справка по этому вопросу дает полный ответ:
"SetIndexDrawBegin() - Устанавливает порядковый номер бара от начала данных, с которого должна начинаться отрисовка указанной линии индикатора."


А в этом случае: если номер бара больше за максимальное значение заданной истории - то расчет индикатора не производим. На счет разницы, думаю, что ответ очевиден.

Если период индикатора, который задан переменной VIX_Period, больше за установленное значение в параметре MaxBars (History) - расчет индикатора не производится...
На счёт различия, я догадывался, что отрисовка и расчёт это разные вещи.
Получается, что через SetIndexDrawBegin() , мы просто ограничиваем видимость индикатора, но при этом расчёты остаются такие же, как если бы была видна вся история видимости индикатора.
Я правильно понял, что 2й способ самый оптимальный?
 

mobidik

-----
Я правильно понял, что 2й способ самый оптимальный?
Да, но с учетом новых требований:
C-подобный:
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
    int limit = rates_total-prev_calculated;
    if(limit>History) limit = History;
   
    //---
    //---
    //---
    //---  return value of prev_calculated for next call
    return(rates_total);
  }
 

gravity

Местный знаток
👋 🤠
Индикатор выводит Comment() на графике.
Если кинуть на график дубль этого же индикатора(заданы разные ID), то комментарий остаётся только от последнего.

Внимание вопрос, уважаемые знатоки)

Есть ли способ избежать конфликта выводимых комментариев?
 
Последнее редактирование:

Ugar

Гуру форума
👋 🤠
Индикатор выводит Comment() на графике.
Если кинуть на график дубль этого же индикатора(заданы разные ID), то комментарий остаётся только от последнего.

Внимание вопрос, уважаемые знатоки)

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