Comprehensive lot size calculation function for mql4 - page 2

 
strontiumDog:

Thirteen, I put in your fractional lot size function and now my functions are coming out as (eg) 337.01 instead of 0.337.  Can you tell me why this might be please?
Not sure where in your code this is happening, as I am still trying to wrap my mind around MQL4 programming.  What programming knowledge I have is from Java, not C++, but judging by this post, your decimal place got skewed by 3 places (1 thousand multiplied in there somewhere, somehow).  The point that this miscalculation is not popping out to me from your code.
 
strontiumDog:

Thirteen, thanks for your input.


I varied my calculation due to http://www.babypips.com/school/undergraduate/senior-year/position-sizing/calculating-position-sizes.html which suggests different calculations based on different scenarios. I've been hacking around with mql4 for a few months now, but it sounds from your post that there is a way to get round these differences.  Surely having different ways of calculating lot size mentioned on the above URL, I need to represent this in code? 

Good point about rounding down - I should be doing that.  Also good point about maxlot, which I need to change.  I also see in your code about the SL calc as an amount rather than a number of pips.  Cheers


What do you think about WHRoeder's modification of your code in his most recent post?  That's quite a significant difference.

strontiumDog, how did your code work out? I'm struggling with similar code and have been surprised how little discussion there is on the correct coding of this. The position size calculator code out there don't take into account the base currency and also how spread affects R/R and lot size (in low time frames).

Can you share your finished code? My code has got too knotted, so I'm going to start with yours again!

 
pt007:

strontiumDog, how did your code work out? I'm struggling with similar code and have been surprised how little discussion there is on the correct coding of this. The position size calculator code out there don't take into account the base currency and also how spread affects R/R and lot size (in low time frames).

Can you share your finished code? My code has got too knotted, so I'm going to start with yours again!



I just worked out that...

   double UnitCost = MarketInfo(Symbol(), MODE_TICKVALUE);

is the tick value in the deposit currency. So that's how we don't need to do the extra base currency conversion. I simply do all the calculations in the deposit currency!

 

@pt007 and for anyone else interested, I had worked out the following code.  I reviewed the functionality today and appears to match with the babypips calculator output: Position Size Calculator: Free Online Forex Position Sizing Calculator

I've tested this on a GBP denominated account, on GBPUSD, AUDUSD and USDJPY in order to check GBP base, GBP neither Base nor Counter, and GBP neither Base nor Counter, and with JPY pairs, and all work.  YMMV:

//+------------------------------------------------------------------+
//| Return lotsize as a double                                                                           |
//+------------------------------------------------------------------+
//
double afxReturnLots(double _risk, double sl, double price) {
    // Set up
    //
    double minlot    = MarketInfo(Symbol(), MODE_MINLOT);
    double maxlot    = MarketInfo(Symbol(), MODE_MAXLOT);
    double tickVal   = MarketInfo(Symbol(), MODE_TICKVALUE);
       
    if(Digits == 3 || Digits == 5) {
        sl *= 10;
    }
    
    // Return position size
    //
    double equ = AccountInfoDouble(ACCOUNT_EQUITY);
    _risk = _risk / 100;
    double numerator   = equ * _risk;
    double denominator = sl  * tickVal;

        

    Print("afxLotSizeCalc: (equ * _risk) / (sl * tickVal): ", equ, ", ", _risk, ", ", sl, ", ", tickVal, " = ",  numerator / denominator);

    if(numerator <= 0 || denominator <= 0) {
        // your choice of error handling
        return(1);
    } else
    if(numerator / denominator <= 0) {
        // your choice of error handling
        return(1);
    } else {
        double result = (numerator / denominator);
        if(result < minlot) {
            result = minlot;
        } else if(result > maxlot) {
            result = maxlot;
        }
        return(result);
    }
}

I am aware of some chat about MODE_TICKVALUE and MODE_TICKSIZE in order to handle a rare edge case.  I do not use this calculation in a robot, but a semi-automated platform where I click a button and thus immediately get to see the SL line and hover to check it is right.  It's been right every time for 18 months across 14 Majors and Crosses, so it's a good place to start no matter what caveats, edge cases or rarities moderators may raise.

M

Position Size Calculator: Free Online Forex Position Sizing Calculator
  • www.babypips.com
BabyPips.com is a free, funny, and easy-to-understa nd guide for teaching beginners how to trade in the foreign exchange market.
 
strontiumDog:

@pt007 and for anyone else interested, I had worked out the following code.  I reviewed the functionality today and appears to match with the babypips calculator output: Position Size Calculator: Free Online Forex Position Sizing Calculator

I've tested this on a GBP denominated account, on GBPUSD, AUDUSD and USDJPY in order to check GBP base, GBP neither Base nor Counter, and GBP neither Base nor Counter, and with JPY pairs, and all work.  YMMV:

//+------------------------------------------------------------------+
//| Return lotsize as a double                                                                           |
//+------------------------------------------------------------------+
//
double afxReturnLots(double _risk, double sl, double price) {
    // Set up
    //
    double minlot    = MarketInfo(Symbol(), MODE_MINLOT);
    double maxlot    = MarketInfo(Symbol(), MODE_MAXLOT);
    double tickVal   = MarketInfo(Symbol(), MODE_TICKVALUE);
       
    if(Digits == 3 || Digits == 5) {
        sl *= 10;
    }
    
    // Return position size
    //
    double equ = AccountInfoDouble(ACCOUNT_EQUITY);
    _risk = _risk / 100;
    double numerator   = equ * _risk;
    double denominator = sl  * tickVal;

        

    Print("afxLotSizeCalc: (equ * _risk) / (sl * tickVal): ", equ, ", ", _risk, ", ", sl, ", ", tickVal, " = ",  numerator / denominator);

    if(numerator <= 0 || denominator <= 0) {
        // your choice of error handling
        return(1);
    } else
    if(numerator / denominator <= 0) {
        // your choice of error handling
        return(1);
    } else {
        double result = (numerator / denominator);
        if(result < minlot) {
            result = minlot;
        } else if(result > maxlot) {
            result = maxlot;
        }
        return(result);
    }
}

I am aware of some chat about MODE_TICKVALUE and MODE_TICKSIZE in order to handle a rare edge case.  I do not use this calculation in a robot, but a semi-automated platform where I click a button and thus immediately get to see the SL line and hover to check it is right.  It's been right every time for 18 months across 14 Majors and Crosses, so it's a good place to start no matter what caveats, edge cases or rarities moderators may raise.

M

double price is not used in the function!?
Reason: