Wrong Lotsize in Order Execution

 

Hello, I am learning to code and came across these 2 functions that calculate the optimal lot size for the order. I tried both of them however, they are both giving me a bigger than supposed lot size sometimes (e.g. returns a 1.5 lot size for a $1000 account) so it's causing an error 134 all the time. My risk percentage is always fixed to 2% for now for this strategy.

double ATR9 = iATR(NULL,0,9,0);
int Magic = 3333;

//---------BUY ORDER------------------------
int executeBuy()
{
   double entry = Ask;
   entry = NormalizeDouble(entry,_Digits);
   
   int shift = iLowest(NULL,0,MODE_LOW,5,1);
   double LowInLastFive = iLow(NULL,0,shift);
   
   double SL = (LowInLastFive - ATR9);
   SL = NormalizeDouble(SL,_Digits);
   double SLpips = (entry - SL) / GetPipValue();
   SLpips = NormalizeDouble(SLpips,_Digits);
   
   double TP = entry + SLpips * 1.5 * GetPipValue();
   TP = NormalizeDouble(TP,_Digits);
   
      return OrderSend(NULL,OP_BUY,CalculateLotSize(SLpips),entry,0,SL,TP,NULL,Magic,0,clrGreen);
}
   


//-----SELL ORDER-------------------------------
int executeSell()
{
   double entry = Bid;
   entry = NormalizeDouble(entry,_Digits);
   
   int shift = iHighest(NULL,0,MODE_HIGH,5,1);
   double HighInLastFive = iHigh(NULL,0,shift);
   
   double SL = (HighInLastFive + ATR9);
   SL = NormalizeDouble(SL,_Digits);
   double SLpips = (SL - entry)/ GetPipValue();
   SLpips = NormalizeDouble(SLpips,_Digits);
   
   double TP = entry - SLpips *1.5 * GetPipValue();
   TP = NormalizeDouble(TP,_Digits);
   
         
      return OrderSend(NULL,OP_SELL,CalculateLotSize(SLpips),entry,0,SL,TP,NULL,Magic,0,clrRed);

}



double GetPipValue()
{
   if(_Digits >=4)
   {
      return 0.0001;
   }
   else
   {
      return 0.01;
   }
}



//-----LOT SIZE FUNCTION 1------------------------------------------

double CalculateLotSize(double SLinPips)
{
   double MaxRiskPerTrade = 2;
   double LotSize = 0;
   
   double nTickValue = MarketInfo(Symbol(), MODE_TICKVALUE);
   
   if ((Digits == 3) || (Digits == 5)){
      nTickValue = nTickValue * 10;
   }
   
   LotSize = (AccountBalance() * MaxRiskPerTrade / 100) / (SLinPips * nTickValue);
   LotSize = MathRound(LotSize / MarketInfo(Symbol(), MODE_LOTSTEP)) * MarketInfo(Symbol(), MODE_LOTSTEP);
   
   return LotSize;
}


//-----LOT SIZE FUNCTION 2------------------------------------------------------------------
double OptimalLotSize(double RiskPrc,double SLpips)
     {
     double accBal = AccountBalance();
     Print("Account Balance: " + accBal);
     
     double LotSize = MarketInfo(NULL,MODE_LOTSIZE);
     Print("Lot Size: " + LotSize);
     
     double TickValue = MarketInfo(NULL,MODE_TICKVALUE);
     
     if(Digits <= 3)
     {
      TickValue = TickValue /100;
     }
     Print("TickValue: " + TickValue);
     
     double LossInDollar = accBal * RiskPrc;
     Print("Loss in Dollar: " + LossInDollar);
     
     double LossInQuoteCurrency = LossInDollar / TickValue;
     Print("Loss in Quote Currency: " + LossInQuoteCurrency);
     
     double optimalLotSize = NormalizeDouble(LossInQuoteCurrency /(SLpips * GetPipValue())/LotSize,2);
     
     return optimalLotSize;
     }
      
    
     //VERSION TWO BASED ON Risk Percentage
     double OptimalLotSize(double RiskPrc, double entry, double SL)
     {
      double SLpips = (entry - SL) / GetPipValue();
      return OptimalLotSize(RiskPrc,SLpips);
     }

Thanks in advance!

 
The fact that you set risk=2% does not necessarily mean the lot size is small. Sometimes the stop loss is so close that smallest choice of risk can lead to large lots(that are not allowed on your account).
 
Yashar Seyyedin #:
The fact that you set risk=2% does not necessarily mean the lot size is small. Sometimes the stop loss is so close that smallest choice of risk can lead to large lots(that are not allowed on your account).

thanks for your reply. but my point is i think there is something wrong with my code in producing lot size and i need help with that. the code is supposed to give me a lot size based on risk percentage AND stop loss, but it calculates a wrong lot size hence failure in order execution for me. Mentioning my risk being fixed at 2% just means that the number can be hard coded for this part and I am seeking if there is a better solution.

 

Hi

You should use real value of tick:

MarketInfo(Symbol(), MODE_TICKVALUE)/(MarketInfo(Symbol(), MODE_TICKSIZE)

not only tick_value – hence you have a a proper divider. And you should also divide by decimal pip value (not simply multiply by 10).

Best Regards