Search code examples
mql4

While there are no MQL4 errors, why there was no GUI drawing produced?


For a learning purpose, I am trying to code a simple MA indicator that changes color when price crosses. Though there are no errors, it draws nothing. Could you review the attached code to show me my mistake?

#property indicator_chart_window
#property indicator_buffers 2

extern int    maperiod = 20;
extern int    maprice  = PRICE_CLOSE;
extern int    mamethod = MODE_SMA;
extern color  colorup  = Green;
extern color  colordn  = Red;

       double mamain[];
       double bufferup[];
       double bufferdn[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init(){
//--- indicator buffers mapping
   SetIndexBuffer( 0, bufferup );
   SetIndexStyle(  0, DRAW_LINE, 0, 2, colorup );
   SetIndexBuffer( 1, bufferdn );
   SetIndexStyle(  1, DRAW_LINE, 0, 2, colordn );
//---
   return( 0 );
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start(){
//---
   int counted_bars = IndicatorCounted();
   if ( counted_bars < 0 ) return( -1 );
   if ( counted_bars > 0 ) counted_bars--;
   int limit = Bars - counted_bars;
   for (   int i = limit; i >= 0 ; i-- )
   {    mamain[i]  = iMA(    NULL, 0, maperiod, 0, 0, 0, i );
   if ( mamain[i] >= iClose( NULL, 0, i ) ) bufferup[i] = mamain[i];
   if ( mamain[i] <= iClose( NULL, 0, i ) ) bufferdn[i] = mamain[i];
   }
//--- return value of prev_calculated for next call
   return( 0 );
  }
//+------------------------------------------------------------------+

Solution

  • "Old"-MQL4 may work for some time, but still, get used to new features:

    extern ENUM_APPLIED_PRICE MAprice  = PRICE_CLOSE; // AVOIDS incompatible values
    extern ENUM_MA_METHOD     MAmethod = MODE_SMA;    // AVOIDS incompatible values
    #define                   MAshift     0           // ADDS   code == intent match-robustness
    extern int                MAperiod = 20;
    extern color              colorUP  =  clrGreen;
    extern color              colorDN  =  clrRed;
    
           double             bufferUP[];
           double             bufferDN[];
    
    int init(){
        ArrayInitialize    bufferUP,  EMPTY_VALUE );
        SetIndexBuffer( 0, bufferUP );
        SetIndexStyle(  0, DRAW_LINE, EMPTY, 2, colorUP );
        SetIndexLabel(  0, "MA_ABOVE_Close" );
    
        ArrayInitialize    bufferDN,  EMPTY_VALUE );
        SetIndexBuffer( 1, bufferDN );
        SetIndexStyle(  1, DRAW_LINE, EMPTY, 2, colorDN );
        SetIndexLabel(  1, "MA_UNDER_Close" );
    
        return( 0 );
    }
    
    int start(){
        int  counted_bars = IndicatorCounted();
        if ( counted_bars < 0 ) return( -1 );
        if ( counted_bars > 0 ) counted_bars--;
    
        for ( int    i = Bars - counted_bars; i >= 0 ; i-- ){
              double C = iClose( _Symbol, PERIOD_CURRENT, i ),
                     A = iMA(    _Symbol, PERIOD_CURRENT,
                                          MAperiod,
                                          MAshift,
                                          MAmethod,
                                          MAprice,
                                          i
                                          );
              if ( A >= C ) bufferUP[i] = A;
              if ( A <= C ) bufferDN[i] = A;
        }
        return( 0 );
    }
    

    New-MQL4.56789 uses another call-signature if #property strict:

    int OnCalculate( const int       rates_total,
                     const int       prev_calculated,
                     const datetime &time_______ARR[],
                     const double   &open_______ARR[],
                     const double   &high_______ARR[],
                     const double   &low________ARR[],
                     const double   &close______ARR[],
                     const long     &tick_volumeARR[],
                     const long     &volume_____ARR[],
                     const int      &spread_____ARR[]
                     ){
    //--- the main loop of calculations 
       for( int i  = prev_calculated - 1;
             (  i <  rates_total
             &&     !IsStopped() );          // AVOID SHARED (!) solo-THREAD BLOCKING
                i++
            ){
         // -----------------------------------------------------------------
              double A = iMA(    _Symbol, PERIOD_CURRENT,
                                          MAperiod,
                                          MAshift,
                                          MAmethod,
                                          MAprice,
                                          i
                                          );
              if ( A >= close______ARR[i] ) bufferUP[i] = A;
              if ( A <= close______ARR[i] ) bufferDN[i] = A;
         // -----------------------------------------------------------------
       }
       return( rates_total );
    }