Mastering New Bar Detection in MetaTrader 4: A Simple Guide

Mike 2011.07.01 23:45 24 0 0
Attachments

Hey fellow traders,

Ever wondered how to detect a new bar in your current timeframe? You're not alone! Many traders are on the lookout for this capability, and it's simpler than you might think.

Detecting New Bars in Your Current Timeframe

Here's a straightforward snippet of code to help you:

void start() {
  static datetime tmp;
  if (tmp != Time[0]) {
    tmp = Time[0];
    // Your code goes here
  }
}

Handling Other Timeframes

Now, if you're wondering about detecting new bars in other timeframes, it’s a bit trickier, but manageable! Unfortunately, MT4 doesn’t support the onBar event directly. However, you can create an array to store the upward times and check these against the current tick. When the right time is reached, you can execute your new bar event.

For instance, if you're backtesting on the M5 timeframe, you can also catch events for M6, M7, and even D1. Why only upward trends, you ask? Well, the challenge lies in generating tick data in MetaTrader. You can find more about that here, or check out these links: A2, A3.

When you reach the D1 timeframe, it gets a bit complicated as the week often starts on a broker-specific schedule, like Sunday at 20:45, and the start of the month can fall mid-week. It's a bit of a can of worms, so I won't dwell on it too much.

There's a comprehensive forum topic discussing this, but I feel many traders miss out on these articles. That's why I decided to share this code with you.

Breaking Down the Code

In the initialization function, you’ll populate the time array with starting times:

  curIndex = utils.periodToPeriodIndex(Period());
  times[curIndex] = Time[0];
  for(int i = curIndex + 1; i < MAX; i++)
    times[i] = times[curIndex] - MathMod(times[curIndex], utils.periodIndexToPeriod(i) * 60);

Next, in the start function, you'll check if enough time has elapsed:

  if (times[curIndex] != Time[0]) {
    times[curIndex] = Time[0];
    onBar(Period());
    for(int i = curIndex + 1; i < MAX; i++) {
      int period = utils.periodIndexToPeriod(i),
      seconds = period * 60,
      time0 = times[curIndex] - MathMod(times[curIndex], seconds);
      if (times[i] != time0) {
        times[i] = time0;
        onBar(period);
      }
    }
  }

Finally, make sure to implement your code within these functions:

void onTick() {
}

void onBar(int period) {
}

And there you have it! That's all there is to it.

Update 1.1: Huge thanks to WHRoeder for the clear code improvements!

List
Comments 0