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.
//+------------------------------------------------------------------+//| 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.
}
我已经成功复制了你提供的答案(在0.01以内),有一个关于ald.MinimalMargin的值的问题。
使用我的IBFX标准账户,我的ald.MinimalMargin总是10美元,对于GBPJPY和EURUSD都是如此,而你的金额却不同(如185.785或147.6)。
你知道为什么你的最低保证金数额不同,而我的却没有?
我复制了你的ald.OperationVolume数额(在0.01以内),有一个问题。
当计算在你的账户上运行时,alld.MinimalMargin是不同的。
当计算在我的IBFX标准账户上运行时,alld.MinimalMargin总是10美元。
问题:知道为什么吗?
下面是我的系统使用IDFX标准账户的警报值。注意ald.MinimalMargin = 10 USD。
aas.Symbol = GBPJPY
aad.VARLimit = 3155 USD
aai.VARPoints = 50 points
aai.Command = 0
处理:
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 = 1000margin required(我插入了这一行)
ald.MinimalVolume = 0.01 lots
输出:
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:
你不断地在论坛上发布这段代码,在这种情况下,你在一个2年的旧线程上发布了这段代码,而且它只对那些将账户面额作为货币对中的对应货币的货币对 正确。
(如果账户面额=美元,货币对为欧元兑美元,那么你的代码是正确的......但对于美元兑日元、欧元兑日元等则是错误的)。
我一直指出这一点,你一直忽视它。
WHRoeder,你是否有这个代码的更新版本,对所有货币对都有效,无论账户面额或是否为反货币?
谢谢。
WHRoeder,你是否有这个代码的更新版本,对所有货币对都有效,无论账户面额或是否为反货币?
该代码对任何货币对都有效。 返回任何货币对的一个刻度的账户货币的变化。不需要做任何改变,除非你的止损点很大,以至于tickValue变化很大(即2000点的SL。)
我一直指出这一点,你却一直视而不见。
据我所知,在这里你可以找到他最新的完整的基本代码集。 向下滚动到他的帖子与附件。
谢谢你!