1
votes

This is my trial to draw the difference between two moving averages as a histogram on H1 time frame. The problem is that it does not change when I change a time frame, especially to lower ones. I am a beginner at MQL4, with no experience or programming background, so please explain to me the mistake.

#property indicator_separate_window
#property indicator_buffers 1
#property indicator_color1  Gray
#property indicator_width1  2

extern int maperiod1 = 25;
extern int maperiod2 = 55;
extern int timefr    = 60;

double mainbuffer[];

int init(){
    SetIndexBuffer( 0, mainbuffer );
    SetIndexStyle(  0, DRAW_HISTOGRAM );
    return(0);
}

int start(){
    int  counted_bars = IndicatorCounted();

    if ( counted_bars < 0) return(-1);
    if ( counted_bars > 0) return( 0);

    int  limit        = ( Bars - counted_bars );

    for ( int    i     = limit; i >= 0; i-- ){
          int    shift = iBarShift( NULL, timefr, Time[i] );
          double maB   = iMA(       NULL, timefr, maperiod1, 0, MODE_EMA, 0, shift );
          double maR   = iMA(       NULL, timefr, maperiod2, 0, MODE_EMA, 0, shift );
          mainbuffer[shift]= ( maB - maR );
    }
    return(0);
}
2
@user3666197: I am happy to hear your feedback based on your domain knowledge, but do please remain calm and civil with your edit messages. As it stands the title is useless and needs to be edited again, since it does not have a subject. Questions are generally better phrased as "how to X" since that makes them useful for many people, "could you help me" means it may only be useful for one person, and would then be "too localised" (i.e. off-topic). - halfer
@user3666197: I will try to edit the title again, but if you do not like it, either flag for a moderator, ping me with @halfer or make a better edit. Please do not roll back, for the reasons I have already given. Apologies for the fuss on your question OP! - halfer

2 Answers

0
votes

In your code you calculate MA of H1 timeframe, that is why there's no difference what happens on smaller timeframes - it checks H1 only.

if (counted_bars>0) return(0); - as far as i can remember, if number of counted bars if positive, you need to decrease it by one in order to recalculate previously known bar: if (counted_bars>0) counted_bars--;

0
votes

Besides the "immunity" to any TimeFrame selection,
the code does not provide means to update in sync with Time[] properly

As Daniel has already noted above the "rigid", hard-coded relation to an extern pre-selected time-frame ( which technically ought be designed as rather some enum:

enum ENUM_GUI_SELECT_TFRAME {
                              M1 = PERIOD_M1,
                              M5 = PERIOD_M5,
                              ...
                              ..
                              .
                              H1 = PERIOD_H1,
                              H4 = PERIOD_H4,
                              ...
                              ..
                              .
                              MN = PERIOD_MN
     };
  //   ++++------------------------------------------ MAKES SURE,
  //   ||||                                           ALWAYS ONLY
  //   ||||                                           PROPER VALUES GET
  //   vvvv                                           EVER SELECTED
extern ENUM_GUI_SELECT_TFRAME timefr = PERIOD_H1;

) there are some further points to solve with code-activation / execution barriers.

What prevents the code from proper updates?

This tandem of conditions:

if ( counted_bars < 0) return(-1);
if ( counted_bars > 0) return( 0);

is met if and only if the IndicatorCounted() == 0, never more.

IndicatorCounted() ~ The function returns the amount of bars not changed after the indicator had been launched last.

So the Custom Indicator works as a devil during the first call, where there were all bars "changed" since the ( non-existent ) previous call. After that, until a newly created bar, the Indicator gets called with having passed the condition because the IndicatorCounted() == 0, but no new bars have yet appeared -- which would thus make the IndicatorCounted() == 1 and the rest of the code of the Custom Indicator will not get executed -- which seems rather the very mirrored logic, the Custom Indicators were equipped with to avoid non-productive loops in case no new bars were created, but to get an immediate update in case a new bar has started.

In other words, even in case the IndicatorCounted() == 0 the last ( hot ) value [0] could still and does change, so if and only if the Custom Indicator value is somehow dependent on this actual ( still changing ) live-value of Close[0], it makes due sense to update the [0] cell of the mainbuffer[].

If it is not dependent on Close[0], it makes no sense to run the code, as it would not update anything.