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

Vasily | 29 марта, 2010

Введение

Те, кто более-менее знаком с рыночными настроениями не понаслышке, знает индикатор 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


Заключение

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