Индикаторный вопрос - страница 3

 
Agent86:
.

Так или иначе, я пытался сделать так, чтобы высокие фракталы формировались только при наступлении другого условия, такого как пересечение iMACD, или пересечение EMA, или пересечение какого-либо другого индикатора.
Таким образом, фракталы будут отображаться на индикаторе только при выполнении всех условий.


Я не совсем понял, что именно вы пытаетесь сделать, но попробуйте следующее: обратите внимание на внешние входы.

#property indicator_chart_window      extern bool condition1 = true;
#property indicator_buffers 3         extern bool condition2 = true;
#property indicator_color1 Red
#property indicator_color2 Blue
#property indicator_color3 White

//---- buffers
double v1[];
double v2[];
double v3[];
double val1;
double val2;
double val3;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int init()
  {
//----
   IndicatorBuffers(3);

   SetIndexArrow(0, 111);
   SetIndexStyle(0,DRAW_ARROW,STYLE_DOT,1,Blue);
   SetIndexBuffer(0, v1);
   SetIndexLabel(0,"Resistance");

   SetIndexArrow(1, 111);
   SetIndexStyle(1,DRAW_ARROW,STYLE_DOT,1,Red);
   SetIndexBuffer(1, v2);
   SetIndexLabel(1,"Support");

   SetIndexArrow(2, 111);
   SetIndexStyle(2,DRAW_ARROW,STYLE_DOT,1,White);
   SetIndexBuffer(2, v3);
   SetIndexLabel(2,"High A"); 
//----
   return(0);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int start()
  {
    
   double   faster = iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,1), //MODE_MAIN
            slower = iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,1); //MODE_SIGNAL
           
            
   int bars = Bars;
//----
  
   for(int i=bars; i>=0; i--)
    {
     if(condition1)
       {
        val1=iFractals(NULL, 0, MODE_UPPER,i);
        if (val1 > 0) v1[i]=High[i];       
       }   
     if(condition2)
       {      
        val2=iFractals(NULL, 0, MODE_LOWER,i);
        if (val2 > 0) v2[i]=Low[i];
       }
     }    
//----
   return(0);
  }
//+------------------------------------------------------------------+
 
WHRoeder:
Как именно вы пришли к такому выводу и в чем заключается функциональная разница?

Я пришел к такому выводу, потому что, скорее всего, я смотрел с точки зрения ООП. Да, это не верно для случая MQL4, я сейчас вспоминаю. Хотя это может быть хорошей практикой?



 

Или может быть что-то вроде этого?

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

#property indicator_chart_window
#property indicator_buffers 3
#property indicator_color1 Red
#property indicator_color2 Blue
#property indicator_color3 White

//---- buffers
double v1[];
double v2[];
double v3[];
double val1;
double val2;
double val3;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int init()
  {
//----
   IndicatorBuffers(3);

   SetIndexArrow(0, 111);
   SetIndexStyle(0,DRAW_ARROW,STYLE_DOT,1,Blue);
   SetIndexBuffer(0, v1);
   SetIndexLabel(0,"Resistance");

   SetIndexArrow(1, 111);
   SetIndexStyle(1,DRAW_ARROW,STYLE_DOT,1,Red);
   SetIndexBuffer(1, v2);
   SetIndexLabel(1,"Support");

   SetIndexArrow(2, 111);
   SetIndexStyle(2,DRAW_ARROW,STYLE_DOT,1,White);
   SetIndexBuffer(2, v3);
   SetIndexLabel(2,"High A"); 
//----
   return(0);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int start()
  {
    
   double   faster=0;
   double   slower=0;         
   int      bars = Bars;
//----
  
   for(int i=bars; i>=0; i--)
    {
     faster = iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,i); //MODE_MAIN
     slower = iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,i); //MODE_SIGNAL
     val1=iFractals(NULL, 0, MODE_UPPER,i);
     val2=iFractals(NULL, 0, MODE_LOWER,i);
     
     if(faster > 0)
      {
       if (val1 > 0) v1[i]=High[i];
      }
      
     if(faster < 0)
      {
       if (val2 > 0) v2[i]=Low[i];
      }        
    }   
