According to MQL4 documentation "MODE_LOTSIZE" must return "Lot size in the base currency". However, some brokers indicate "MODE_LOTSIZE" as "Lot size in the account currency". In this case, "MODE_MARGINREQUIRED" means 1 lot size in the account currency divided by constant "AccountLeverage ()". Thank you for effective collaboration.
The calculation of lot size is the calculation of maximum loss allowable. Risk is the open price - the initial stop loss (Buy: Ask-SL, Sell: SL-Bid) Maximum loss is risk times the loss per pip. That is what you want to be 2% of account balance. Nothing to do with margin. Figure where your open and stops will be, then lot size follows from that.
//+------------------------------------------------------------------+//| Lot size computation. |//+------------------------------------------------------------------+double LotSize(double SLpoints){
/*double TEF.value, // Import from ComputeTEF
//double at.risk; // Export to init/start
//bool need2refresh; // Import from RelTradeContext
//int op.code; // -1/OP_BUY/OP_SELL // Import from setDIR *//* This function computes the lot size for a trade.
* Explicit inputs are SL relative to bid/ask (E.G. SL=30*points,)
* Implicit inputs are the MM mode, the MM multiplier, count currently
* filled orders by all EA's vs this EA/pair/period count and history.
* Implicit inputs are all used to reduce available balance the maximum
* dollar risk allowed. StopLoss determines the maximum dollar risk possible
* per lot. Lots=maxRisk/maxRiskPerLot
**************************************************************************/if (need2refresh) Refresh();
/*++++ Compute lot size based on account balance and MM mode*/{
double ab = AccountBalance();
switch(Money.Management.F0M1G2){
case MMMODE_FIXED:
at.risk = Money.Management.Multiplier;
break;
case MMMODE_MODERATE:
// See https://www.mql5.com/en/articles/1526 Fallacies, Part 1: Money// Management is Secondary and Not Very Important. // %used/trade=
at.risk = MathSqrt(Money.Management.Multiplier * ab)/ab; // ~const rate.
at.risk = MathSqrt(Money.Management.Multiplier * ab
* MathPow( 1 - at.risk, OrdersTotal() ));
break;
case MMMODE_GEOMETRICAL:
at.risk = Money.Management.Multiplier * ab *
MathPow(1 - Money.Management.Multiplier, OrdersTotal());
break;
}
double maxLossPerLot = SLpoints * PointValuePerLot(),
/* Number of lots wanted = at.risk / maxLossPerLot rounded/truncated to
* nearest lotStep size.
*
* However, the broker doesn't care about the at.risk/account balance. They
* care about margin. Margin used=lots used*marginPerLot and that must be
* less than free margin available. */
marginFree = AccountFreeMargin(),
marginPerLot = MarketInfo( Symbol(), MODE_MARGINREQUIRED ),
// So I use, the lesser of either.
size = MathMin(marginFree / marginPerLot, at.risk / maxLossPerLot),
minLot = MarketInfo(Symbol(), MODE_MINLOT),
LotStep = MarketInfo(Symbol(), MODE_LOTSTEP);
/*---- Compute lot size based on account balance and MM mode*/}
double adjFact = IfD(MathMin(1, TEF.value), 1, TEF.Enable01);
while (true){ // Adjust for broker, test for margin, combine with TEF
size = MathFloor(size/LotStep)*LotStep;
if (size < minLot){ // Insufficient margin.Print(
"LotSize(SL=", DoubleToStr(SLpoints/pips2dbl, Digits.pips), ")=",
size, " [risk=", at.risk, AccountCurrency(), "/", maxLossPerLot,
", margin=", marginFree, "/", marginPerLot,
", MMM=", Money.Management.F0M1G2,"x",
Money.Management.Multiplier,
", ExtraOO=", OrdersTotal(),
"]" );
size=0; break; }
/* size<minLot should be sufficient, but the tester was generating error
* 134 even when marginFree should have been OK. So I also use
* AccountFreeMarginCheck which aggrees with the tester.
* https://forum.mql4.com/35056 */double AFMC = AccountFreeMarginCheck(Symbol(), op.code, size);
/**/if (AFMC < 0) size *= 0.95;
elseif (adjFact < 1){ size = MathMax(minLot,size*adjFact);adjFact=1;}
elsebreak; // We're good to go.
}
at.risk = size * maxLossPerLot; // Export for Commentreturn(size);
} // LotSizedouble PointValuePerLot() { // Value in account currency of a Point of Symbol./* In tester I had a sale: open=1.35883 close=1.35736 (0.00147)
* gain$=97.32/6.62 lots/147 points=$0.10/point or $1.00/pip.
* IBFX demo/mini EURUSD TICKVALUE=0.1 MAXLOT=50 LOTSIZE=10,000
* IBFX demo/standard EURUSD TICKVALUE=1.0 MAXLOT=50 LOTSIZE=100,000
* $1.00/point or $10.00/pip.
*
* https://forum.mql4.com/33975 CB: MODE_TICKSIZE will usually return the
* same value as MODE_POINT (or Point for the current symbol), however, an
* example of where to use MODE_TICKSIZE would be as part of a ratio with
* MODE_TICKVALUE when performing money management calculations which need
* to take account of the pair and the account currency. The reason I use
* this ratio is that although TV and TS may constantly be returned as
* something like 7.00 and 0.00001 respectively, I've seen this
* (intermittently) change to 14.00 and 0.00002 respectively (just example
* tick values to illustrate). */return( MarketInfo(Symbol(), MODE_TICKVALUE)
/ MarketInfo(Symbol(), MODE_TICKSIZE) ); // Not Point.
}
You keep posting this code over and over in the forum, and in this case you thread-necro'ed a 2yr old thread to do so, and it is only correct for currency pairs that have the account's denomination as the counter-currency in the currency pair.
(If account denomination = USD and currency pair EURUSD then your code is correct...but it is wrong for USDJPY, EURJPY, etc)
WHRoeder, do you have an updated version of this code that is valid for all currency pairs regardless of account denomination or being counter-currency?
roy7: WHRoeder, do you have an updated version of this code that is valid for all currency pairs regardless of account denomination or being counter-currency?
That code IS valid for any pair.
return( MarketInfo(Symbol(), MODE_TICKVALUE)
/ MarketInfo(Symbol(), MODE_TICKSIZE) ); // Not Point.
Returns the change in account currency for one tick of the pair, any pair. No changes are needed, unless your stops are so big that tickValue changes significantly (I.E. 2000 pip SL.)
1005phillip 2010.09.18 17:29 I keep pointing this out, you keep ignoring it.
I have successfully duplicated the answers you provided (within .01) and have one question about the values for ald.MinimalMargin.
Using my IBFX standard account, my ald.MinimalMargin is always $10, for both GBPJPY and EURUSD, whereas your amounts vary (such as 185.785 or 147.6).
Do you have any idea why your minimal margin amounts vary but mine do not?
I've duplicated your ald.OperationVolume amounts (within .01) and have one question.
When the calculation runs on your account, the ald.MinimalMargin varies.
When the calculation runs on my IBFX standard account, the ald.MinimalMargin is always $10.
QUESTION: Any idea why?
Here are the Alert values on my system using IDFX standard account. Notice that ald.MinimalMargin = 10 USD.
aas.Symbol = GBPJPY
aad.VARLimit = 3155 USD
aai.VARPoints = 50 points
aai.Command = 0
Processing:
ald.MinimalMargin = 10 USD
ald.MinimalPoint = 0.0942 USD
ali.PositionPoints = 106 points
aai.VARPoints = 50 points
ald.VARPositions = 0.4717 positions
aad.VARLimit = 3155 USD
ald.PositionLimit = 6688.6 USD
ald.VolumeLimit = 6.6886 lots
ald.VolumeStep = 0.01 lots
ald.NominalMargin = 1000 margin required (I inserted this line)
ald.MinimalVolume = 0.01 lots
Output:
ald.OperationVolume = 6.68
However, some brokers indicate "MODE_LOTSIZE" as "Lot size in the account currency".
In this case, "MODE_MARGINREQUIRED" means 1 lot size in the account currency divided by constant "AccountLeverage ()".
Thank you for effective collaboration.
Hello.The revised sample of the operation volume computing:You keep posting this code over and over in the forum, and in this case you thread-necro'ed a 2yr old thread to do so, and it is only correct for currency pairs that have the account's denomination as the counter-currency in the currency pair.
(If account denomination = USD and currency pair EURUSD then your code is correct...but it is wrong for USDJPY, EURJPY, etc)
I keep pointing this out, you keep ignoring it.
WHRoeder, do you have an updated version of this code that is valid for all currency pairs regardless of account denomination or being counter-currency?
Thanks.
WHRoeder, do you have an updated version of this code that is valid for all currency pairs regardless of account denomination or being counter-currency?
That code IS valid for any pair. Returns the change in account currency for one tick of the pair, any pair. No changes are needed, unless your stops are so big that tickValue changes significantly (I.E. 2000 pip SL.)
I keep pointing this out, you keep ignoring it.
As far as i know HERE you will find his latest complete basic code collection. Scroll down to his post with the attachment.
Thank you!