Проблема в стрелочном индикаторе

 

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


//+------------------------------------------------------------------+
//|                                                        ARADX.mq4 |
//|                        Copyright 2015, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots   2
//--- plot UP
#property indicator_label1  "UP"
#property indicator_type1   DRAW_ARROW
#property indicator_color1  clrLimeGreen
#property indicator_width1  2
//--- plot DN
#property indicator_label2  "DN"
#property indicator_type2   DRAW_ARROW
#property indicator_color2  clrRed
#property indicator_width2  2
//--- indicator buffers




int try=1;


double         UPBuffer[];
double         DNBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,UPBuffer);
   SetIndexBuffer(1,DNBuffer);
   SetIndexArrow(0,233);
   SetIndexArrow(1,234);
   
   
//---
   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[])
  {
//---
   int i,counted_bars=IndicatorCounted();
//----

if(Bars<=5) return(0);
//----
i=Bars-5-1-1;
if(counted_bars>=5) i=Bars-counted_bars-1;
while(i>=0)
{
   
   UPBuffer [i]=-5;
   DNBuffer [i]=-5;
   
   Glav (i); 
     i--;
    }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+

void Glav (int i)
{   double L1, L2, L3;
    L1=iCustom (Symbol (), 0, "NewProg1", 0, i);
    L2=iCustom (Symbol (), 0, "NewProg1", 0, i+1);
    L3=iCustom (Symbol (), 0, "NewProg1", 0, i+2);
    
    
   
    if (L3>L2 && L2<L1 && try==1){
     
      UPBuffer [i]=Low[i]-5*Point;
      
      try=2;
     }
  
    if (L3<L2 && L2>L1 && try==2){
     
      
      DNBuffer [i]=High[i]+5*Point;
      
      try=1;
     }
}


Это пример пока простой, и вся проблема из-за переменной try в операторе if (без него всё работает). Но без него никак,так как дальше в планах индикатор, у которого несколько видов стрелок. Как обойти данное ограничение?

Открой новые возможности в MetaTrader 5 с сообществом и сервисами MQL5
Открой новые возможности в MetaTrader 5 с сообществом и сервисами MQL5
  • www.mql5.com
Задавайте вопросы по техническому анализу, обсуждайте торговые системы и улучшайте свои навыки программирования торговых стратегий на языке MQL5. Общайтесь и обменивайтесь опытом на форуме с трейдерами всего мира и помогайте ответами новичкам — наше сообщество развивается вместе с вами. Оптимизируй советника - и получи лучшего из...
 
Murat Ishakov:

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

Попробуй заменить просчет баров в истории:

   int i;                             // Индекс бара   
   i = rates_total-prev_calculated-1; // Индекс первого не посчитанного
   while(i >= 0)                      // Цикл по не посчитанным барам
    {   
   UPBuffer [i]=0.0;
   DNBuffer [i]=0.0;
   Glav (i);  
   i--;
    }
 
FXwin:

Попробуй заменить просчет баров в истории:

Да, работает. Но вот другой набросок, уже посложнее, и уже не работает


//+------------------------------------------------------------------+
//|                                                        ARADX.mq4 |
//|                        Copyright 2015, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_chart_window
#property indicator_buffers 4
#property indicator_plots   4
//--- plot UP
#property indicator_label1  "UP"
#property indicator_type1   DRAW_ARROW
#property indicator_color1  clrLimeGreen
#property indicator_width1  2
//--- plot DN
#property indicator_label2  "DN"
#property indicator_type2   DRAW_ARROW
#property indicator_color2  clrRed
#property indicator_width2  2
//--- plot UPP
#property indicator_label3  "UPP"
#property indicator_type3   DRAW_ARROW
#property indicator_color3  clrLimeGreen
#property indicator_width3  2
//--- plot DNP
#property indicator_label4  "DNP"
#property indicator_type4   DRAW_ARROW
#property indicator_color4  clrRed
#property indicator_width4  2
//--- indicator buffers

input int      K=5;
input int      D=3;
input int      Zam=3;
input int      BMA=12;
input int      MMA=26;
input int      MACDMA=9;
input int      MAP=50;
input double Min=30.0;
input double Max=70.0;

int Sit;

double         UPBuffer[];
double         DNBuffer[];
double         UPPBuffer[];
double         DNPBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,UPBuffer);
   SetIndexBuffer(1,DNBuffer);
   SetIndexBuffer(2,UPPBuffer);
   SetIndexBuffer(3,DNPBuffer);
   SetIndexArrow(0,233);
   SetIndexArrow(1,234);
   SetIndexArrow(2,162);
   SetIndexArrow(3,162);
   
   Sit=5;

//---
   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[])
  {
//---
   int i;                             // Индекс бара   
   i = rates_total-prev_calculated-1; // Индекс первого не посчитанного
   while(i >= 0)  
{

      UPBuffer [i]=-5;
      DNBuffer [i]=-5;
      UPPBuffer [i]=-5;
      DNPBuffer [i]=-5;

      Glav(i);
      i--;
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+

void Glav(int i)
  {
   double SG[5],SS[5],MG[5],MS[5],MA[5];

   SG [1]=iStochastic (Symbol(), 0, K, D, Zam, 0, 0, 0, i+1);
   SG [2]=iStochastic (Symbol(), 0, K, D, Zam, 0, 0, 0, i+2);

   MG [1]=iMACD (Symbol(), 0, BMA, MMA, MACDMA, 0, 0, i+1);
   MG [2]=iMACD (Symbol(), 0, BMA, MMA, MACDMA, 0, 0, i+2);

   MA [1]=iMA (Symbol (), 0, MAP, 0, 1, 0, i+1);
   MA [2]=iMA (Symbol (), 0, MAP, 0, 1, 0, i+2);

   if(Sit<5)
     {
      if(Sit==1)
        {
         if(SG[2]>Max && SG[1]<Max)
           {
            UPPBuffer[i]=High[i]+50*Point;
            Sit=5;
           }
        }

      if(Sit==2)
        {
         if(SG[2]<Min && SG[1]>Min)
           {
            DNPBuffer[i]=Low[i]-50*Point;
            Sit=5;
           }
        }
     }

   if(Sit==5)
     {
      if(Close[i+1]>MA[1])
        {
         if(MG[2]<0 && MG[1]>0)
           {
            UPBuffer[i]=Low[i]-50*Point;
            Sit=1;
           }

         if(MG[2]>0 && MG[1]>0 && MG[2]<MG[1])
           {
            if(SG[2]<Min && SG[1]>Min)
              {
               UPBuffer[i]=Low[i]-50*Point;
               Sit=1;
              }
           }

        }

      if(Close[i+1]<MA[1])
        {
         if(MG[2]>0 && MG[1]<0)
           {
            DNBuffer[i]=High[i]+50*Point;
            Sit=2;
           }

         if(MG[2]<0 && MG[1]<0 && MG[2]>MG[1])
           {
            if(SG[2]>Max && SG[1]<Max)
              {
               DNBuffer[i]=High[i]+50*Point;
               Sit=2;
              }
           }
        }
     }

  }
//+------------------------------------------------------------------+
 
Murat Ishakov:

Да, работает. Но вот другой набросок, уже посложнее, и уже не работает

Ошибка: выход за пределы массива

Исправлено

Файлы:
StoMA.mq4  10 kb
 
FXwin:

Ошибка: выход за пределы массива

Исправлено

Спасибо. Теперь работает. Но теперь в тестере почему то на нулевом баре бывает что стрелка появляется и пропадает, но у меня же индикатор не перерисовывается

 
Murat Ishakov:

Но теперь в тестере почему то на нулевом баре бывает что стрелка появляется и пропадает, но у меня же индикатор не перерисовывается

Сброс буферов надо убрать.

int start() {
   int i,limit;
   int counted_bars=IndicatorCounted();   
   if (counted_bars<0) return(-1);
   if (counted_bars>0) counted_bars--;
       limit = MathMin(Bars-counted_bars,Bars-1);
   if (counted_bars==0) {
       limit--;       // чтобы не выйти за пределы массива при counted_bars==0
       limit-=10;     // в расчетах используется смещение на 10 баров вглубь истории, поэтому добавим это смещение при первом расчете
       }else{         // индикатор уже рассчитывался ранее, counted_bars>0                
       limit++;}      // при повторных вызовах увеличим limit на 1, чтобы гарантированно обновлять значения индикатора для последнего бара
//----   
   for(i=limit; i>=0; i--) Glav(i);
return(0);}
 
FXwin:

Сброс буферов надо убрать.

Нет, тоже не помогло. Но... Выход найден! Просто не надо рисовать стрелку на нулевом баре, только на первом, и работает с моим первоначальным способом подсчёта баров

//+------------------------------------------------------------------+
//|                                                        ARADX.mq4 |
//|                        Copyright 2015, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_chart_window
#property indicator_buffers 4
#property indicator_plots   4
//--- plot UP
#property indicator_label1  "UP"
#property indicator_type1   DRAW_ARROW
#property indicator_color1  clrLimeGreen
#property indicator_width1  2
//--- plot DN
#property indicator_label2  "DN"
#property indicator_type2   DRAW_ARROW
#property indicator_color2  clrRed
#property indicator_width2  2
//--- plot UPP
#property indicator_label3  "UPP"
#property indicator_type3   DRAW_ARROW
#property indicator_color3  clrLimeGreen
#property indicator_width3  2
//--- plot DNP
#property indicator_label4  "DNP"
#property indicator_type4   DRAW_ARROW
#property indicator_color4  clrRed
#property indicator_width4  2
//--- indicator buffers

input int      K=5;
input int      D=3;
input int      Zam=3;
input int      BMA=12;
input int      MMA=26;
input int      MACDMA=9;
input int      MAP=50;
input double Min=30.0;
input double Max=70.0;

int Sit;

double         UPBuffer[];
double         DNBuffer[];
double         UPPBuffer[];
double         DNPBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,UPBuffer);
   SetIndexBuffer(1,DNBuffer);
   SetIndexBuffer(2,UPPBuffer);
   SetIndexBuffer(3,DNPBuffer);
   SetIndexArrow(0,233);
   SetIndexArrow(1,234);
   SetIndexArrow(2,162);
   SetIndexArrow(3,162);

   Sit=5;

//---
   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[])
  {
//---
   int i,counted_bars=IndicatorCounted();
//----

if(Bars<=5) return(0);
//----
i=Bars-5-1-1;
if(counted_bars>=5) i=Bars-counted_bars-1;
while(i>=0)
{
     

      Glav(i+1);
      i--;
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+

void Glav(int i)
  {
   double SG1,SG2,MG1,MG2,MA1,MA2;

   SG1=iStochastic (Symbol(), 0, K, D, Zam, 0, 0, 0, i);
   SG2=iStochastic (Symbol(), 0, K, D, Zam, 0, 0, 0, i+1);

   MG1=iMACD (Symbol(), 0, BMA, MMA, MACDMA, 0, 0, i);
   MG2=iMACD (Symbol(), 0, BMA, MMA, MACDMA, 0, 0, i+1);

   MA1=iMA (Symbol (), 0, MAP, 0, 1, 0, i);
   MA2=iMA (Symbol (), 0, MAP, 0, 1, 0, i+1);

   if(Sit<5)
     {
      if(Sit==1)
        {
         if(SG2>Max && SG1<Max)
           {
            UPPBuffer[i]=High[i]+50*Point;
            Sit=5;
           }
        }

      if(Sit==2)
        {
         if(SG2<Min && SG1>Min)
           {
            DNPBuffer[i]=Low[i]-50*Point;
            Sit=5;
           }
        }
     }

   if(Sit==5)
     {
      if(Close[i+1]>MA1)
        {
         if(MG2<0 && MG1>0)
           {
            UPBuffer[i]=Low[i]-50*Point;
            Sit=1;
           }

         if(MG2>0 && MG1>0 && MG2<MG1)
           {
            if(SG2<Min && SG1>Min)
              {
               UPBuffer[i]=Low[i]-50*Point;
               Sit=1;
              }
           }

        }

      if(Close[i+1]<MA1)
        {
         if(MG2>0 && MG1<0)
           {
            DNBuffer[i]=High[i]+50*Point;
            Sit=2;
           }

         if(MG2<0 && MG1<0 && MG2>MG1)
           {
            if(SG2>Max && SG1<Max)
              {
               DNBuffer[i]=High[i]+50*Point;
               Sit=2;
              }
           }
        }
     }

  }
//+------------------------------------------------------------------+
 
Murat Ishakov:

Нет, тоже не помогло. Но... Выход найден! Просто не надо рисовать стрелку на нулевом баре, только на первом, и работает с моим первоначальным способом подсчёта баров

Можно... Но, тогда не получится торговать по сигналам индикатора, а в остальном все замечательно

ЗЫ Метаквотам: DrawArrow действительно не отрисовывается в реальном времени :(

 
Алексей Тарабанов:

Можно... Но, тогда не получится торговать по сигналам индикатора, а в остальном все замечательно

ЗЫ Метаквотам: DrawArrow действительно не отрисовывается в реальном времени :(

Да, попробовал, к сожалению нет. Но ведь первый вариант с двумя буферами рисуется отлично в реальном времени

 
Murat Ishakov:

Да, попробовал, к сожалению нет. Но ведь первый вариант с двумя буферами рисуется отлично в реальном времени

Какой первый вариант?

 
Алексей Тарабанов:

Какой первый вариант?

В начале темы