I'm creating my first indicator in MT4.
I think I tracked down where my bug is, and the 1st thing I notice has got me stumped.
The first time my indicator runs on Period_M15 the Bar # is 65001 (option max bars in chart is set to 65000) and Time shows 1970.01.01.
I'm looking at the chart and the left most bar is dated 2008.07.08 22:45, which is how far back my history file goes for M15.
Can someone explain how this works? How can the indicator find a bar that isn't on the chart?
If the max bars on your chart is 65000 and the current bar is 0 then the leftmost bar is 65000 - 1 = 64999 . . . not 65001
Try Bars-1 not Bar+1 ? show your code ?
iCountedBars = IndicatorCounted();
if (iCountedBars < 0)
if(iCountedBars > 0)
// recount last bar in case ticks were missed during last calculation
iBar = Bars - iCountedBars;
if (Period() == 15)
if (iBar > 100)
// this only executes once - when the indicator is first loaded onto the chart
Alert(iBar + " " + Bars + " " + TimeToStr(Time[iBar],TIME_DATE|TIME_MINUTES));
// Alert displays "65010 65010 1970.01.01 00:00"
// but my chart's left most bar is 2008.07.09 22:45 which matches my history file
while (iBar >= 0)
// my Code
I took out my code and verified that this code displays the results I see.
I have verified that max bars in chart is 65000 (I triple checked to make sure there were only 3 "0"s so it's not 650000.
I thought that maybe the chart starts with 65000. Obviously it is not destroying the oldest bar as new bars are created. I have had to restart MT4 several times, but the chart still starts with where it was when MT4 crashed.
I have triple verified that my chart and history only go back to 2008.07.09
First time this is run IndicatorCounted() will give you a value of -1 . . .
From here: https://docs.mql4.com/customind/IndicatorCounted
"Note: The latest bar is not considered to be calculated and, in the most cases,
it is necessary to recalculate only this bar. However, there occur some boundary
cases where custom indicator is called from the expert at the first tick of the
new bar. It is possible that the last tick of the previous bar had not been
processed (because the last-but-one tick was
being processed when this last tick came), the custom indicator was not
called and it was not calculated because of this. To avoid indicator calculation
errors in such situations, the IndicatorCounted() function returns the count of
bars minus one."
so Bars - -1 = Bars +1
I don't do a lot of work with Indicators so hopefully someone will correct me if I'm wrong . .
Sorry, you overlooked the "if (iCountedBars < 0) return(-1)", so it doesn't run when IndicatorCounted() < 0.
But the issue is how iBar and Bars get to 65010 (year 1970) when my chart and history only goe back to 2008?
Update: Bars is now returning 65013. I have dealt with that issue, but I still want an explanation so I'm prepared next time.
I don't understand the relationship.
Bars is returning 65013, and when I do "TimeToString(Time, TIME_DATE|TIME_MINUTES)" I get 1970.01.01 00:00.
Now this is really weird. I do "Alert(iBarShift(NULL,0,D'2008.07.09 22:45'));" and I get 65013.
So when I ask what time corresponds to bar 65013 I get a date in 1970. But when I ask what bar corresponds to D'2008 ...' I get bar 65013.
There obviously is not a one to one correspondence between bars and dates.
I think a new bar formed between you executing these bits of code . . .
This all makes sense, let me explain with a simplified example.
Bars is the "Number of bars in the current chart." so if it is equal to 10 then the bar numbers will be as follows:
9 .. 8 .. 7 .. 6 .. 5 .. 4 .. 3 .. 2 .. 1 .. 0
don't forget that the currently forming bar is bar number 0
So when you ask for the Time of bar number 10 . . well, it doesn't exist so you get returned 0, 0 seconds since 1 January, 1970 is the 1 January, 1970.
When you ask for the bar shift of a certain date (the date of the leftmost bar) you get 9 because you shift 9 times to get there from 0.
iBar = Bars -1 - iCountedBars;