Would you say that 0 (as in ZERO) is equal to 0.000001???

 

Hello again (from the the latest 'up and coming' MetaTrader 4 expert)!!! LOL!!!

Here's one for you.

Would you say that 0 (as is ZERO) is equal to 0.000001??? Stupid question??? Read on!!! LOL!!!

Take a look at the first chart.

In the last (second) indicator on the chart I am 'forcing' the 'main' or 'core' buffer of the indicator to be 0 up until 30 June 2011 i.e. the indicator must only start calculating from 1 July 2011 (which it is doing correctly thanks to some help and guidance received from my previous and first post here). The problem is what happens AFTER 30 June 2011 i.e. from 1 July 2011. The white line represents the 'main' or 'core' buffer of the indicator. I've denoted the 'problem' with a white block(s). Note that the white line is not contiguous from 1 July 2011. The 'main' or 'core' buffer of the indicator is 0 up until the close on 30 June 2011 (quite correctly so), the calculations start on 1 July 2011, and a day or two later, the result of the calculations is 0 BUT note how, at that point, the the white line is not correctly drawn i.e. there should not be a gap and the reason there IS a gap is because at that particular point in time the result of the calculations is 0.

For interest sake and for demonstration purposes the buffer is defined thus:

At the beginning: double BufferName=[]

In the int init( ) section: SetIndexEmptyValue( 0, 0.0 ); (It just happens to be the first buffer defined so it's reference is 0)

Then the calculations start and this is the result:

At first I thought it was a problem with my code and calculations but I've checked them manually (you know: with a calculator) and they're 100% correct i.e. at the point in question the value of the indicator IS INDEED 0.

So here's the only fix THUS far that I've been able to come up with:

At the beginning: double BufferName=[]

In the int init( ) section: SetIndexEmptyValue( 0, 0.000001); (I chose six decimal places because no instrument I know has six decimals in its price quote).

Here is the result of the above change:

Can you see the difference???

You'll note also that where the indicator is 'forced' to be 0 i.e. prior to 1 July 2011 the white line representing the 'main' or 'core' buffer of the indicator is also drawn unlike in the first chart.

Now I'm the first person to admit that adding or subtracting a figure of 0.000001 just to correct the display is most certainly not going to affect the correct results of the calculations (especially given that the result of the calculations are whole numbers i.e. no decimals) but I was just wondering if this is a MetaTrader 4 'funny' or if I'm doing something wrong.

I guess what I'm saying is that it would APPEAR that if an indicator (ANY indicator) has a value of 0 at any time then it's output is simply not drawn / displayed by MetaTrader 4 (unless, as I say, I'm doing something wrong).

Note that this is an INDICATOR I'm talking about here i.e. if you draw an 'Object' e.g. a horizontal line at 0 then the line is indeed displayed.

Regards,

Dale.

 
Without seeing your code I can't say for certain what the problem is . . but I can make a guess. I suspect you have an problem when you are comparing doubles . . . the simplest way to get round this is to NormalizeDouble them to the required precision before/as you compare them.
 

Good morning (well it's morning here in South Africa anyway).

I found my own problem!!! Simply ELIMINATE the SetIndexEmptyValue()!!! After RE-READING the documentation what that function EXPLICITLY does is to tell MetaTrader 4 to NOT display or output any zero values on the chart (I incorrectly thought it was ensuring that the indicator value was initialised to zero before starting to calculate). So my adding the 0.000001 was 'forcing' the buffer to not have a value of zero (no matter how small the value may have been).

The only way I found the problem was by creating another test code with NO calculations i.e. just something simple setting the value to either 0 or 1 and then playing around with my 0.000001 figure or commenting out the SetIndexEmptyValue().

Here's an example if you're interested in 'playing':

#property indicator_separate_window

#property indicator_buffers 1
#property indicator_color1 White

double TestBuffer[];

//

int init( )

   {
            
   IndicatorDigits( 0 );

   IndicatorBuffers( 1 );
   
   SetIndexStyle( 0, DRAW_LINE );
   SetIndexBuffer( 0, TestBuffer );
   SetIndexLabel( 0, "TestBuffer" );


   SetIndexEmptyValue( 0, 0.000001 );
   //If you set the second parameter to 0.0 then NO output. Otherwise (more elegant) remove the function!!!

   return( 0 );

   }

//

int deinit( )

   {

   return( 0 );

   }

//

int start( )

   {

   int counted_bars = IndicatorCounted( );

   int i, limit;
   
   double TodaysHigh;

   if( counted_bars == 0 ) limit = Bars - 1;

   if( counted_bars > 0 ) limit = Bars - counted_bars;

   for( i = limit; i >= 0; i-- )

      {
      
         if( TimeYear( Time[i] ) >= 2011 ) if( TimeMonth( Time[i] ) >= 7 )

            TestBuffer[ i ] = 1;
       
         else
         
            TestBuffer[ i ] = 0;
      }   

   return( 0 );

   }

//

But thanks to taking the time and going to the trouble of giving me some input. I think I'll go look at what 'NormalizeDouble' does (might be a further improvement).

But I'm pleased I don't have to 'tinker' with 'artificial values' in order to get the display right!!! LOL!!!

But thanks again. (This is always a problem when learning new languages i.e. I came fromn the good 'ol 'dBase/Clipper/FoxPro days', then Visual FoxPro (big adjustment), then to C# (even BIGGER adjustment), and NOW THIS!!! LOL!!!

Regards,

Dale.

 
dpaterso:

Good morning (well it's morning here in South Africa anyway).

I found my own problem!!! Simply ELIMINATE the SetIndexEmptyValue()!!!

Well done, It's Morning here too (UK) :-)
 

Hello again,

Hmmmnnn... I have a feeling you're right with your 'NormalizeDouble' suggestion unfortunately.

In the code that I posted above it works perfectly (the 'solution' that I THOUGHT I'd found) but on my indicator that I'm working with it causes HAVOC i.e. instead of displaying the correct values it sets ALL values (for the ENTIRE indicator even where there are SUPPOSED to be values from the calculations as well as where the value is being 'forced' to be zero) to some RIDICULOUS number like 24145478587 (not exactly but a number of that magnitude anyway) right across the board (chart). So I'm back to having to have SetIndexEmptyValue( 0, 0.0000001) (I've simply increased the number of decimal places to as many as I can get away with without getting a total 'nothing' output.

It's a strange one though i.e. if you read the documentation it does say that the SetIndexEmptyValue( 0, 0.0 ) will not display anything on the chart if the value of the index is zero. But changing the '0.0' part to any other number (like 0.7 for example) doesn't seem to change any actual indicator values it just sort of 'shifts' the 'scaling' of the indicator. Unless I'm not reading or understanding the documentation correctly. Put another way: SURELY it would have been simpler to have a function that went something along the lines of 'SetIndexEmptyValue( 0, .F. )' (i.e. 'False' to NOT draw anything if the value is zero) or 'SetIndexEmptyValue( 0, .T. )' (i.e. 'True' and DO draw something if the value is zero)!!! LOL!!! Maybe that's what the documentation is trying to tell me i.e. use ANY number OTHER than '0.0' to draw zero values but it's sure one hell of a complicated way of doing things and, as I say, using any other number appears to affect the 'scaling value' (at the right of the chart) even although it doesn't affect the value of the indicator itself (and of course DOES draw when the value is zero).

My only problem (if your 'NormalizeDouble' is the solution) then that creates another problem i.e. I read about it in the documentation and the 'NormalizeDouble' function, if I'm not mistaken, is directly related to the 'Digits' setting and this (these) indicators can, will, and must be able to be used with intruments where there may sometimes be NO decimals.

But I'll 'play around' some more and see what I can come up with. Although my '0.0000001' 'solution' works and doesn't affect the indicator (and solves my problem) it's definitely not the most elegant and I fear it's not 'robust' e.g. even with my C# code I've had occasion (oddly enough also due to the different ways different processors handle floating points) where an indicator value was 'correct' on all of my PCs (all AMD processors but different models and speeds and different motherboards etc.) but produced WAY different values on an Intel Dual Core processor for instance!!! That had me 'befuddled' for DAYS!!! And I think this has something to do with the problem here too. Unfortunately the indicator in question does a lot of divisions and multiplications etc. and I have to 'trap' for every possible 'wrong doing' (like dividing by zero without crashing the PC)!!! LOL!!!

Regards,

Dale.

 

the empty value is normally (if you dont set it do something different) set to 0x7FFFFFFF (there is also a constant EMPTY_VALUE). You should not change this if you don't have a very good reason and know what you are doing. Also for EAs that use iCustom() it is the unwritten convention to check a buffer value empty value to detect whether it contains something. If you want the line to disappear then initialize the buffer values before your starting date to EMPTY_VALUE (they probably are already).

 
dpaterso:

Hello again,

Hmmmnnn... I have a feeling you're right with your 'NormalizeDouble' suggestion unfortunately.

My only problem (if your 'NormalizeDouble' is the solution) then that creates another problem i.e. I read about it in the documentation and the 'NormalizeDouble' function, if I'm not mistaken, is directly related to the 'Digits' setting and this (these) indicators can, will, and must be able to be used with intruments where there may sometimes be NO decimals.

Unfortunately the indicator in question does a lot of divisions and multiplications etc. and I have to 'trap' for every possible 'wrong doing' (like dividing by zero without crashing the PC)!!! LOL!!!

If there are no decimals then Digits will be 0, so NormalizeDouble will return the double rounded to whole digits. But you can use NormalizeDouble with your own variable, you don't only use it with Digits.

The divisions and multiplications aren't a problem . . the problem comes with comparisons,

double a;

a = a*b;
if (a == 0){do stuff};

a is nominally zero, 0.0000000001 but not actually zero so the test is false, but if you Normalize it then the test will work.

double a;

a = a*b;
if (NormalizeDouble(a, Digits) == 0){do stuff};
 

Working with Doubles in MQL4 - MQL4 Articles

setting empty value to 0.000001 is RIDICULOUS. What if the value calculated is 0.000001001, that's not the empty value so it may be shown.

 

Hello.

Thank you both for the input.

The indicator code doesn't do comparisons or anything like that i.e. no '==' comparisons or anything like that. Also: the indicator itself only returns rounded whole numbers (I think that's the word) i.e. numbers with no decimals so it shouldn't be a problem i.e. 0.000001001 rounded to the nearest whole number (no decimals) is still 0. As a matter of fact none of this is of any consequence in the indicator code itself i.e. it calculates perfectly with or without decimal pricing. It's just the very last final output that's converted and rounded to a whole number (no decimals) and if that rounded whole number (no decimals) just HAPPENS to be a zero well, then, as I've discovered, MetaTrader simply won't display anything at that particular point on the indicator (and if it's a line on the indicator it leaves out the segement joining the points as is displayed in my FIRST chart posted above today). In other words: this is a more of a display problem really not a calculation problem. If there was no rounding involved of the final output value and I used IndicatorDigits( Digits ) or set IndicatorDigits( ) to the maximum allowed (or simply left it out) then I'd not be having this problem (unless by SHEER 'Murphy's Law' the final output just HAPPENED to be 0.0000000 at some point (and there's little to no chance of that happening I'm sure but then anything is possible)!!! LOL!!!

Regards,

Dale.

Edit:

Actually all of the above being said it doesn't make any sense. In my very first example (post) where there was a gap in the line the actual value there (when manually calculated) was REALLY 0 (a rounded whole number) so THEORETICALLY my removing SetIndexEmptyValue( 0, 0.0 ) should have worked i.e. the value was indeed zero and I was instructing the indicator to display 0 values. It worked perfectly on my working example posted a bit later but TOTALLY messed with my indicator when I removed the function. Very odd.

 

You are NOT going to believe this!!!

All morning I played around with this stuff and, as you know, I thought I'd found the solution (simply not using the SetIndexEmptyValue( 0, 0.0 ). In my working example posted that solved the problem but when I did the same thing to my indicator code it messed up the whole indicator ouput (as I noted) so I reverted back to using my SetIndexEmptyValue( 0, 0,0000001 ) solution.

Anyway, obviously, I had other things to do today so I had rebooted my PC once or twice since originally posting and making changes. I then posted my above message and thought 'just let me take another look at this'. I SWEAR to you that without changing ANYTHING ELSE in the code except for AGAIN removing the SetIndexEmptyValue( 0, 0.0 ) from the code: it now works perfectly (and as it should)!!! How weird is that???

Oh well: I'll reboot again, go wash the dishes, come back, compile the code again (without making any changes), and see if it STILL works!!! LOL!!! And by the way: the problem that I experienced after originally removing the SetIndexEmptyValue( 0, 0000001 ) was not limited to a particular MetaTrader 4 installation i.e. I have MetaTrader 4 installed from five different brokers. Also: I have a batch file that deletes all the compiled files from all of the installations (this to make sure that when I first open any one of the installations after making changes to the code then the code is compiled afresh by that particular installation and not simply copied from a single source).

STRANGE but TRUE!!! (After ALL the above)!!! LOL!!!

Sorry about that chaps (although you NEVER know i.e. I may be back with the same issue. Who knows.).

Regards,

Dale.

 
Sounds exactly like a double issue to me . . . but without seeing your code we can't be sure. When I mentioned comparisons I meant == != >= <= > and <, the technical term is "Operations of relation" https://docs.mql4.com/basis/operations/relation
Reason: