Besoin d'une formule de moneymanagement LOT size basée sur le SL et le risque du compte ! - page 3

 

OK les gars ! Ce code a été écrit par moi et c'est ce que j'utilise dans mes propres EA. Il est assez complexe car, en plus du Risk% et du StopLoss, il prend également en compte le Risk% de la marge et corrige la taille du lot en fonction de la taille minimale, maximale et par paliers. Il utilise également toujours la valeur minimale du solde actuel et de l'équité au lieu de n'utiliser qu'une seule de ces valeurs. Je pense que c'est plus sûr ainsi.

Veuillez noter, cependant, qu'elle n'utilise pas le spread dans le calcul, car je le calcule séparément lors du calcul du StopLoss à utiliser. La fonction ci-dessous, utilise donc une taille de stop loss relative. Dans mes EA, l'argument dblStopLossPips est calculé au préalable en fonction de divers facteurs tels que la stratégie, le spread, l'ATR, etc. ; la valeur finale transmise à la fonction dblLotsRisk() est donc déjà une valeur finale pour le calcul de la taille du lot à utiliser.

// Function to Determine Tick Point Value in Account Currency

        double dblTickValue( string strSymbol )
        {
                return( MarketInfo( strSymbol, MODE_TICKVALUE ) );
        }
        

// Function to Determine Pip Point Value in Account Currency

        double dblPipValue( string strSymbol )
        {
                double dblCalcPipValue = dblTickValue( strSymbol );
                switch ( MarketInfo( strSymbol, MODE_DIGITS ) )
                {
                        case 3:
                        case 5:
                                dblCalcPipValue *= 10;
                                break;
                }
                
                return( dblCalcPipValue );
        }
        

// Calculate Lot Size based on Maximum Risk & Margin

        double dblLotsRisk( string strSymbol, double dblStopLossPips,
                double dblRiskMaxPercent, double dblMarginMaxPercent,
                double dblLotsMin, double dblLotsMax, double dblLotsStep )
        {
                double
                        dblValueAccount = MathMin( AccountEquity(), AccountBalance() )
                ,       dblValueRisk    = dblValueAccount * dblRiskMaxPercent / 100.0
                ,       dblValueMargin  = AccountFreeMargin() * dblMarginMaxPercent / 100.0
                ,       dblLossOrder    = dblStopLossPips * dblPipValue( strSymbol )
                ,       dblMarginOrder  = MarketInfo( strSymbol, MODE_MARGINREQUIRED )
                ,       dblCalcLotMin
                                = MathMax( dblLotsMin, MarketInfo( strSymbol, MODE_MINLOT ) )
                ,       dblCalcLotMax
                                = MathMin( dblLotsMax, MarketInfo( strSymbol, MODE_MAXLOT ) )
                ,       dblModeLotStep  = MarketInfo( strSymbol, MODE_LOTSTEP )
                ,       dblCalcLotStep  = MathCeil( dblLotsStep / dblModeLotStep ) * dblModeLotStep
                ,       dblCalcLotLoss
                                = MathFloor( dblValueRisk / dblLossOrder / dblCalcLotStep ) * dblCalcLotStep
                ,       dblCalcLotMargin
                                = MathFloor( dblValueMargin / dblMarginOrder / dblCalcLotStep ) * dblCalcLotStep
                ,       dblCalcLot = MathMin( dblCalcLotLoss, dblCalcLotMargin )
                ;
                
                if ( dblCalcLot < dblCalcLotMin ) dblCalcLot = dblCalcLotMin;
                if ( dblCalcLot > dblCalcLotMax ) dblCalcLot = dblCalcLotMax;

                return ( dblCalcLot );
        }
 
GumRai:

J'ai mal à la tête rien qu'en essayant de comprendre les parenthèses !

Pour être honnête, je n'ai absolument aucune idée de ce que vous essayez d'obtenir ici.

Je ne vois pas en quoi MODE_STOPLEVEL ou SPREAD sont pertinents, vous devriez sûrement baser vos calculs sur la distance stop-loss du prix actuel ?

La devise du compte ne devrait pas faire de différence, le calcul devrait être le même car TICKVALUE est dans la devise du compte.

Veuillez noter qu'en mettant votre ligne de code sur 2 lignes, le message n'est pas aussi large et est plus facile à lire sans avoir à scroller de droite à gauche :)

J'ai posté il y a quelques pages, une image dans laquelle j'ai illustré ma formule pour calculer le lot, mais le pipvalue ou tickvalue ou quoi que ce soit d'autre est toujours en train de s'embrouiller. cotation->monnaie de base et d'autres choses qui sont confuses, mais jusqu'à présent ma formule a fait un bon travail, bien que je ne sois pas sûr qu'elle soit correcte.

