Mastering IndicatorCounted()

The forum for experienced coders to upload their helpful hints, tips and lessons.
Post Reply
Big Be
Trader
Posts: 52
Joined: Thu Nov 01, 2012 6:12 pm

Mastering IndicatorCounted()

Post by Big Be »

Lesson 1

Mastering IndicatorCounted makes a major difference in the behavior and results of indicators. This knowledge may help you to turn a slow indicator into a fast indicator. This affects EA's as well, at least indirectly when indicators are called.
Note: “SetIndexDrawBegin” only affects the display, not the calculations.

The first lesson is that the MetaEditor's help file, etc., has a mistake that has been endlessly copied. Your ordinary indicator needs to recalculate two bars back. In theory one bar, but in practice two is safe. The maximum value of IndicatorCounted is Bars – 1.
So the help file gives the useful lines:

int counted_bars = IndicatorCounted();
counted_bars--;

But this next line from the help file:

limit = Bars - counted_bars – 1;

results, when on the current bar, in a limit of '1', NOT '2' which is what we want. Why have two lines that just take you back where you started? This calculates as:

(Bars - counted_bars) – 1

If Bars = 1000, then when on the current bar, counted_bars = 998, so you have:

(1000 – 998) – 1 = 1

So you have two choices:

counted_bars--;
limit = Bars - counted_bars;

OR just:
limit = Bars - counted_bars + 1;

You can check how all this is behaving with Comment statements, such as:
Comment(“ Bars “,Bars," counted_bars ",counted_bars, " limit ",limit);
When running, 'limit' should equal '2'.


Big Be
Last edited by Big Be on Wed Feb 20, 2013 11:21 pm, edited 1 time in total.
"Big Be"
Big Be
Trader
Posts: 52
Joined: Thu Nov 01, 2012 6:12 pm

Re: Mastering IndicatorCounted()

Post by Big Be »

Lesson 2

Correctly setting up “limit” can have a huge effect on the left end of a chart. With some indicators this can affect hundreds of bars from the left. This is important if you are trying to understand an indicator over time. If I knew computer graphics I would draw you pretty pictures, but for now I will use simple word pictures. I suggest you draw it and label it. It will only take a minute.
Draw a horizontal line.
The left end is the number 'Bars', the right end is '0'. You can write 'counted_bars' below and to the left. 'counted_bars' starts at 'Bars' as '0', and ends at '1', one left of '0', with a value of 'Bars-1'.
Everything you subtract from 'Bars' reduces the 'limit' length from the left.
You don't want to start plotting before the longest Length used in the indicator, as it won't be accurate. What I have found to work is to use longest Length plus two plus how many bars back are looked back to and used. For example if you have 'i + 3' as your biggest shift back data point in your code, you end up with Length + 2 + 3.
Then you can use:

counted_bars--;
limit = Bars – MathMax(counted_bars, Length + 2 + 3);

It will start plotting at Length + 2 + 3 from the left, and follow counted_bars after that. If the limit loop uses ++, it will count up to the same point, from the right.

This will often clean up or fix a troublesome indicator. This is not a universal fix; it gives you the principles that you can adapt to the code in front of you. Take the time to work with it and understand it and you will be rewarded with more reliable and better results, sometimes much better.

I will admit that though this usually works, occasionally the exact number to add or subtract has been a matter of trial and error in a complicated indicator.

Notes:
If two lines are being calculated independently in one indicator, “limit” can be calculated differently for each.
If you are careless in coding you can end up at times with a negative value for limit!


Big Be
"Big Be"
l00py

Re: Mastering IndicatorCounted()

Post by l00py »

Remember that IndicatorCounted() can return 0. So the code:

int counted_bars = IndicatorCounted();
counted_bars--;

counted_bars will equal -1

(Bars - counted_bars) let's say 100 - -1 = 101 :twisted:

OR

limit = Bars - counted_bars + 1;
100 = 100 - -1 + 1;

int counted_bars = IndicatorCounted();
if (counted_bars < 0) return(-1);
if (counted_bars > 0) counted_bars--;

I know Empty4 handles these types of errors but you are wasting resources on the error process Empty4 would use - do this in c++ and find out what happens to your code :)

HTH :)
atharmian
Trader
Posts: 169
Joined: Tue Oct 16, 2012 7:43 am

Re: Mastering IndicatorCounted()

Post by atharmian »

BigBe,

Just came across your thread and read your TSD link too, as I have struggled as a newbie...

Your insight into changing to (Bars-countedbars +1) is excellent; had come across this problem, later changing to MathMax(limit, maxBars+1) to solve one missing bar problem with the max bars set to 20, but only getting 19 bars at times !

Questions:

1. The IndicatorCounted()( problem I encountered was with trying to change Baluda's CSS single TF v1.0.8 to MTF, i.e., having indi instances showing various TFs in the SAME sub-window.

See http://www.stevehopwoodforex.com/phpBB3 ... f=45&t=629

IndicatorCounted() is only for the current TF, Period(), so this creates the question of using iBarShift() for other TFs, in which case above becomes tricky- I expanded limit to limit*TF to make sure I have enough relevant TF bars to give me shift instances equivalent to limit in M1.

2. One way of minimizing CPU load is to simply do what hanover @FF does: to define RefreshEveryXMin so that the Start() loop, instead of running with every incoming tick, will run only every X= 1 minute, 5 min, or so.


See http://www.forexfactory.com/showthread.php?t=163158

Any further thoughts?

(I later found out that using iBarShift was unnecessary with CSSv1.0.8 since the calc functions already were using shift, TF as parameters in respective TFs. I then had the problem with buffer indicator over-writes, since only the last table and currency line chart appeared if you were running a loop in the same mq4 for various TFs.)

Regards,
Athar.


Big Be wrote:Lesson 1

Mastering IndicatorCounted makes a major difference in the behavior and results of indicators. This knowledge may help you to turn a slow indicator into a fast indicator. This affects EA's as well, at least indirectly when indicators are called.
Note: “SetIndexDrawBegin” only affects the display, not the calculations.

The first lesson is that the MetaEditor's help file, etc., has a mistake that has been endlessly copied. Your ordinary indicator needs to recalculate two bars back. In theory one bar, but in practice two is safe. The maximum value of IndicatorCounted is Bars – 1.
So the help file gives the useful lines:

int counted_bars = IndicatorCounted();
counted_bars--;

But this next line from the help file:

limit = Bars - counted_bars – 1;

results, when on the current bar, in a limit of '1', NOT '2' which is what we want. Why have two lines that just take you back where you started? This calculates as:

(Bars - counted_bars) – 1

If Bars = 1000, then when on the current bar, counted_bars = 998, so you have:

(1000 – 998) – 1 = 1

So you have two choices:

counted_bars--;
limit = Bars - counted_bars;

OR just:
limit = Bars - counted_bars + 1;

You can check how all this is behaving with Comment statements, such as:
Comment(“ Bars “,Bars," counted_bars ",counted_bars, " limit ",limit);
When running, 'limit' should equal '2'.


Big Be
ovo.cz

Re: Mastering IndicatorCounted()

Post by ovo.cz »

I wonder if anyone coded a workaround for the annoying behaviour of IndicatorCounted() on offline charts. In short, all indicators using this method recalculate all bars with every single tick on offline charts.
In particular, use of the offline charts expects a window message to update the chart

Code: Select all

PostMessageA(hwnd, WM_COMMAND, 0x822c, 0);
After the message is sent to the offline chart, the IndicatorCounted() on that chart returns the highest possible value, causing the indicator to recalculate values for the entire scope. The message appears with every tick, and the offline charts suffer from useless heavy load.
My suggestion is to have a function, that would directly replace the IndicatorCounted() method in indicators code, but returned some realistic value after the refresh message.

Has anyone seen some a solution for that?
User avatar
milanese
TechAdmin
Posts: 3293
Joined: Wed Jan 09, 2013 9:02 am
Location: btr rdx, r8 +

Re: Mastering IndicatorCounted()

Post by milanese »

ovo.cz wrote:I wonder if anyone coded a workaround for the annoying behaviour of IndicatorCounted() on offline charts. In short, all indicators using this method recalculate all bars with every single tick on offline charts.
In particular, use of the offline charts expects a window message to update the chart

Code: Select all

PostMessageA(hwnd, WM_COMMAND, 0x822c, 0);
After the message is sent to the offline chart, the IndicatorCounted() on that chart returns the highest possible value, causing the indicator to recalculate values for the entire scope. The message appears with every tick, and the offline charts suffer from useless heavy load.
My suggestion is to have a function, that would directly replace the IndicatorCounted() method in indicators code, but returned some realistic value after the refresh message.

Has anyone seen some a solution for that?
This could be interessting for you http://www.forexfactory.com/showthread. ... 301&page=9

Cheers :)
Tommaso
Global Prime is the official SHF broker :yahoo:
Searching for Servers and Workstations with individual configuration?
Just PM
:smile: Click here to go to the BoardKnowledgeBase
NOTE: Cookies and JavaScript are required for the using the board, with full functionality
ovo.cz

Re: Mastering IndicatorCounted()

Post by ovo.cz »

milanese wrote:
ovo.cz wrote:I wonder if anyone coded a workaround for the annoying behaviour of IndicatorCounted() on offline charts. In short, all indicators using this method recalculate all bars with every single tick on offline charts.
In particular, use of the offline charts expects a window message to update the chart

Code: Select all

PostMessageA(hwnd, WM_COMMAND, 0x822c, 0);
After the message is sent to the offline chart, the IndicatorCounted() on that chart returns the highest possible value, causing the indicator to recalculate values for the entire scope. The message appears with every tick, and the offline charts suffer from useless heavy load.
My suggestion is to have a function, that would directly replace the IndicatorCounted() method in indicators code, but returned some realistic value after the refresh message.

Has anyone seen some a solution for that?
This could be interessting for you http://www.forexfactory.com/showthread. ... 301&page=9

Cheers :)
Tommaso
Cool, I knew I was not the only one!
Thanks a lot for the link, Tommaso.
Post Reply

Return to “Coding Lessons - info for all”