User-defined bars

Instead of fixed bar periods, bars can also cover fixed price ranges or can be defined by other criteria. Some traders believe that those special bars help their trading, because they make the chart look simpler. Zorro supports a user-defined bar function for special bars of any kind. Predefined functions for Range, Renko, Haiken Ashi, or Point-and-Figure bars are included. The bar function can be used for single-asset or multiple-asset strategies, or for strategies that use multiple bar types simultaneously. In the case of single-asset strategies the individual bars are also plotted in the chart.


Range bars (see code)


 

bar(vars Open, vars High, vars Low, vars Close, vars Price, DATE Start, DATE Time): int

User-supplied function for defining a bar. Used to create special bar types or to replace the mean price by a different algorithm. The bar function is automatically called whenever a new price quote arrives or a price tick is read from a historical file. It can modify the candle and determine when the bar ends.

Parameters:

Open, High,
Low, Close,
Price

Series with two elements of the corresponding price; f.i. Close[1] is the close price of the previous bar, and Close[0] is the most recent price. The prices of the current bar can be modified by the bar function. Price is the mean price and can be omitted when not used in the function.

Start Optional start time of the bar in the OLE DATE format. Can be omitted when not used in the function.
Time Optional time of the most recent tick or price quote. Can be omitted when not used in the function.

Returns:

0 - close the bar at the normal end of the BarPeriod.
- close the bar now, and call the bar function again at the next price tick.
4 - keep the bar open, and call the bar function again at the next price tick.
8 - call the bar function only at the end of every bar.

Remarks:

Examples (see also SpecialBars.c):

var BarRange = 0.0030; // 0.3 cents bar range

// Range Bars, standard (high-low)
int bar(vars Open,vars High,vars Low,vars Close)
{
  if(Open[0] != Close[1]) {
    High[0] = max(Open[0],Close[1]);
    Low[0] = min(Open[0],Close[1]);
    Open[0] = Close[1];
  }
  if(High[0]-Low[0] >= BarRange)
    return 1;
  return 4;
}

// Renko Bars, standard
int bar(vars Open,vars High,vars Low,vars Close)
{
  Open[0] = roundto(Close[1],BarRange);
  if(Close[0]-Open[0] >= BarRange) {
    Close[0] = Open[0]+BarRange;
    High[0] = Close[0];
    Low[0] = Open[0];
    return 1;
  }
  if(Open[0]-Close[0] >= BarRange) {
    Close[0] = Open[0]-BarRange;
    High[0] = Open[0];
    Low[0] = Close[0];
    return 1;
  }
  return 4;
}

// Renko Bars with wicks
int bar(vars Open,vars High,vars Low,vars Close)
{
  Open[0] = roundto(Close[1],BarRange);
  if(Close[0]-Open[0] >= BarRange) { 
    Close[0] = Open[0]+BarRange;
    return 1;
  }
  if(Close[0]-Open[0] <= -BarRange) { 
    Close[0] = Open[0]-BarRange;
    return 1;
  }
  return 4;
}

// Renko Bars, variant
int bar(vars Open, vars High, vars Low, vars Close)
{
  var OpenDiff = abs(Close[0]-Open[1]);
  var CloseDiff = abs(Close[0]-Close[1]);
  if(OpenDiff < CloseDiff) // we have a valley or peak
     Open[0] = Open[1];
  else  // we are moving with the trend
     Open[0] = roundto(Close[1],BarRange);
  if(Close[0]-Open[0] >= BarRange) {  // going up
    Close[0] = Open[0]+BarRange;
    High[0] = Close[0];
    Low[0] = Open[0];
    return 1;
  }
  if(Open[0]-Close[0] >= BarRange) { // going down
    Close[0] = Open[0]-BarRange;
    High[0] = Open[0];
    Low[0] = Close[0];
    return 1;
  }
  return 4;
}

// Mean Renko Bars
int bar(vars Open, vars High, vars Low, vars Close)
{
Open[0] = 0.5*(Close[1]+Open[1]);
if(Close[0] <= Open[0] - BarRange) {
Close[0] = Open[0] - BarRange;
return 1;
} else if(Close[0] >= Open[0] + BarRange) {
Close[0] = Open[0] + BarRange;
return 1;
}
return 4;
}
// Haiken Ashi Bars int bar(vars Open,vars High,vars Low,vars Close) { Close[0] = (Open[0]+High[0]+Low[0]+Close[0])/4; Open[0] = (Open[1]+Close[1])/2; High[0] = max(High[0],max(Open[0],Close[0])); Low[0] = min(Low[0],min(Open[0],Close[0])); return 8; } // Point-and-Figure Bars int bar(vars Open,vars High,vars Low,vars Close) { static int direction = 0; if(direction == 1 && High[0]-Close[0] >= BarRange) { Open[0] = round(Low[0],BarRange); Close[0] = round(High[0],BarRange); Low[0] = Open[0]; High[0] = Close[0]; direction = 0; return 1; } if(direction == 0 && Close[0]-Low[0] >= BarRange) { Open[0] = round(High[0],BarRange); Close[0] = round(Low[0],BarRange); High[0] = Open[0]; Low[0] = Close[0]; direction = 1; return 1; } return 4; }

See also:

Bars and Candles, Bar, BarPeriod, tick, TMF, user supplied functions

► latest version online