Download MetaTrader 5

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

To add comments, please log in or register
Sebastian Lenk
208
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

Enrique Dangeroux
276
Enrique Dangeroux  
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

https://www.mql5.com/en/forum/214894#comment_5697033

How to calculate lots using multiplier according to number of opened orders?
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...
Fernando Carreiro
3835
Fernando Carreiro  

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
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...
Anthony Garot
329
Anthony Garot  
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.

whroeder1
16755
whroeder1  
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;
    }
    


Anthony Garot
329
Anthony Garot  

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


Fernando Carreiro
3835
Fernando Carreiro  
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!
nicholishen
1344
nicholishen  

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);
To add comments, please log in or register