//----
   return(0);
  }
//+------------------------------------------------------------------+
 
diostar:
Я пришел к такому выводу, потому что, скорее всего, смотрел с точки зрения ООП. Да, это не верно для случая MQL4, как я сейчас помню. Хотя это может быть хорошей практикой?

Это всегда хорошая практика - ограничивать область видимости. Это всегда хорошая практика - определять переменную/объект там, где они используются, и инициализировать их в этой точке.

Определение объекта вне цикла приводит к конструкции по умолчанию плюс N присваиваний. Определение внутри цикла приводит к N конструкциям со значением - обычно быстрее.

Никогда не беспокойтесь об оптимизации, пока не докажете, что изменения имеют значение.

 
WHRoeder:

Хорошей практикой всегда является ограничение области применения. Хорошей практикой всегда является определение переменной/объекта там, где они используются, и их инициализация в этой точке.

Определение объекта вне цикла приводит к конструкции по умолчанию плюс N присваиваний. Определение внутри цикла приводит к N конструкциям со значением - обычно быстрее.

Никогда не беспокойтесь об оптимизации, пока не докажете, что изменение имеет значение.

Это должно относиться и к итератору. for (int i=0; . ..
 
diostar:
Это должно применяться и к его итератору. for (int i=0;.. .
Я согласен, но я не писал этот код.
 
Хорошо, теперь у меня есть несколько вариантов рабочего кода, спасибо.

Хотя, я немного не понимаю, почему объявление переменных (более быстрых и более медленных) вне цикла не работает, в то время как внутри цикла все в порядке.

И все же int i = Bars будет работать вне цикла или внутри цикла?


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

Итак, теперь я могу работать над сравнением некоторых индикаторных времен, я попытаюсь разобраться в этом сейчас.

Например:
Compare v1[i] to v2[i] Currently formed indicator Times && / || if(v1[i] time is > v2[i] time) and other comparations like this.

Спасибо за все советы, это была большая помощь.
 
WHRoeder:

Хорошей практикой всегда является ограничение области применения. Хорошей практикой всегда является определение переменной/объекта там, где они используются, и их инициализация в этой точке.

Определение объекта вне цикла приводит к конструкции по умолчанию плюс N присваиваний. Определение внутри цикла приводит к N конструкциям со значением - обычно быстрее.

Никогда не беспокойтесь об оптимизации, пока не докажете, что изменение имеет значение.

Я предполагаю, что это верно для всех, а не только для индикаторов / пользовательских индикаторов?
 
Agent86:
Хорошо, теперь у меня есть несколько вариантов рабочего кода, спасибо.

Хотя, я немного не понимаю, почему объявление переменных (быстрее и медленнее) вне цикла не подходит, в то время как внутри цикла все в порядке

.

И все же int i = Bars будет работать вне цикла или внутри цикла?


Вы должны рассмотреть, что именно вы делаете, когда вы создаете индикатор, вы применяете свой код к каждому бару на графике, это означает, что вам нужно получить значение индикатора macd, как оно было для каждого из этих исторических баров.

В вашем первоначальном коде вы так и сделали:

double   faster = iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,1), 
последний параметр 1 - это значение macd, которое было на баре 1 графика, баре, предшествующем текущему бару, который индексируется как бар 0

Очевидно, что вы не хотите использовать это единственное значение macd в вашем условном операторе на всем историческом графике.

Вам нужно индексировать macd на тот же индекс бара, что и каждый бар, поэтому, например, на баре 500 вам нужно следующее

faster = iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,500) 

последний параметр должен меняться в соответствии с номером бара, к которому ваш индикатор применяет свои алгоритмы.

Вот почему он нужен внутри цикла, поэтому вы можете использовать итератор цикла ( i ) для последнего параметра, таким образом, вы получите значение macd, как оно было для каждого бара исторического графика.

faster = iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,i), 

Надеюсь, это поможет немного прояснить ситуацию.

 
WHRoeder:
Попробуйте это изменение
Почему for(int i = Bars-1 ?

И почему это лучше, чем for(int i = Bars)?

Пожалуйста, посоветуйте, спасибо.

Причина обращения: