How do I round the lot size so it is evenly divisible by two?

 

Below is a simple test script that uses an allegedly correct routine to make sure the orderLotSize is evenly divisibly by 2. I think the routine does, indeed, always provide an even number that is divisible by 2.

The problem, as shown in this example, is that an input value of .50 is returned as .48 after the routine (the value is not wrong, but not .50 which _is_ evenly divisible by 2).

Is there a better routine to round numbers?

P.S. In a real trading situation, the initial proposed lot size might be 2% of margin resulting in 1.67. The routine does, indeed, change this to 1.66.

// aaaTEST rounding.mq4

int start()
{
//An alleged routine that (correctly) seems to make result divisible by 2
//However, it has one problem: in this example, it changes .50 to .48.
double orderLotSize = 0.50;
orderLotSize = orderLotSize - MathMod( orderLotSize, 2 * MarketInfo( Symbol(), MODE_LOTSTEP ) );
orderLotSize = NormalizeDouble(orderLotSize, 2);

Alert("orderLotSize=", orderLotSize);

return(0);
}

 
Hello,
Even lot size code sample:

int    start ()
{
double OrderLotSize = 0.51                                         ;
double OrderLotStep = MarketInfo   ( Symbol ()    , MODE_LOTSTEP ) ;
 
double StepsInput   = OrderLotSize / OrderLotStep                  ;
double StepsOutput  = MathFloor    ( StepsInput   / 2 ) * 2        ;
double EvenLotSize  = OrderLotStep * StepsOutput                   ;
 
Alert  ( "               "                                       ) ;
Alert  ( "EvenLotSize  = "         , EvenLotSize                 ) ;
Alert  ( "Output:        "                                       ) ;
Alert  ( "               "                                       ) ;
Alert  ( "StepsOutput  = "         , StepsOutput                 ) ;
Alert  ( "StepsInput   = "         , StepsInput                  ) ;
Alert  ( "Processing:    "                                       ) ;
Alert  ( "               "                                       ) ;
Alert  ( "OrderLotSize = "         , OrderLotSize                ) ;
Alert  ( "OrderLotStep = "         , OrderLotStep                ) ;
Alert  ( "Input:         "                                       ) ;
}
Best regards,
Ais.
 

If you are looking to have a value divisible by two which is also a multiple of LOTSTEP, then:


Force the original value to a multiple of LOTSTEP

Halve the result value,

Normailize the result,

Double the result;


???

orderLotSize = orderLotSize - MathMod( orderLotSize, MarketInfo( Symbol(), MODE_LOTSTEP ) );

orderLotSize = 2 * NormalizeDouble( orderLotSize / 2, 2 );

???



Hope this helps.

 
Ais wrote >>

Best regards,

First, thanks guys for your reply. Unfortunately, there are inconsistent answers with each routine. Using the test script attached below, I ran both

algorithms for some sample lot sizes. The results are often OK, and at times not acceptable when (1) the final lot size is increased, and (2) a perfectly even lot size is reduced by .02.

[I'm sorry for the info below: spaces and tabs don't seem to keep the columns separate.]

// Here are the test results:
//
//.........................Routine 1...........Routine 2
// Beginning...........Final..................Final
// Lot Size......... orderLotSize1.....orderLotSize2
//
// 0.40 0.40 0.40
// 0.41 0.40 0.40
// 0.42 0.42 0.42
// 0.43 0.42 0.42
// 0.44 0.44 0.44
// 0.45 0.44 _0.46_ increase in lot size
// 0.46 0.46 0.46
// 0.47 0.46 0.46
// 0.48 0.48 0.48
// 0.49 0.48 0.48
// 0.50 0.50 0.50
// 0.51 0.50 0.50
// 0.52 0.52 0.52
// 0.53 0.52 _0.54_ increase in lot size
// 0.54 0.54 0.54
// 0.55 0.54 _0.56_ increase in lot size )
// 0.56 0.56 0.56
// 0.57 0.56 0.56
// 0.58 _0.56_ 0.58 decrease in lot size (even though starting number was even)
// 0.59 0.58 0.58
// 0.60 0.60 0.60
// 0.61 0.60 0.60
// 0.62 0.62 0.62
// 0.63 0.63 0.63
// 0.64 0.64 0.64
// 0.65 0.64 _0.66_ increase in lot size
// 0.66 0.66 0.66
// 0.67 0.66 _0.68_ increase in lot size
// 0.68 0.68 0.68
// 0.69 0.68 0.68
// 0.70 0.70 0.70
// 0.71 0.70 0.70
// 0.72 0.72 0.72
// 0.73 0.73 0.73
// 0.74 0.74 0.74
// 0.75 0.74 0.74
// 0.76 0.76 0.76
// 0.77 0.76 _0.78_ increase in lot size

// 0.78 0.78 0.78

// 1.53 1.52 1.52
// 1.55 1.54 _1.56_ increase in lot size
// 1.58 1.58 1.58

 
Why so worried about divide by 2?
 
phy wrote >>
Why so worried about divide by 2?

A lot size which is divisible by 2 means 1/2 the profit can be taken early in the trade, with the remaining 1/2 left in the trade. For example, start with 1.76 lot size, take the profit on .88 lot size, and later take the money for .88 lot size.

 
Hello,
Lot size adjusting code sample:

//< afd.AdjustLotSize >
 
//< head>
 
double afd.AdjustLotSize             ( // input 2 / code  7 / output 1
                                       //
       double aad.InputLotSize       , // input 1 / 2
       int    aai.Fractions            // input 2 / 2
                                       //
                                     ) //
 
//</head>
 
{//<body>
 
double   ald.OrderLotStep    = MarketInfo       ( Symbol ()        , MODE_LOTSTEP  )                           ; //  1
double   ald.StepsInput      = aad.InputLotSize / ald.OrderLotStep                                             ; //  2
int      ali.StepsRounded    = MathRound        ( ald.StepsInput                   )                           ; //  3
int      ali.StepsOutput     = MathFloor        ( ali.StepsRounded / aai.Fractions ) * aai.Fractions           ; //  4
double   ald.AdjustedLotSize = ali.StepsOutput  * ald.OrderLotStep                                             ; //  5
                                                                                                                 //  6
Alert  ( "                      "                       ) ;
Alert  ( "ald.AdjustedLotSize = " , ald.AdjustedLotSize ) ;
Alert  ( "Output:               "                       ) ;
Alert  ( "                      "                       ) ;
Alert  ( "ali.StepsOutput     = " , ali.StepsOutput     ) ;
Alert  ( "ali.StepsRounded    = " , ali.StepsRounded    ) ;
Alert  ( "ald.StepsInput      = " , ald.StepsInput      ) ;
Alert  ( "Processing:           "                       ) ;
Alert  ( "                      "                       ) ;
Alert  ( "ald.OrderLotStep    = " , ald.OrderLotStep    ) ;
Alert  ( "aai.Fractions       = " , aai.Fractions       ) ;
Alert  ( "aad.InputLotSize    = " , aad.InputLotSize    ) ;
Alert  ( "Input:                "                       ) ;
 
return ( ald.AdjustedLotSize )                                                                                 ; //  7
 
}//</body>
 
//</afd.AdjustLotSize >
 
 
//< init >
int    init ()
{
double avd.InputLotSize    = 0.58                                                   ;
int    avi.Fractions       = 2                                                      ;
double avd.AdjustedLotSize = afd.AdjustLotSize ( avd.InputLotSize , avi.Fractions ) ;
}
//</init >
 
Best regards,
Ais.
 

Ok.

Calculate intial lot size that is 1/2 of what you want, and double it.

Later, you can close half.

 

I believe lotstep is always 0.1 or 0.01 so you can do

double lotstep = MarketInfo(Symbol(),MODE_LOTSTEP)*2

Then calculate the lot size the usual way using the new lotstep wll ensure it is divisable by 2

Of course you should test for the original size of LOTSTEP to be sure what it is

 
chaffinsjc:

Below is a simple test script that uses an allegedly correct routine to make sure the orderLotSize is evenly divisibly by 2. I think the routine does, indeed, always provide an even number that is divisible by 2.

double orderLotSize = 0.50;
orderLotSize = orderLotSize - MathMod( orderLotSize, 2 * MarketInfo( Symbol(), MODE_LOTSTEP ) );
orderLotSize = NormalizeDouble(orderLotSize, 2);

  1. double orderLotSize = 0.50,
           ls           = MarketInfo( Symbol(), MODE_LOTSTEP );
    orderLotSize = MathCeil(orderLotSize / (2 * LS) ) * ls;


  2. Not necessary see my code for partial close
  3. Never use NormalizeDouble, ever. It's a kludge Bid/Ask: (No Need) to use NormalizeDouble in OrderSend - MQL4 forum
Reason: