Индикаторы: Custom Moving Average Input Color

 

Custom Moving Average Input Color:

Модификация индикатора "Custom Moving Average": теперь во входных параметрах можно передавать цвет линии..

Во входных параметрах добавлен пункт: "цвет линии".

Custom Moving Average Input Color

Вы наверное часто замечали, что если в эксперте есть обращение к индикатору Moving Average, то такой индикатор в визуальном режиме тестера отображается ТОЛЬКО красным цветом. Еще хуже ситуация, когда эксперт обращается не к одному, а сразу к трем индикаторам Moving Average - все три индикатора опять таки отображаются красным цветом

Three MA in one color

и визуально отличить один от другого очень трудно.

Чтобы решить вопрос с визуальным отображением индикаторов Moving Average в тестере стратегий и был добавлен параметр "цвет линии". Соответственно в советнике теперь нужно обращаться не к iMA, а к iCustom (пример из кода Crossing of two iMA) :

//--- create handle of the indicator iMA
   handle_iMA_First=iCustom(m_symbol.Name(),Period(),"Custom Moving Average Input Color",
                            InpMAPeriodFirst,InpMAShiftFirst,InpMAMethodFirst,InpMAFirstColor,PRICE_CLOSE);
//handle_iMA_First=iMA(Symbol(),Period(),InpMAPeriodFirst,InpMAShiftFirst,InpMAMethodFirst,PRICE_CLOSE);
//--- if the handle is not created 
   if(handle_iMA_First==INVALID_HANDLE)
     {
      //--- tell about the failure and output the error code 
      PrintFormat("Failed to create handle of the iMA indicator for the symbol %s/%s, error code %d",
                  Symbol(),
                  EnumToString(Period()),
                  GetLastError());
      //--- the indicator is stopped early 
      return(INIT_FAILED);
     }

На примере советника Crossing of two iMA, теперь в визуальном тестере стратегий вызов трех индикаторов визуально отлично различается:

Crossing of two iMA

Автор: Vladimir Karputov

 
Можно написать утилиту, которая будет менять любую линию/гистограмму (и т.д.) произвольного индикатора по принципу, что показан на видео
 
Молодцы! Спасибо!
 

Я адаптировал код, чтобы включить настройки веса линии и стиля:


//+------------------------------------------------------------------+
//| Пользовательская скользящая средняя Colour.mq5 |
//| Copyright 2009-2017, MetaQuotes Software Corp.|
//|http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "2009-2017, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.001"
//--- настройки индикатора
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrRed
//--- входные параметры
input int               InpMAPeriod=13;            // Период
input int               InpMAShift=0;              // Смена
input ENUM_MA_METHOD    InpMAMethod=MODE_SMMA;     // Метод
input color             InpColor=clrYellow;        // Цвет
input ENUM_LINE_STYLE   InpMAStyle=STYLE_SOLID;      // Стиль
input int               InpMAWidth=1;              // Ширина


//--- индикаторные буферы
double               ExtLineBuffer[];
//+------------------------------------------------------------------+
//| Простая скользящая средняя|
//+------------------------------------------------------------------+
void CalculateSimpleMA(int rates_total,int prev_calculated,int begin,const double &price[])
  {
   int i,limit;
//--- был изменен первый расчет или количество баров
   if(prev_calculated==0)// первый расчет
     {
      limit=InpMAPeriod+begin;
      //--- установите пустое значение для первых предельных баров
      for(i=0;i<limit-1;i++) ExtLineBuffer[i]=0.0;
      //--- вычислите первое видимое значение
      double firstValue=0;
      for(i=begin;i<limit;i++)
         firstValue+=price[i];
      firstValue/=InpMAPeriod;
      ExtLineBuffer[limit-1]=firstValue;
     }
   else limit=prev_calculated-1;
//--- главный цикл
   for(i=limit;i<rates_total && !IsStopped();i++)
      ExtLineBuffer[i]=ExtLineBuffer[i-1]+(price[i]-price[i-InpMAPeriod])/InpMAPeriod;
//---
  }
//+------------------------------------------------------------------+
//| экспоненциальная скользящая средняя|
//+------------------------------------------------------------------+
void CalculateEMA(int rates_total,int prev_calculated,int begin,const double &price[])
  {
   int    i,limit;
   double SmoothFactor=2.0/(1.0+InpMAPeriod);
//--- был изменен первый расчет или количество баров
   if(prev_calculated==0)
     {
      limit=InpMAPeriod+begin;
      ExtLineBuffer[begin]=price[begin];
      for(i=begin+1;i<limit;i++)
         ExtLineBuffer[i]=price[i]*SmoothFactor+ExtLineBuffer[i-1]*(1.0-SmoothFactor);
     }
   else limit=prev_calculated-1;
//--- главный цикл
   for(i=limit;i<rates_total && !IsStopped();i++)
      ExtLineBuffer[i]=price[i]*SmoothFactor+ExtLineBuffer[i-1]*(1.0-SmoothFactor);
//---
  }
//+------------------------------------------------------------------+
//| Линейное взвешенное скользящее среднее|
//+------------------------------------------------------------------+
void CalculateLWMA(int rates_total,int prev_calculated,int begin,const double &price[])
  {
   int        i,limit;
   static int weightsum;
   double     sum;
//--- был изменен первый расчет или количество баров
   if(prev_calculated==0)
     {
      weightsum=0;
      limit=InpMAPeriod+begin;
      //--- установите пустое значение для первых предельных баров
      for(i=0;i<limit;i++) ExtLineBuffer[i]=0.0;
      //--- вычислите первое видимое значение
      double firstValue=0;
      for(i=begin;i<limit;i++)
        {
         int k=i-begin+1;
         weightsum+=k;
         firstValue+=k*price[i];
        }
      firstValue/=(double)weightsum;
      ExtLineBuffer[limit-1]=firstValue;
     }
   else limit=prev_calculated-1;
//--- главный цикл
   for(i=limit;i<rates_total && !IsStopped();i++)
     {
      sum=0;
      for(int j=0;j<InpMAPeriod;j++) sum+=(InpMAPeriod-j)*price[i-j];
      ExtLineBuffer[i]=sum/weightsum;
     }
//---
  }
//+------------------------------------------------------------------+
//| сглаженное скользящее среднее|
//+------------------------------------------------------------------+
void CalculateSmoothedMA(int rates_total,int prev_calculated,int begin,const double &price[])
  {
   int i,limit;
//--- был изменен первый расчет или количество баров
   if(prev_calculated==0)
     {
      limit=InpMAPeriod+begin;
      //--- установите пустое значение для первых предельных баров
      for(i=0;i<limit-1;i++) ExtLineBuffer[i]=0.0;
      //--- вычислите первое видимое значение
      double firstValue=0;
      for(i=begin;i<limit;i++)
         firstValue+=price[i];
      firstValue/=InpMAPeriod;
      ExtLineBuffer[limit-1]=firstValue;
     }
   else limit=prev_calculated-1;
//--- главный цикл
   for(i=limit;i<rates_total && !IsStopped();i++)
      ExtLineBuffer[i]=(ExtLineBuffer[i-1]*(InpMAPeriod-1)+price[i])/InpMAPeriod;
//---
  }
//+------------------------------------------------------------------+
//| Пользовательская функция инициализации индикатора |
//+------------------------------------------------------------------+
void OnInit()
  {
//--- отображение индикаторных буферов
   SetIndexBuffer(0,ExtLineBuffer,INDICATOR_DATA);
//--- установите точность
   IndicatorSetInteger(INDICATOR_DIGITS,_Digits+1);
//--- устанавливает первый бар, от которого будет отрисовываться индекс
   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,InpMAPeriod);
//---- линия смещается при рисовании
   PlotIndexSetInteger(0,PLOT_SHIFT,InpMAShift);
//--- цветная линия
   PlotIndexSetInteger(0,PLOT_LINE_COLOR,InpColor);
//--- строка стиля
   PlotIndexSetInteger(0,PLOT_LINE_STYLE,InpMAStyle);
//--- ширина линии
   PlotIndexSetInteger(0,PLOT_LINE_WIDTH,InpMAWidth);

//--- имя для DataWindow
   string short_name="unknown ma";
   switch(InpMAMethod)
     {
      case MODE_EMA :  short_name="EMA";  break;
      case MODE_LWMA : short_name="LWMA"; break;
      case MODE_SMA :  short_name="SMA";  break;
      case MODE_SMMA : short_name="SMMA"; break;
     }
   IndicatorSetString(INDICATOR_SHORTNAME,short_name+"("+string(InpMAPeriod)+")");
//---- устанавливает пустое значение линии рисования.
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
//---- инициализация выполнена
  }
//+------------------------------------------------------------------+
//| Скользящая средняя|
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])
  {
//--- проверка количества баров
   if(rates_total<InpMAPeriod-1+begin)
      return(0);// недостаточно баров для расчета
//--- был изменен первый расчет или количество баров
   if(prev_calculated==0)
      ArrayInitialize(ExtLineBuffer,0);
//--- устанавливает первый бар, от которого будет отрисовываться индекс
   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,InpMAPeriod-1+begin);

//--- расчет
   switch(InpMAMethod)
     {
      case MODE_EMA:  CalculateEMA(rates_total,prev_calculated,begin,price);        break;
      case MODE_LWMA: CalculateLWMA(rates_total,prev_calculated,begin,price);       break;
      case MODE_SMMA: CalculateSmoothedMA(rates_total,prev_calculated,begin,price); break;
      case MODE_SMA:  CalculateSimpleMA(rates_total,prev_calculated,begin,price);   break;
     }
//--- возвращаем значение prev_calculated для следующего вызова
   return(rates_total);
  }
//+------------------------------------------------------------------+
 
И можно ли добавить возможность изменять толщину линии из советника?
 
Pirata Independent #:
И можно ли добавить возможность изменять толщину линии из советника?

Да, в начале индикатора:


 
И как он модифицируется из кода эксперта?