Скачать MetaTrader 5

Создание индикатора с возможностями графического управления

29 марта 2010, 16:05
Vasily
11
4 250

Введение

Те, кто более-менее знаком с рыночными настроениями не понаслышке, знает индикатор MACD, или полное название Схождение Расхождение Скользящих Средних, знает его как мощный инструмент анализа движения цены, которым пользуются трейдеры с первых моментов появления методов компьютерного анализа. Я и сам в течение длительного времени исследовал индикатор MACD, который стабильно заработал себе место на графике, я видел множество разновидностей с разными возможностями разными алгоритмами расчета и решил свести все известные мне вариации в один индикатор.

Определение модификаций

Данный индикатор будет состоять из MACD-линий и oSMA-гистограммы.  Выделим основные различные модификации MACD:
  1. MACD Элдера, также известна как импульсная система;
  2. MACD Элдера без проверки по скользящей линии;
  3. oSMA окрашивается при падении или росте показателя;
  4. Показывается только oSMA-гистограмма;
  5. Показываются только MACD линии;

Начальная подготовка индикатора

Для расчета нам потребуется параметры:

  1. Значение Быстрой Линии MACD;
  2. Значение Медленной Линии MACD;
  3. Значение Сигнальной Линии MACD;
  4. Значение Линии проверки Тренда по методу Элдера;

Для отображения данного индикатора нам потребуются:

  1. Линия MACD;
  2. Сигнальная линия;
  3. Цветная гистограмма OSMA с отображением 3-х цветов.

Перейдём в меню создания индикатора:

Рис 1. Создание индикатора при помощи Мастера MQL5

Рис 2. Определение общих параметров индикатора в Мастере MQL5

Рис 3. Определение параметров отображения индикатора в Мастере MQL5

Создание  индикатора

У нас появился первоначальный шаблон для создания индикатора. Сначала для нашего индикатора необходимо рассчитать MACD-линию.

Не будем углубляться в точную формулу расчета данной линии - воспользуемся функцией iMACD:

int  iMACD(
   string              symbol,              // имя символа
   ENUM_TIMEFRAMES      period,              // период
   int                 fast_ema_period,     // период быстрой средней
   int                 slow_ema_period,     // период медленной средней
   int                 signal_period,       // период усреднения разности
   ENUM_APPLIED_PRICE    applied_price        // тип цены или handle
   );

Эта функция возвращает хэндл соответствующей копии индикатора. Используя этот хэндл, в дальнейшем можно получать данные, рассчитанные соответствующим индикатором. Данные соответствующего буфера (технические индикаторы содержат рассчитанные данные в своих внутренних буферах, которых, в зависимости от индикатора, может быть до 5) можно копировать в mql5-программу при помощи функции CopyBuffer(). 

Далее сформируем запрос на данные MACD через функцию iMACD:

int MACDhadling =  iMACD(NULL,0,Fast,Slow,Signal,PRICE_CLOSE);

данное действие вернёт нам хэндл соответствующей копии индикатора.

Скопируем данные в необходимый нам буфер через функцию CopyBuffer:

int  CopyBuffer(
   int       indicator_handle,     // handle индикатора
   int       buffer_num,           // номер буфера индикатора
   int       start_pos,            // откуда начнем 
   int       count,                // сколько копируем
   double    buffer[]              // массив, куда будут скопированы данные
   );

Сформируем запрос на MACD-линию индикатора:

CopyBuffer(MACDhadling,0,0,НовыеДанные,MACDlineBuffer);

Получим сигнальную линию индикатора:

CopyBuffer(MACDhadling,1,0,НовыеДанные,SignallineBuffer);

Теперь сведём все вместе, и посмотрим что получилось:

int MACDhadling=iMACD(NULL,0,Fast,Slow,Signal,PRICE_CLOSE);
CopyBuffer(MACDhadling,0,0,rates_total,MACDlineBuffer);
CopyBuffer(MACDhadling,1,0,rates_total,SignallineBuffer);

Теперь у нас есть посчитанная линия MACD и Сигнальная линия.

Продолжим дальше.

Так как буферы

MACDlineBuffer

и

SignallineBuffer

получены путём копирования, то индексация у них будет с конца графика.

Исторически сложилось так, что доступ к данным в ценовом массиве производился с конца данных. Физически новые данные всегда дописываются в конец массива, но индекс текущего (незавершенного) бара всегда равен нулю. Индекс 0 в массиве-таймсерии означает данные текущего бара, то есть бара, который соответствует незавершенному промежутку времени на данном таймфрейме.

Для того чтобы направление потока данных было одинаково во всех буферах, необходимо перевернуть остальные буферы:

ArraySetAsSeries(HistogramBuffer,false);
ArraySetAsSeries(HistogramColors,false);

Нам необходимо получить данные гистограммы - она рассчитываться путём вычитания Сигнальной линии из Линии MACD:

for(int i=0;i<rates_total;i++)
  {
   HistogramBuffer[i]=MACDlineBuffer[i]-SignallineBuffer[i];
  }

Сведем все вместе:

ArraySetAsSeries(HistogramBuffer,false);
ArraySetAsSeries(HistogramColors,false);

int MACDhadling=iMACD(NULL,0,Fast,Slow,Signal,PRICE_CLOSE);
CopyBuffer(MACDhadling,0,0,rates_total,MACDlineBuffer);
CopyBuffer(MACDhadling,1,0,rates_total,SignallineBuffer);

for(int i=0;i<rates_total;i++)
  {
   HistogramBuffer[i]=MACDlineBuffer[i]-SignallineBuffer[i];
   HistogramColors[i]=1; 
  }


Создание  графической системы управления индикатором

У нас есть 5 разновидностей данного индикатора.

Для начала реализуем пункты 3,4.

    3. Показывается только oSMA-гистограмма;
    4. Показываются только MACD-линии.

Создадим соответствующие кнопки.

Для пункта 4:

ObjectCreate(0,"ShowMACD",OBJ_BUTTON,ChartWindowFind(),100,100);   //создаём кнопку
ObjectSetInteger(0,"ShowMACD",OBJPROP_XDISTANCE,75);              //назначаем координаты 
ObjectSetInteger(0,"ShowMACD",OBJPROP_YDISTANCE,5);
ObjectSetInteger(0,"ShowMACD",OBJPROP_CORNER,CORNER_RIGHT_UPPER);  // и угол привязки
ObjectSetString(0,"ShowMACD",OBJPROP_TEXT,"ShowMACD");            // надпись для кнопки 
ObjectSetInteger(0,"ShowMACD",OBJPROP_FONTSIZE,8);
ObjectSetInteger(0,"ShowMACD",OBJPROP_XSIZE,70);                 // размеры кнопки 
ObjectSetInteger(0,"ShowMACD",OBJPROP_YSIZE,20);
ObjectSetInteger(0,"ShowMACD",OBJPROP_SELECTABLE,false);         // и возможность выделять

В случае случайного удаления кнопки или сдвига при следующем тике, кнопка вернётся обратно.

Для пункта 3:

ObjectCreate(0,"ShowOsMA",OBJ_BUTTON,ChartWindowFind(),100,100);
ObjectSetInteger(0,"ShowOsMA",OBJPROP_XDISTANCE,75);
ObjectSetInteger(0,"ShowOsMA",OBJPROP_YDISTANCE,30);
ObjectSetInteger(0,"ShowOsMA",OBJPROP_CORNER,CORNER_RIGHT_UPPER);
ObjectSetString (0,"ShowOsMA",OBJPROP_TEXT,"Show OsMA");
ObjectSetInteger(0,"ShowOsMA",OBJPROP_FONTSIZE,8);
ObjectSetInteger(0,"ShowOsMA",OBJPROP_XSIZE,70);
ObjectSetInteger(0,"ShowOsMA",OBJPROP_YSIZE,20);
ObjectSetInteger(0,"ShowOsMA",OBJPROP_SELECTABLE,false);

Создадим условия для нажатой или не нажатой кнопки для условия 4.

Для этого надо посмотреть индексы буферов.

SetIndexBuffer(0,MACDlineBuffer,INDICATOR_DATA);
SetIndexBuffer(1,SignallineBuffer,INDICATOR_DATA);
SetIndexBuffer(2,HistogramBuffer,INDICATOR_DATA);
SetIndexBuffer(3,HistogramColors,INDICATOR_COLOR_INDEX);
if(ObjectGetInteger(0,"ShowMACD",OBJPROP_STATE)!=1)
  {
   PlotIndexSetInteger(0,PLOT_DRAW_TYPE,DRAW_NONE); // буфер с индексом 0 не отрисовывается
   PlotIndexSetInteger(1,PLOT_DRAW_TYPE,DRAW_NONE); // буфер с индексом 1 не отрисовывается
  }
else
  {
   PlotIndexSetInteger(0,PLOT_DRAW_TYPE,DRAW_LINE); // буфер с индексом 0 рисуется линией
   PlotIndexSetInteger(1,PLOT_DRAW_TYPE,DRAW_LINE); // буфер с индексом 1 рисуется линией
  }

При нажатой кнопке Линии MACD будут рисоваться, если кнопка не нажата, то линии MACD не рисуются.

Создадим условия для нажатой или не нажатой кнопки для условия 3:

if(ObjectGetInteger(0,"ShowOsMA",OBJPROP_STATE)!=1)
  {
   PlotIndexSetInteger(2,PLOT_DRAW_TYPE,DRAW_NONE);          // буфер с индексом 2 не отрисовывается
  }
else
  {
   PlotIndexSetInteger(2,PLOT_DRAW_TYPE,DRAW_COLOR_HISTOGRAM); // буфер с индексом 2 рисуется цветной гистограммой
  }

Создадим две кнопки для следующий условий и расположим их в нижнем правом углу.

ObjectCreate(0,"2color",OBJ_BUTTON,ChartWindowFind(),100,100);
ObjectSetInteger(0,"2color",OBJPROP_XDISTANCE,75);
ObjectSetInteger(0,"2color",OBJPROP_YDISTANCE,50);
ObjectSetInteger(0,"2color",OBJPROP_CORNER,CORNER_RIGHT_LOWER);
ObjectSetInteger(0,"2color",OBJPROP_FONTSIZE,8);
ObjectSetInteger(0,"2color",OBJPROP_XSIZE,70);
ObjectSetInteger(0,"2color",OBJPROP_YSIZE,20);
ObjectSetInteger(0,"2color",OBJPROP_SELECTABLE,false);
ObjectSetString (0,"2color",OBJPROP_TEXT,"MultiColor");

ObjectCreate(0,"Impulse",OBJ_BUTTON,ChartWindowFind(),100,100);
ObjectSetInteger(0,"Impulse",OBJPROP_XDISTANCE,75);
ObjectSetInteger(0,"Impulse",OBJPROP_YDISTANCE,25);
ObjectSetInteger(0,"Impulse",OBJPROP_CORNER,CORNER_RIGHT_LOWER);
ObjectSetInteger(0,"Impulse",OBJPROP_FONTSIZE,8);
ObjectSetInteger(0,"Impulse",OBJPROP_XSIZE,70);
ObjectSetInteger(0,"Impulse",OBJPROP_YSIZE,20);
ObjectSetInteger(0,"Impulse",OBJPROP_SELECTABLE,false);

Для проверки импульса по системе Элдера, необходимо добавить новый массив, в котором будут находиться значения EldersMA.

Для этого необходимо добавить единицу к общему количеству буферов.

#property indicator_buffers 4

меняем на:

#property indicator_buffers 5

и объявляем новый буфер.

double         EldersiEMA[];

Объявляем его как буфер для внутренних расчетов:

SetIndexBuffer(4,EldersiEMA,INDICATOR_CALCULATIONS);

Теперь скопируем в него значение экспоненциальной скользящей средней:

CopyBuffer(iMA(NULL,0,EldersEMA,0,MODE_EMA,PRICE_CLOSE),0,0,rates_total,EldersiEMA); // можно сделать все в 1 строчку

Так как буфер получен функцией копирования, то обращение данных в нём идёт с конца графика, как и у всех остальных буферов нашего графика.

Теперь распишем условия для 2-х цветной OsMA:

if (ObjectGetInteger(0,"2color",OBJPROP_STATE))
  {
   for(int i=1;i<rates_total;i++)
     {
      if(HistogramBuffer[i] > HistogramBuffer[i-1]) HistogramColors[i]=0; // если гистограмма растёт, то цвет 0
      if(HistogramBuffer[i] < HistogramBuffer[i-1]) HistogramColors[i]=1; // если гистограмма падает, то цвет 1
     }
  }
else
  {
   ObjectSetString(0,"2color",OBJPROP_TEXT,"MultiColor");
   // тут будут условия для многоцветной OSMA
  }

Номера цветов нужно посмотреть в строчке:

#property indicator_label3  "Histogram"
#property indicator_type3   DRAW_COLOR_HISTOGRAM
#property indicator_color3  DeepSkyBlue,Red,Green

причем номер первого цвета будет равен 0, второго 1, третьего 2 и так далее.

Теперь распишем условия Вариаций Импульсной системы:

if (ObjectGetInteger(0,"Impulse",OBJPROP_STATE)) // проверка кнопки выбора системы
  {
   ObjectSetString(0,"Impulse",OBJPROP_TEXT,"Impulse");  // если проверка тренда по MACD-линии
   for(int i=1;i<rates_total;i++)
     {
      // гистограмма растет И MACD-линия растет
      if((HistogramBuffer[i]>HistogramBuffer[i-1]) && (MACDlineBuffer[i]>MACDlineBuffer[i-1])) HistogramColors[i]=0;
      else
        {
         // гистограмма падает И MACD-линия падает 
         if((HistogramBuffer[i]<HistogramBuffer[i-1]) && (MACDlineBuffer[i]<MACDlineBuffer[i-1])) HistogramColors[i]=1;
         else HistogramColors[i]=2; // если ни одно из условий не выполняеться
        }
     }
  }
else 
  {
   ObjectSetString(0,"Impulse",OBJPROP_TEXT,"Elder's");  // если проверка тренда по ЕМА-линии          
   for(int i=1;i<rates_total;i++)
     {
      // гистограмма растет И еМА-линия растёт 
      if((HistogramBuffer[i]>HistogramBuffer[i-1]) && (EldersiEMA[i]>EldersiEMA[i-1])) HistogramColors[i]=0;
      else
        {
         // гистограмма падает И еМА-линия падает 
         if((HistogramBuffer[i]<HistogramBuffer[i-1]) && (EldersiEMA[i]<EldersiEMA[i-1])) HistogramColors[i]=1;
         else HistogramColors[i]=2;// если ни одно из условий не выполняеться                  
        }
     }

  }

Теперь вставим условия Вариаций Импульсной системы в условия отображения OsMA:

if (ObjectGetInteger(0,"2color",OBJPROP_STATE))
  {
   for(int i=1;i<rates_total;i++)
     {
      if(HistogramBuffer[i] > HistogramBuffer[i-1]) HistogramColors[i]=0;
      if(HistogramBuffer[i] < HistogramBuffer[i-1]) HistogramColors[i]=1;
     }
  }
else
  {
   ObjectSetString(0,"2color",OBJPROP_TEXT,"MultiColor");
   if(ObjectGetInteger(0,"Impulse",OBJPROP_STATE))
     {
      ObjectSetString(0,"Impulse",OBJPROP_TEXT,"Impulse");
      for(int i=1;i<rates_total;i++)
        {
         if((HistogramBuffer[i]>HistogramBuffer[i-1]) && (MACDlineBuffer[i]>MACDlineBuffer[i-1])) HistogramColors[i]=0;
         else
           {
            if((HistogramBuffer[i]<HistogramBuffer[i-1]) && (MACDlineBuffer[i]<MACDlineBuffer[i-1])) HistogramColors[i]=1;
            else HistogramColors[i]=2;
           }
        }
     }
   else 
     {
      ObjectSetString(0,"Impulse",OBJPROP_TEXT,"Elder's");
      for(int i=1;i<rates_total;i++)
        {
         if((HistogramBuffer[i]>HistogramBuffer[i-1]) && (EldersiEMA[i]>EldersiEMA[i-1])) HistogramColors[i]=0;
         else
           {
            if((HistogramBuffer[i]<HistogramBuffer[i-1]) && (EldersiEMA[i]<EldersiEMA[i-1])) HistogramColors[i]=1;
            else HistogramColors[i]=2;
           }
        }
     }
  }

Теперь для предотвращения лишних миганий кнопок, создадим условия:

if (ObjectGetInteger(0,"2color",OBJPROP_STATE)) ObjectSetString (0,"2color",OBJPROP_TEXT,"2ColorMACD");
else ObjectSetString(0,"2color",OBJPROP_TEXT,"MultiColor");
if (ObjectGetInteger(0,"Impulse",OBJPROP_STATE)) ObjectSetString (0,"Impulse",OBJPROP_TEXT,"Impulse");
else ObjectSetString(0,"Impulse",OBJPROP_TEXT,"Elder's");     

