Risk per trade code not working

 

Hi all,

New here and also new to coding/programming, so I apologise in advanced for any stupid questions. I am trying to code into my first EA the ability to only risk 2% per trade.

I have the following which basically defines how large the stop loss is in pips (for pair GBPUSD, 5 digits).

   HighOpenCandle = iHigh(NULL,0,1);
   LowOpenCandle = iLow(NULL,0,1);
   stopLossSize = NormalizeDouble(((HighOpenCandle - LowOpenCandle)*100000), 2);

I have the calculation as below;

double CalculateLotSize(double SL)
   {
   double LotSize;
   double nTickValue = MarketInfo(Symbol(), MODE_TICKVALUE);
   //---
      LotSize = (AccountBalance()*MaxRiskPerTrade)/(SL*nTickValue*1000);
      LotSize = MathRound(LotSize/MarketInfo(Symbol(),MODE_LOTSTEP))*MarketInfo(Symbol(),MODE_LOTSTEP);
      return NormalizeDouble(LotSize, 2);

In my OrderSend commands, they are as below;

            if (getTotalPendingOrders(OP_BUYSTOP) < 1) {
               oSend1 = OrderSend(Symbol(),OP_BUYSTOP,CalculateLotSize(stopLossSize),pricebuy,5,stopLossBuy,takeprofitbuy,"Pending Buy Trade Entered",12345,0,clrGreen);
            }
            if (getTotalPendingOrders(OP_SELLSTOP) < 1) {
               oSend2 = OrderSend(Symbol(),OP_SELLSTOP,CalculateLotSize(stopLossSize),pricesell,5,stopLossSell,takeprofitsell,"Pending Sell Trade Entered",12345,0,clrRed);

Now when I try to backsolve the EA test results back to what I should be getting from the above calculations, they do not tie back.

For example, a 150 pip stop loss of 1.3 lots. However the EA is showing me different values which don't tie back when the stop losses are hit. You can see in the below screenshot.

https://imgur.com/jMo0ldo

It seems to me like the LotSize is being calculated once and once only (hence the same SL value each time). What could I be doing wrong?

Thanks

EDIT*

Actually the SL changes very slightly when I scroll further down and look at other trades. See second image below;

https://imgur.com/r5SHu5i

Imgur
  • 2020.01.13
  • imgur.com
Post with 0 votes and 1 views.
 
How do I calculate lot size?
How do I calculate lot size?
  • 2008.09.22
  • www.mql5.com
Let's say my mini account has margin of $10,000, and I want to risk 2% on the next trade (that is, simply use $200 to buy of co...
 
Try with these :

enum lot_mode
{
lot_perc_balance_sl=0,//% With SL (risked)
lot_perc_balance_tp=1,//% With TP (to gain)
lot_static=2//Static 
};
enum lot_amount
{
lot_amo_balance=0,//Balance
lot_amo_equity=1,//Equity
lot_amo_fm=2//FreeMargin
};
input lot_mode LotMode=lot_perc_balance_sl;//Lot Mode : 
input lot_amount LotAmount=lot_amo_equity;//Lot Amount : 
input double LotOrRisk=2;//Lot or Risk%
input bool VolumeStepFix=false;//Volume Step Fix ? 
enum lotround
{
lotround_up=0,//Round Up (ceil)
lotround_dw=1,//Round Down (floor)
lotround_rn=2//Auto Round
};
input lotround VolumeStepMode=lotround_dw;//Volume Step Mode : 
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   
//---
   return(INIT_SUCCEEDED);
  }

double CalculateLotSize(string symbol,
                        lot_mode lmode,
                        lot_amount lamount,
                        double risk_lot,
                        int ticks_sl,
                        int ticks_tp,
                        double multiplier)
{
double returnio=risk_lot;
//basics 
double balance_on_open=AccountBalance();
if(lamount==lot_amo_equity) balance_on_open=AccountEquity();
if(lamount==lot_amo_fm) balance_on_open=AccountFreeMargin();
//value of one tick for one lot 
double votol=SymbolInfoDouble(symbol,SYMBOL_TRADE_TICK_VALUE);
if(lmode==lot_perc_balance_sl||lmode==lot_perc_balance_tp)
{
double amount_to_trade=(balance_on_open/100)*risk_lot;
double desired_value_per_tick=amount_to_trade;
if(lmode==lot_perc_balance_sl) desired_value_per_tick=amount_to_trade/((double)ticks_sl);
if(lmode==lot_perc_balance_tp) desired_value_per_tick=amount_to_trade/((double)ticks_tp);
double resulting_lot=desired_value_per_tick/votol;
returnio=resulting_lot;
}
if(VolumeStepFix) returnio=PassThroughLotStep(symbol,returnio,VolumeStepMode);
CheckLot(symbol,returnio);
return(returnio);
}



//CHECK LOT 
double CheckLot(string symbol,double lot)
{
double returnio=lot;
double max_lot=MarketInfo(symbol,MODE_MAXLOT);
double min_lot=MarketInfo(symbol,MODE_MINLOT);
int lot_digits=LotDigits(min_lot);
returnio=NormalizeDouble(returnio,lot_digits);
if(returnio<=min_lot) returnio=min_lot;
if(returnio>=max_lot) returnio=max_lot;
returnio=NormalizeDouble(returnio,lot_digits);
return(returnio);
}
//CHECK LOT ENDS HERE
double PassThroughLotStep(string symbol,double lot,lotround round_mode)
{
double newlot=lot;
   double minlot=MarketInfo(symbol,MODE_MINLOT);
   double maxlot=MarketInfo(symbol,MODE_MAXLOT);
   double lotstep=MarketInfo(symbol,MODE_LOTSTEP);
   //Print("Vol Step :"+lotstep);
   //without lotstep
   if(lotstep<=0)
   {
   if(newlot>maxlot) newlot=maxlot;
   if(newlot<minlot) newlot=minlot;
   }
   //with lotstep
   if(lotstep>=0)
   {
   double times=newlot/lotstep;
   int int_times=(int)MathFloor(times);
   //Print("times :"+times+" IntTimes :"+int_times);
   double remnant=times-((double)int_times);
   //Print("remnant :"+remnant);
   //if any remnants
     if(remnant>0)
     {
     //round 
       if(round_mode==lotround_rn)
       {
       remnant=MathRound(remnant);
       }
     //up
       if(round_mode==lotround_up)
       {
       remnant=MathCeil(remnant);
       }
     //down
       if(round_mode==lotround_dw)
       {
       remnant=MathFloor(remnant);
       }
     newlot=((double)int_times+remnant)*lotstep;
     }
   //if any remnants ends here 
   if(newlot>maxlot) newlot=maxlot;
   if(newlot<minlot) newlot=minlot;   
   }
return(newlot);
}

//Find Lot Digits 
int LotDigits(double lot)
{
int returnio=0;
double digitos=0;
double transfer=lot;
while(transfer<1)
{
digitos++;
transfer=transfer*10;
} 
returnio=(int)digitos;
//Print("Lot ("+lot+") Digits "+digitos+" Returnio "+returnio);
return(returnio);
}
*edit : if these are called during onInit inside an indicator after a platform restart on an already open chart with the indicator attached ,they will not result in anything as MarketInfo and SymbolInfo will not have acquired data yet*