ロットサイズ自動計算機能?

 

こんにちは、またまたお邪魔します :-)どなたか、自動的にロットサイズを計算する便利で小さなMQL4関数を お持ちではないでしょうか(どんなシンボルでも)。


ありがとうございます。

Shawn

 
 


Phillipさん、ありがとうございます。日本円のペアで問題があったようですね。これは解決されたのでしょうか?


ありがとうございます。

ショーン

 
shawnh:


Phillipさん、ありがとうございます。日本円のペアで問題があったようですね。これは解決されたのでしょうか?


ありがとうございます。

ショーン




何を言っているのかさっぱりわからないのですが? 日本円のペアで問題なく動作します。 あなたのお金を預けるかもしれないどんなコードでもそうですが、あなたはコードを調査し、いくつかの手動計算でその正しさを確認する必要があります。 コードは正しいのですが、確実ではありません:)

 

1.A サンプルロットサイズ計算 https://www.mql5.com/en/code/8583

2.AIS1 トレーディングロボット https://www.mql5.com/en/code/8700

//< 7.7.2. Risk Management > //<192>
//< 7.7.3. Operation Size Control > //<202>

 
shawnh:

どなたか、利用可能な株式のリスクと希望するストップロスのサイズ(ピップ単位)に基づいて、(どのシンボルでも)ロットサイズを自動的に計算する便利で小さなMQL4関数をお持ちではないでしょうか?

//+------------------------------------------------------------------+
//| Lot size computation.                                            |
//+------------------------------------------------------------------+
double  LotSize(double risk){
/*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   = risk * 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(risk/pips2dbl, Digits.pips), ")=",
            size, " [risk=", at.risk, AccountCurrency(),    "/", maxLossPerLot,
                    ", margin=",    marginFree,             "/", marginPerLot,
                    ", MMM=",       Money.Management.F0M1G2,"x",
                    Money.Management.Multiplier,    ", OO=",   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;
        else if (adjFact < 1){  size  = MathMax(minLot,size*adjFact);adjFact=1;}
        else break; // We're good to go.
    }
    at.risk = size * maxLossPerLot;                     // Export for Comment
    return(size);
}   // LotSize
double 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.
}
 

Phillipさん、あなたのコードを私のEAに入れたら、見事に動作しました - 本当にありがとうございます。AISとWHRoederの回答にも感謝します。


ありがとうございました。

ショーン

 

それを聞いてうれしいShawn!

もしあなたがより新しいバージョン(あなたが持っているものにバグはありません)をお望みなら、私はそれを共有するよりも幸せです。

変更点は主に、既存のEAと統合して使用するためにインクルードファイルをより簡単にすることです。 すでに他のEAを実装されているようなので、今更どうこう言うつもりはありません。

 

Phillipさん、その新しい「使いやすい」インクルードファイルが欲しいのですが、投稿していただくか、送っていただけませんか?

ありがとうございます。

 

もちろん、私のコードがあるコンピュータに戻ったら、それを投稿します。

そういえば、コードバンクにもアップロードしたほうがいいかもしれないね。

 

Step 1: この記事の添付ファイルをすべてインクルードパスに入れる(... \experts\include*.mqh)

ステップ2: EAのトップに以下を追加し、添付ファイルに含まれるコール関数にアクセスできるようにします。

#include <OrderReliable_2010.10.12.mqh>
#include <Trade_Position_Management_2010.10.29.mqh>

ステップ3:リスクへの資本の予算額に基づいてロットサイズを計算するために、以下を追加します。

   // Determine position lotsize based on order direction and market prices
   double CurrentEquityAtRisk=(MaxPercentEquityAtRisk/100.)*AccountBalance();
   double CurrentLotSize=LotSize(CurrentEquityAtRisk,OpenPrice_ND,StopLossPrice_ND,CurrentOrderType); // Compute the max possible lotsize for the risk equity
   Print("Max allowed EquityAtRisk = $",DoubleToStr(CurrentEquityAtRisk,2)," and Max computed Lotsize = ",CurrentLotSize);
   CurrentLotSize=NormalizeLotSize(CurrentLotSize);   // Normalize the lotsize to conform with the Broker's specific quantized position allowances
   if(CurrentLotSize<MarketInfo(CurrentSymbol,MODE_MINLOT)) CurrentLotSize=MarketInfo(CurrentSymbol,MODE_MINLOT);
   if(CurrentLotSize> MarketInfo(CurrentSymbol,MODE_MAXLOT)) CurrentLotSize=MarketInfo(CurrentSymbol,MODE_MAXLOT);

MaxPercentEquityAtRiskをEAのどこかで定義したと仮定して、ストップがヒットした場合に取引ごとに完全な損失のリスクにさらす最大許容資本とする。このコードの部分は、まずopenpriceとstoplossprice(ピップではなく実際の市場価格、ブローカーに送る注文と同じもの)をもとに最大ロットを決定し、次に予算リスク資本を超えていない範囲でブローカーが受け入れる最大ポジションサイズを決定する。

ステップ4:計算結果をログに出力したり、注文コメントとして取引に追加したい場合は、次のように追加することもできます。

   // Determine the actual equity at risk of total loss for the position's normalized lotsize
   CurrentEquityAtRisk=EquityAtRisk(CurrentLotSize,OpenPrice_ND,StopLossPrice_ND,CurrentOrderType);
   if(TakeProfitBidPrice>0.01)
      {
      CurrentProfitPotential=ProfitPotential(CurrentLotSize,OpenPrice_ND,TakeProfitPrice_ND,CurrentOrderType);
      Print("Current EquityAtRisk = $",DoubleToStr(CurrentEquityAtRisk,2)," and Current Lotsize = ",CurrentLotSize," and Profit Target = $"
            ,DoubleToStr(CurrentProfitPotential,2)," for a ",DoubleToStr(CurrentProfitPotential/CurrentEquityAtRisk,1),":1 Profit:Loss ratio");
      Order_Comment=StringConcatenate("EaR = $",DoubleToStr(CurrentEquityAtRisk,2)," & Profit = $",DoubleToStr(CurrentProfitPotential,2));
      }
   else
      {
      Print("Current EquityAtRisk = $",DoubleToStr(CurrentEquityAtRisk,2)," and Current Lotsize = ",CurrentLotSize);
      Order_Comment=StringConcatenate("EquityAtRisk = $",DoubleToStr(CurrentEquityAtRisk,2));
      }

ステップ5: 注文を出す (ordersendreliable メソッドを使用)

   // Place the order
   ticket = OrderSendReliable(CurrentSymbol,CurrentOrderType,CurrentLotSize,OpenPrice_ND,MarketInfo(CurrentSymbol,MODE_SPREAD)
            ,StopLossPrice_ND,TakeProfitPrice_ND,Order_Comment,0,0,Aqua);

https://c.mql5.com/mql4/forum/2010/10/OrderReliable_2010.10.12.mqh