Отрисовка индикатора. Как исправить?

 

Доброго времени суток уважаемые программисты и трейдеры.

Столкнулся с таким явлением. При установке индикатора на график, как и положено, появляются стрелки в низ и вверх в нужных местах.

Но как он работает в реальном времени и в тестере, он рисует так:

Но как только перезагрузишь индикатор, то отрисовка становится правильной.

Может быть кто знает, что нужно сделать, что бы рисовал всегда нак на  первом рисунке?

Вот его код:

#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 Blue
#property indicator_color2 Red
//---- input parameters
extern string symbolhint = "Symbol (leave blank for current chart):";
extern string symbol = "";
extern string tfhint = "timeframe (in Minutes, 0 for current):";
extern int timeFrame = 0;
extern int cciPeriod = 6;
extern int atrPeriod = 12;
extern int momentumPeriod = 7;
extern int rsiPeriod = 7;
extern int adxPeriod = 7;
extern string indihint1 = "periods for control:";
extern int rsiControlPeriod = 12;
extern int adxControlPeriod = 12;
extern int rsiTrigger = 50;
extern int adxTrigger = 20;
extern string subtracthint = "default: -2, -1";
extern double subtractFromSignalVal = -2.0;
extern double subtractFromIndiVal = -1.0;
extern string hl0 = "-=------------------------------------------------------=-";
extern bool showBuySignals = true;
extern bool showSellSignals = true;
extern string wingdingshint = "default: 233, 234";
extern int wingdingsUpArrow = 233;
extern int wingdingsDownArrow = 234;
extern string hl1 = "-=------------------------------------------------------=-";
extern string alerthint = "optional settings:";
extern bool Alerts = false;
extern bool PlaySounds = false;
extern string alerthint1 = "Want change sounds for signals?";
extern string alerthint2 = "(must be in MT4\sounds\ directory";
extern string alerthint3 = "and have extension .wav)";
extern string LongSignalSoundFile = "alert.wav";
extern string ShortSignalSoundFile = "alert.wav";
extern bool SignalMail = False;

//---- buffers
double ExtMapBuffer1[];
double ExtMapBuffer2[];
//----

int    nShift;   
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {

//----    
    SetIndexStyle(0, DRAW_ARROW, 0, 1);
    SetIndexArrow(0, wingdingsUpArrow);
    SetIndexBuffer(0, ExtMapBuffer1);
//----
    SetIndexStyle(1, DRAW_ARROW, 0, 1);
    SetIndexArrow(1, wingdingsDownArrow);
    SetIndexBuffer(1, ExtMapBuffer2);
//---- name for DataWindow and indicator subwindow label
    IndicatorShortName("#MomentumChartSignalsIndicator"); // (" + indiName + ")
    SetIndexLabel(0, "BUY SIGNAL");
    SetIndexLabel(1, "SELL SIGNAL"); 
//----
    switch(Period())
      {
        case     1: nShift = 1;   break;    
        case     5: nShift = 3;   break; 
        case    15: nShift = 5;   break; 
        case    30: nShift = 10;  break; 
        case    60: nShift = 15;  break; 
        case   240: nShift = 20;  break; 
        case  1440: nShift = 80;  break; 
        case 10080: nShift = 100; break; 
        case 43200: nShift = 200; break;               
      }
//----
    return(0);
  }
//+------------------------------------------------------------------+
//| Custor indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//----
    return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
double momVal, atrVal, cciVal, rsiVal, adxVal, adxPLUSVal, adxMINUSVal;
double signalVal, indiVal;
double adx1Val, adx1PLUSVal, adx1MINUSVal, rsi1Val;
int start()
  {
    int limit;
    int counted_bars = IndicatorCounted();
//---- check for possible errors
    if(counted_bars < 0) 
        return(-1);
//---- last counted bar will be recounted
    if(counted_bars > 0) 
        counted_bars--;
    limit = Bars - counted_bars;
//----
string signalSentAlready = "NONE";
if (symbol == "0" || symbol == "") symbol = Symbol();
    for(int i = 0; i < limit; i++)
      { // start loop
     
        // current data:
         momVal = iMomentum(symbol,timeFrame,momentumPeriod,PRICE_TYPICAL,i);
         atrVal = iATR(symbol,timeFrame,atrPeriod,i);
         cciVal = iCCI(symbol,timeFrame,cciPeriod,PRICE_TYPICAL,i);
         rsiVal = iRSI(symbol,timeFrame,rsiPeriod,PRICE_TYPICAL,i);
         adxVal = iADX(symbol,timeFrame,adxPeriod,PRICE_TYPICAL,MODE_MAIN,i);
         adxPLUSVal = iADX(symbol,timeFrame,adxPeriod,PRICE_TYPICAL,MODE_PLUSDI,i);
         adxMINUSVal = iADX(symbol,timeFrame,adxPeriod,PRICE_TYPICAL,MODE_MINUSDI,i);
        
        if((atrVal+adxVal)!=0)
         signalVal =(momVal/(atrVal+adxVal))-subtractFromSignalVal; // -2
        if(adxVal!=0)
         indiVal = ((atrVal+cciVal+rsiVal)/adxVal) - subtractFromIndiVal; // -1
        
         // triggerData:
          adx1Val = iADX(symbol,timeFrame,adxControlPeriod,PRICE_CLOSE,MODE_MAIN,i);
          adx1PLUSVal = iADX(symbol,timeFrame,adxControlPeriod,PRICE_CLOSE,MODE_PLUSDI,i);
          adx1MINUSVal = iADX(symbol,timeFrame,adxControlPeriod,PRICE_CLOSE,MODE_MINUSDI,i);
          rsi1Val = iRSI(symbol,timeFrame,rsiControlPeriod,PRICE_CLOSE,i);

        //---- SELL SIGNAL:
        if(signalVal < indiVal && adx1MINUSVal < adx1PLUSVal && rsi1Val > rsiTrigger && adx1Val > adxTrigger)
         {
           if (signalSentAlready != "short")
            {
             if (showSellSignals) ExtMapBuffer2[i] = High[i] + nShift*Point;
              if (Alerts) { Alert("SELL SIGNAL at ", symbol,": ",Close[0]," (TF ",Period(),")"); }
              if (PlaySounds) { PlaySound(ShortSignalSoundFile); }
              if (SignalMail) { SendMail(""+symbol+" SELL SIGNAL","SELL SIGNAL on "+symbol+": "+Close[0]+" (Timeframe: "+Period()+")"); }
             signalSentAlready = "short";
            }
         }
         
        //---- BUY SIGNAL:
        if(signalVal > indiVal && adx1PLUSVal < adx1MINUSVal && rsi1Val < rsiTrigger && adx1Val > adxTrigger)
         {
           if (signalSentAlready != "long")
            {
             if (showBuySignals) ExtMapBuffer1[i] = Low[i] - nShift*Point;
              if (Alerts) { Alert("BUY SIGNAL at ", symbol,": ",Close[0]," (TF ",Period(),")"); }
              if (PlaySounds) { PlaySound(LongSignalSoundFile); }
              if (SignalMail) { SendMail(""+symbol+" BUY SIGNAL","BUY SIGNAL on "+symbol+": "+Close[0]+" (Timeframe: "+Period()+")"); }
             signalSentAlready = "long";
            }
         }
         
      } // end loop
//----
    return(0);
  }
//+------------------------------------------------------------------+
 

Следующая свеча много выше предыдущей - индикатор рисует красную стрелку - продавай. Через минуту формируется следующая свеча еще выше - индикатор рисует следующую красную стрелку - продавай. Через минуту формируется следующая свеча еще выше - индикатор опять рисует красную стрелку - продавай. Ну а что - он прав. Если там продавали, то тут и подавно надо продавать.

Если сменить таймфрейм туда-сюда или перезапустить индикатор или правой кнопкой по графику, Обновить - лишние стрелки исчезают, т.к. индикатор ведет расчет от последней свечи. Или надо предыдущую стирать? Есть и такие индикаторы. Следующая свеча много выше предыдущей - индикатор рисует красную стрелку - продавай. Через минуту формируется следующая свеча еще выше - индикатор стирает прошлую стрелку и рисует следующую красную стрелку - продавай здесь, там была ложная тревога. Так лучше?

А то, что Вы нарисовали - похоже на ошибку терминала. Пора писать в СервисДек. Или переписать индикатор используя функцию OnCalculate()

 
Vadim Kazakevich:

Но как только перезагрузишь индикатор, то отрисовка становится правильной.

Может быть кто знает, что нужно сделать, что бы рисовал всегда нак на  первом рисунке?


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

Если переписать индикатор с правильным доступом к истории (слева направо, т. е. из прошлого в будущее), то все его очарование сразу пропадет. Вывод: не заслуживает такой индикатор внимания к своей персоне.

 
Vadim Kazakevich:

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

Можно обнулять значение буферов, но тогда будет одна стрелка бегать по барам пока цена действительно не поменяет направление,
а по умолчанию стрелка появляется на каждом баре пока цена не развернётся.

Вот с обнулёнными значениями буферов (жёлтые зелёные стрелки)


Файлы:
arrows.mq4  7 kb
 
FXwin:

Можно обнулять значение буферов, но тогда будет одна стрелка бегать по барам пока цена действительно не поменяет направление,
а по умолчанию стрелка появляется на каждом баре пока цена не развернётся.

Вот с обнулёнными значениями буферов (жёлтые зелёные стрелки)


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

 
Ihor Herasko:

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


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