и удалим строчки смены текста из кода.

Сводим всё вместе:

//+------------------------------------------------------------------+
//|                                            MACD_By_CoreWinTT.mq5 |
//|                        Copyright 2010, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "2010, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 5
#property indicator_plots   3
//---- plot MACDline
#property indicator_label1  "MACDline"
#property indicator_type1   DRAW_LINE
#property indicator_color1  Green
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//---- plot Signalline
#property indicator_label2  "Signalline"
#property indicator_type2   DRAW_LINE
#property indicator_color2  Red
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1
//---- plot Histogram
#property indicator_label3  "Histogram"
#property indicator_type3   DRAW_COLOR_HISTOGRAM
#property indicator_color3  DeepSkyBlue,Red,Green
#property indicator_style3  STYLE_SOLID
#property indicator_width3  2

//--- input parameters
input int      Fast=12;
input int      Slow=26;
input int      Signal=9;
input int      EldersEMA=13;
//--- indicator buffers
double         MACDlineBuffer[];
double         SignallineBuffer[];
double         HistogramBuffer[];
double         HistogramColors[];
double         EldersiEMA[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,MACDlineBuffer,INDICATOR_DATA);
   SetIndexBuffer(1,SignallineBuffer,INDICATOR_DATA);
   SetIndexBuffer(2,HistogramBuffer,INDICATOR_DATA);
   SetIndexBuffer(3,HistogramColors,INDICATOR_COLOR_INDEX);
   SetIndexBuffer(4,EldersiEMA,INDICATOR_CALCULATIONS);
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| 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[])
  {
   ArraySetAsSeries(HistogramBuffer,false);
   ArraySetAsSeries(HistogramColors,false);

   int MACDhadling=iMACD(NULL,0,Fast,Slow,Signal,PRICE_CLOSE);
   CopyBuffer(MACDhadling,0,0,rates_total,MACDlineBuffer);
   CopyBuffer(MACDhadling,1,0,rates_total,SignallineBuffer);

   for(int i=0;i<rates_total;i++) { HistogramBuffer[i]=MACDlineBuffer[i]-SignallineBuffer[i];HistogramColors[i]=1; }

   ObjectCreate(0,"ShowMACD",OBJ_BUTTON,ChartWindowFind(),100,100);
   ObjectSetInteger(0,"ShowMACD",OBJPROP_XDISTANCE,75);
   ObjectSetInteger(0,"ShowMACD",OBJPROP_YDISTANCE,5);
   ObjectSetInteger(0,"ShowMACD",OBJPROP_CORNER,CORNER_RIGHT_UPPER);
   ObjectSetString(0,"ShowMACD",OBJPROP_TEXT,"ShowMACD");
   ObjectSetInteger(0,"ShowMACD",OBJPROP_FONTSIZE,8);
   ObjectSetInteger(0,"ShowMACD",OBJPROP_XSIZE,70);
   ObjectSetInteger(0,"ShowMACD",OBJPROP_YSIZE,20);
   ObjectSetInteger(0,"ShowMACD",OBJPROP_SELECTABLE,false);

   ObjectCreate(0,"ShowOsMA",OBJ_BUTTON,ChartWindowFind(),100,100);
   ObjectSetInteger(0,"ShowOsMA",OBJPROP_XDISTANCE,75);
   ObjectSetInteger(0,"ShowOsMA",OBJPROP_YDISTANCE,30);
   ObjectSetInteger(0,"ShowOsMA",OBJPROP_CORNER,CORNER_RIGHT_UPPER);
   ObjectSetString(0,"ShowOsMA",OBJPROP_TEXT,"Show OsMA");
   ObjectSetInteger(0,"ShowOsMA",OBJPROP_FONTSIZE,8);
   ObjectSetInteger(0,"ShowOsMA",OBJPROP_XSIZE,70);
   ObjectSetInteger(0,"ShowOsMA",OBJPROP_YSIZE,20);
   ObjectSetInteger(0,"ShowOsMA",OBJPROP_SELECTABLE,false);

   if(ObjectGetInteger(0,"ShowMACD",OBJPROP_STATE)!=1)
     {
      PlotIndexSetInteger(0,PLOT_DRAW_TYPE,DRAW_NONE);
      PlotIndexSetInteger(1,PLOT_DRAW_TYPE,DRAW_NONE);
     }
   else
     {
      PlotIndexSetInteger(0,PLOT_DRAW_TYPE,DRAW_LINE);
      PlotIndexSetInteger(1,PLOT_DRAW_TYPE,DRAW_LINE);
     }

   if(ObjectGetInteger(0,"ShowOsMA",OBJPROP_STATE)!=1)
     {
      PlotIndexSetInteger(2,PLOT_DRAW_TYPE,DRAW_NONE);
     }
   else
     {
      PlotIndexSetInteger(2,PLOT_DRAW_TYPE,DRAW_COLOR_HISTOGRAM);
     }

   ObjectCreate(0,"2color",OBJ_BUTTON,ChartWindowFind(),100,100);
   ObjectSetInteger(0,"2color",OBJPROP_XDISTANCE,75);
   ObjectSetInteger(0,"2color",OBJPROP_YDISTANCE,50);
   ObjectSetInteger(0,"2color",OBJPROP_CORNER,CORNER_RIGHT_LOWER);
   ObjectSetInteger(0,"2color",OBJPROP_FONTSIZE,8);
   ObjectSetInteger(0,"2color",OBJPROP_XSIZE,70);
   ObjectSetInteger(0,"2color",OBJPROP_YSIZE,20);
   ObjectSetInteger(0,"2color",OBJPROP_SELECTABLE,false);
   ObjectSetString(0,"2color",OBJPROP_TEXT,"MultiColor");

   ObjectCreate(0,"Impulse",OBJ_BUTTON,ChartWindowFind(),100,100);
   ObjectSetInteger(0,"Impulse",OBJPROP_XDISTANCE,75);
   ObjectSetInteger(0,"Impulse",OBJPROP_YDISTANCE,25);
   ObjectSetInteger(0,"Impulse",OBJPROP_CORNER,CORNER_RIGHT_LOWER);
   ObjectSetInteger(0,"Impulse",OBJPROP_FONTSIZE,8);
   ObjectSetInteger(0,"Impulse",OBJPROP_XSIZE,70);
   ObjectSetInteger(0,"Impulse",OBJPROP_YSIZE,20);
   ObjectSetInteger(0,"Impulse",OBJPROP_SELECTABLE,false);
   ObjectSetString(0,"Impulse",OBJPROP_TEXT,"Impulse");

   if(ObjectGetInteger(0,"2color",OBJPROP_STATE)) ObjectSetString(0,"2color",OBJPROP_TEXT,"2ColorMACD");
   else ObjectSetString(0,"2color",OBJPROP_TEXT,"MultiColor");
   if(ObjectGetInteger(0,"Impulse",OBJPROP_STATE)) ObjectSetString(0,"Impulse",OBJPROP_TEXT,"Impulse");
   else ObjectSetString(0,"Impulse",OBJPROP_TEXT,"Elder's");

   CopyBuffer(iMA(NULL,0,EldersEMA,0,MODE_EMA,PRICE_CLOSE),0,0,rates_total,EldersiEMA);

   if(ObjectGetInteger(0,"2color",OBJPROP_STATE))
     {
      for(int i=1;i<rates_total;i++)
        {
         if(HistogramBuffer[i] > HistogramBuffer[i-1]) HistogramColors[i]=0;
         if(HistogramBuffer[i] < HistogramBuffer[i-1]) HistogramColors[i]=1;
        }

     }
   else
     {
      if(ObjectGetInteger(0,"Impulse",OBJPROP_STATE))
        {
         for(int i=1;i<rates_total;i++)
           {
            if((HistogramBuffer[i]>HistogramBuffer[i-1]) && (MACDlineBuffer[i]>MACDlineBuffer[i-1])) HistogramColors[i]=0;
            else
              {
               if((HistogramBuffer[i]<HistogramBuffer[i-1]) && (MACDlineBuffer[i]<MACDlineBuffer[i-1])) HistogramColors[i]=1;
               else HistogramColors[i]=2;
              }
           }
        }

      else
        {
         for(int i=1;i<rates_total;i++)
           {
            if((HistogramBuffer[i]>HistogramBuffer[i-1]) && (EldersiEMA[i]>EldersiEMA[i-1])) HistogramColors[i]=0;
            else
              {
               if((HistogramBuffer[i]<HistogramBuffer[i-1]) && (EldersiEMA[i]<EldersiEMA[i-1])) HistogramColors[i]=1;
               else HistogramColors[i]=2;
              }
           }

        }

     }

//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+

Блок-схема алгоритма приведена на рис.4:


Рис 4. Блок-схема алгоритма работы индикатора.


Рис 4. Блок-схема алгоритма работы индикатора

Результат работы индикатора приведен на рис. 5-7.

Рис. 5

Рис. 6

Рис. 7


Заключение

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

Прикрепленные файлы |
Последние комментарии | Перейти к обсуждению на форуме трейдеров (11)
Vasily
Vasily | 5 апр 2010 в 19:56

и также чтобы он пересчитывал при нажатии кнопок

и не приходилось ждать нового тика или переключать тайм фреймы

Sergey Gromyhalov
Sergey Gromyhalov | 18 июн 2013 в 22:00

Индикатор просто замечательный, статья на 5+, автор Умница!

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

Nikolay Demko
Nikolay Demko | 19 июн 2013 в 11:44
Radmin:

Индикатор просто замечательный, статья на 5+, автор Умница!

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

В том виде как есть его и не возможно портировать, MQL4 не имеет тех возможностей что и MQL5.

Конкретно по этому индикатору не хватает объектов..

OBJ_BUTTON

Но если делать для себя то могу дать совет, объекты "кнопки" можно заменить скриптами которые будут менять глобальные переменные, а скрипты повесить на горячие клавиши. Соответственно управление завязать не на кнопки а на состояние глобальных переменных.

Rustamzhan Salidzhanov
Rustamzhan Salidzhanov | 19 июн 2013 в 14:04
Urain:

В том виде как есть его и не возможно портировать, MQL4 не имеет тех возможностей что и MQL5.

Конкретно по этому индикатору не хватает объектов..

Но если делать для себя то могу дать совет, объекты "кнопки" можно заменить скриптами которые будут менять глобальные переменные, а скрипты повесить на горячие клавиши. Соответственно управление завязать не на кнопки а на состояние глобальных переменных.

  а вот у меня все работает... странно :)

 

Roberto_Ev
Roberto_Ev | 14 окт 2016 в 13:48
Rustamzhan Salidzhanov:

  а вот у меня все работает... странно :)

 

 Desculpe Vasily, eu não entendo nada de Programação.

Estou procurando por um MACD que tenha 5 linhas, sendo que as quatro primeiras receba as mesmas configurações, SM, EMA, ..., porem a última possa receber uma configuração SM, EMA, ... diferente.

Até não sei se isso é possível, mas, se sim, como faço para adicionar em seu código?

OBS: esta última é de um período extremamente longo.  

Grato.

-------------------------------------------------------------------------------------

Перевод Google

К сожалению Vasile, ничего не знаю о программировании знаю.

Я ищу для MACD, который имеет 5 строк, причем первые четыре получают те же настройки, SM, EMA, ..., но последний может получить конфигурацию SM, EMA, ... разные.

Я даже не знаю, если это возможно, но, если да, то как я могу добавить в свой код?

Примечание: Последний является чрезвычайно длительный период.

Благодарный.
Когда нужно использовать указатели в MQL5 Когда нужно использовать указатели в MQL5

Все объекты в MQL5 по умолчанию передаются по ссылке, но есть возможность использовать и указатели объектов. При этом есть опасность получить в качестве параметра функции указатель неинициализированного объекта. В этом случае работа программы будет завершена критически с последующей выгрузкой. Автоматически создаваемые объекты как правило такой ошибки не вызывают, и в этом отношении они достаточно безопасны. В этой статье мы попробуем разобраться в чем разница между ссылкой и указателей, когда оправдано использование указателей и как написать безопасный код с использованием указателей.

Построение излучений индикаторов в MQL5 Построение излучений индикаторов в MQL5

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

Стили рисования в MQL5 Стили рисования в MQL5

В MQL4 есть 6 типов графического отображения индикаторов, а MQL5 доступно уже 18 стилей рисования. Поэтому, возможно, стоит написать статью о стилях рисования в MQL5. В данной статье мы рассмотрим подробности работы со стилями графического отображения индикаторов. Кроме того, мы создадим индикатор для иллюстрации всех этих стилей и уточним особенности графических построений.

Создание тиковых индикаторов Создание тиковых индикаторов

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