По чему эксперт получает "через раз" сигнал от индикатора?

 
Здравствуйте Господа!
У меня следующий вопрос.
Эксперт получает сигнал short / long от всем известного индикатора ASCtrend. При тестировании, просмотрев график, замечаю, что не на всех образовавшихся точках, эксперт выполняят операции. Думал что проблемма в длинном коде индикатора, вставлял в эксперта задержку Sleep, но безрезультатно. Подскажите пожалуйста кто знает, в чём проблема.
 
Doctorcoot:
Здравствуйте Господа!
У меня следующий вопрос.
Эксперт получает сигнал short / long от всем известного индикатора ASCtrend. При тестировании, просмотрев график, замечаю, что не на всех образовавшихся точках, эксперт выполняят операции. Думал что проблемма в длинном коде индикатора, вставлял в эксперта задержку Sleep, но безрезультатно. Подскажите пожалуйста кто знает, в чём проблема.
Вообще то у таких индюков есть множество реализаций. А в данном форуме, если память мне не изменяет, нет никого, кто обладал бы телепатическими способностями. А посему, чтобы что либо спросить, принято выложить код на всеобщее обозрение. И лучше всего это делать через пимпочку редактора MQL, потому как прикрепленный файл нужно скачивать и исследовать в MetaEditor.
Будь ласка, продемонстрируй код.
 
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_color1 Aqua
#property indicator_color2 Magenta
 
extern int RISK=4;
extern int AllBars=250;
int up=0,dn=0;
double val1buffer[];
double val2buffer[];
double doc[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
      SetIndexStyle(0,DRAW_ARROW,EMPTY);
      SetIndexArrow(0,108);
      SetIndexBuffer(0, val1buffer);
 
      SetIndexStyle(1,DRAW_ARROW,EMPTY);
      SetIndexArrow(1,108);
      SetIndexBuffer(1, val2buffer);
      SetIndexBuffer(2,doc);
      return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
   {
     return(0);
   }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
// int    counted_bars=IndicatorCounted();
 
int start()
{   
   
   double value2;
   double value3;
   double value10=10;
   double value11;
   double x1=70;
   double x2=30;
   int TrueCount;
   int counter;
   int MRO1;
   int MRO2;
   int i1;
   double Range;
   double AvgRange;
   double val1;
   double val2;
   double Table_value2[500][2];
   int counted_bars=IndicatorCounted();
   
   value10=3+RISK*2;
   x1=67+RISK;
   x2=33-RISK;
   value11=value10;
  //---------------------------- 
    
   if(counted_bars<0) return (-1);
   if(counted_bars>0) counted_bars--;       //last bar recounted
   int i;
   int shift = Bars-counted_bars-1;
   if (shift > AllBars) shift = AllBars;
         
  for(i=shift; i>0; i--)
   {
   
 
 
   
                 
      counter=i;
      Range=0;
      AvgRange=0;
      for (counter=i ;counter<=i+9;counter++)
      {
         AvgRange=AvgRange+MathAbs(High[counter]-Low[counter]);
      }
      Range=AvgRange/10;
      
      
      counter=i;
      TrueCount=0;
      while (counter<i+9 && TrueCount<1)
      {
         if (MathAbs(Open[counter]-Close[counter+1])>=Range*2.0 )
               TrueCount++;
         counter++;
      }
 
      if (TrueCount>=1) 
            MRO1=counter ; 
      else 
            MRO1=-1;
            
      counter=i;
      TrueCount=0;
      while (counter<i+6 && TrueCount<1)
      {
           if(MathAbs(Close[counter+3]-Close[counter])>=Range*4.6)
            {TrueCount++;}
           counter++;
      }
      
      if(TrueCount>=1) 
            MRO2=counter; 
      else 
            MRO2=-1;
            
      if (MRO1>-1) 
            value11=3; 
      else 
            value11=value10;
            
      if (MRO2>-1) 
            value11=4; 
      else 
           value11=value10;
          
            
      value2=100-MathAbs(iWPR(NULL,0,value11,i));
      Table_value2[i][0]=i;
      Table_value2[i][1]=value2;
      val1=0;
      val2=0;
      value3=0;
      //-------------------     val1  
      if (value2<x2 )  //  x2 = 30
      {
         i1=1;
         while (Table_value2[i+i1][1]>=x2 && Table_value2[i+i1][1]<=x1)
         {i1++;}
 
         if (Table_value2[i+i1][1]>x1)
         {
            value3=High[i]+Range*0.5;
            val1=value3;
         }
      }
      
      //-------------------     val2  
      if ( value2>x1) // x1 = 70 
      {  
            i1=1;
            while (Table_value2[i+i1][1]>=x2 && Table_value2[i+i1][1]<=x1)
            {i1++;}
            
            if (Table_value2[i+i1][1]< x2)
            {
               value3=Low[i]-Range*0.5;
               val2=value3;
            } 
      }
      
      
       
     
      if (val2!=0 && up==0 )
      {     
           val1buffer[i]= val2-1*Point;
           up=1;
           dn=0;
           if(shift<=2)
           {
            doc[0]=1;
            }
      }  
      if (val1 !=0 && dn==0)
      {
      
            val2buffer[i]= val1+1*Point;
            dn=1;
            up=0;
            if(shift<=2)
            {
            doc[0]=2;
            }
       }
   
   }
return(0);
 
}
Это индикатор. Обращение из эксперта обычное через iCustom. Если возвращает 1 - buy, а если 2 - sell.
 
Дело скорее всего не в индикаторе, а в эксперте, который не открывает ордер, если уже имеется открытый
 

Да нет. У меня там предусмотрено, если открыт в другую стороно, сначало закрываем, а потом открываем новый. Да и ведь через несколько точек срабатывает. Похоже что в момент, когда индикатор показывает цыфру, эксперт уже проскакивает нужный код, или ещё не доходит. А может и тестр забавляется.

 

Наверное, нужно ещё раз пересмотреть код индикатора.
Без комментариев сразу не понять, но по-моему в этой строке

for(i=shift; i>0; i--)

следует использовать >= , чтобы считался и нулевой бар.

Лучше принять как шаблон для построения индикаторов следующий код:

//--------------------------------------------------------------------
int start()                         // Специальная функция start()
   {
   int i,                           // Индекс бара
       Counted_bars;                // Количество просчитанных баров 
//--------------------------------------------------------------------
   Counted_bars=IndicatorCounted(); // Количество просчитанных баров 
   i=Bars-Counted_bars-1;           // Индекс первого непосчитанного
   while(i>=0)                      // Цикл по непосчитанным барам
      {
      // === сюда вставить расчёт ===
      i--;                          // Расчёт индекса следующего бара
      }
//--------------------------------------------------------------------
   return;                          // Выход из спец. ф-ии start()
   }
//--------------------------------------------------------------------
 
SK. писал (а):

Наверное, нужно ещё раз пересмотреть код индикатора.
Без комментариев сразу не понять, но по-моему в этой строке

for(i=shift; i>0; i--)

следует использовать >= , чтобы считался и нулевой бар.

Лучше принять как шаблон для построения индикаторов следующий код:

//--------------------------------------------------------------------
int start()                         // Специальная функция start()
   {
   int i,                           // Индекс бара
       Counted_bars;                // Количество просчитанных баров 
//--------------------------------------------------------------------
   Counted_bars=IndicatorCounted(); // Количество просчитанных баров 
   i=Bars-Counted_bars-1;           // Индекс первого непосчитанного
   while(i>=0)                      // Цикл по непосчитанным барам
      {
      // === сюда вставить расчёт ===
      i--;                          // Расчёт индекса следующего бара
      }
//--------------------------------------------------------------------
   return;                          // Выход из спец. ф-ии start()
   }
//--------------------------------------------------------------------




Чем лучше?
 

Может, ничем особо и не лучше. Несколько привычней свиду, немного компактней. С точки зрения работоспособности можно использовать любой способ. Я имел ввиду, что если использовать один и тот же шаблон, то любые отклонения от шаблона бросаются в глаза, легко ориентироваться.

Например, в рассматриваемом коде мне представляется инородной строка:

 if(counted_bars>0) counted_bars--;       //last bar recounted
Я думаю, что неправильно каждый новый индикатор строить как-то оригинально, всякий раз изобретая велосипед.
 
Добовлял знак равенства, результаты ещё хуже. Выполняются операции, там где даже точки не появляются. И всё же, мне интересно, почему точки рисует, а ордера не всегда открывает. Команды ведь в одном месте находятся?. К стати добовлял буферную переменную во фрактальный индикатор, та же ошибка всплывает.
   Если б я что нибудь понимал в программировании, проявил бы к этому моменту принципиальный интерес. А пока, скрывая свою необразованность, ссылаю всё на несовершенство MQ4. Да простят меня авторы.
 
Во-первых, возьмите нормальный индикатор:
//+------------------------------------------------------------------+
//|                                               ASC_Trend_1sig.mq4 |
//|                                              thanks to komposter |C0Rpus - big thanks CHANGE2002, STEPAN and SERSH
//|                                         komposterius[@]mail[.]ru |
//+------------------------------------------------------------------+
#property copyright "thanks to komposter"
#property link      "komposterius[@]mail[.]ru"
 
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 Lime
#property indicator_color2 Red
 
extern double RISK = 3;
/*extern*/ double K = 0.5;
 
double buf0[]; //ASC_Trend_Up
double buf1[]; //ASC_Trend_Down
 
int init()
{
    IndicatorShortName( "ASC_Trend" );
    IndicatorDigits ( MarketInfo( Symbol(), MODE_DIGITS ) );
 
    SetIndexBuffer( 0 , buf0 );
    SetIndexStyle ( 0 , DRAW_ARROW , EMPTY , 1 );
    SetIndexArrow( 0 , 217);
    SetIndexDrawBegin( 0 , 12 );
    SetIndexLabel( 0 , "ASC_Trend_Up");
 
    SetIndexBuffer( 1 , buf1 );
    SetIndexStyle ( 1 , DRAW_ARROW , EMPTY , 1 );
    SetIndexArrow( 1 , 218);
    SetIndexDrawBegin( 1 , 12 );
    SetIndexLabel( 1 , "ASC_Trend_Down");
 
return(0);
}
 
int ASC_Trend_Prev = 1;
 
int start()
{
    int counted_bars=IndicatorCounted();
    if ( counted_bars < 0 ) { Print( "counted_bars < 0 !" ); return(-1); }
    if ( Bars < 100 ) { Print( "Bars < 100 !" ); return(-1); }
    if ( counted_bars > 0 ) { counted_bars -- ; }
 
   int limit = Bars - 12;
   if ( counted_bars > 0 ) { limit = Bars - counted_bars - 12; }
 
    double x1 = 67 + RISK, x2 = 33 - RISK;
    for ( int i = limit; i >= 0; i -- )
    {
        double ASC_Trend_Up = 0, ASC_Trend_Down = 0, SummRange = 0, AvgRange = 0;
 
        for ( int u = i + 9; u >= i; u -- )
        { SummRange += High[u] - Low[u]; }
        AvgRange = SummRange / 10;
 
        int WprPeriod = 3 + RISK * 2;
 
        for ( u = i + 9; u >= i; u -- )
        {
            if ( MathAbs( Open[u] - Close[u+1] ) >= AvgRange * 2 )
            { WprPeriod = 3; break; }
        }
 
        for ( u = i + 6; u >= i; u -- )
        {
            if ( MathAbs( Close[u+3] - Close[u] ) >= AvgRange * 4.6 )
            { WprPeriod = 4; break; }
        }
 
        double WprAbs = 100 + iWPR( Symbol(), 0, WprPeriod, i );
 
        if ( WprAbs > x1 && ASC_Trend_Prev == -1 )
        { ASC_Trend_Up = Low[i] - AvgRange * K; ASC_Trend_Prev = 1; }
 
        if ( WprAbs < x2 && ASC_Trend_Prev == 1 )
        { ASC_Trend_Down = High[i] + AvgRange * K; ASC_Trend_Prev = -1; }
 
        buf0[i] = ASC_Trend_Up;
        buf1[i] = ASC_Trend_Down;
    }
return(0);
}

А во-вторых, берите его значения не с 0-го, а с 1-го бара.
Удачи!
 
     Благодарю Вас за внимание к моему круглосуточному образованию, в сфере програмирования на MQ4, но можно ли еще одну подсказку. Как мне из этого "симпатичного" индикатора, вытащить информацию в код эксперта. Как я понимаю буфера buf0[] и buf1[] ,заняты под координаты  сигнальных значков, по этому нужно создать дополнительный буфер, куда можно подовать два разных значения,   для считывания экспертом, на пример Trend[]. Но в какое место мне вставить условия переменной, чтоб если Up, то Trend[0] = 0; а если Down, то Trend[0] = 1; Как ни пробовал, ни чего не выходит. Наверное у меня не правильное представление об общении экспертов с индикаторами. Научите пожалуйста.
Причина обращения: