Can't get the grasp on position sizing

 
Hello,

I suspect I'm getting the wrong results from my code when calculating position sizing.

What I want to do is, calculate the number of lots I need to open my order of. They are dependent on the stop loss placement, and the money I would like to lose if that stop loss value is achieved.

My main suspect is that I'm missing something regarding the leverage, but I'm not sure.

This is my current formula (C++ code):


double stoplossDiff = fabs(price - stoploss); // fabs is absolute value
double tvts = tickValue / tickSize;
double lots = moneyToRisk / (stoplossDiff * tvts);

It seems to be working fine for forex pairs, but when I try with Silver with a risk of 200$, I get an order size of 3.58 lots, which starts in a position of -800$. Of course, if the SL was hit, the loss would be even bigger.

These are the values I get when debugging:

lots = 3.58
stoplossDiff = 0.011520
tvts = 4780.93 - (tick value: 4.788093, tick size: 0.001)


Any help would be appreciated.

Best regards.

 
    • 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 but it takes account of the exchange rates of the pair vs. your account currency.)
    • 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
  1. 4.78809/0.001 is 4788.09 not 4780.9 (typo or ?)
  2. stoplossDiff therefor represents 551.578 (in account currency)/per lot, and 3.58 lots means a risk of 1974.65 (in account currency.)
  3. Either your risk isn't calculated correctly (you didn't show and we can't guess.) Or the TV/TS is wrong from the broker (you didn't specify a pair and we can't guess.)
 
whroeder1:
    • 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 but it takes account of the exchange rates of the pair vs. your account currency.)
    • 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
  1. 4.78809/0.001 is 4788.09 not 4780.9 (typo or ?)
  2. stoplossDiff therefor represents 551.578 (in account currency)/per lot, and 3.58 lots means a risk of 1974.65 (in account currency.)
  3. Either your risk isn't calculated correctly (you didn't show and we can't guess.) Or the TV/TS is wrong from the broker (you didn't specify a pair and we can't guess.)

You made an error :

stoplossDiff * tvts is 4788.09 * 0.011520 = 55.1578

so 3.58 is 197.468 USD, which is probably correct with the rounding.

 
Guillermo:
Hello,

I suspect I'm getting the wrong results from my code when calculating position sizing.

What I want to do is, calculate the number of lots I need to open my order of. They are dependent on the stop loss placement, and the money I would like to lose if that stop loss value is achieved.

My main suspect is that I'm missing something regarding the leverage, but I'm not sure.

This is my current formula (C++ code):


double stoplossDiff = fabs(price - stoploss); // fabs is absolute value
double tvts = tickValue / tickSize;
double lots = moneyToRisk / (stoplossDiff * tvts);

It seems to be working fine for forex pairs, but when I try with Silver with a risk of 200$, I get an order size of 3.58 lots, which starts in a position of -800$. Of course, if the SL was hit, the loss would be even bigger.

These are the values I get when debugging:

lots = 3.58
stoplossDiff = 0.011520
tvts = 4780.93 - (tick value: 4.788093, tick size: 0.001)


Any help would be appreciated.

Best regards.

Nothing to do with leverage.

All the calculation seems correct (except the typo ? reported by WHRoeder).

When you open a position you have to take into account the spread, I have currently for XAGUSD (silver) a spread of 0.035 (Alpari). That's 3 times your stoploss.

Your stoploss is too tight (incorrectly calculated ?)

 
Thanks for the reply. I have made this little test script in order to debug what might be wrong.

void OnStart() {
   double risk_percent = 0.2;
  
   double risk = AccountBalance() * risk_percent / 100;
  
   double price = Ask; // Assume BUY order
   double stop_loss = Ask - 0.015;
  
   double tickValue = MarketInfo(Symbol(), MODE_TICKVALUE);
   double tickSize = MarketInfo(Symbol(), MODE_TICKSIZE);
  
   double dpl = tickValue / tickSize; // delta per lot
   double sl_diff = MathAbs(price - stop_loss);
  
   double lots = risk / (sl_diff * dpl);
  
   PrintFormat("Pair %s | Ask %f | risk %f | dpl %f | sl_diff %f | lots %f", Symbol(), Ask, risk, dpl, sl_diff, lots);

}

I dragged it into SILVER chart (XM Demo Account, account currency is EUR), and this is what I got:

lots_calc SILVER,M1: Pair SILVER | Ask 16.106000 | risk 193.243580 | dpl 4782.309282 | sl_diff 0.015000 | lots 2.693867

Then, I immediately opened a buy order of 2.69 lots and the loss of it was already on around -560EUR.

I am not taking commission into account, but I don't think that is the problem. Do you have any clue from this point?

Thank you,

Best regards.

EDIT:


Alain Verleyen:

Nothing to do with leverage.

All the calculation seems correct (except the typo ? reported by WHRoeder).

When you open a position you have to take into account the spread, I have currently for XAGUSD (silver) a spread of 0.035 (Alpari). That's 3 times your stoploss.

Your stoploss is too tight (incorrectly calculated ?)


Oops, I saw your answer after posting this. That makes sense, perhaps that's what I'm missing... I will think about it for a bit and come back later, since it will take me a while.

Best regards.
Files:
lots_calc.mq4  1 kb
 
Alain Verleyen: You made an error ... so 3.58 is 197.468 USD, which is probably correct with the rounding.
dN e e d   m o r e   c o f f e e
Guillermo:
   double price = Ask; // Assume BUY order
   double stop_loss = Ask - 0.015;
You buy at the Ask and sell at the Bid. The size of your SL is 0.015 (and includes the spread.) Bid - .015 is a SL of 0.015 (excluding the spread.)
 
whroeder1:
d
You buy at the Ask and sell at the Bid. The size of your SL is 0.015 (and includes the spread.) Bid - .015 is a SL of 0.015 (excluding the spread.)
So, it makes sense to make sure the following holds true, right?

BUY ORDER
  • TP must be set to a value higher than the Ask value at the time of opening.
  • SL must be set to a value lower than the Bid value at the time of opening.

SEL ORDER

  • TP must be set to a value lower than the Bid value at the time of opening.
  • SL must be set to a value higher than the Ask value at the time of opening.

I think I'm discovering some (somehow unrelated, somehow related) flaws in my EA due to this.

Thank you for your help.

Best regards.

 

Guillermo: SL must be set to a value lower than the Bid value at the time of opening.

Not just lower, but at least MODE_STOPLEVEL points lower. Requirements and Limitations in Making Trades - Appendixes - MQL4 Tutorial
 
Guillermo:
So, it makes sense to make sure the following holds true, right?

No. Should be :

BUY ORDER

  • TP must be set to a value higher than the Bid Ask value at the time of opening.
  • SL must be set to a value lower than the Bid value at the time of opening.

SEL ORDER

  • TP must be set to a value lower than the Ask Bid value at the time of opening.
  • SL must be set to a value higher than the Ask value at the time of opening.

And add to this the remark of WHRoeder about Stop Levels.

Reason: