Почему не рисуются линии индикатора в MT4

 
#property strict

//---- indicator settings
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_color1  Blue //H1
#property indicator_color2  Red //H4
#property indicator_color3  Lime //D1
//---- indicator buffers
double ExtBuffer1[];
double ExtBuffer2[];
double ExtBuffer3[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
void OnInit(void)
  {
//---- 3 indicator buffers mapping
   SetIndexBuffer(0,ExtBuffer1);
   SetIndexBuffer(1,ExtBuffer2);
   SetIndexBuffer(2,ExtBuffer3);
//---- drawing settings
   SetIndexStyle(0,DRAW_LINE);
   SetIndexStyle(1,DRAW_LINE);
   SetIndexStyle(2,DRAW_LINE);
//---- index labels
   SetIndexLabel(0,"H1");
   SetIndexLabel(1,"H4");
   SetIndexLabel(2,"D1");
  }
//+------------------------------------------------------------------+
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[])
  {
      ExtBuffer1[0]=iMA(NULL,PERIOD_H1,200,0,MODE_SMMA,PRICE_MEDIAN,0);
      ExtBuffer2[0]=iMA(NULL,PERIOD_H4,200,0,MODE_SMMA,PRICE_MEDIAN,0);
      ExtBuffer3[0]=iMA(NULL,PERIOD_D1,200,0,MODE_SMMA,PRICE_MEDIAN,0);
//---- done
   return(rates_total);
  }
//+------------------------------------------------------------------+

Добрый день!

Немного подправил исходник аллигатора, хотел вместо его линий рисовать 3 простых горизонтальных линий по текущим значениям МА200 с трёх старших таймфреймов.

Но линии почему-то не рисуются. Почему?

 
Rice:

Добрый день!

Немного подправил исходник аллигатора, хотел вместо его линий рисовать 3 простых горизонтальных линий по текущим значениям МА200 с трёх старших таймфреймов.

Но линии почему-то не рисуются. Почему?

Для рисования линии нужно указать значения хотя бы в двух соседних элементах буфера, а здесь значение пишется постоянно в один и тот же элемент - индекс 0.

В крайнем случае подождите формирования нового бара и тогда получите отображение линии на двух барах. Или в тестере еще можно посмотреть.

 
Ihor Herasko:

Для рисования линии нужно указать значения хотя бы в двух соседних элементах буфера, а здесь значение пишется постоянно в один и тот же элемент - индекс 0.

В крайнем случае подождите формирования нового бара и тогда получите отображение линии на двух барах. Или в тестере еще можно посмотреть.

О! Вижу нарисовались три малюсеньких чёрточки. Но я хотел просто горизонтальную линию по текущим значениям 200й, поэтому и нулевой индекс, так как для построения горизонтальной прямой нужна всего одна координата. Кстати, линии пропадают при переключении таймфрейма, а мне нужно, чтобы линии двигались синхронно с изменением 200й на соответствующих таймфреймах. Видимо, аллигатор, как основа для такого индикатора не подходит.

Да, в тестере рисуются кривые линии, а мне нужно три прямых с трёх таймфреймов 200й средней на текущем баре.
 
Rice:

О! Вижу нарисовались три малюсеньких чёрточки. Но я хотел просто горизонтальную линию по текущим значениям 200й, поэтому и нулевой индекс, так как для построения горизонтальной прямой нужна всего одна координата. Кстати, линии пропадают при переключении таймфрейма, а мне нужно, чтобы линии двигались синхронно с изменением 200й на соответствующих таймфреймах. Видимо, аллигатор, как основа для такого индикатора не подходит.

Да, в тестере рисуются кривые линии, а мне нужно три прямых с трёх таймфреймов 200й средней на текущем баре.

Рисуйте линию типа OBJ_TREND не используя индикаторные буферы с помощью функции ObjectCreate().

 
Vitalii Ananev:

Рисуйте линию типа OBJ_TREND не используя индикаторные буферы с помощью функции ObjectCreate().

Спасибо за подсказку, но в справке подробно расписан скрипт. Теперь как перенести это всё в индикаторную форму?..

 
Rice:

Спасибо за подсказку, но в справке подробно расписан скрипт. Теперь как перенести это всё в индикаторную форму?..

В функции OnCalculate() рисуете линию с заданными координатами (ObjectCreate()), если она еще не нарисована (ObjectFind()) , если уже нарисована просто перемещаете ее (ObjectMove())  В качестве цены используете значение iМА. В качестве времени Time[0], вторая координата времени Time[0]+PeriodSeconds()*Shift. Где Shift - желаемое смещение линии в будущее. В итоге должно получится примерно так как на картинке. Если это индикатор нужен только для визуального отображения и вы его не будете использовать в советнике то индикаторные буферы вообще не нужны. Такой способ подходит только если вам нужно видеть текущие значения iMA и не нужны значения, что были в прошлом. 

P.S. Нулевой индекс iMA лучше не использовать. Так как это еще не закрытый бар и его значения будут меняться каждый новый тик. Ваша линия будет дергаться.  Для ускорения работы индикатора лучше сделать контроль формирования бара и после чего менять координаты линии. 

 
Vitalii Ananev:

В функции OnCalculate() рисуете линию с заданными координатами (ObjectCreate()), если она еще не нарисована (ObjectFind()) , если уже нарисована просто перемещаете ее (ObjectMove())  В качестве цены используете значение iМА. В качестве времени Time[0], вторая координата времени Time[0]+PeriodSeconds()*Shift. Где Shift - желаемое смещение линии в будущее. В итоге должно получится примерно так как на картинке. Если это индикатор нужен только для визуального отображения и вы его не будете использовать в советнике то индикаторные буферы вообще не нужны. Такой способ подходит только если вам нужно видеть текущие значения iMA и не нужны значения, что были в прошлом. 

P.S. Нулевой индекс iMA лучше не использовать. Так как это еще не закрытый бар и его значения будут меняться каждый новый тик. Ваша линия будет дергаться.  Для ускорения работы индикатора лучше сделать контроль формирования бара и после чего менять координаты линии. 

   if(ObjectFind(0,"H1")!=0)
     if(!ObjectMove(0,"H1",0,Time[0],iMA(NULL,PERIOD_H1,200,0,MODE_EMA,PRICE_CLOSE,0)))
     { 
      Print(__FUNCTION__, 
            ": не удалось найти горизонтальную линию! Код ошибки = ",GetLastError()); 
      return(false); 
     } 
   else
    if(!ObjectCreate(0,"H1",OBJ_HLINE,0,0,iMA(NULL,PERIOD_H1,200,0,MODE_EMA,PRICE_CLOSE,0))) 
     { 
      Print(__FUNCTION__, 
            ": не удалось создать горизонтальную линию! Код ошибки = ",GetLastError()); 
      return(false); 
     } 

С созданием вроде всё нормально, а с перемещением нет: даже не создаёт линию.

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

С созданием вроде всё нормально, а с перемещением нет: даже не создаёт линию.

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

Попробуйте вот эту функцию.

void TrendLine(string name,datetime time1,double price1,datetime time2,double price2)
{
    if (ObjectFind(0,name)==-1)
    {
      ObjectCreate(0,name, OBJ_TREND, 0, time1, price1, time2,price2);
    } else
    {
      ObjectMove(0,name,0,time1,price1);
      ObjectMove(0,name,1,time2,price2);
    } 
}
 
Vitalii Ananev:

Попробуйте вот эту функцию.

Спасибо, но мне нужна строго горизонтальная линия (OBJ_HLINE), как я с самого начала написал.

 
Rice:

Спасибо, но мне нужна строго горизонтальная линия (OBJ_HLINE), как я с самого начала написал.

Так не проблема, надо только чуток поменять код.

void HLine(string name,double price)
{   
    if (ObjectFind(0,name)==-1)
    {   
      ObjectCreate(0,name, OBJ_HLINE, 0, 0, price);
    } else
    {
      ObjectMove(0,name,0,0,price);
      
    } 
}
 

В итоге у вас должно получиться примерно так.

#property strict

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
void OnInit(void)
  {

  }
//+------------------------------------------------------------------+
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[])
  {
      double MAH1=iMA(NULL,PERIOD_H1,200,0,MODE_SMMA,PRICE_MEDIAN,0);
      double MAH4=iMA(NULL,PERIOD_H4,200,0,MODE_SMMA,PRICE_MEDIAN,0);
      double MAD1=iMA(NULL,PERIOD_D1,200,0,MODE_SMMA,PRICE_MEDIAN,0);
      HLine("H1",MAH1);
      HLine("H4",MAH4);
      HLine("D1",MAD1);
//---- done
   return(rates_total);
  }