Индикатор от индикатора - непонятные артефакты

 
Код индикатора TSI-Osc

//+------------------------------------------------------------------+
//|                                                          TSI.mq4 |
//|                      Copyright © 2005, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2005, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net"

#property indicator_separate_window
#property indicator_buffers 2
#property indicator_color1 White
#property indicator_color2 Red
#property indicator_maximum 100
#property indicator_minimum -100
#property indicator_level1 0
//---- input parameters
extern int       First_R=8;
extern int       Second_S=5;
extern int       SignalPeriod=5;
extern int       Mode_Smooth=1;
//---- buffers
double TSI_Buffer[];
double SignalBuffer[];
double MTM_Buffer[];
double EMA_MTM_Buffer[];
double EMA2_MTM_Buffer[];
double ABSMTM_Buffer[];
double EMA_ABSMTM_Buffer[];
double EMA2_ABSMTM_Buffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
   IndicatorBuffers(8);
   SetIndexBuffer(2, MTM_Buffer);
   SetIndexBuffer(3, EMA_MTM_Buffer);
   SetIndexBuffer(4, EMA2_MTM_Buffer);
   SetIndexBuffer(5, ABSMTM_Buffer);
   SetIndexBuffer(6, EMA_ABSMTM_Buffer);
   SetIndexBuffer(7, EMA2_ABSMTM_Buffer);

   SetIndexStyle(0,DRAW_LINE);
   SetIndexBuffer(0,TSI_Buffer);
   SetIndexLabel(0,"TSI");
   SetIndexStyle(1,DRAW_LINE);
   SetIndexBuffer(1,SignalBuffer);
   SetIndexLabel(1,"Signal");
   IndicatorShortName("TSI"+"("+First_R+","+Second_S+","+SignalPeriod+")");

//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custor indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//---- TODO: add your code here
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   int    counted_bars=IndicatorCounted();
   int limit,i;
   limit=Bars-counted_bars-1;
   for (i=Bars-1;i>=0;i--)
      {
      MTM_Buffer[i]=Close[i]-Close[i+1];//iMomentum(NULL,0,1,PRICE_CLOSE,i);
      ABSMTM_Buffer[i]=MathAbs(MTM_Buffer[i]);
      }
      
   for (i=Bars-1;i>=0;i--)
      {
      EMA_MTM_Buffer[i]=iMAOnArray(MTM_Buffer,0,First_R,0,MODE_EMA,i);
      EMA_ABSMTM_Buffer[i]=iMAOnArray(ABSMTM_Buffer,0,First_R,0,MODE_EMA,i);
      }

   for (i=Bars-1;i>=0;i--)
      {
      EMA2_MTM_Buffer[i]=iMAOnArray(EMA_MTM_Buffer,0,Second_S,0,MODE_EMA,i);
      EMA2_ABSMTM_Buffer[i]=iMAOnArray(EMA_ABSMTM_Buffer,0,Second_S,0,MODE_EMA,i);
      }

   for (i=limit;i>=0;i--)
      {
      TSI_Buffer[i]=100.0*EMA2_MTM_Buffer[i]/EMA2_ABSMTM_Buffer[i];
      }
   for (i=limit;i>=0;i--)
      {
      SignalBuffer[i]=iMAOnArray(TSI_Buffer,0,SignalPeriod,0,Mode_Smooth,i);
      }
      
//---- TODO: add your code here
   
//----
   return(0);
  }
//+------------------------------------------------------------------+



Работает норамльно, переключение тайм-фреймов не приводит к сбоям.

На основе этого индикатора написан второй - TSI Signals, который выдает сигналы к покупке или продаже при пересечении линий индикатора TSI-Osc.

//+------------------------------------------------------------------+
//|                                                  TSI Signals.mq4 |
//|                      Copyright © 2005, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2005, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net"

#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 Red
#property indicator_color2 MediumBlue
//---- input parameters
extern int       First_R=8;
extern int       Second_S=5;
extern int       SignalPeriod=5;
extern int       Mode_Smooth=1;
extern int       ArrowShift=5;
//---- buffers
double ExtMapBuffer1[];
double ExtMapBuffer2[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
   SetIndexStyle(0,DRAW_ARROW);
   SetIndexArrow(0,217);
   SetIndexBuffer(0,ExtMapBuffer1);
   SetIndexLabel(0,"UpArrow");
   SetIndexEmptyValue(0,0.0);
   SetIndexStyle(1,DRAW_ARROW);
   SetIndexArrow(1,218);
   SetIndexBuffer(1,ExtMapBuffer2);
   SetIndexLabel(1,"DownArrow");
   SetIndexEmptyValue(1,0.0);
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custor indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//---- TODO: add your code here
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   int    counted_bars=IndicatorCounted();
   int limit,i;
   double curTSI=0.0,prevTSI=0.0,curSignal=0.0,prevSignal=0.0;
   limit=Bars-counted_bars-First_R-Second_S-SignalPeriod;
   for (i=limit;i>=0;i--)
      {
      curTSI=iCustom(NULL,0,"TSI-Osc",First_R,Second_S,SignalPeriod,Mode_Smooth,0,i);
      prevTSI=iCustom(NULL,0,"TSI-Osc",First_R,Second_S,SignalPeriod,Mode_Smooth,0,i+1);
      curSignal=iCustom(NULL,0,"TSI-Osc",First_R,Second_S,SignalPeriod,Mode_Smooth,1,i);
      prevSignal=iCustom(NULL,0,"TSI-Osc",First_R,Second_S,SignalPeriod,Mode_Smooth,1,i+1);
      if ((curTSI>curSignal)&&(prevTSI<prevSignal)) ExtMapBuffer1[i]=Close[i]+3*ArrowShift*Point;
      if ((curTSI<curSignal)&&(prevTSI>prevSignal)) ExtMapBuffer2[i]=Close[i]-ArrowShift*Point;
      }
//---- TODO: add your code here
   
//----
   return(0);
  }
//+------------------------------------------------------------------+



Так вот, этот второй начинает глючить при переключении тайм-фреймов.


 
Rosh, ты же вроде бы никогда не страдал такой постановкой вопросов =)))
 
Rosh, ты же вроде бы никогда не страдал такой постановкой вопросов =)))


"Все течет, но ничего не меняется" - из дневника сантехника Потапова. :)

Что значит не страдал. Что-то подобное я уже писал несколько раз. В первый раз было неправильное использование мувингов от буферов - вопрос снялся. Второй раз просто не работало - вопрос снялся из-за отсутствия ответа и понимания (пришлось сделать тупо через любимое в нашей стране место). Это третий раз - ошибок явных я не вижу, использования неправильной инициализации буферов нет (потому как нет инициализации, грубо говоря), в обход пройти - можно, конечно, но я не встречал в мануале предупреждений о нежелательности использования индикатора от индикатора.
 
По-моему, индикатор от индикатора тут не причем. При инициализации TSI-Signals нормально не очищаются индикаторные массивы. И вроде как это с самых первых билдов тянется. Помогает принудительная очистка при деинициализации. В твоем случае:
int deinit()
  {
   for(int i=0;i<Bars;i++)
    {
     ExtMapBuffer1[i]=0.0;
     ExtMapBuffer2[i]=0.0;
    }
   SetIndexEmptyValue(0,0.0);
   SetIndexEmptyValue(1,0.0);
   return(0);
  }



Хотя это извращение.

 
По-моему, индикатор от индикатора тут не причем. При инициализации TSI-Signals нормально не очищаются индикаторные массивы. И вроде как это с самых первых билдов тянется. Помогает принудительная очистка при деинициализации. В твоем случае:
int deinit()
  {
   for(int i=0;i<Bars;i++)
    {
     ExtMapBuffer1[i]=0.0;
     ExtMapBuffer2[i]=0.0;
    }
   SetIndexEmptyValue(0,0.0);
   SetIndexEmptyValue(1,0.0);
   return(0);
  }



Хотя это извращение.



Есть такое подозрение. В таком случае может лучше использовать ArrayInitialize(ExtMapBuffer1,0.0)?
Хотя и тут есть две проблемы:
1. Рука не поднимается использовать функцию инициализации в деструкторе.
2. Эта процедура нежелательна из соображений экономии ресурсов процессора (я заметил, что просчитанные буфера при возврате в тайм-фрейм не пересчитываются).
3. Есть и третья проблема - разработчики скажут, что это корявое написание кода. :(
 
Я чего-то и не смотрел на функцию ArrayInitialize, сразу-то не мог написать про нее? ;)
Нарисуй такие связки в блоке Init:
// ...
ArrayInitialize(ExtMapBuffer1,0.0);
SetIndexEmptyValue(0,0.0);
// ...
ArrayInitialize(ExtMapBuffer2,0.0);
SetIndexEmptyValue(1,0.0);
// ...


и никакие деструкторы не нужны.

 
Хотя все равно не понятно, почему сами индикаторные массивы не очищаются при инициализации (без принудительной очистки).
 
Rosh, ты же вроде бы никогда не страдал такой постановкой вопросов =)))


"Все течет, но ничего не меняется" - из дневника сантехника Потапова. :)

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

я имел в виду _глубину_раскрытия_проблемы_, точное описание предпринятых действий и грамотно сформулированный вопрос - то, что часто просто необходимо для ответа, или хотя бы для того, чтоб твой код кто-то посмотрел =)))
 
to komposter

Думаю, ты прав. Лениво было все описывать, проще накинуть на график индикатор и все станет ясно. Хотя понимаю, что другим будет лениво накидывать индикатор на график :)
Если бы нужно было мне , я бы эту граблю, думаю, обошел бы. Но она неочевидна, нигде нет предупреждений по корректной работе с буферами. Согласен, что хороший стиль - это проверка всех возможных и невозможных ошибок.
 
Я чего-то и не смотрел на функцию ArrayInitialize, сразу-то не мог написать про нее? ;)
Нарисуй такие связки в блоке Init:
// ...
ArrayInitialize(ExtMapBuffer1,0.0);
SetIndexEmptyValue(0,0.0);
// ...
ArrayInitialize(ExtMapBuffer2,0.0);
SetIndexEmptyValue(1,0.0);
// ...


и никакие деструкторы не нужны.



В принципе, для данного индикатора это наверно решение, так как количество ненулевых значений очень мало.
 
Так вот, этот второй начинает глючить при переключении тайм-фреймов

Сегодня кардинально решим эту проблему.
При переключении таймфреймов индикаторы будут полностью переинициализироваться автоматически.
Причина обращения: