# How To Manage 0.5 or 0.05 Price Steps (Tick Value, Tick Size) in order to avoid Error 130

168

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

408

Sebastian Lenk:

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```
How to calculate lots using multiplier according to number of opened orders?
• 2017.09.01
• www.mql5.com
Hello guys. I'd like to place every consequitive order using multiplier. Now I've hardcoded my prefered lots using an array. I don't like it...
4306

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

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

MathRound fails for one particular number
• 2017.12.31
• www.mql5.com
Good evening! I am using to round a couple of doubles to two decimal places. Works, apart from one double: Any ideas...
1817

Sebastian Lenk:

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.

17945

Anthony Garot: The somewhat solid, but not elegant way:
`MathRound(num * 20.) / 20.;`
1. Don't hard code constants. Replace your 20. with 1/TickSize. Then your result is exactly the same as Fernando Carreiro's post.
2. 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;
}
```

1817

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 . . . .

4306

Anthony Garot: My apologies to @Fernando Carreiro ! I totally missed the code part of your post. It was early morning, not enough coffee . . . .

No worries! No need to apologise!
1869

Alternative (easy) option:

You can use the CDouble (wrapper) library for MQL4/5.

```CDouble open_price = 13080.007921837498;

double rounded_to_ticksize = open_price.AsRoundedTick();```

...or...

`double open_price = CDouble::RoundToTick(13080.007921837498);`