Сделать индикатор кликабельным/редактировать параметры из основного окна.

 

Здравствуйте. Написал аналог индикатора RSI, c тем лишь отличием, что он отображается не линией в дополнительном окне, а в зависимости от значения - окрашивает ту или иную свечу в определенный цвет.

Но столкнулся с проблемой, что его нельзя настраивать (менять период, значение перекупленности/перепроданности, итд), просто кликнув на свечу (как например редактировать скользящую среднюю, кликнув на нее, итд).

Каждый раз необходимо идти по длинному пути, а именно: клик правой кнопкой на графике -> список индикаторов -> выбираем индикатор.

Подскажите, чего не хватает в коде, для реализации "кликабельности", и почему другие индикаторы (те же скользящие средние) прекрасно обходятся без этого?

Код:

#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 6
#property indicator_plots   2
#property indicator_label1  "Candles Colors"
#property indicator_label2  "RSI Count"
#property indicator_type1   DRAW_COLOR_CANDLES
#property indicator_color1  clrRed,clrLime,clrYellow
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1


//--- input parameters
input int                  Periods     =     14;
input int                  OB          =     54;
input int                  OS          =     46;
input ENUM_APPLIED_PRICE   Price       =     PRICE_CLOSE;
input ENUM_TIMEFRAMES      TimeFrame   =     PERIOD_CURRENT;

//--- indicator buffers
double         RSIBuf[];
double         CandBuf1[];
double         CandBuf2[];
double         CandBuf3[];
double         CandBuf4[];
double         CandColors[];
int            RSICnt, limit;
double         RSI;
bool           firsttime;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,CandBuf1,INDICATOR_CALCULATIONS);
   SetIndexBuffer(1,CandBuf2,INDICATOR_CALCULATIONS);
   SetIndexBuffer(2,CandBuf3,INDICATOR_CALCULATIONS);
   SetIndexBuffer(3,CandBuf4,INDICATOR_CALCULATIONS);
   SetIndexBuffer(4,CandColors,INDICATOR_COLOR_INDEX);
   SetIndexBuffer(5,RSIBuf,INDICATOR_DATA);
   ArrayInitialize(CandBuf1,0);
   ArrayInitialize(CandBuf2,0);
   ArrayInitialize(CandBuf3,0);
   ArrayInitialize(CandBuf4,0);
   ArrayInitialize(RSIBuf,0);
   ArraySetAsSeries(CandBuf1,true);
   ArraySetAsSeries(CandBuf2,true);
   ArraySetAsSeries(CandBuf3,true);
   ArraySetAsSeries(CandBuf4,true);
   ArraySetAsSeries(CandColors,true);
   ArraySetAsSeries(RSIBuf,true);
   ResetLastError();
   firsttime=true;
   RSICnt=iRSI(_Symbol,TimeFrame,Periods,Price);
   if(RSICnt == INVALID_HANDLE)
     {
      Print("Не удалось инициализировать индикатор RSI_ColBars");
      return INIT_FAILED;
     }
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| 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[])
  {
   if(rates_total<=Periods)
      return(0);
   limit = rates_total - prev_calculated;
   if(prev_calculated > 0)
      ++limit;
   CopyBuffer(RSICnt,0,0,limit,RSIBuf);
   CopyOpen(_Symbol,TimeFrame,0,limit,CandBuf1);
   CopyHigh(_Symbol,TimeFrame,0,limit,CandBuf2);
   CopyLow(_Symbol,TimeFrame,0,limit,CandBuf3);
   CopyClose(_Symbol,TimeFrame,0,limit,CandBuf4);
   for(int i = 0; i<limit; i++)
     {
      RSI = RSIBuf[i];
      if(RSI>OB)
         CandColors[i] = 1;
      if(RSI<OS)
         CandColors[i] = 0;
      if(RSI<OB&&RSI>OS)
         CandColors[i] = 2;
     }
   return(rates_total);
  }
//+------------------------------------------------------------------+
 
Заменить все четыре INDICATOR_CALCULATIONS на INDICATOR_DATA
 
Dmitry Fedoseev #:
Заменить все четыре INDICATOR_CALCULATIONS на INDICATOR_DATA

С одной стороны вроде бы спасает (при клике по High/Low свечей, индикатор действительно открывает свойства), с другой стороны, в "окне данных" появляются четыре лишних строчки, а именно дублирование OHLC каждой свечи (собственно именно из-за этого я в свое время и сделал код таким, каким его представил на обзор, чтобы в окне данных была только строчка RSICount и помимо цвета свечи, при необходимости, можно было бы узнать точное значение на текущий момент).

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

 

В конец инита:

   PlotIndexSetInteger(0,PLOT_SHOW_DATA,false);
   PlotIndexSetInteger(1,PLOT_SHOW_DATA,false);
   PlotIndexSetInteger(2,PLOT_SHOW_DATA,false);
   PlotIndexSetInteger(3,PLOT_SHOW_DATA,false);
   return(INIT_SUCCEEDED);
  }
 
Dmitry Fedoseev #:

В конец инита:

Благодарю.

Хватило одной строчки (если кто-то с аналогичным кодом столкнется с аналогичной проблемой):

PlotIndexSetInteger(0,PLOT_SHOW_DATA,false);

т.к. при размещении остальных - пропадала и RSICount, а она как раз нужна.

Теперь все работает должным образом.

 
AltAndGen #:

Благодарю.

Хватило одной строчки (если кто-то с аналогичным кодом столкнется с аналогичной проблемой):

т.к. при размещении остальных - пропадала и RSICount, а она как раз нужна.

Теперь все работает должным образом.

Точно, одной строчки достаточно. Вся пачка буферов для свечей за один считается. Поэтому вот это вот:

 PlotIndexSetInteger(1,PLOT_SHOW_DATA,false);

относится к буферу с RSI.