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//
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.
{double | int }
- typed variablesIf 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:
int( ... )
or double( ... )
( (int) CandleBody_1 / _Point )
As said above, calling
(int) NormalizeDouble(...)
is a double-nonsense ( well beyond a belt + suspenders paradigm ), first, as a historically built-in functionNormalizeDouble
still returnsdouble
, thus providing zero-benefit from spending CPU to crunch the numbers once it still yields adouble
, next as the division of the number adouble
value of_Point
is very expensive and inefficient, compared to the fact, the_Point
is related toint
value ofDigits
by a formula of1 / 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 isint( MAKE_aPriceDOMAIN_VALUE_an_INT_NUM_OF_POINTs * CandleBody_1 )
,
re-using a constantint MAKE_aPriceDOMAIN_VALUE_an_INT_NUM_OF_POINTs = MathPow( 10, Digits );