The problem is not fully defined. If you say you want to risk 2% then you have to fix one of the variables: the stop loss level or the trade volume. Since you're asking about calculating the lot size that means you don't want it fixed but that requires you to become interested in stop loss pips even though you say you're not. If you don't have a stop loss then risking 2% means taking a fixed lot size, e.g. 1.0, and waiting till your current losses reach 2% of the initial margin. You don't need to calculate the lot size here as you see.
Once stop loss level enters the view, the calculation is simple:
double tradeVolume = AccountFreeMargin() * Risk/100 / ( StopLossPoints * MarketInfo( Symbol(), MODE_TICKVALUE ) );
That is, given a stop loss level for any particular trade, you will always have the specified percentage of your initial margin lost if the stop loss is taken.
You will also want to normalize the resulting value by MODE_LOTSTEP and cap it with MODE_MINLOT and MODE_MAXLOT.
The problem is not fully defined. If you say you want to risk 2% then you have to fix one of the variables: the stop loss level or the trade volume. Since you're asking about calculating the lot size that means you don't want it fixed but that requires you to become interested in stop loss pips even though you say you're not. If you don't have a stop loss then risking 2% means taking a fixed lot size, e.g. 1.0, and waiting till your current losses reach 2% of the initial margin. You don't need to calculate the lot size here as you see.
Once stop loss level enters the view, the calculation is simple:
double tradeVolume = AccountFreeMargin() * Risk/100 / ( StopLossPoints * MarketInfo( Symbol(), MODE_TICKVALUE ) );
That is, given a stop loss level for any particular trade, you will always have the specified percentage of your initial margin lost if the stop loss is taken.
You will also want to normalize the resulting value by MODE_LOTSTEP and cap it with MODE_MINLOT and MODE_MAXLOT.
This produces an answer of 6.66 on a mini-account. Does that seem about right?
double risk3 = 2.0;
stopLossPips = 30;
double orderLotSize3 = AccountFreeMargin() * risk3/100 / ( stopLossPips * MarketInfo( Symbol(), MODE_TICKVALUE ) );
orderLotSize3 = orderLotSize3 - MathMod( orderLotSize3, 2*MarketInfo( Symbol(), MODE_LOTSTEP ) );
orderLotSize3 = NormalizeDouble(orderLotSize3, 2);
Only If MODE_TICKVALUE is 1.0 which looks weird (but depends on the properties of the mini-account). What is MODE_TICKVALUE for the instrument in question and your mini-account? For EURUSD, a standard account, and a 1:100 leverage it's $10 giving a trading volume of 0.66 lots for the 2% risk the and the 30 pp stop.
Hello.
int init ()
{
double ad.Volume ;
string as.Symbol = "EURUSD" ;
double ad.LotStep = MarketInfo ( as.Symbol , MODE_LOTSTEP ) ;
double ad.MinimalVolume = MarketInfo ( as.Symbol , MODE_MINLOT ) ;
double ad.NominalLot = MarketInfo ( as.Symbol , MODE_LOTSIZE ) ;
double ad.NominalMargin = MarketInfo ( as.Symbol , MODE_MARGINREQUIRED ) ;
double ad.QuoteAsk = MarketInfo ( as.Symbol , MODE_ASK ) ;
double ad.QuoteBid = MarketInfo ( as.Symbol , MODE_BID ) ;
double ad.EquityQuant = 0.01 ;
double ad.MarginLimit = AccountEquity () * ad.EquityQuant ;
double ad.VolumeLimit = ad.MarginLimit / ad.NominalMargin ;
if ( ad.VolumeLimit < ad.MinimalVolume )
ad.Volume = 0 ;
else { int ai.Steps = MathFloor ( ( ad.VolumeLimit - ad.MinimalVolume ) / ad.LotStep ) ;
ad.Volume = ad.MinimalVolume + ad.LotStep * ai.Steps ; }
double ad.Leverage = AccountLeverage () ;
double ad.RealLeverage = ad.Leverage ;
double ad.MarginBuy.1 = ad.QuoteAsk * ad.Volume * ad.NominalLot / ad.RealLeverage ;
double ad.MarginSell.1 = ad.QuoteBid * ad.Volume * ad.NominalLot / ad.RealLeverage ;
double ad.MarginBuy.2 = AccountFreeMargin () - AccountFreeMarginCheck ( as.Symbol , OP_BUY , ad.Volume ) ;
double ad.MarginSell.2 = AccountFreeMargin () - AccountFreeMarginCheck ( as.Symbol , OP_SELL , ad.Volume ) ;
Alert ( "ad.MarginSell.2 = " , ad.MarginSell.2 , " " , AccountCurrency () ) ;
Alert ( "ad.MarginBuy.2 = " , ad.MarginBuy.2 , " " , AccountCurrency () ) ;
Alert ( "ad.MarginSell.1 = " , ad.MarginSell.1 , " " , AccountCurrency () ) ;
Alert ( "ad.MarginBuy.1 = " , ad.MarginBuy.1 , " " , AccountCurrency () ) ;
Alert ( "ad.Volume = " , ad.Volume , " " , "lots" ) ;
Alert ( "Output :" ) ;
Alert ( " " ) ;
Alert ( "ai.Steps = " , ai.Steps ) ;
Alert ( "ad.LotStep = " , ad.LotStep , " " , "lots" ) ;
Alert ( "ad.MinimalVolume = " , ad.MinimalVolume , " " , "lots" ) ;
Alert ( "ad.VolumeLimit = " , ad.VolumeLimit , " " , "lots" ) ;
Alert ( "ad.MarginLimit = " , ad.MarginLimit , " " , AccountCurrency () ) ;
Alert ( "ad.NominalMargin = " , ad.NominalMargin , " " , AccountCurrency () ) ;
Alert ( "ad.RealLeverage = " , ad.RealLeverage ) ;
Alert ( "ad.NominalLot = " , ad.NominalLot , " " , StringSubstr ( as.Symbol , 0 , 3 ) ) ;
Alert ( "Processing :" ) ;
Alert ( " " ) ;
Alert ( "ad.EquityQuant = " , ad.EquityQuant ) ;
Alert ( "AccountEquity () = " , AccountEquity () , " " , AccountCurrency () ) ;
Alert ( "as.Symbol = " , as.Symbol ) ;
Alert ( "Input :" ) ;
Alert ( " " ) ;
Alert ( "AccountCurrency () = " , AccountCurrency () ) ;
}
Ais.
2. Calculation of the "ad.Margin****.2" is more universal but some symbols may have miscounts.
3. Real leverage and "AccountLeverage ()" may differ.
4. Real leverage calculation formula depends on forex symbol parsing.
Example.
...
//<method 24>
int air.Ticker.Compute.4
(//<0>
){//<24>
if ( avi.Ticker.Conversion == ac.Direct )
{ avi.Ticker.ConversionDigits = avi.Ticker.QuoteDigits ;
avd.Ticker.ConversionAsk = avd.Ticker.QuoteAsk ;
avd.Ticker.ConversionBid = avd.Ticker.QuoteBid ;
avd.Ticker.RealLeverage = avd.Ticker.QuoteAsk * avd.Ticker.NominalLot / avd.Ticker.NominalMargin ; }
else if ( avi.Ticker.Conversion == ac.DirectCross )
{ avi.Ticker.ConversionDigits = MarketInfo ( avs.Ticker.ConversionSymbol , MODE_DIGITS ) ;
avd.Ticker.ConversionAsk = MarketInfo ( avs.Ticker.ConversionSymbol , MODE_ASK ) ;
avd.Ticker.ConversionBid = MarketInfo ( avs.Ticker.ConversionSymbol , MODE_BID ) ;
avd.Ticker.RealLeverage = ( avd.Ticker.ConversionAsk + avd.Ticker.ConversionBid ) / 2
* avd.Ticker.NominalLot / avd.Ticker.NominalMargin ; }
else if ( avi.Ticker.Conversion == ac.Inverse )
{ avi.Ticker.ConversionDigits = 8 - avi.Ticker.QuoteDigits ;
avd.Ticker.ConversionAsk = 1.0 / avd.Ticker.QuoteBid ;
avd.Ticker.ConversionBid = 1.0 / avd.Ticker.QuoteAsk ;
avd.Ticker.RealLeverage = avd.Ticker.NominalLot / avd.Ticker.NominalMargin ; }
else { avi.Ticker.ConversionDigits = 8 - MarketInfo ( avs.Ticker.ConversionSymbol , MODE_DIGITS ) ;
avd.Ticker.ConversionAsk = 1.0 / MarketInfo ( avs.Ticker.ConversionSymbol , MODE_BID ) ;
avd.Ticker.ConversionBid = 1.0 / MarketInfo ( avs.Ticker.ConversionSymbol , MODE_ASK ) ;
avd.Ticker.RealLeverage = ( avd.Ticker.ConversionAsk + avd.Ticker.ConversionBid ) / 2
* avd.Ticker.NominalLot / avd.Ticker.NominalMargin ; }
}//</method 24>
...
I think the easiest method to get amount of margin needed for one lot is
MarketInfo(Symbol(),MODE_MARGINREQUIRED);
I usually use following formula to calculate lots:
double OneLotMargin = MarketInfo(Symbol(),MODE_MARGINREQUIRED);
double FreeMargin = AccountFreeMargin();
double lotMM = FreeMargin/OneLotMargin*Risk/100;
double LotStep = MarketInfo(Symbol(),MODE_LOTSTEP);
lotMM = NormalizeDouble(lotMM/LotStep,0)*LotStep;
However you asked about how to calculate amount of lots that use fixed amount of margin for example 200$ in this case the foolowing formula should be changed to:
double OneLotMargin = MarketInfo(Symbol(),MODE_MARGINREQUIRED);
double MarginAmount = 200; //this means we want to use 200$ for trade
double lotMM = MarginAmount/OneLotMargin;
double LotStep = MarketInfo(Symbol(),MODE_LOTSTEP);
lotMM = NormalizeDouble(lotMM/LotStep,0)*LotStep;
For example, "minimal lot" may be 0.10, "lot step" may be 0.01.
In this case, simple calculation methods may produce incorrect operation volume, for example, 0.05.
For example, "minimal lot" may be 0.10, "lot step" may be 0.01.
In this case, simple calculation methods may produce incorrect operation volume, for example, 0.05.
I'm using the code you mentioned at 'Ищу функцию вычисления размера лота.'. Thank you.
I HAVE ONE QUESTION ABOUT THIS CODE: Does it always produce and even numbered lotsize (such as 6.66 and not 6.67).
That's good if it does. I just don't understand why it does.
The attached code is in a Script file format, so you could paste the code into a new script and run it immediately.
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
Let's say my mini account has margin of $10,000, and I want to risk 2% on the next trade (that is, simply use $200 to buy <some amount> of contracts).
[I realize this is a limited view of "risk". I'm not interested in stopLoss pips, or profit targets, or whatever.]
Using MetaTrader, I get the following mini account information from my broker:
accountLeverage = AccountLeverage(); // value = 200
modeLotSize = MarketInfo("EURUSDm", MODE_LOTSIZE); // value = 10000
modeLotStep = MarketInfo("EURUSDm", MODE_LOTSTEP); // value = .01
modeMinLot = MarketInfo("EURUSDm", MODE_MINLOT) ); // value = .01
QUESTION: How do I calculate the lot size for $200? (It would be useful to know the cost of a minimum size lot. In this case, the minimum size lot is .01).
QUESTION: Is the lot size calculation formula the same for all currency pairs?
Thank you very much in advance.