Dear All,
My Broker extended the digits from 1 to 2 for DE30. Unfortunately at the second digit only 0 and 5 are allowed.
Valid Prices: 13080.00, 13080.05, 13080.10
Invalid Prices: 13080.01, 13080.02, 13080.03, 13080.04, 13080.06, ...
Until now I used NormalizeDouble(Price, Digits); in oder to get valid prices.
Unfortunately this is no more working. Are there any other methods available to round the price?
BR Sebastian
Solid and elegant way:
double dblLotsMinimum = SymbolInfoDouble( _Symbol, SYMBOL_VOLUME_MIN ), dblLotsMaximum = SymbolInfoDouble( _Symbol, SYMBOL_VOLUME_MAX ), dblLotsStep = SymbolInfoDouble( _Symbol, SYMBOL_VOLUME_STEP );// Adjust Volume for allowable conditions double dblLotsNext = fmin( dblLotsMaximum, // Prevent too greater volume fmax( dblLotsMinimum, // Prevent too smaller volume round( dblLots ) * dblLotsStep ) ); // Align to Step value
- 2017.09.01
- www.mql5.com
Sebastian Lenk: My Broker extended the digits from 1 to 2 for DE30. Unfortunately at the second digit only 0 and 5 are allowed.
Valid Prices: 13080.00, 13080.05, 13080.10
Invalid Prices: 13080.01, 13080.02, 13080.03, 13080.04, 13080.06, ...
Until now I used NormalizeDouble(Price, Digits); in oder to get valid prices.
Unfortunately this is no more working. Are there any other methods available to round the price?
You must NOT use NormalizeDouble(). You must use the Tick-Size to correctly set the price values. This has been discussed on the forum many times, so do a search but the most common post you will see goes something like this ...
whroeder1:
Do NOT use NormalizeDouble, EVER. For ANY Reason. It's a kludge, don't use it. It's use is always wrong
- SL/TP (stops) need to be normalized to tick size (not Point.) (On 5Digit Broker Stops are only allowed to be placed on full pip values. How to find out in mql? - MQL4 and MetaTrader 4 - MQL4 programming forum) and abide by the limits Requirements and Limitations in Making Trades - Appendixes - MQL4 Tutorial and that requires understanding floating point equality Can price != price ? - MQL4 and MetaTrader 4 - MQL4 programming forum
- Open price for pending orders need to be adjusted. On Currencies, Point == TickSize, so you will get the same answer, but it won't work on Metals. So do it right: Trailing Bar Entry EA - MQL4 and MetaTrader 4 - MQL4 programming forum or Bid/Ask: (No Need) to use NormalizeDouble in OrderSend - MQL4 and MetaTrader 4 - MQL4 programming forum
- Lot size must also be adjusted to a multiple of LotStep and check against min and max. If that is not a power of 1/10 then NormalizeDouble is wrong. Do it right.
- Account Balance * percent/100 = RISK = OrderLots * (|OrderOpenPrice - OrderStopLoss| * DeltaPerLot + CommissionPerLot) (Note OOP-OSL includes the SPREAD, and DeltaPerLot is usually around $10/pip but it takes account of the exchange rates of the pair vs. your account currency.)
- Do NOT use TickValue by itself - DeltaPerLot and verify that MODE_TICKVALUE is returning a value in your deposit currency, as promised by the documentation, or whether it is returning a value in the instrument's base currency (EUR, in this case).
MODE_TICKVALUE is not reliable on non-fx instruments with many brokers.- You must normalize lots properly and check against min and max.
- You must also check FreeMargin to avoid stop out
In essence, make sure that your price quotes, are properly aligned to the Tick size (see following examples).
... double tickSize = SymbolInfoDouble( _Symbol, SYMBOL_TRADE_TICK_SIZE ); ... double normalised_price = round( price / tick_size ) * tick_size; ... // Or use a function double Round2Ticksize( double price ) { double tick_size = SymbolInfoDouble( _Symbol, SYMBOL_TRADE_TICK_SIZE ); return( round( price / tick_size ) * tick_size ); }
You may also benefit from reading this: https://www.mql5.com/en/forum/223705#comment_6279080
- 2017.12.31
- www.mql5.com
Dear All,
My Broker extended the digits from 1 to 2 for DE30. Unfortunately at the second digit only 0 and 5 are allowed.
Valid Prices: 13080.00, 13080.05, 13080.10
Invalid Prices: 13080.01, 13080.02, 13080.03, 13080.04, 13080.06, ...
Until now I used NormalizeDouble(Price, Digits); in oder to get valid prices.
Unfortunately this is no more working. Are there any other methods available to round the price?
BR Sebastian
The somewhat solid, but not elegant way:
MathRound(num * 20.) / 20.;
I'd probably go with @Enrique Dangeroux 's suggestion.
MathRound(num * 20.) / 20.;
- Don't hard code constants. Replace your 20. with 1/TickSize. Then your result is exactly the same as Fernando Carreiro's post.
- Write self-documenting code:
double round_nearest(double v, double to){ return to * MathRound(v / to); } double round_down( double v, double to){ return to * MathFloor(v / to); } double round_up( double v, double to){ return to * MathCeil( v / to); } double normalize_price(double p, double d=0.0){ double tickSize = MarketInfo(_Symbol, MODE_TICKSIZE); if(d > 0) return round_up(p, tickSize); if(d < 0) return round_down(p, tickSize); return round_nearest(p, tickSize); } double normalize_lots(double lots){ double lotStep = MarketInfo(_Symbol, MODE_LOTSTEP); return round_down(lots, lotStep); return lots; }
whroeder1:
Then your result is exactly the same as Fernando Carreiro's post.
My apologies to @Fernando Carreiro ! I totally missed the code part of your post. It was early morning, not enough coffee . . . .
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
Dear All,
My Broker extended the digits from 1 to 2 for DE30. Unfortunately at the second digit only 0 and 5 are allowed.
Valid Prices: 13080.00, 13080.05, 13080.10
Invalid Prices: 13080.01, 13080.02, 13080.03, 13080.04, 13080.06, ...
Until now I used NormalizeDouble(Price, Digits); in oder to get valid prices.
Unfortunately this is no more working. Are there any other methods available to round the price?
BR Sebastian