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の値について1つ質問があります。
私のIBFXスタンダード口座では、GBPJPYもEURUSDもald.MinimalMarginは常に10ドルですが、御社の金額は様々です(185.785や147.6など)。
なぜあなたのミニマムマージンは変化し、私のミニマムマージンは変化しないのか、何かお分かりになりますか?
ald.OperationVolumeの金額を複製したのですが(0.01以内)、1つ質問があります。
あなたの口座で計算を実行すると、ald.MinimalMarginの値が変化します。
私のIBFXスタンダード口座で計算すると、ald.MinimalMarginは常に10ドルになります。
質問: なぜか心当たりはありますか?
IDFX標準口座を使用した私のシステムでのAlertの値は以下の通りです。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.VARLimit = 0.4719 USD ald.VARPositions = 0.4719 USD aai.VARLimit = 0.4719 USD ald.VARPositions = 0.4727 USDPositionLimit = 6688.6 USD
ald.VolumeLimit = 6.6886 lots
ald.VolumeStep = 0.01 lots
ald.NominalMargin = 1000margin required(I inserted this line)
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年前のスレッドをスレッドネクロして投稿しています。
(口座の通貨がUSDで通貨ペアがEURUSDの場合、あなたのコードは正しいのですが、USDJPYやEURJPYなどでは間違っています)。
私はこのことを指摘し続けていますが、あなたはそれを無視し続けています。
WHRoeder さん、口座の額面や反対通貨であることに関係なく、すべての通貨ペアで有効なこのコードの更新版はありますか?
ありがとうございます。
WHRoeder, このコードの更新版で、口座の額面や反対通貨に関係なく、すべての通貨ペアで有効なものはありますか?
そのコードはどのペアにも有効です。 ペアの1ティックの口座通貨の変化を返します、任意のペア。ストップが大きすぎてtickValueが大きく変化しない限り、変更は必要ありません(例:2000 pip SL.)
何度も指摘してるのに、無視し続けてるよね。
私の知る限り、ここであなたは彼の最新の完全な基本的なコードコレクションを見つけることが できます。添付ファイルのある彼の投稿までスクロールダウンしてください。
ありがとうございました。