0

My print formatting is giving me random answers, despite my coding being correct. I'm trying to display the candle bar lengths of the previous two candle bars prior to a trade entry. Here is the coding I've used.

PCL1 & PCL2 are the relevant field entries. They are divided by _Point to give an integer formatting.

PCL2 = Previous Candle Stick length, Shift 2

PCL1 = Previous Candle Stick length, Shift 1

In this example I have focused on the Shift2 Candlestick

Short_Bull_2_Close   =  iClose( Symbol(), 0, 2 );
Short_Bull_2_Open    =  iOpen(  Symbol(), 0, 2 );
CandleBody_2         =  ( Short_Bull_2_Close - Short_Bull_2_Open );
                     // Gives the Candlebody length in pips.

And this is my printf() coding:

printf( "PCL1 [%d] PCL2 [%d]", CandleBody_1 / Point,
                               CandleBody_2 / Point
        ); // ___________________________________________________________  SELL//

However, all I get is as pictured & highlighted..enter image description here

user3666197
  • 1
  • 6
  • 50
  • 92

2 Answers2

0

you must convert to integer, you may think that you obtain a real number equivalent to integer but converter doesn't think so.

printf("%d",  (int)NormalizeDouble(CandleBody_2/Point,0) );
user3666197
  • 1
  • 6
  • 50
  • 92
Daniel Kniaz
  • 4,603
  • 2
  • 14
  • 20
0

1) MQL4 is a strong typed language ( declaration precedes any use of a variable )
+ MQL4 has a historical feature of a number "normalisation"

An assumption (cit.) "They are divided by _Point to give an integer" does not hold.

Once any number has been declared double in a source code as:

double upFractal = 0.0,
       dnFractal = 0.0;

the MQL4-compiler handles these numbers forever in an IEEE-754 floating point number representation and calls particular sub-version of operations on any arithmetics operation such number is entring into. The reason is simple, double has different handling than ( New-MQL4.56789 ) float, the more than int et al. Some numbers, represented in IEEE-754, are inexact by-definition, some could remain exact ( if they happen to be some direct power-of-2 and still in it's "virgin"-state ( have not yet been spoiled by any arithmetic operation, that would introduce an un-avoidable im-precision into their binary-representatio ) ).

Why im-precision?
Why un-avoidable?

For non-virgin numbers, the binary-representation may yield into an infinitely-long description of the value. On the contrary, the storage of any value in MQL4 is restricted to { 1 | 4 | 8 }-bytes of memory-space and thus the infinite-representation is un-avoidably cut at some distance, introducing a principal im-precision , expressed by:

DBL_EPSILON ~ 2.2204460492503131e-016
FLT_EPSILON ~ 1.192092896e-07
beyond which any two numbers, represented in IEEE-754 binary-format, look to the compiled code as "equal", even if they are not principally equal, just due to the IEEE-754 format inherent im-precision.

For indeed historical reasons, double typed values ought have been always NormalizeDouble() converted, if one wants to send these to the MetaTrader Server-side processing and/or compare values on a fair ground.

2) MQL4 operations with {double | int }- typed variables

If one had declared a variable to be double, it remains double forever.
If one had declared a variable to be int, even an int/3 will remain int, ignoring the fractional products of division operation ( which sometimes causes headaches to not so carefull MQL4 coders ).

The same applied to an initial assumption above yields to a surprise, that double/double -> double even in cases, the division could be satisfactorily considered ( almost ) integer. So never assume a type conversion to happen just by the values of the operands.

For that purpose, there are two sorts of syntax-supports:

  • an explicit conversion function int( ... ) or double( ... )
  • an inline typecast directive ( (int) CandleBody_1 / _Point )

Epilogue: ( ... a must read for Custom Indicator designers, where CPU-performance kills )

As said above, calling (int) NormalizeDouble(...) is a double-nonsense ( well beyond a belt + suspenders paradigm ), first, as a historically built-in function NormalizeDouble still returns double, thus providing zero-benefit from spending CPU to crunch the numbers once it still yields a double, next as the division of the number a double value of _Point is very expensive and inefficient, compared to the fact, the _Point is related to int value of Digits by a formula of 1 / 10^Digits -- so the fastest and cleanest way to do the conversion, without spending avoidable CPU-cycles, is MULTIPLICATION ...
yes,
from a computer-side of fast & efficient processing, the best is
int( MAKE_aPriceDOMAIN_VALUE_an_INT_NUM_OF_POINTs * CandleBody_1 ),
re-using a constant
int MAKE_aPriceDOMAIN_VALUE_an_INT_NUM_OF_POINTs = MathPow( 10, Digits );

user3666197
  • 1
  • 6
  • 50
  • 92