Does anyone have ready code to calculate the number of significant digits for a volume? Something like SymbolInfoInteger(_Symbol, SYMBOL_DIGITS), but only for volume. For example, for the case SymbolInfoDouble( _Symbol, SYMBOL_VOLUME_STEP) = "1.0" - the answer would be "0", for "0.1" - "1", for "0.01" - "2" etc.
Let me clarify a nuance. For a volume step like "0.1", "0.01", "0.001" I have.
The code should work for the following cases like "0.2", "0.11", 0.023" etc.
There is no code specificallyfor volume. There is for anything.
Does anyone have ready-made code for calculating the number of significant digits for a volume? Something like SymbolInfoInteger(_Symbol, SYMBOL_DIGITS), but only for volume. For example, for the case SymbolInfoDouble( _Symbol, SYMBOL_VOLUME_STEP) = "1.0" - the answer would be "0", for "0.1" - "1", for "0.01" - "2" etc.
Let me clarify a nuance. For a volume step like "0.1", "0.01", "0.001" I have. The code should work for the following cases like "0.2", "0.11", 0.023" etc.
Specifically for volumes can be simple:
int N=0;
double step=SymbolInfoDouble(symbol,SYMBOL_VOLUME_STEP);
if(step-1.0<0) N++;
if(step-0.1<0) N++;
if(step-0.01<0) N++;
sergeev MetaDriver Valmars Well-formulated question is half the answer. :) Sorry, I went to bed already, I failed to describe the task accurately. I will try again.
I'm talking about passing a normalized volume to a trade order. It is what we do with the price:
Price normalisation - I think it's clear to everyone.
At my time (since MT4), I read somewhere in MT articles that it would be desirable to normalize the volume as well. Actually, I wrote the functionGetVolumeDigits(string Symbol) to find the smallest possible value of volume according to broker's conditions. There are at least two implementations (the result is the same): Implementation #1.
int GetVolumeDigits(stringSymbol) {
int VolumeDigits = 0;
double VolumeStep = SymbolInfoDouble(Symbol, SYMBOL_VOLUME_STEP);
while (VolumeStep < 1) {
VolumeStep *= 10;
VolumeDigits++;
}
return VolumeDigits;
}
Implementation №2.
int GetVolumeDigits(stringSymbol) {
return (int)MathLog10(1.0 / SymbolInfoDouble(Symbol, SYMBOL_VOLUME_STEP));
}
Both of them perfectly work for variants with min step = 1.0, 0.1, 0.01, 0.001, etc. That is, if the minimum step is 1.0, the function will return 0; if the step is 0.1, the function will return 1, etc. What if the minimum step is 1.1, or 0.11, or 0.011, for example? This algorithm will incorrectly show the least significant digit. Of course, you can assert that there are no such cases in practice. I want just to consider such a hypothetical possibility in my Expert Advisor. I thought that maybe someone would share their experience in this matter...
Yeah, I get it, you want the result to be a multiple of VolumeStep. Well, it has nothing to do with Digits, first calculate the volume with Digits and then reduce it to the nearest multiple of VolumeStep.
It's about sending the normalized volume to the trade order. I just want to consider this hypothetical possibility in our Expert Advisor.
which "hypothetical" tool are we talking about?
1. The variant from MetaDriver is suitable for you. CountSignedDigits will show the number of characters in any lot.
2. Knowing the number of dig dig its you can do the normalisation like this:
double MinLot; // минимальный лот по символуdouble MaxLot; // максимальный лот по символуdouble LotStep; // шаг лота по символуint dig; // знаковость лота узнали из функции CountSignedDigitsdouble NL(double lot)
{
if (lot<=MinLot) return(MinLot); // проверка на минимальныйdouble d=MathFloor((lot-MinLot)/StepLot); // сколько ЦЕЛЫХ шагов умещается в проверяемом лоте
lot=MinLot+StepLot*d; // рассчитали по этому целому числу
lot=MathMin(lot, MaxLot); lot=NormalizeDouble(lot, dig);// не забыли проверить на максимальный// нормализовалиreturn(lot); // вернули
}
sergeev Thanks for the lot validation function. I'm using a similar construction/branching of checks. My question is focused on finding the youngest place in the lot, to normalize it. In particular, MetaDriver gave his construction for "everything". :) However, it is not without flaws (or my compiler is glitchy). Below is the code and execution result:
voidOnStart() {
Print(CountSignedDigits(110.0));
Print(CountSignedDigits(11.0));
Print(CountSignedDigits(1.1));
Print(CountSignedDigits(0.11));
Print(CountSignedDigits(0.011));
Print(CountSignedDigits(0.0011));
Print(CountSignedDigits(0.00011));
}
int CountSignedDigits(double x) {
for (int i = 0; i < 1000; i++, x *= 10)
if (x - MathFloor(x) < DBL_MIN * 2)
return i;
return -1;
}
Result:
2011.07.0313:15:21 test (EURUSD,M5) 52011.07.0313:15:21 test (EURUSD,M5) 42011.07.0313:15:21 test (EURUSD,M5) 18 - Здесь только у меня бяка вылазиет?
2011.07.0313:15:21 test (EURUSD,M5) 22011.07.0313:15:21 test (EURUSD,M5) 12011.07.0313:15:21 test (EURUSD,M5) 02011.07.0313:15:21 test (EURUSD,M5) 0
Next option (CountSignedDigits function is the same):
void OnStart() {
doublevalue = 110.0;
int count = 9;
while (count) {
Print(DoubleToString(value), " - ", CountSignedDigits(value));
value /= 10;
count--;
}
}
Result:
2011.07.0313:23:32 test (EURUSD,M5) 0.00000110 - 22 - Почему-то здесь бяка...
2011.07.0313:23:32 test (EURUSD,M5) 0.00001100 - 21 -
2011.07.0313:23:32 test (EURUSD,M5) 0.00011000 - 52011.07.0313:23:32 test (EURUSD,M5) 0.00110000 - 42011.07.0313:23:32 test (EURUSD,M5) 0.01100000 - 3 - Здесь уже все нормально. Почему результаты разные?!
2011.07.0313:23:32 test (EURUSD,M5) 0.11000000 - 22011.07.0313:23:32 test (EURUSD,M5) 1.10000000 - 12011.07.0313:23:32 test (EURUSD,M5) 11.00000000 - 02011.07.0313:23:32 test (EURUSD,M5) 110.00000000 - 0
My question is focused on determining the lowest place in the lot to normalize it.
You don't need to define dig for the lot, just normalise it to the right step:
lot = NormalizeDouble( lot / lot_step, 0 ) * lot_step;
if ( lot < lot_min ) lot = lot_min;
if ( lot > lot_max ) lot = lot_max;
Even if when sending a trade request, the variable lot will get rubbish (in the second decimal place), it will be rejected by the terminal itself.
At least, I haven't had any problems during several years of using this design.
And if you want to reinsure, you can normalize it to 8th decimal place (with reserve) - if after "correct" normalization trash appears, it will be much further.
Does anyone have ready code to calculate the number of significant digits for a volume?
Something like SymbolInfoInteger(_Symbol, SYMBOL_DIGITS), but only for volume.
For example, for the case SymbolInfoDouble( _Symbol, SYMBOL_VOLUME_STEP) = "1.0" - the answer would be "0", for "0.1" - "1", for "0.01" - "2" etc.
Let me clarify a nuance. For a volume step like "0.1", "0.01", "0.001" I have.
The code should work for the following cases like "0.2", "0.11", 0.023" etc.
There is no code specificallyfor volume. There is for anything.
The script is for checking in the trailer.A script to check in the trailer.
You mean that..., and I thought I should check the allowable lot before placing an order.
;)
I don't really know what he wants. We'll see what he says. I'm just practising my telepathy. ;)
Does anyone have ready-made code for calculating the number of significant digits for a volume?
Something like SymbolInfoInteger(_Symbol, SYMBOL_DIGITS), but only for volume.
For example, for the case SymbolInfoDouble( _Symbol, SYMBOL_VOLUME_STEP) = "1.0" - the answer would be "0", for "0.1" - "1", for "0.01" - "2" etc.
Let me clarify a nuance. For a volume step like "0.1", "0.01", "0.001" I have.
The code should work for the following cases like "0.2", "0.11", 0.023" etc.
Specifically for volumes can be simple:
sergeev
MetaDriver
Valmars
Well-formulated question is half the answer. :) Sorry, I went to bed already, I failed to describe the task accurately. I will try again.
I'm talking about passing a normalized volume to a trade order.
It is what we do with the price:
Price normalisation - I think it's clear to everyone.
At my time (since MT4), I read somewhere in MT articles that it would be desirable to normalize the volume as well.
Implementation №2.Actually, I wrote the functionGetVolumeDigits(string Symbol) to find the smallest possible value of volume according to broker's conditions. There are at least two implementations (the result is the same):
Implementation #1.
Both of them perfectly work for variants with min step = 1.0, 0.1, 0.01, 0.001, etc. That is, if the minimum step is 1.0, the function will return 0; if the step is 0.1, the function will return 1, etc.
What if the minimum step is 1.1, or 0.11, or 0.011, for example? This algorithm will incorrectly show the least significant digit.
Of course, you can assert that there are no such cases in practice. I want just to consider such a hypothetical possibility in my Expert Advisor. I thought that maybe someone would share their experience in this matter...
It's about sending the normalized volume to the trade order.
I just want to consider this hypothetical possibility in our Expert Advisor.
which "hypothetical" tool are we talking about?
1. The variant from MetaDriver is suitable for you. CountSignedDigits will show the number of characters in any lot.
2. Knowing the number of dig dig its you can do the normalisation like this:
sergeev
Thanks for the lot validation function. I'm using a similar construction/branching of checks.
My question is focused on finding the youngest place in the lot, to normalize it.
In particular, MetaDriver gave his construction for "everything". :) However, it is not without flaws (or my compiler is glitchy). Below is the code and execution result:
Result:
Next option (CountSignedDigits function is the same):
Result:
Changed the following line in OnStart:
Result:
Either I'm doing something wrong (please correct), or MetaDriver made a mistake in theory (when designing the algorithm).
My question is focused on determining the lowest place in the lot to normalize it.
Even if when sending a trade request, the variable lot will get rubbish (in the second decimal place), it will be rejected by the terminal itself.
At least, I haven't had any problems during several years of using this design.
And if you want to reinsure, you can normalize it to 8th decimal place (with reserve) - if after "correct" normalization trash appears, it will be much further.