Risk depends on your initial stop loss, lot size, and the value of the symbol. It does not depend on margin and leverage. No SL means you have infinite risk (on leveraged symbols). Never risk more than a small percentage of your trading funds, certainly less than 2% per trade, 6% total.

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.

AccountBalance * percent/100 = RISK = OrderLots * (OrderOpenPrice  OrderStopLoss * DeltaPerLot + CommissionPerLot) (Note OOPOSL 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 and verify that MODE_TICKVALUE is returning a value in your deposit currency, as promised by the documentation, or whether it is returning a value in the instrument's base currency.
MODE_TICKVALUE is not reliable on nonfx instruments with many brokers  MQL4 programming forum (2017)
Is there an universal solution for Tick value?  Currency Pairs  General  MQL5 programming forum (2018)
Lot value calculation off by a factor of 100  MQL5 programming forum (2019) 
You must normalize lots properly and check against min and max.

You must also check FreeMargin to avoid stop out

For MT5, see 'Money Fixed Risk'  MQL5 Code Base (2017)
Most pairs are worth about $10 per PIP. A $5 risk with a (very small) 5 PIP SL is $5/$10/5 or 0.1 Lots maximum.
Great thanks for all those precise data, and links.
Thanks to you I finally managed to find matching numbers.
Great thanks for all those precise data, and links.
Thanks to you I finally managed to find matching numbers.
I am facing a similar issue and have spent hours trying to work out where I've gone wrong. Did you work out what your formula needs to be to calculate an accurate lot size for XAUUSD type orders?
In python, use the order_calc_profit function and apply it in a way similar to the following MQL5 equivalent ...
Forum on trading, automated trading systems and testing trading strategies
SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE) sometimes zero
Fernando Carreiro, 2022.08.23 16:51
Instead of using the Tick Value directly, consider using the function OrderCalcProfit, because it will apply the correct profit calculation method depending on the CALC_MODE for that symbol.Forum on trading, automated trading systems and testing trading strategies
SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE) sometimes zero
Fernando Carreiro, 2022.08.23 17:41
You can! These are the steps I take. I supply the function with a lot size equal to the “Max Lot Size” allowed for the symbol in question, then calculate the ratio needed to achieve the fractional risk that I wish to apply, to get the correct volume for the order. I then align that with the “Lot Step” and finally check it against both the maximum and minimum allowed lots for the symbol.
The reason I use the “maximum” lots instead of just “1.0” lots as a reference value is because there is no guarantee that the value of 1.0 is within the minimum and maximum values allowed. Given that using 1.0, or the maximum, gives equivalent results anyway (by using the ratio method), I choose to use the “max lots” as the reference point which also offers the most precision for the calculation.
Something like this ...
// This code will not compile. It is only a example reference if( OrderCalcProfit( eOrderType, _Symbol, dbLotsMax, dbPriceOpen, dbPriceStopLoss, dbProfit ) ) { dbOrderLots = fmin( fmax( round( dbRiskMax * dbLotsMax / ( dbProfit * dbLotsStep ) ) * dbLotsStep, dbLotsMin ), dbLotsMax ); // the rest of the code ... };Forum on trading, automated trading systems and testing trading strategies
How to calculate lots using multiplier according to number of opened orders?
Fernando Carreiro, 2017.09.01 21:57
Don't use NormalizeDouble(). Here is some guidance (code is untested, just serves as example):
// Variables for Symbol Volume Conditions double dblLotsMinimum = SymbolInfoDouble( _Symbol, SYMBOL_VOLUME_MIN ), dblLotsMaximum = SymbolInfoDouble( _Symbol, SYMBOL_VOLUME_MAX ), dblLotsStep = SymbolInfoDouble( _Symbol, SYMBOL_VOLUME_STEP ); // Variables for Geometric Progression double dblGeoRatio = 2.8, dblGeoInit = dblLotsMinimum; // Calculate Next Geometric Element double dblGeoNext = dblGeoInit * pow( dblGeoRatio, intOrderCount + 1 ); // Adjust Volume for allowable conditions double dblLotsNext = fmin( dblLotsMaximum, // Prevent too greater volume fmax( dblLotsMinimum, // Prevent too smaller volume round( dblGeoNext / dblLotsStep ) * dblLotsStep ) ); // Align to Step valueForum on trading, automated trading systems and testing trading strategies
Volume Limit Reached  Validation for new Expert Advisor error
Fernando Carreiro, 2022.07.22 18:22
Your EA must be coded to read the broker's contract specifications, such volume limitations, and prevent that from happening.
SYMBOL_VOLUME_MIN
double
SYMBOL_VOLUME_MAX
Maximal volume for a deal
double
SYMBOL_VOLUME_STEP
Minimal volume change step for deal execution
double
SYMBOL_VOLUME_LIMIT
Maximum allowed aggregate volume of an open position and pending orders in one direction (buy or sell) for the symbol. For example, with the limitation of 5 lots, you can have an open buy position with the volume of 5 lots and place a pending order Sell Limit with the volume of 5 lots. But in this case you cannot place a Buy Limit pending order (since the total volume in one direction will exceed the limitation) or place Sell Limit with the volume more than 5 lots.
double
In python, use the order_calc_profit function and apply it in a way similar to the following MQL5 equivalent ...
I suggest you look at it again. If you trying to calculate your order volume for a specific stoploss risk, then use the order_calc_profit as described in my previous post.
Please note however, that stoploss risk and appropriate volume for it has nothing to do with leverage or margin. That is something completely separate, which you can obtain using order_calc_margin.
If however, you just need the tick value, or point value just use the python equivalent of the following ...
Forum on trading, automated trading systems and testing trading strategies
Fernando Carreiro, 2022.05.18 21:05
double dbTickSize = SymbolInfoDouble( _symbol, SYMBOL_TRADE_TICK_SIZE ), // Tick size dbTickValue = SymbolInfoDouble( _symbol, SYMBOL_TRADE_TICK_VALUE ), // Tick value dbPointSize = SymbolInfoDouble( _symbol, SYMBOL_POINT ), // Point size dbPointValue = dbTickValue * dbPointSize / dbTickSize; // Point valueRemember, it's best to use tick size and tick value in your calculations, instead of point size and its value.
I think we're trying to work out what the lot size should be from the amount of risk we are willing to take. What you're sharing looks great but that will calculate the profit made and I don't see how that will help unless it's used inversely. I did give it a quick try in python but it was spitting out "None" results, so I must be doing something wrong.
I think you mean StopLoss and not TakeProfit. In my post I talk about "Risk", not "Reward", and hence why I use " dbProfit" in the ratio, since a loss will be a negative profit.
I think you mean StopLoss and not TakeProfit. In my post I talk about "Risk", not "Reward", and hence why I use " dbProfit" in the ratio, since a loss will be a negative profit.
// This code will not compile. It is only a example reference if( OrderCalcProfit( eOrderType, _Symbol, dbLotsMax, dbPriceOpen, dbPriceStopLoss, dbProfit ) ) { dbOrderLots = fmin( fmax( round( dbRiskMax * dbLotsMax / ( dbProfit * dbLotsStep ) ) * dbLotsStep, dbLotsMin ), dbLotsMax ); // the rest of the code ... };
dbRiskMax = abs(mt5.account_info().balance * 0.01) # 1% risk of account balance converted into negative integerprofit = mt5.order_calc_profit(eOrderType, _Symbol, dbLotsMax, dbPriceOpen, dbPriceStopLoss)dbLotSize = round(( dbRiskMax / profit ) * dbLotsMax, 2)
# BTCUSDdbRiskMax = abs(50000.0 * 0.01)dbRiskMax = 500.0profit = mt5.order_calc_profit(mt5.ORDER_TYPE_BUY, BTCUSD, 25.0, 21525, 21200)profit = 8125.0dbLotSize = round(( 500.0 / 8125.0 ) * 25.0, 2)dbLotSize = 1.54# should be 0.002 micro lots
 You can also get "LotsMax", when the stop loss is very small or your stoploss price is in the wrong place.
 Don't take the absolute value of the balance as you could have a negative balance. So, simply test that the balance is actually positive before applying the calculation.
 You removed the part of the code that aligns the volume to the allowable volume steps. You can't just use any any value you want you have to make it a valid volume as per the allowed steps.
 You removed the protections of checking for the maximum and minimum allowable volume. Again, there are limits in place you must adhere to or the order will fail.
 The solution you came up with, is distorting the logic and not resolving the root cause of the original calculation not giving you the correct answer.
EDIT: In my example, I am using a positive Risk, not as a negative. If you want to use it as negative then adjust the calculation as such, by removing the "" in front of "dbProfit".
dbOrderLots = fmin( fmax( round( dbRiskMax * dbLotsMax / ( dbProfit * dbLotsStep ) ) * dbLotsStep, dbLotsMin ), dbLotsMax );
 Free trading apps
 Over 8,000 signals for copying
 Economic news for exploring financial markets
You agree to website policy and terms of use
Hello,
I'm currently developping forex robot using Python API for Metatrader 5. Among different things, this robot places trades given by external signals (with price, SL and TP).
pipValue = (pipStep/ currentPrice) * lotSize
Applied to given trade above (result in dollars):
pipValue = (0.001/1849.32)*100000*0.01 = 0.005407393
Total trade value (in dollars, without any leverage)
tradeValue = 0.005407393 * (1849.32  1848.03)/0.01 = 0.6976
From this point, I can't find any way to include leverage and exchange rate for finding this 2,4€ profit.
Thank you for those who can help on this theorical point.