fonction de calcul automatique de la taille des lots ?

 

Bonjour à tous, de retour pour vous harceler :-) Quelqu'un aurait-il une petite fonction MQL4 très pratique qui calcule automatiquement la taille du lot (pour n'importe quel symbole) en fonction du pourcentage de risque de mon capital disponible et de la taille de mon stoploss en pips ?


Merci !

Shawn

 
 


Merci Phillip ! Il semble que le code avait quelques problèmes avec les paires JPY. Cela a-t-il été résolu ?


Merci

Shawn

 
shawnh:


Merci Phillip ! Il semble que le code avait quelques problèmes avec les paires JPY. Cela a-t-il été résolu ?


Merci

Shawn




Je n'ai aucune idée de ce à quoi vous faites référence ? Cela fonctionne bien avec les paires JPY. Comme avec n'importe quel code auquel vous pouvez confier votre argent, vous devriez examiner le code et confirmer son exactitude avec quelques calculs manuels. Le code est correct, mais il n'est pas infaillible :)

 

1. Un échantillon : Calcul de la taille du lot https://www.mql5.com/en/code/8583

2. AIS1 Trading Robot https://www.mql5.com/en/code/8700

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

 
shawnh:

Quelqu'un aurait-il une petite fonction MQL4 très pratique qui calcule automatiquement la taille du lot (pour n'importe quel symbole) en fonction du pourcentage de risque de mon capital disponible et de la taille de mon stoploss en pips ?

//+------------------------------------------------------------------+
//| 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, j'ai mis votre code dans mon EA et il fonctionne à merveille - merci beaucoup. Merci également à AIS et WHRoeder pour leurs réponses !


Merci

Shawn

 

Heureux de l'entendre Shawn !

Je modifie continuellement les codes, si vous souhaitez une version plus récente (il n'y a pas de bogues dans ceux que vous avez), je serais plus qu'heureux de la partager.

Les changements consistent principalement à rendre le fichier d'inclusion plus facile à intégrer et à utiliser avec votre EA existante. Puisque vous avez déjà réussi à implémenter l'autre, cela ne fait peut-être aucune différence pour vous maintenant.

 

Phillip, j'aimerais beaucoup avoir ce nouveau fichier include "plus facile à utiliser", pourrais-tu le poster ou me l'envoyer, j'essaie de le faire aujourd'hui en fait.

Merci !

 

Bien sûr, je le posterai quand je serai de retour à l'ordinateur qui a mes codes.

Je devrais probablement le télécharger sur la banque de codes aussi maintenant que j'y pense.

 

Étape 1 : Placez toutes les pièces jointes de cet article dans votre chemin d'inclusion (...\experts\include\*.mqh)

Étape 2 : Ajoutez ce qui suit au sommet de votre EA afin qu'il ait accès aux fonctions d'appel contenues dans les fichiers joints.

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

Étape 3 : Pour calculer la taille du lot sur la base d'un montant budgétisé de capitaux propres à risquer, ajoutez ce qui suit : 1.

   // 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);

En supposant que vous ayez défini MaxPercentEquityAtRisk quelque part dans votre EA pour qu'il s'agisse de l'équité maximale autorisée à mettre au risque d'une perte complète par transaction dans le cas où les stops sont atteints, cette partie du code déterminera d'abord la taille maximale du lot sur la base du prix d'ouverture et du prix du stoploss (pas de pips mais le prix réel du marché, la même chose que vous envoyez dans votre ordre au courtier), puis elle déterminera la taille maximale de la position que le courtier acceptera sans dépasser l'équité à risque budgétée.

Étape 4 : si vous souhaitez que les résultats des calculs soient imprimés dans votre journal ou ajoutés à la transaction en tant que commentaire d'ordre, vous pouvez également ajouter les éléments suivants

   // 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));
      }

Étape 5 : Passez votre ordre (en utilisant la méthode 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