MQL4 - automated forex trading   /  

Forum

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

Back to topics list To post a new topic, please log in or register

avatar
50
chaffinsjc 2008.10.30 00:42 

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);
}

article

Registration Is Closed!

Everybody could apply for participation in the Automated Trading Championship 2007 within 3 months. 2011 people have been registered. 731 Expert Advisors have already been checked and are ready to start the contest.


avatar
2980
Ais 2008.10.31 01:57 
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.

avatar
18
wabbit 2008.10.31 02:14 

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.


avatar
50
chaffinsjc 2008.10.31 21:11 
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

Attached files:
  aaaTEST_even_lot_size.mq4 (3.48 KB)

avatar
2462
phy 2008.10.31 21:16 
Why so worried about divide by 2?

avatar
50
chaffinsjc 2008.10.31 21:27 
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.


avatar
2980
Ais 2008.11.01 02:02 
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.

avatar
2462
phy 2008.11.01 08:36 

Ok.

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

Later, you can close half.

Back to topics list  

To add comments, please log in or register