Le SPREAD n'est peut-être pas pertinent, mais le stoplevel est nécessaire. Je place le SL le plus près possible du prix d'ouverture de l'ordre qui est le stoplevel, mais à cause des fluctuations et des pics, je dois parfois l'ajuster manuellement, c'est pourquoi j'ai mis une variable STOPSLIP avec laquelle je peux ajuster le SL à la volatilité ou autre.

FMIC:

OK les gars ! Ce code a été écrit par moi et c'est ce que j'utilise dans mes propres EA. Il est assez complexe car, en plus du Risk% et du StopLoss, il prend également en compte le Risk% de la marge et corrige la taille du lot en fonction de la taille minimale, maximale et du Step Size. Il utilise également toujours la valeur minimale du solde actuel et de l'équité au lieu de n'utiliser qu'une seule de ces valeurs. Je pense que c'est plus sûr de cette façon.

Veuillez noter, cependant, qu'elle n'utilise pas le spread dans le calcul, car je le calcule séparément lors du calcul du StopLoss à utiliser. La fonction ci-dessous, utilise donc une taille de stop loss relative. Dans mes EA, l'argument dblStopLossPips est calculé au préalable en fonction de divers facteurs tels que la stratégie, le spread, l'ATR, etc. ; ainsi, la valeur finale transmise à la fonction dblLotsRisk() est déjà une valeur finale afin de calculer la taille du lot à utiliser.

Merci, je vais le tester et vous faire part de mes commentaires !

Bien que je ne comprenne pas pourquoi vous avez mis tant de variables ici, le code entier peut être adapté en 1 ligne :)

 
Proximus:

J'ai posté il y a quelques pages, une image dans laquelle j'ai illustré ma formule pour calculer le lot.Mais le pipvalue ou tickvalue ou quoi que ce soit d'autre est toujours en train de s'embrouiller.cotation->monnaie de base et d'autres choses qui sont confuses, mais jusqu'à présent ma formule a fait un bon travail, bien que je ne sois pas sûr qu'elle soit correcte.

Le SPREAD n'est peut-être pas pertinent, mais le stoplevel est nécessaire. Je place le SL le plus près possible du prix d'ouverture de l'ordre qui est le stoplevel, mais à cause des fluctuations et des pics, je dois parfois l'ajuster manuellement, c'est pourquoi j'ai mis une variable STOPSLIP avec laquelle je peux ajuster le SL à la volatilité ou autre.

Merci, je vais le tester et donner mon avis !

Bien que je ne comprenne pas pourquoi vous avez mis tant de variables ici, le code entier peut être adapté en 1 ligne :)


Oui, le code pourrait être mis en une seule ligne, mais croyez-moi, ce n'est JAMAIS une bonne façon de coder, à moins que vous n'essayiez d'extraire chaque cycle de CPU de votre code pour être le plus rapide de la planète.

C'est pourquoi "GumRai " s'est plaint d'avoir mal à la tête en essayant de comprendre l'autre code. Il n'était tout simplement pas très lisible ou facile à comprendre et cela le rend très difficile à déboguer.

Ma méthode est peut-être plus verbeuse mais elle est plus facile à déboguer et à maintenir, ainsi que plus lisible et plus facile à comprendre pour d'autres personnes comme vous.

Mais n'hésitez pas à compacter tout cela en une seule ligne. Mais ne vous plaignez pas si cela ne donne pas les mêmes résultats. Je vous laisse le soin de déboguer CELA.

 

Désolé de rouvrir ce fil de discussion, mais il est crucial de confirmer quelque chose, alors voici la fonction que j'ai trouvé (je le mets public, vous pouvez me remercier plus tard) :

double LOTUNITSTORISK()
{
double LOTS=((AccountBalance()*RISKPERCENT/100) / (  MarketInfo(Symbol(), MODE_TICKVALUE)*MarketInfo(Symbol(), MODE_TICKSIZE)*STOPSIZE     ));
return LOTS;
}


Cette fonction doit retourner les unités de lot basées sur le risque du compte, et calculées via un compte EUR, puisque l'EUR est toujours la devise de base.

L'unité de lot signifie = la taille réelle de l'argent d'une position, donc pour un compte de 100 € avec un risque de 1%, il devrait retourner 1€ qui, basé sur le STOPLOSS, par exemple un stoploss de 100 pipettes, devrait être de 1000 unités de lot (0,01 LOT EN ÉQUIVALENT MT4).

Il est essentiel que la devise du compte soit l'EURO, rien d'autre.

Une fois que nous appelons le LOTUNITTORISK(), nous diviserons les résultats par 100.000 pour obtenir la taille réelle du lot au format MT4 (1000 unités de lot 0.01 LOT en MT4)

RISKPERCENT =est un int et peut être 1,2,3,4 le % de risque que nous prenons.

STOPSIZE = est un int et c'est le nombre de pipettes (pips/10 sur un broker à 5 chiffres) que notre taille de stoploss est, donc par exemple 60 pipette SL est un 6 pip SL

Je veux savoir si la fonction calcule les LOT UNITS correctement, veuillez la tester et si vous trouvez une erreur, veuillez m'aider :)

Mille mercis !

 
Proximus:
MarketInfo(Symbol(), MODE_TICKVALUE)* MarketInfo(Symbol(), MODE_TICKSIZE)*STOPSIZE

Risk  = lotsize * StopSize * TickValue /  TickSize
         1      *  0.0100  *  $10.00   / 0.0001
$1000 = one lot * 100 pips *  $10.00   / pip
  1. Vous placez le stop là où il doit être - là où la raison de la transaction n'est plus valable. Par exemple, si vous négociez un rebond de support, le stop passe sous le support.
  2. Solde du compte * pourcentage = RISK = (OrderOpenPrice - OrderStopLoss)*DIR * OrderLots * DeltaPerlot (Note OOP-OSL inclut le SPREAD)
  3. N'utilisez PAS TickValue par lui-même - DeltaPerlot
  4. Vous devez également vérifier FreeMargin pour éviter le stop out.
 
WHRoeder:
  1. Vous placez le stop là où il doit être - là où la raison de la transaction n'est plus valable. Par exemple, si vous négociez un rebond de support, le stop passe sous le support.
  2. Solde du compte * pourcentage = RISK = (OrderOpenPrice - OrderStopLoss)*DIR * OrderLots * DeltaPerlot (Note OOP-OSL inclut le SPREAD)
  3. N'utilisez PAS TickValue par lui-même - DeltaPerlot
  4. Vous devez également vérifier FreeMargin pour éviter le stop out.

1) La fonction ne renvoie que la taille du lot en unité monétaire et non en unité MT4, rien d'autre, lorsque je place les ordres, respectivement le STOPSIZE sera ajouté / soustrait de l'offre en cas d'achat et de la demande en cas de vente, tout comme MT4 gère le TP et le SL.

ACHAT ouvert à ASK, fermé à BID

VENTE ouvert à BID, fermé à ASK.

2) Je ne peux pas utiliser l'homme OrderOpenprice parce qu'aucun ordre n'est ouvert avant que cette fonction ne soit calculée. Les spreads ne sont pas inclus, ils seront traités lorsque j'ajouterai/substracterai le STOPSIZE après l'ouverture de l'ordre.

Mais avant cela, nous devons déterminer la taille du lot, c'est logique.

3) Je ne comprends pas.

4) Evidemment, mais j'insiste encore une fois sur le fait que la fonction de placement d'ordre est exécutée après cela, et a peu à voir avec cette fonction.Le seul but de cette fonction est de déterminer la taille du lot, rien d'autre.


TickValue /  TickSize

Incorrect, si je les divise, j'obtiens le mauvais chiffre, peut-être pour les comptes en USD, mais il s'agit d'un compte en EUR, il faut les multiplier.

 
Proximus:

BUY ouvert à ASK, fermé à BID SELL ouvert à BID, fermé à ASK

2) Je ne peux pas utiliser OrderOpenprice.

3) Je ne comprends pas.

4)t, si je les divise, j'obtiens un nombre erroné, peut-être pour les comptes en USD, mais c'est un compte en EUR. Ils doivent être multipliés.

  1. Le Ask est le OrderOpenPrice pour un achat.
  2. Le Bid est l'OrderOpenPrice pour une vente. Pourquoi ne pouvez-vous pas l'utiliser, vous devez le connaître pour le passer à OrderSend ?
  3. Vous DEVEZ utiliser tickvalue/ticksize. La valeur du tick en elle-même n'a aucun sens.
  4. Vous DEVEZ diviser pour obtenir les unités correctes (Changement de prix) * (tickValue) / (changement de prix) vous donne une valeur. 10 $ par pip = 1 $ par point = valeur/changement. Rappelez-vous que le résultat en est la devise du compte, donc lorsque vous le divisez par votre risque, vous obtenez un nombre pur, à nouveau les unités annulent $risk(BAL%)/$risk(SL). Si vous devez faire plusieurs calculs, c'est que vous faites quelque chose de mal ou que les valeurs du courtier sont faussées.
 
WHRoeder:
Proximus:

BUY ouvert à ASK, fermé à BID SELL ouvert à BID, fermé à ASK

2) Je ne peux pas utiliser OrderOpenprice

3) Je ne comprends pas.

4)t, si je les divise, j'obtiens un nombre erroné, peut-être pour les comptes en USD, mais c'est un compte en EUR, il faut les multiplier.

  1. Le Ask est le OrderOpenPrice pour un achat.
  2. Le Bid est l'OrderOpenPrice pour une vente. Pourquoi ne pouvez-vous pas l'utiliser, vous devez le connaître pour le passer à OrderSend ?
  3. Vous DEVEZ utiliser tickvalue/ticksize. Tickvalue par lui-même n'a aucun sens.
  4. Vous DEVEZ diviser pour obtenir les unités correctes (Changement de prix) * (tickValue) / (changement de prix) vous donne une valeur. 10 $ par pip = 1 $ par point = valeur/changement. Rappelez-vous que le résultat en est la devise du compte, donc lorsque vous le divisez par votre risque, vous obtenez un nombre pur, à nouveau les unités annulent $risk(BAL%)/$risk(SL). Si vous devez faire plusieurs calculs, c'est que vous faites quelque chose de mal ou que les valeurs du courtier sont faussées.


1,2 Je sais cela, mais comprenez-moi que cela est géré par une autre fonction qui n'a rien à voir avec celle-ci.

3) Si je comprends bien, le tickvalue est la valeur d'un pip dans la devise de base, donc en fonction de la paire que j'utilise, il faudra soit le diviser, soit le multiplier. Dans le cas d'un compte EUR, il semble qu'il faille multiplier et non diviser.

Voici une image qui illustre mieux la situation :


Sur l'EUR/USD pour un trade à 3% de risque nous devons ouvrir 1798 unités, arrondi à 0.02 LOTS en unités MT4 pour y parvenir.

La taille du STOPLOSS est déterminée par une autre fonction.

Je l'ai testée, mais je ne suis pas sûr que la formule soit vraiment précise, c'est ce que j'essaie de déterminer ici, alors aidez-moi à le faire.

 

J'ai moi aussi essayé de comprendre le calcul de la taille des lots en fonction du SL, du risque du compte ET du niveau d'appel de marge, surtout lorsque le niveau d'appel de marge n'est pas de 100 % mais de 120 %, par exemple. La meilleure réponse que j'ai trouvée est ce que WHRoeder a partagé ici dans son code whrea.mq4. Le code whrea.mq4 avait besoin d'être corrigé mais WHRoeder a déjà donné cette correction ici dans sa réponse au commentaire de RaptorUK. La réponse complète au calcul de la taille du lot est donc là, mais un certain effort est nécessaire pour comprendre pleinement ce que WHRoeder a partagé.

J'ai joint le code que j'ai extrait et modifié du code whrea.mq4 de WHRoeder pour le compiler avec la dernière version de MT4 afin de calculer la taille du lot pour une transaction longue où le niveau d'appel de marge est supérieur à 100 %.

Cependant, je ne suis pas sûr que la multiplication par le % du MarginCallLevel soit correcte pour prendre en compte le % du Margin Call Level pour éviter un appel de marge. Si le niveau d'appel de marge est de 100 %, les deux lignes de code sont correctes, mais si le niveau d'appel de marge est de 120 %, la multiplication par le % du niveau d'appel de marge constitue-t-elle un test d'appel de marge correct ? Si non, quelle est la bonne façon de procéder ? WHRoeder, pouvez-vous nous aider ? William, j'ai fait de mon mieux.

Voici le code de la section Margin Test pour une transaction longue :

extern double MarginCallLevel = 120; //As a percentage

double MarginCallLevel1 = MarginCallLevel * 0.01; 

        double  AFMC    = AccountFreeMarginCheck(Symbol(), OP_BUY, tradesize),
                        eRisk   = equityatrisk + atrisknew;

        //Test for margin
        //Note: Not sure if multiplying by the MarginCallLevel % here is correct to 
        //take the Margin Call Level % into account for avoiding a margin call.
        //If the MarginCallLevel is 100% then both lines of code would be correct
        //but if the MarginCallLevel is 120% would multiplying by the MarginCallLevel %
        //be a correct Margin Call test? If not, then what is the correct way to do this?

        //if (AFMC*0.99 <= eRisk){
        if (AFMC*0.99 <= eRisk*MarginCallLevel1){
            tradesize *= 0.95;    // Must still round to lotStep.
            continue;   }   // Prevent margin call if new trade goes against us.
Dossiers :
 

... dans cette partie du code il y a un problème avec la nouvelle compilation (error ---> 'MarketInfo' - illegal switch expression type) peut-être que tout était OK jusqu'à la mise à jour de MT4 build 600+ ... mais depuis cela ne fonctionne plus.

// Function to Determine Pip Point Value in Account Currency

        double dblPipValue( string strSymbol )
        {
                double dblCalcPipValue = dblTickValue( strSymbol );
                switch ( MarketInfo( strSymbol, MODE_DIGITS ) )
                {
                        case 3:
                        case 5:
                                dblCalcPipValue *= 10;
                                break;
                }
                
                return( dblCalcPipValue );
        }
        

Donc, pourriez-vous s'il vous plaît poster une version plus récente ... si bien sûr vous êtes toujours là.