- 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 = RISK = (OrderOpenPrice - OrderStopLoss)*DIR * OrderLots * DeltaPerlot (Note OOP-OSL includes the SPREAD)
- Do NOT use TickValue by itself - DeltaPerlot
- You must also check FreeMargin to avoid stop out
. . . my question is: is this code (a) correct as far as you're concerned as regards the lot size calculations listed, and (b) the most efficient way of doing it to your mind? . . .
My answer is: no and no.
Why did you vary your lot calculation (replicated below for illustration) based on whether the account currency was part of the currency pair?
... if(crossCurr == AccountCurrency()) { lots = (riskCapital / stopLoss) / tickValue; Print("Calculated lots (A/C currency = Quote currency): ", lots); } else if(baseCurr == AccountCurrency()) { // lots = ((Ask * riskCapital) / stopLoss) / tickValue; Print("Calculated lots (A/C currency = Base currency): ", lots); } else if(crossCurr != AccountCurrency() && baseCurr != AccountCurrency()) { lots = riskCapital / (stopLoss * tickValue); Print("Calculated lots (A/C currency neither Base nor Quote currency): ", lots); } ...
If RiskAmount, StoplossValue, and PointValue (i.e., a ratio of tickvalue and ticksize) are all denominated in deposit currency, why the need to determine if the account currency is part of the currency pair? I don't believe you need to do this.
bearing in mind stopLoss is an integer in (adjusted) pips
I'm not sure what you mean by "adjusted", but stoploss in this calculation (i.e., lotsize = RiskAmount / StoplossValue) should be a value in deposit currency, not a size in pips or points.
lots = MathRound(lots/lotStep) * lotStep;
In the above code snippet, what will happen when you round up? The answer is that you will risk more than you defined in your riskCapital. I believe the better course is to always round down (using MathFloor()).
if(lots < minLot) {
lots = minLot;
}
What about maxlot? While most of us will probably never reach our brokers' defined maxlot (mine is 50 standard lots and I'm still only trading at <=1 standard lot), it is better to check the calculated lotsize against maxlot just to make sure.
The following is the fixed fractional position size function that I'm currently using. It isn't perfect, but it might give you some insight to my comments above.
double PositionSize_FixedFractional(int StoplossDistance_inPoints, double RiskPercent, double AcctBalance = 0) { double lotstep = MarketInfo(Symbol(), MODE_LOTSTEP), minlot = MarketInfo(Symbol(), MODE_MINLOT), maxlot = MarketInfo(Symbol(), MODE_MAXLOT); // validate passed parameters if (RiskPercent <= 0 || StoplossDistance_inPoints <= 0) return (minlot); else if (AcctBalance <= 0) AcctBalance = AccountBalance(); // calculate raw lotsize double PointValue = MarketInfo(Symbol(), MODE_TICKVALUE) / (MarketInfo(Symbol(), MODE_TICKSIZE) / Point), RiskAmount = MathFloor(AcctBalance * RiskPercent / 0.01) * 0.01, StoplossValue = StoplossDistance_inPoints * PointValue, lotsize = RiskAmount / StoplossValue; // condition raw lotsize lotsize = MathFloor(lotsize / lotstep) * lotstep; lotsize = MathMax(MathMin(lotsize, maxlot), minlot); // return conditioned lotsize return (lotsize); }
.
double PointValue = MarketInfo(Symbol(), MODE_TICKVALUE) / (MarketInfo(Symbol(), MODE_TICKSIZE) / Point),
- 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 = RISK = (OrderOpenPrice - OrderStopLoss)*DIR * OrderLots * DeltaPerlot (Note OOP-OSL includes the SPREAD)
- Do NOT use TickValue by itself - DeltaPerlot
- You must also check FreeMargin to avoid stop out
- 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 = RISK = (OrderOpenPrice - OrderStopLoss)*DIR * OrderLots * DeltaPerlot (Note OOP-OSL includes the SPREAD)
- Do NOT use TickValue by itself - DeltaPerlot
- You must also check FreeMargin to avoid stop out
WHRoeder,
Re what you put:
1. don't understand what you mean, please clarify
2. I've already calculated risk, so I don't understand your point here either.
3. You presumably have predicted that in my code, tickValue is calculated as
double tickValue = (MarketInfo(Symbol(),MODE_TICKVALUE));
and from your other forum post of DeltaPerLot, it should be
double tickValue = MarketInfo(Symbol(),MODE_TICKVALUE) / MarketInfo(Symbol(),MODE_TICKSIZE;
?
4. I am already checking AccountFreeMargin in the line which assigns a value to riskCapital - or did you mean elsewhere?
Thanks
My answer is: no and no.
Why did you vary your lot calculation (replicated below for illustration) based on whether the account currency was part of the currency pair?
If RiskAmount, StoplossValue, and PointValue (i.e., a ratio of tickvalue and ticksize) are all denominated in deposit currency, why the need to determine if the account currency is part of the currency pair? I don't believe you need to do this.
I'm not sure what you mean by "adjusted", but stoploss in this calculation (i.e., lotsize = RiskAmount / StoplossValue) should be a value in deposit currency, not a size in pips or points.
In the above code snippet, what will happen when you round up? The answer is that you will risk more than you defined in your riskCapital. I believe the better course is to always round down (using MathFloor())
What about maxlot? While most of us will probably never reach our brokers' defined maxlot (mine is 50 standard lots and I'm still only trading at <=1 standard lot), it is better to check the calculated lotsize against maxlot just to make sure.
The following is the fixed fractional position size function that I'm currently using. It isn't perfect, but it might give you some insight to my comments above.
.
Thirteen, thanks for your input.
I varied my calculation due to http://www.babypips.com/school/undergraduate/senior-year/position-sizing/calculating-position-sizes.html which suggests different calculations based on different scenarios. I've been hacking around with mql4 for a few months now, but it sounds from your post that there is a way to get round these differences. Surely having different ways of calculating lot size mentioned on the above URL, I need to represent this in code?
Good point about rounding down - I should be doing that. Also good point about maxlot, which I need to change. I also see in your code about the SL calc as an amount rather than a number of pips. Cheers
What do you think about WHRoeder's modification of your code in his most recent post? That's quite a significant difference.
WHRoeder:
double PointValue = MarketInfo(Symbol(), MODE_TICKVALUE) / (MarketInfo(Symbol(), MODE_TICKSIZE) / Point),
- 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 = RISK = (OrderOpenPrice - OrderStopLoss)*DIR * OrderLots * DeltaPerlot (Note OOP-OSL includes the SPREAD)
- Do NOT use TickValue by itself - DeltaPerlot
- You must also check FreeMargin to avoid stop out
- This has nothing to do with the code I posted above.
- Yes, I understand your equation. We are saying the same thing, just expressing it in a different way. Your DeltaPerlot is similar to my PointValue.
- As you can see, I'm not using TickValue alone. Not sure why you repeated this mantra.
- I do a FreeMargin check in another part of the code.
double PointValue = MarketInfo(Symbol(), MODE_TICKVALUE) / (MarketInfo(Symbol(), MODE_TICKSIZE) / Point),
My answer is: no and no.
Why did you vary your lot calculation (replicated below for illustration) based on whether the account currency was part of the currency pair?
If RiskAmount, StoplossValue, and PointValue (i.e., a ratio of tickvalue and ticksize) are all denominated in deposit currency, why the need to determine if the account currency is part of the currency pair? I don't believe you need to do this.
I'm not sure what you mean by "adjusted", but stoploss in this calculation (i.e., lotsize = RiskAmount / StoplossValue) should be a value in deposit currency, not a size in pips or points.
In the above code snippet, what will happen when you round up? The answer is that you will risk more than you defined in your riskCapital. I believe the better course is to always round down (using MathFloor()).
What about maxlot? While most of us will probably never reach our brokers' defined maxlot (mine is 50 standard lots and I'm still only trading at <=1 standard lot), it is better to check the calculated lotsize against maxlot just to make sure.
The following is the fixed fractional position size function that I'm currently using. It isn't perfect, but it might give you some insight to my comments above.
.
Thirteen, I put in your fractional lot size function and now my functions are coming out as (eg) 337.01 instead of 0.337. Can you tell me why this might be please?
If you ask something like that, you still got a lot of homework to do.
Have you ever try different calculation logic and figure out why it happen like that?
Thirteen, I put in your fractional lot size function and now my functions are coming out as (eg) 337.01 instead of 0.337. Can you tell me why this might be please?
Please post an example which shows: (1) risk amount, (2) stoploss distance, (3) currency pair, (4) tickvalue, (5) ticksize, (6) Point, and (7) the value of MarketInfo(Symbol(), LOTSIZE).
Couple of quick things to remember: the stoploss distance you give to the function must be in integer points, and the RiskPercent must be decimal form (e.g., 10% = 0.1 and 2% = 0.02).
Right after spending basically all day researching and double checking bits of code from all over the place, I didn't find a nice, reliable, but simple and easy to implement function in one place that I could drop into my code which would give me the lot size, adjusted for JPY and 3/5 digit brokers and based on a risk percentage of the margin in my account. OK, I know the code below may not be complete, but from a few tests with different pairs it looks like it correctly calculates lot size when I print out what it is doing and compare the manually calculated values in an online pos size calculator.
For the benefit of the world at large, here is the code, and my question is: is this code (a) correct as far as you're concerned as regards the lot size calculations listed, and (b) the most efficient way of doing it to your mind?
Thanks
In init(), note calculation of tickValue:
then bearing in mind stopLoss is an integer in (adjusted) pips:
23 |
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
Right after spending basically all day researching and double checking bits of code from all over the place, I didn't find a nice, reliable, but simple and easy to implement function in one place that I could drop into my code which would give me the lot size, adjusted for JPY and 3/5 digit brokers and based on a risk percentage of the margin in my account. OK, I know the code below may not be complete, but from a few tests with different pairs it looks like it correctly calculates lot size when I print out what it is doing and compare the manually calculated values in an online pos size calculator.
For the benefit of the world at large, here is the code, and my question is: is this code (a) correct as far as you're concerned as regards the lot size calculations listed, and (b) the most efficient way of doing it to your mind?
Thanks
In init(), note calculation of tickValue:
then bearing in mind stopLoss is an integer in (adjusted) pips: