MM LotSize calculation for Balance Risk Percent & Stoploss

 

My initial balance is 1000 USD
Risk per trade 30%
Stoploss 2000 pips for USDJPY 122.622000

How do I calculate Lot Size?

 
  1. 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.
  2. Account Balance * percent = RISK = (OrderOpenPrice - OrderStopLoss)*DIR * OrderLots * DeltaPerlot (Note OOP-OSL includes the SPREAD)
  3. Do NOT use TickValue by itself - DeltaPerlot
  4. You must normalize lots properly and check against min and max.
  5. You must also check FreeMargin to avoid stop out
 
void LotsCalc()//int Magic,bool debug,double initial_deposit,double LotSize,double RiskPercent) 
{
  
  double current_balance = 0;
 
   int nOrders = 0;    datetime OCTs[];
    for(int iPos=(OrdersHistoryTotal()-1); iPos >= 0; iPos--) if (
        OrderSelect(iPos, SELECT_BY_POS, MODE_HISTORY)  // Only orders w/
    &&  OrderMagicNumber()  == Magic             // my magic number
    &&  OrderSymbol()       == Symbol()             // and my pair.
    &&  OrderType()         <= OP_SELL//Avoid cr/bal forum.mql4.com/32363#325360
    )
    {
     
     double True_Profit = OrderProfit()+OrderSwap()+OrderCommission();
     current_balance += True_Profit;
     if (debug) Print("True Profit="+True_Profit+";current_balance="+current_balance+";OrderProfit="+OrderProfit()+";OrderSwap()="+OrderSwap()+";OrderCommission()="+OrderCommission()+";OrderType()="+OrderType()+";OrderOpenPrice="+OrderOpenPrice()+";OrderClosePrice="+OrderClosePrice()+";OrderOpenTime()="+OrderOpenTime()+";OrderTicket()="+OrderTicket()+";OrderLots()="+OrderLots());
     // current_balance
         // double profit = (OrderClosePrice()-OrderOpenPrice())*OrderLots()*MarketInfo(OrderSymbol(),MODE_TICKVALUE)/Point;
   //if (debug) Print ("profit="+profit);
    }
    current_balance += initial_deposit;
    
   if (debug) Print(Symbol() +";AccountFreeMargin()="+AccountFreeMargin()+";initial_deposit="+initial_deposit+"; current_balance="+current_balance); 


   if(MarketInfo(Symbol(),MODE_MINLOT) == 0.1) int LotsDigit = 1;
   else if(MarketInfo(Symbol(),MODE_MINLOT) == 0.01) LotsDigit = 2;
   double MinLots = NormalizeDouble(MarketInfo(Symbol(),MODE_MINLOT),LotsDigit);
   double MaxLots = NormalizeDouble(MarketInfo(Symbol(),MODE_MAXLOT),LotsDigit);
   //double normalized_balance = NormalizeDouble(AccountFreeMargin(),2);
   current_balance=current_balance*0.95;
   double normalized_balance = NormalizeDouble(current_balance,2);
   double RiskDollars = (RiskPercent/100) *normalized_balance;
   RiskDollars = NormalizeDouble(RiskDollars,0);
   // slippage? spread?
   double RiskStopLoss = StopLoss*10 +Slippage*10+MarketInfo(Symbol(), MODE_SPREAD);
   
   double pip_value =  MarketInfo(Symbol(), MODE_TICKVALUE); // pip value in USD deposit currency
   Print (" RiskDollars="+ RiskDollars+";RiskStopLoss="+RiskStopLoss+";pip_value="+pip_value+";RSL*pipvalue="+(pip_value*RiskStopLoss));
   LotSize = NormalizeDouble( RiskDollars/(pip_value*RiskStopLoss),2) ;
   
   if(LotSize > MaxLots) LotSize = MaxLots;
   if(LotSize < MinLots) LotSize = MinLots; 
   
double ticksize = MarketInfo(Symbol(), MODE_TICKSIZE);
double tickvalue = MarketInfo(Symbol(), MODE_TICKVALUE);
int modespread=MarketInfo(Symbol(), MODE_SPREAD);

     /*
      Print(Symbol()+Period()+" Tick Value="+tickvalue);
      Print(Symbol()+Period()+" Tick Size="+ticksize);
      Print(Symbol()+Period()+" SPREAD="+modespread);
      */
    
   if (debug) Print ("tick value="+tickvalue+";ticksize="+ticksize+";spread="+modespread+";normalized_balance = NormalizeDouble(current_balance,2)"+"="+normalized_balance+";LotSize="+LotSize+";RiskDollars="+RiskDollars+";RiskStopLoss Pips="+RiskStopLoss); 
   
}
 

is this more or less correct way to do it?

One EA, 3 Currency pairs, GBPJPY + USDJPY + CHFJPY

for each I want to give 1000 USD balance

did I do mistakes? 

 

Also Two EAs, one chart GBPJPY, one account, 1st EA GBPJPY 3 Lots BUY, 2nd EA 2 lots SELL ... trouble 1 Lot BUY?

different magic numbers

MT4, cancels them out?

YES?

 

I don't understand the need to use tick size, if tick value gives my pair's USD equiv...
for example StopLoss = 2000 pips, and pip value is 0.81 then 1 lot Risk in USD is StopLoss * Pip_Value = 2000 * 0.81 = 1620 USD
in order to risk 30% from 1000 USD ( 300 USD ) we need to trade 

LOT_SIZE = 300 USD / 1620 USD =  0.18 Lots

 You say it is better to do like this?

