Need help to calculate Lot Size from a Fixed Value Risk, Stop Loss and Broker Commission

 

Hi all.

I need to calculate the lot size based on a fixed amount of the account base currency and a StopLoss. But I need to remove the amount charged by the commission on ECN brokers.

For EURUSD 5 Digit works fine... but  not for other pair like USDJPY

 

Then i do this:

extern double InvestMoney = 5.00;   // Max Money to Risk
extern double SL_PIPs = 2;   // Stop Loss In PIPs
extern double BrokerComm = 7;   // Broker Commission

void OnTick()
{
   // ... etc

   double MyLot = CalculateLotSize();
  

   // ... etc
}

double CalculateLotSize()
{

   double MyPoint = _Point;
   if( _Digits==3 || _Digits==5 ) MyPoint *=10; 

   double MaxLot=MarketInfo( _Symbol, MODE_MAXLOT );
   double MinLot=MarketInfo( _Symbol, MODE_MINLOT );
   double LotSize= MarketInfo( _Symbol,MODE_LOTSIZE) * MyPoint;
   double LotStep= MarketInfo( _Symbol, MODE_LOTSTEP );  
   
   // Computes the Lot size, removing the commission
   double lot = InvestMoney / ( LotSize * SL_PIPs + BrokerComm );
 
   if( lot > MaxLot ){ lot=MaxLot; }
   if( lot < MinLot ){ lot=MinLot; }
   int lotdigits = 2;

   if(LotStep==0.1){ lotdigits=1; }
   if(LotStep==0.01){ lotdigits=2; }
   if(LotStep==0.001){ lotdigits=3; }

   lot=MathFloor(lot*MathPow(10,lotdigits))/MathPow(10,lotdigits);

   return NormalizeDouble( lot, lotdigits );

}

 

EXAMPLE #1 ( Without Commission )

  • InvestMoney = 5.00 USD
  • SL_PIPs = 2 PIPs
  • BrokerComm = 0 USD
MyLot will result in 0.25 lots


If my order closes on StopLoss, i will lost: 

  • Trade lost: 0.25 lot x 2 PIPs x $ 10 USD = 5.00 USD 
  • Trade Commission: 0
  • Total lost: 5.00


EXAMPLE #2 ( With Broker Commission )

  • InvestMoney = 5.00 USD
  • SL_PIPs = 2 PIPs
  • BrokerComm = 7 USD

MyLot will result in 0.18 lots


If my order closes on StopLoss, i will lost:  

  • Trade lost: 0.18 lot x 2 PIPs x $ 10 USD = 3.60 USD 
  • Trade Commission: 0.18 lot x 7 usd = 1.26 USD
  • Total lost: 3.60 + 1.26 = 4.86

Here, if lot goes to 0.19 or more the Total Loss will be greater than $ 5,00... Then the result of 0.18 lots s fine!



As i say earlier, for EURUSD 5 Digit is working... and other USD pairs... but not for all, for example USDJPY 3 digit... results a value below tha 0.01 then is rounded to minimum of 0.01.

 

Can you help me to improve this function? 

 
  • 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, and DeltaPerLot is usually around $10/pip)
  • 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
 

Thanks WHRoeder... 

 

WHRoeder:
  • Account Balance * percent/100 = RISK = OrderLots * (|OrderOpenPrice - OrderStopLoss| * DeltaPerLot + CommissionPerLot) (Note OOP-OSL includes the SPREAD, and DeltaPerLot is usually around $10/pip)

I try with the following values on EURUSD and works fine

  • Risk = $ 5 USD 
  • Open Price =  1.12317
  • StopLoss =  1.12337
  • Tick Value = 1
  • Tick Size = 0.00001
  • DeltaPerLot = 1 / 0.00001 = 100000
  • Broker Commision: $ 7
  • Lot = 5 * ( |1.12317 - 1.12337| * 100000 + 7)  = 135

The Lot calculation gives me  a value of 135 lots, Can you please check if the formula is wrong ?

 

--- EDITED  ---

think i found it... I just change the  *  to  /  and the calculation gives me 0.18 lot.... And test the formula in a couple of pairs and works fine! Include USDJPY that with my old formula does not works.

 

Thank you for your help! 


Here my new Function... It's growing ;-D:

extern double LotFix=0.01; // If not Auto Managed, use fixed lot
extern double RiskAutoManaged=true;
extern double Risk=0.5; // 0.5%
extern double BrokerComm=7; // Broker Commission

double point;

int OnInit(){

   point = _Point;
   if( _Digits==3 || _Digits==5 ) point *=10;

   return(INIT_SUCCEEDED);
}

void OnTick()
{
   // To Compute a lot
   RefreshRates();
   double price=Ask;
   double SL = NormalizeDouble(price-StopLoss*point, _Digits);
   
   double lot=LotFix;
   if( RiskAutoManaged==true ){
      lot=MMComputeRisk(Risk, MathAbs(price-SL), BrokerComm);
   }

   MessageBox( "My lot is: ", lot);

   // Etc...
}
   

double MMComputeRisk(double RiskPercent, double sl, double comm)
{

   double MMBalance, MMRiskMoney;
   double MMMaxLot=MarketInfo( _Symbol, MODE_MAXLOT );
   double MMMinLot=MarketInfo( _Symbol, MODE_MINLOT );
   double MMLotStep= MarketInfo( _Symbol, MODE_LOTSTEP ); 
   double MMTickValue = MarketInfo( _Symbol, MODE_TICKVALUE);
   double MMTickSize = MarketInfo( _Symbol, MODE_TICKSIZE);
   
   int lotdigits=0;
   do
   {
      lotdigits++;
      MMLotStep*=10;
   }while(MMLotStep<1);
   
   MMBalance = MathMin(AccountBalance(), AccountEquity());
   MMRiskMoney=MMBalance*RiskPercent/100;
   double lot = MMRiskMoney / ( sl * ( MMTickValue / MMTickSize ) + comm );
   lot=NormalizeDouble( MathFloor(lot*MathPow(10,lotdigits))/MathPow(10,lotdigits), lotdigits );
   if( lot > MMMaxLot ){ lot=MMMaxLot; }
   if( lot < MMMinLot ){ lot=MMMinLot; }

   return NormalizeDouble( lot, lotdigits );
   
}
 

Hello... 

Test it in couple of assets in ICMarket Trie ECN account with Forex Majors, Forex Minors, Forex Exotics and Metals and works fine!

 

But, the calculation is not fine in CFD Indexes, i can put 20, 200 or 2000 PIPs of StopLoss but results only 1 lot calculated...

 

Hello again.

 

As i say, this code do not works for CFD indexes, mas for me it's fine because just use it in forex...

I need just more one tip...

 

I need to caculate a profit/loss in a amount of pips of an asset. How can i do this ?

 

I try to do someting like this:

double MMTickValue = MarketInfo( _Symbol, MODE_TICKVALUE);
double MMTickSize = MarketInfo( _Symbol, MODE_TICKSIZE);
double MyLot = 0.25; 
double TargetPips=2; 
double point = _Point;

if( _Digits==3 || _Digits==5 ) point *=10; 

// Compute my Profit/Loss based on PIPs i need
double result = MyLot * TargetPips * point * ( MMTickValue / MMTickSize );

Print("My Result: ", result);

 

It's that?! or i miss something?

 
Yes, except for the spread.
  • 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, and DeltaPerLot is usually around $10/pip)
  • 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
 
WHRoeder:
Yes, except for the spread.

Then it's fine... i just need to compute a minimum profit to close trade... based on this calculation and number of trades.. if the calculation is ok... for me it's done!

 

Thanks! 

 


Wemerson Guimaraes #:

Thanks WHRoeder... 

 

I try with the following values on EURUSD and works fine

  • Risk = $ 5 USD 
  • Open Price =  1.12317
  • StopLoss =  1.12337
  • Tick Value = 1
  • Tick Size = 0.00001
  • DeltaPerLot = 1 / 0.00001 = 100000
  • Broker Commision: $ 7
  • Lot = 5 * ( |1.12317 - 1.12337| * 100000 + 7)  = 135

The Lot calculation gives me  a value of 135 lots, Can you please check if the formula is wrong ?

 

--- EDITED  ---

think i found it... I just change the  *  to  /  and the calculation gives me 0.18 lot.... And test the formula in a couple of pairs and works fine! Include USDJPY that with my old formula does not works.

 

Thank you for your help! 


Here my new Function... It's growing ;-D:

Dear   Wemerson Guimaraes,

I need this indicator with the same functions, so Can you share this Indicator ?


Many thanks,

Hung Tran

Reason: