MT4 Create Object indicator

 

Hello gang, 

Sorry for the very basic post, im trying to figure out why i dont see any rectangles on my chart.

Im using Alert, Comment, Print to 'look for bugs' on the code, but its quite hard. Also not much of a C coder, so im opened to any other comments.
To simplify the explanation of this indicator here, let say we are using the 1 Hour timeframe and we set the indicator to DAILY (1440) , this should create rectangle objects on daily open and close.
Day open = Day at 00:00 , with price
Day close = Day at 23:59 , with price

Example

Ideally, i will implement the other timeframes. ie chart = 1 min and Indicator = 240 etc..
Worth noting i have excluded from the code bellow the function RectangleCreate(). I got the code from the Docs and it works fine. Im assuming the problem is my logic inside the main for loop.


Thanks very much for any light shed on the matter.


datetime _timeOpen, _timeClose;

// MAIN
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[])
{

  //--- dont work on wrong time frame
  if( Period() >= InpTimeFrame/2 )
    return( rates_total );
    
  //--- main
  double _priceOpen;
  int max = rates_total - 1;
  
  for( int i = max ; i >= 0 ; i-- )
  //for( int i = 0 ; i < rates_total - 1 ; i++ )
  {
    // initialize _timeOpen. The whole chart comes from this value.
    if( i == max )
    {
      _timeOpen   = time[i];
      _priceOpen  = open[i];      
      SetDefinitions( time[i] );
      Print( StringFormat( " Bar: %i TimeOpen: %s TimeClose: %s" , i, TimeToStr( _timeOpen ) , TimeToStr( _timeClose ) ) );
    }
      
    if( time[ i ] > _timeClose )
    {
    
      if( ObjectFind( 0, InpBoxname + "_" + _timeClose ) != 0  )  
        RectangleCreate( 0, InpBoxname + "_" + _timeClose, 0, _timeOpen, _priceOpen, time[ i + 1 ], close[ i + 1 ], InpColor,STYLE_SOLID,1,InpFillRectangle,false,false,true,0);
      SetDefinitions( time[i] );
    
    }
  }
  
 return( rates_total );
}


void SetDefinitions( const datetime time )
{
  if( InpTimeFrame == PERIOD_D1 )
  {
    // Any bar at any timeframe should return 'day @ 00:00'
    _timeOpen = StrToTime( StringFormat( "D'%i.%i.%i'",
    TimeYear ( time ),
    TimeMonth( time ),
    TimeDay  ( time ) ) );
    //Alert( _timeOpen );
    
    
    // Any bar at any time frame should return 'day @ 23:59'
    _timeClose = _timeOpen + ( (60*60*24) - 60 );
    //Alert( _timeClose );
  }
  
  if( InpTimeFrame == PERIOD_H1 )
  {
    // wip
  }
  if( InpTimeFrame == PERIOD_H4 )
  {
    // wip
  }

}
Documentation on MQL5: Constants, Enumerations and Structures / Objects Constants / Object Types
Documentation on MQL5: Constants, Enumerations and Structures / Objects Constants / Object Types
  • www.mql5.com
Object Types - Objects Constants - Constants, Enumerations and Structures - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5
 

Hey !! it seems i found it.

Using "print" for debugging really did the trick.
The problem was how i was assigning the date string to the variable: from "D'%i.%i.%i'" to " %i.%i.%i

    entry = StringFormat( "%i.%i.%i",
    TimeYear ( time ),
    TimeMonth( time ),
    TimeDay  ( time ) );

Ill paste bellow the working code, just the partial code again. Still i think this is a bit too over complicated. But its seems to be doing the trick for H4 as well and seems to play well on the Terminal. 

//+------------------------------------------------------------------+
//|  MAIN                                                            |
//+------------------------------------------------------------------+
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[])
{

  //--- dont work on wrong time frame
  if( Period() >= InpTimeFrame/2 )
    return(rates_total);
    
  //--- main
  double _priceOpen;
  int max = prev_calculated - 1;
  
  for( int i = max ; i >= 0 ; i-- )
  //for( int i = 0 ; i < rates_total - 1 ; i++ )
  {

      
    // initialize _timeOpen. The whole chart comes from this value.
    if( i == max )
    {
      _timeOpen   = time[i];
      _priceOpen  = open[i];      
      SetDefinitions( time[i] );     
    }
    
    
    if( time[ i ] > _timeClose && i + 1 < max )
    {
    
      if( ObjectFind( 0, InpBoxname + "_" + _timeClose ) != 0  )  
        RectangleCreate( 0, InpBoxname + "_" + _timeClose, 0, _timeOpen, _priceOpen, _timeClose, close[ i + 1 ], InpColor,STYLE_SOLID,1,InpFillRectangle,false,false,true,0);
      // refresh values
      _priceOpen  = open[i];
      SetDefinitions( time[i] );
      //Print( StringFormat( " Bar: %i TimeOpen: %s TimeClose: %s" , i, TimeToStr( _timeOpen ) , TimeToStr( _timeClose ) ) );
    
    }
      
  }

 return(rates_total);
}


void SetDefinitions( const datetime time )
{
  string entry;
  
  if( InpTimeFrame == PERIOD_D1 )
  {
    // Any bar at any timeframe should return 'day @ 00:00'
    entry = StringFormat( "%i.%i.%i",
    TimeYear ( time ),
    TimeMonth( time ),
    TimeDay  ( time ) );
    
    _timeOpen = StrToTime( entry );   
    
    // Any bar at any time frame should return 'day @ 23:59'
    _timeClose = _timeOpen + ( (60*60*24) - 60 );

  }
  
  if( InpTimeFrame == PERIOD_H1 )
  {
    // wip
  }
  if( InpTimeFrame == PERIOD_H4 )
  {
    int mod = MathMod( TimeHour ( time ) , 4 );
    
    entry = StringFormat( "%i.%i.%i %i:00",
    TimeYear ( time ),
    TimeMonth( time ),
    TimeDay  ( time ),
    TimeHour ( time ) - mod );
    
    // Any bar at any time frame should return ' 1st mod 4 position hour:00'
    _timeOpen = StrToTime( entry );   
    
    // Any bar at any time frame should return ' 1st mod 4 position hour:59'
    _timeClose = _timeOpen + ( (60*60*4) - 60 );
    
  }
  
    Print( StringFormat( " Time: %s TimeOpen: %s TimeClose: %s" , TimeToStr(time), TimeToStr( _timeOpen ) , TimeToStr( _timeClose ) ) );
    //Print( StrToTime( entry ) );

}
 

Super stoked with the code, it takes a while to draw everything but its looking "really nice" from a developers point of view :D

this is me trading today using the indicator for the first time, ill prolly get reckoned as usual.
its set to month, week, day & 4h on the 15 chart. So far not written on stone.


Indie in action


This is the current version of SetDefinition function:

void SetDefinitions( const datetime time )
{
  string entry;
  
  // // MONTH
  if( InpTimeFrame == PERIOD_MN1 )
  {   
    int nextyear = TimeYear( time );
    
    entry = StringFormat( "%i.%i.1 00:00",
    TimeYear ( time ),
    TimeMonth( time ) );
   
    // Any bar at any time frame should return ' 1st mod 4 position hour:00'
    _timeOpen = StrToTime( entry );   
    
    // // add 1 to month 
    int mod = MathMod( ( TimeMonth( time ) - 1 ) + 1 , 12 ) + 1;
    // // add year if december
    if( TimeMonth(time) == 12 )
           nextyear++;
    
    entry = StringFormat( "%i.%i.1 00:00", nextyear, mod );
    
    // Any bar at any time frame should return ' 1st mod 4 position hour:59'
    _timeClose = StrToTime( entry );
   
  }
  
  // // WEEK
  if( InpTimeFrame == PERIOD_W1 )
  {   
    entry = StringFormat( "%i.%i.%i %i:00",
    TimeYear ( time ),
    TimeMonth( time ),
    TimeDay  ( time ),
    TimeHour ( time ) );
    
    int getMonday = ( TimeDayOfWeek( time ) - 1 ) * (60*60*24);
    
    // Any bar at any time frame should return ' 1st mod 4 position hour:00'
    _timeOpen = StrToTime( entry ) - getMonday;   
    
    // Any bar at any time frame should return ' 1st mod 4 position hour:59'
    _timeClose = _timeOpen + ( (60*60*24*5) - 60 );
    
  }
  
  // // DAILY
  if( InpTimeFrame == PERIOD_D1 )
  {
    // Any bar at any timeframe should return 'day @ 00:00'
    entry = StringFormat( "%i.%i.%i",
    TimeYear ( time ),
    TimeMonth( time ),
    TimeDay  ( time ) );
    
    _timeOpen = StrToTime( entry );   
    
    // Any bar at any time frame should return 'day @ 23:59'
    _timeClose = _timeOpen + ( (60*60*24) - 60 );

  }
  
  // // HOURLY
  if( InpTimeFrame == PERIOD_H1 )
  {
    entry = StringFormat( "%i.%i.%i %i:00",
    TimeYear ( time ),
    TimeMonth( time ),
    TimeDay  ( time ),
    TimeHour ( time ) );
    
    // Any bar at any time frame should return '  hour:00'
    _timeOpen = StrToTime( entry );   
    
    // Any bar at any time frame should return '  hour:59'
    _timeClose = _timeOpen + ( (60*60) - 60 );
  }
  
  // // FOUR HOUR
  if( InpTimeFrame == PERIOD_H4 )
  {
    int mod = MathMod( TimeHour ( time ) , 4 );
    
    entry = StringFormat( "%i.%i.%i %i:00",
    TimeYear ( time ),
    TimeMonth( time ),
    TimeDay  ( time ),
    TimeHour ( time ) - mod );
    
    // Any bar at any time frame should return ' 1st mod 4 position hour:00'
    _timeOpen = StrToTime( entry );   
    
    // Any bar at any time frame should return ' 1st mod 4 position hour:59'
    _timeClose = _timeOpen + ( (60*60*4) - 60 );
    
  }  
}