pip_value = (MarketInfo(pair, MODE_TICKVALUE) / MarketInfo(pair, MODE_TICKSIZE) ) * Point ?
to get true pip value?
void LotsCalc()//int Magic,bool debug,double initial_deposit,double LotSize,double RiskPercent) 

{

  

  double current_balance = 0;

 

   int nOrders = 0;    datetime OCTs[];

    for(int iPos=(OrdersHistoryTotal()-1); iPos >= 0; iPos--) if (

        OrderSelect(iPos, SELECT_BY_POS, MODE_HISTORY)  // Only orders w/

    &&  OrderMagicNumber()  == Magic             // my magic number

    &&  OrderSymbol()       == Symbol()             // and my pair.

    &&  OrderType()         <= OP_SELL//Avoid cr/bal forum.mql4.com/32363#325360

    )

    {

     

     double True_Profit = OrderProfit()+OrderSwap()+OrderCommission();

     current_balance += True_Profit;

     if (debug) Print("True Profit="+True_Profit+";current_balance="+current_balance+";OrderProfit="+OrderProfit()+";OrderSwap()="+OrderSwap()+";OrderCommission()="+OrderCommission()+";OrderType()="+OrderType()+";OrderOpenPrice="+OrderOpenPrice()+";OrderClosePrice="+OrderClosePrice()+";OrderOpenTime()="+OrderOpenTime()+";OrderTicket()="+OrderTicket()+";OrderLots()="+OrderLots());

     // current_balance

         // double profit = (OrderClosePrice()-OrderOpenPrice())*OrderLots()*MarketInfo(OrderSymbol(),MODE_TICKVALUE)/Point;

   //if (debug) Print ("profit="+profit);

    }

    current_balance += initial_deposit;

    

   if (debug) Print(Symbol() +";AccountFreeMargin()="+AccountFreeMargin()+";initial_deposit="+initial_deposit+"; current_balance="+current_balance); 





   if(MarketInfo(Symbol(),MODE_MINLOT) == 0.1) int LotsDigit = 1;

   else if(MarketInfo(Symbol(),MODE_MINLOT) == 0.01) LotsDigit = 2;

   double MinLots = NormalizeDouble(MarketInfo(Symbol(),MODE_MINLOT),LotsDigit);

   double MaxLots = NormalizeDouble(MarketInfo(Symbol(),MODE_MAXLOT),LotsDigit);

   //double normalized_balance = NormalizeDouble(AccountFreeMargin(),2);

   current_balance=current_balance*0.95;

   double normalized_balance = NormalizeDouble(current_balance,2);

   double RiskDollars = (RiskPercent/100) *normalized_balance;

   RiskDollars = NormalizeDouble(RiskDollars,0);

   // slippage? spread?

   double RiskStopLoss = StopLoss*10 +Slippage*10+MarketInfo(Symbol(), MODE_SPREAD);

   

   double pip_value =  (MarketInfo(Symbol(), MODE_TICKVALUE)/ MarketInfo(Symbol(), MODE_TICKSIZE)) * Point; // true stable pip value in USD deposit currency

   Print (" RiskDollars="+ RiskDollars+";RiskStopLoss="+RiskStopLoss+";pip_value="+pip_value+";1 lot risk RSL*pipvalue="+(pip_value*RiskStopLoss));

   LotSize = NormalizeDouble( RiskDollars/(pip_value*RiskStopLoss),2) ;

   

   if(LotSize > MaxLots) LotSize = MaxLots;

   if(LotSize < MinLots) LotSize = MinLots; 

   

double ticksize = MarketInfo(Symbol(), MODE_TICKSIZE);

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

int modespread=MarketInfo(Symbol(), MODE_SPREAD);



     /*

      Print(Symbol()+Period()+" Tick Value="+tickvalue);

      Print(Symbol()+Period()+" Tick Size="+ticksize);

      Print(Symbol()+Period()+" SPREAD="+modespread);

      */

    

   if (debug) Print ("tick value="+tickvalue+";ticksize="+ticksize+";spread="+modespread+";normalized_balance = NormalizeDouble(current_balance,2)"+"="+normalized_balance+";LotSize="+LotSize+";RiskDollars="+RiskDollars+";RiskStopLoss Pips="+RiskStopLoss); 

   

}



//-------------------------------------------------------------------+


 


 
pip_value = (MarketInfo(pair, MODE_TICKVALUE) / MarketInfo(pair, MODE_TICKSIZE) ) * Point ?
is not a pip value, it's a point value. For pips you must adjust for 4/5 digit brokers.
 
ah, who cares they are all 3/5 digits now
 
zI1:
ah, who cares they are all 3/5 digits now
They are not
 

alpari is 3/5 digits

who is not? 

 
zI1: ah, who cares they are all 3/5 digits
Irrelevant:

There is Tick, PIP, and Point. They are all different in general. A tick is the smallest change of price. A Point is the least significant digit quoted. In currencies a pip is defined as 0.0001 (or for JPY 0.01)

On a 4 digit broker a point (0.0001) = pip (0.0001). [JPY 0.01 == 0.01] On a 5 digit broker a point (0.00001) = 1/10 pip (0.00010/10). Just because you quote an extra digit doesn't change the value of a pip. (0.0001 == 0.00010) EA's must adjust pips to points (for mq4.) In currencies a tick is a point. Price can change by least significant digit (1.23456 -> 1.23457)

In metals a Tick is still the smallest change but is larger than a point. If price can change from 123.25 to 123.50, you have a TickSize of 0.25 and a point of 0.01. Pip has no meaning.

This is why you don't use TickValue by itself. Only as a ratio with TickSize. See DeltaValuePerLot()

What is a TICK? - MQL4 forum
Reason: