Calculating Maximum Lots

 

I have written an indicator to calculate your lot size and maximum lot size based of percent of account you are risking and stoploss distance.

 

 It works most of the time on most pairs. But, every so often I get an insufficient funds error even though I am using the calculated lot size based on risk and SL which is less than my calculated maximum lot size. Could someone please look at my code and tell me what is wrong?

 

Kind Regards,

Tom 

 

//+------------------------------------------------------------------+
//|                                                    Lots_Size.mq4 |
//|                                     Copyright 2015, Tom Parimore |
//|                                              tparimore@yahoo.com |
//+------------------------------------------------------------------+
#property copyright "Tom Parimore"
#property link      "tparimore@yahoo.com"

// Last Updated  9/28/15  9:00 PM


   extern double Stop_Loss    = 10.0;  // pips
   extern double Percent_Risk =  3.3;
   extern bool   Show_Risk    =  true;
   extern string  xxxxxxxxxxxx  = "**************************************************************";
   extern int Corner = 1;
   extern int XDISTANCE1 = 25;
   extern int YDISTANCE  = 85;
   

#property indicator_chart_window
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  { 
    return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
    ObjectDelete("LotTitle");
    ObjectDelete("LotInput");
    ObjectDelete("LotMax");
    ObjectDelete("LotRisk");
    
    return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {                
    double DPPPL = MarketInfo(Symbol(), MODE_TICKVALUE)*10;    // Dollars Per Pip Per Lots (DPPPL)
    
    
    string Text[4];                     // Declaring a string array
    color  Color[2];                    // Declaring an array of colors      
                     
    Color[0]= Yellow;                   // Object color ..
    Color[1]= Gray;


    ObjectCreate("LotTitle", OBJ_LABEL, 0, 0, 0);                // Creating obj.
    ObjectSet("LotTitle", OBJPROP_CORNER, Corner);               // Reference corner
    ObjectSet("LotTitle", OBJPROP_XDISTANCE, XDISTANCE1);        // X coordinate
    ObjectSet("LotTitle", OBJPROP_YDISTANCE, YDISTANCE);         // Y coordinate

    ObjectCreate("LotInput", OBJ_LABEL, 0, 0, 0);              // Creating obj.
    ObjectSet("LotInput", OBJPROP_CORNER, Corner);             // Reference corner
    ObjectSet("LotInput", OBJPROP_XDISTANCE, XDISTANCE1);      // X coordinate
    ObjectSet("LotInput", OBJPROP_YDISTANCE, YDISTANCE+20);    // Y coordinate
   
    ObjectCreate("LotMax", OBJ_LABEL, 0, 0, 0);                 // Creating obj.
    ObjectSet("LotMax", OBJPROP_CORNER, Corner);                // Reference corner
    ObjectSet("LotMax", OBJPROP_XDISTANCE, XDISTANCE1);         // X coordinate
    ObjectSet("LotMax", OBJPROP_YDISTANCE, YDISTANCE+40);       // Y coordinate
    
    ObjectCreate("LotRisk", OBJ_LABEL, 0, 0, 0);             // Creating obj.
    ObjectSet("LotRisk", OBJPROP_CORNER, Corner);            // Reference corner
    ObjectSet("LotRisk", OBJPROP_XDISTANCE, XDISTANCE1);     // X coordinate
    ObjectSet("LotRisk", OBJPROP_YDISTANCE, YDISTANCE+60);   // Y coordinate
                
    
    double AFM  = AccountFreeMargin();
    double MRPL = MarketInfo(Symbol(),MODE_MARGINREQUIRED);  // Margin Requirement Per $100k (1 Lot)
    
    double DRSK = AFM * Percent_Risk / 100;   // Dollar Risked
    if (MRPL==0)return(0);
    double MAXL = floor((AFM - DRSK)/MRPL*100)/100; // Max Lots with Dollar Risk
    double MAXDPP = MAXL * DPPPL;    // Dollar per pip with Max Lots
    if (MAXDPP==0)return(0);
    double MAXSL  = DRSK / MAXDPP;   // Stop Loss with Max Lots (Trade will margin out at MAXSL)
    if (DPPPL==0)return(0);
    double Lots = floor(DRSK / (DPPPL * Stop_Loss)*100)/100;
    double DPP  = Lots * DPPPL;
    
  
      
    
    Text[0]=  "Lots    SL    $/PIP";
    Text[1] = "Input:   " +  DoubleToStr(Lots,2) + "   " + DoubleToStr(Stop_Loss,1) + "   $" + DoubleToStr( DPP,2);
    Text[2] = "Max:    " +   DoubleToStr( MAXL,2) + "   " +  DoubleToStr( MAXSL,1)  + "   $"  + DoubleToStr( MAXDPP,2);
    if(Show_Risk) Text[3] = "Risk:    " +  DoubleToStr(Percent_Risk,1)  + "%       $" + DoubleToStr( DRSK,2);
    else Text[3] = ""; 

             
    ObjectSetText("LotTitle",     Text[0],10,"Arial",Color[0]);
    if(Lots <= MAXL ) ObjectSetText("LotInput",   Text[1],10,"Arial",Color[0]);
    else              ObjectSetText("LotInput",   Text[1],10,"Arial",Color[1]);
    ObjectSetText("LotMax",      Text[2],10,"Arial",Color[0]);
    ObjectSetText("LotRisk",  Text[3],10,"Arial",Color[0]);
    

    
   
   return(0);
  }
//+------------------------------------------------------------------+
 
I know there is someone who can help me. I have struggled with this for a year.  My maximum lot size calculation is obviously wrong, but I can't figure it out. Please help. Thanks again. ---Tom
 

WHRoeder  wrote    "marginFree = AccountFreeMargin()*0.95, // Allow some slack"   (https://forum.mql4.com/35056)

maybe this is what I need to do, allow some slack?

 

I thought about using a "While" loop to calculate the MAX LOT SIZE using  AccountFreeMarginCheck(Symbol(),OP_BUY,Lots). However, my broker/journal  says "FreeMarginCheck function cannot be called from a Custom Indicator".

 

Thanks for looking,

Tom 

 
tparimore: "FreeMarginCheck function cannot be called from a Custom Indicator".
  1. You are taking a percent of free margin.
    • You place the stop where it needs to be - where the reason for the trade is no longer valid. E.g. trading a support bounce the stop goes below the support.
    • Account Balance * percent/100 = RISK = OrderLots * (|OrderOpenPrice - OrderStopLoss| * DeltaPerlot + CommissionPerLot) (Note OOP-OSL includes the SPREAD)
    • Do NOT use TickValue by itself - DeltaPerlot
    • You must normalize lots properly and check against min and max.
    • You must also check FreeMargin to avoid stop out

  2. Indicators can not trade so I'm not surprised the function can't be called.
  3. See also my GUI at Indicators: Money Manager Graphic Tool - MQL5.community traders' Forum - Page 5 It's a graphic EA, so you can put the SL where it needs to be. I will be adding the free margin checks to it soon, so book mark the link.
  4. Please use the link button (control-K) Use the link button See the difference: https://www.mql5.com/en/forum/128506
  5. Do NOT use NormalizeDouble, EVER. For ANY Reason. It's a kludge, don't use it. It's use is always wrong
 
Thank you WHRoeder.
Reason: