Come si calcola la dimensione del lotto?

 

Diciamo che il mio mini conto ha un margine di 10.000 dollari, e voglio rischiare il 2% sul prossimo trade (cioè, semplicemente usare 200 dollari per comprare <qualche quantità> di contratti).

[Mi rendo conto che questa è una visione limitata del "rischio". Non sono interessato ai pip di stopLoss, o agli obiettivi di profitto, o altro].

Usando MetaTrader, ottengo le seguenti informazioni sul mini conto dal mio broker:

accountLeverage = AccountLeverage(); // valore = 200
modeLotSize = MarketInfo("EURUSDm", MODE_LOTSIZE); // valore = 10000
modeLotStep = MarketInfo("EURUSDm", MODE_LOTSTEP); // valore = .01
modeMinLot = MarketInfo("EURUSDm", MODE_MINLOT) ); // valore = .01

DOMANDA: Come faccio a calcolare la dimensione del lotto per $200? (Sarebbe utile conoscere il costo di un lotto di dimensione minima. In questo caso, il lotto di dimensione minima è .01).

DOMANDA: La formula di calcolo della dimensione del lotto è la stessa per tutte le coppie di valute?

Grazie mille in anticipo.

 

Il problema non è completamente definito. Se dici che vuoi rischiare il 2% allora devi fissare una delle variabili: il livello di stop loss o il volume di scambio. Dato che stai chiedendo di calcolare la dimensione del lotto, significa che non la vuoi fissa, ma questo richiede che tu sia interessato ai pip dello stop loss anche se dici di non esserlo. Se non hai uno stop loss allora rischiare il 2% significa prendere un lotto fisso, per esempio 1.0, e aspettare che le tue perdite attuali raggiungano il 2% del margine iniziale. Qui non c'è bisogno di calcolare la dimensione del lotto come vedi.


Una volta che il livello di stop loss entra nella vista, il calcolo è semplice:


double tradeVolume = AccountFreeMargin() * Risk/100 / ( StopLossPoints * MarketInfo( Symbol(), MODE_TICKVALUE ) );


Cioè, dato un livello di stop loss per ogni particolare trade, avrete sempre la percentuale specificata del vostro margine iniziale perso se lo stop loss viene preso.


Vorrai anche normalizzare il valore risultante da MODE_LOTSTEP e tapparlo con MODE_MINLOT e MODE_MAXLOT.

 
bstone wrote >>

Il problema non è completamente definito. Se dici di voler rischiare il 2% allora devi fissare una delle variabili: il livello di stop loss o il volume di scambio. Dato che stai chiedendo di calcolare la dimensione del lotto, significa che non la vuoi fissa, ma questo richiede che tu sia interessato ai pip dello stop loss anche se dici di non esserlo. Se non hai uno stop loss allora rischiare il 2% significa prendere un lotto fisso, per esempio 1.0, e aspettare che le tue perdite attuali raggiungano il 2% del margine iniziale. Qui non c'è bisogno di calcolare la dimensione del lotto come vedi.


Una volta che il livello di stop loss entra nella vista, il calcolo è semplice:

double tradeVolume = AccountFreeMargin() * Risk/100 / ( StopLossPoints * MarketInfo( Symbol(), MODE_TICKVALUE ) );


Cioè, dato un livello di stop loss per ogni particolare trade, avrete sempre la percentuale specificata del vostro margine iniziale perso se lo stop loss viene preso.

Si vorrà anche normalizzare il valore risultante da MODE_LOTSTEP e tapparlo con MODE_MINLOT e MODE_MAXLOT.

Questo produce una risposta di 6,66 su un conto mini. Vi sembra giusto?

doppio rischio3 = 2,0;
stopLossPips = 30;
double orderLotSize3 = AccountFreeMargin() * risk3/100 / ( stopLossPips * MarketInfo( Symbol(), MODE_TICKVALUE ) );
orderLotSize3 = orderLotSize3 - MathMod( orderLotSize3, 2*MarketInfo( Symbol(), MODE_LOTSTEP ) );
orderLotSize3 = NormalizeDouble(orderLotSize3, 2);

 

Solo se MODE_TICKVALUE è 1,0, il che sembra strano (ma dipende dalle proprietà del mini-account). Qual è il MODE_TICKVALUE per lo strumento in questione e il tuo mini-conto? Per EURUSD, un conto standard e una leva di 1:100 è di 10 dollari che dà un volume di trading di 0,66 lotti per il 2% di rischio e lo stop di 30 pp.

 
Hello.

int    init ()
{

double ad.Volume                                                                                                ;

string as.Symbol            = "EURUSD"                                                                          ;

double ad.LotStep           = MarketInfo ( as.Symbol , MODE_LOTSTEP        )                                    ;
double ad.MinimalVolume     = MarketInfo ( as.Symbol , MODE_MINLOT         )                                    ;
double ad.NominalLot        = MarketInfo ( as.Symbol , MODE_LOTSIZE        )                                    ;
double ad.NominalMargin     = MarketInfo ( as.Symbol , MODE_MARGINREQUIRED )                                    ;
double ad.QuoteAsk          = MarketInfo ( as.Symbol , MODE_ASK            )                                    ;
double ad.QuoteBid          = MarketInfo ( as.Symbol , MODE_BID            )                                    ;

double ad.EquityQuant       = 0.01                                                                              ;
double ad.MarginLimit       = AccountEquity () * ad.EquityQuant                                                 ;
double ad.VolumeLimit       = ad.MarginLimit   / ad.NominalMargin                                               ;

if   ( ad.VolumeLimit       < ad.MinimalVolume )
       ad.Volume            = 0                                                                                 ;
else { int ai.Steps         = MathFloor ( ( ad.VolumeLimit - ad.MinimalVolume ) / ad.LotStep )                  ;
       ad.Volume            = ad.MinimalVolume + ad.LotStep * ai.Steps                                          ; }

double ad.Leverage          = AccountLeverage ()                                                                ;
double ad.RealLeverage      = ad.Leverage                                                                       ;

double ad.MarginBuy.1       = ad.QuoteAsk * ad.Volume * ad.NominalLot / ad.RealLeverage                         ;
double ad.MarginSell.1      = ad.QuoteBid * ad.Volume * ad.NominalLot / ad.RealLeverage                         ;

double ad.MarginBuy.2       = AccountFreeMargin () - AccountFreeMarginCheck ( as.Symbol , OP_BUY  , ad.Volume ) ;
double ad.MarginSell.2      = AccountFreeMargin () - AccountFreeMarginCheck ( as.Symbol , OP_SELL , ad.Volume ) ;

Alert ( "ad.MarginSell.2    = " , ad.MarginSell.2    , " " , AccountCurrency ()                               ) ;
Alert ( "ad.MarginBuy.2     = " , ad.MarginBuy.2     , " " , AccountCurrency ()                               ) ;
Alert ( "ad.MarginSell.1    = " , ad.MarginSell.1    , " " , AccountCurrency ()                               ) ;
Alert ( "ad.MarginBuy.1     = " , ad.MarginBuy.1     , " " , AccountCurrency ()                               ) ;
Alert ( "ad.Volume          = " , ad.Volume          , " " , "lots"                                           ) ;
Alert ( "Output :"                                                                                            ) ;
Alert ( " "                                                                                                   ) ;
Alert ( "ai.Steps           = " , ai.Steps                                                                    ) ;
Alert ( "ad.LotStep         = " , ad.LotStep         , " " , "lots"                                           ) ;
Alert ( "ad.MinimalVolume   = " , ad.MinimalVolume   , " " , "lots"                                           ) ;
Alert ( "ad.VolumeLimit     = " , ad.VolumeLimit     , " " , "lots"                                           ) ;
Alert ( "ad.MarginLimit     = " , ad.MarginLimit     , " " , AccountCurrency ()                               ) ;
Alert ( "ad.NominalMargin   = " , ad.NominalMargin   , " " , AccountCurrency ()                               ) ;
Alert ( "ad.RealLeverage    = " , ad.RealLeverage                                                             ) ;
Alert ( "ad.NominalLot      = " , ad.NominalLot      , " " , StringSubstr ( as.Symbol , 0 , 3 )               ) ;
Alert ( "Processing :"                                                                                        ) ;
Alert ( " "                                                                                                   ) ;
Alert ( "ad.EquityQuant     = " , ad.EquityQuant                                                              ) ;
Alert ( "AccountEquity   () = " , AccountEquity   () , " " , AccountCurrency ()                               ) ;
Alert ( "as.Symbol          = " , as.Symbol                                                                   ) ;
Alert ( "Input :"                                                                                             ) ;
Alert ( " "                                                                                                   ) ;
Alert ( "AccountCurrency () = " , AccountCurrency ()                                                          ) ;
}
Best regards,
Ais.
 
Important.
1. Calculation of the "ad.Margin****.1" is correct for "***USD" symbols if USD is account currency.
2. Calculation of the "ad.Margin****.2" is more universal but some symbols may have miscounts.
3. Real leverage and "AccountLeverage ()" may differ.
4. Real leverage calculation formula depends on forex symbol parsing.
Example.
...

//<method 24>
int    air.Ticker.Compute.4

 (//<0>

){//<24>

if      ( avi.Ticker.Conversion      ==   ac.Direct      )
        { avi.Ticker.ConversionDigits =         avi.Ticker.QuoteDigits                                                 ;
          avd.Ticker.ConversionAsk    =         avd.Ticker.QuoteAsk                                                    ;
          avd.Ticker.ConversionBid    =         avd.Ticker.QuoteBid                                                    ;
          avd.Ticker.RealLeverage     =         avd.Ticker.QuoteAsk * avd.Ticker.NominalLot / avd.Ticker.NominalMargin ; }

else if ( avi.Ticker.Conversion      ==   ac.DirectCross )
        { avi.Ticker.ConversionDigits =         MarketInfo ( avs.Ticker.ConversionSymbol    , MODE_DIGITS )            ;
          avd.Ticker.ConversionAsk    =         MarketInfo ( avs.Ticker.ConversionSymbol    , MODE_ASK    )            ;
          avd.Ticker.ConversionBid    =         MarketInfo ( avs.Ticker.ConversionSymbol    , MODE_BID    )            ;
          avd.Ticker.RealLeverage     = ( avd.Ticker.ConversionAsk + avd.Ticker.ConversionBid ) / 2
                                        * avd.Ticker.NominalLot    / avd.Ticker.NominalMargin                          ; }

else if ( avi.Ticker.Conversion      ==   ac.Inverse     )
        { avi.Ticker.ConversionDigits =   8   - avi.Ticker.QuoteDigits                                                 ;
          avd.Ticker.ConversionAsk    =   1.0 / avd.Ticker.QuoteBid                                                    ;
          avd.Ticker.ConversionBid    =   1.0 / avd.Ticker.QuoteAsk                                                    ;
          avd.Ticker.RealLeverage     =                              avd.Ticker.NominalLot  / avd.Ticker.NominalMargin ; }

else    { avi.Ticker.ConversionDigits =   8   - MarketInfo ( avs.Ticker.ConversionSymbol    , MODE_DIGITS )            ;
          avd.Ticker.ConversionAsk    =   1.0 / MarketInfo ( avs.Ticker.ConversionSymbol    , MODE_BID    )            ;
          avd.Ticker.ConversionBid    =   1.0 / MarketInfo ( avs.Ticker.ConversionSymbol    , MODE_ASK    )            ;
          avd.Ticker.RealLeverage     = ( avd.Ticker.ConversionAsk + avd.Ticker.ConversionBid ) / 2
                                        * avd.Ticker.NominalLot    / avd.Ticker.NominalMargin                          ; }

}//</method 24>

... 
Best regards,
Ais.
 
Hello.
Another method of operation volume computing is in https://www.mql5.com/ru/forum/111267.
Best regards,
Ais.
 

Penso che il metodo più semplice per ottenere la quantità di margine necessaria per un lotto sia


MarketInfo(Symbol(),MODE_MARGINREQUIRED);


Di solito uso la seguente formula per calcolare i lotti:

double OneLotMargin = MarketInfo(Symbol(),MODE_MARGINREQUIRED);
double FreeMargin = AccountFreeMargin();
double lotMM = FreeMargin/OneLotMargin*Risk/100;
double LotStep = MarketInfo(Symbol(),MODE_LOTSTEP);
lotMM = NormalizeDouble(lotMM/LotStep,0)*LotStep;

Tuttavia hai chiesto come calcolare la quantità di lotti che utilizzano un importo fisso di margine per esempio 200$ in questo caso la formula di foolowing dovrebbe essere cambiata in:

double OneLotMargin = MarketInfo(Symbol(),MODE_MARGINREQUIRED);
double MarginAmount = 200; //this means we want to use 200$ for trade
double lotMM = MarginAmount/OneLotMargin;
double LotStep = MarketInfo(Symbol(),MODE_LOTSTEP);
lotMM = NormalizeDouble(lotMM/LotStep,0)*LotStep;

 
Hello.
Note, that "minimal lot" and "lot step" may differ.
For example, "minimal lot" may be 0.10, "lot step" may be 0.01.
In this case, simple calculation methods may produce incorrect operation volume, for example, 0.05.
Best regards,
Ais.
 
Ais wrote >>
Hello.
Another method of operation volume computing is in 'Ищу функцию вычисления размера лота.'.
Best regards,
Ais.

Ais
wrote
>>
Hello.
Note, that "minimal lot" and "lot step" may differ.
For example, "minimal lot" may be 0.10, "lot step" may be 0.01.
In this case, simple calculation methods may produce incorrect operation volume, for example, 0.05.
Best regards,
Ais.

Sto usando il codice che hai menzionato a 'Ищу функцию вычисления размера лота. Grazie.

HO UNA DOMANDA SU QUESTO CODICE: Produce sempre un numero pari di lotto (come 6.66 e non 6.67).

È buono se lo fa. Ma non capisco perché lo fa.

Il codice allegato è in un formato di file Script, quindi si potrebbe incollare il codice in un nuovo script ed eseguirlo immediatamente.

 
Hello.
Correct code must be able to produce any valid result.
Examples.




Best regards,
Ais.