Calculating Max Position Size

Hello,

I have the following code...

maxLots = AccountFreeMargin() / MarketInfo(Symbol(),MODE_MARGINREQUIRED);
lotStep = MarketInfo(Symbol(), MODE_LOTSTEP);
maxLots = floor(((maxLots / lotStep) * lotStep) * 100) / 100;
maxLots = NormalizeDouble(maxLots, 2);

With \$1,000 in Free Margin on an account with 50:1 leverage, it says I can open 0.36 lots of GBPUSD. However, when I try to open a position of that size, it fails due to insufficient margin.

Can anyone tell me what I am doing wrong?

All the best,
Fred

Frederick Langemark: it says I can open 0.36 lots ... it fails due to insufficient margin.

Margin has nothing to do with lotstep. Risk depends on your initial stop loss, lot size, and the value of the pair. In code (MT4):

1. 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.
2. 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.)
3. 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 non-fx instruments with many brokers.
4. You must normalize lots properly and check against min and max.
5. You must also check FreeMargin to avoid stop out
Most pairs are worth about \$10 per PIP. A \$5 risk with a (very small) 5 PIP SL is \$5/\$10/5=0.1 Lots maximum.

Or You Could Simply Work It Out From Scratch And Not Be A Yodeller :P

//MQL5
#property version   "1.00"

void OnTick()
{   //Account Currency GBP // Pair NZDUSDmicro
// Get Free Account Margin in Account Currency the Ask Price for Acc Curr to your pairs Quote Symbol and invert the Ex Rate.
double freeAccMarg         =  NormalizeDouble(AccountInfoDouble(ACCOUNT_MARGIN_FREE),_Digits); 			//GBP
double askAccToQuoteInv    =  NormalizeDouble((1/askAccToQuote),_Digits);						//Inverts Rate so is USDGBPmicro as my broker does not offer this pari

// Convert Free Account Margin Amount to Free Margin in Quote Currency and get Ask Price for your pair then invert the Ex Rate.
double freeQuoteMarg       =  NormalizeDouble((freeAccMarg * askAccToQuoteInv),_Digits);				//GBP to USD

double lots                =  1.0;                                                      	//Single Lot
double lotSize             =  1000;							//Lot Size of your account - Usually 100,000 -This is for a micro acc
double lotsXlotsize        =  lots*lotSize;						//Times the Lot By LotSize
long leverage              =  AccountInfoInteger(ACCOUNT_LEVERAGE);			//Get Account Leverage
double reqMarg             =  NormalizeDouble((lotDivLev * askQuoteToBase),_Digits);	//Required Margin Quote Price USD\$ Amount for 1 Lot =  lotsXlotsize * your pairs ask price NZDUSDmicro

double AvailableLots       =  NormalizeDouble((freeQuoteMarg/reqMarg),2);			//Available lots = (Free Margin in Quote Currency USD / Required Margin To Buy 1 Lot of NZD in USD)

Comment( "freeAccMarg: ", freeAccMarg,
"\nfreeQuoteMarg: ", freeQuoteMarg,
"\nlots: ", lots,
"\nlotSize: ", lotSize,
"\nlotsXlotsize: ", lotsXlotsize,
"\nleverage: ", leverage,
"\nlotDivLev: ", lotDivLev,
"\nRequired Margin For 1 Lot: ", reqMarg,
"\nAvailableLots: ", AvailableLots
);

}

I also found that OrderCalcMargin() worked but I felt that there was a lack of clarity due to its simplified nature.

Check Out Orchard Forex's Tutorial on Tick,Lot,Risk he helped a lot.

https://orchardforex.com/category/tutorials/

Frederick Langemark:

Hello,

I have the following code...

With \$1,000 in Free Margin on an account with 50:1 leverage, it says I can open 0.36 lots of GBPUSD. However, when I try to open a position of that size, it fails due to insufficient margin.

Can anyone tell me what I am doing wrong?

All the best,
Fred

Try this script, I use this code in my indicator :

double maxlot,lotstep;
void OnStart()
{
if(MarketInfo(Symbol(),MODE_MARGINREQUIRED)>0)
{
lotstep = MarketInfo(Symbol(),MODE_LOTSTEP);
maxlot = (AccountFreeMargin())/MarketInfo(Symbol(),MODE_MARGINREQUIRED);
maxlot   = DoubleToStr(MathFloor(maxlot/lotstep)*lotstep,2);
}