Come si calcola la dimensione del lotto? - pagina 2

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




Best regards,
Ais.

Ho duplicato con successo le risposte che hai fornito (entro 0,01) e ho una domanda sui valori di ald.MinimalMargin.

Usando il mio conto standard IBFX, il mio ald.MinimalMargin è sempre $10, sia per GBPJPY che per EURUSD, mentre i vostri importi variano (come 185,785 o 147,6).

Hai qualche idea del perché i tuoi importi di margine minimo variano mentre i miei no?

 

Ho duplicato i tuoi importi ald.OperationVolume (entro .01) e ho una domanda.

Quando il calcolo viene eseguito sul tuo conto, l'ald.MinimalMargin varia.

Quando il calcolo viene eseguito sul mio conto standard IBFX, l'ald.MinimalMargin è sempre $10.

DOMANDA: Qualche idea del perché?

Ecco i valori di Alert sul mio sistema usando il conto standard IDFX. Notate che ald.MinimalMargin = 10 USD.

aas.Symbol = GBPJPY
aad.VARLimit = 3155 USD
aai.VARPoints = 50 punti
aai.Command = 0

Elaborazione:
ald.MinimalMargin = 10 USD
ald.MinimalPoint = 0.0942 USD
ali.PositionPoints = 106 punti
aai.VARPoints = 50 punti
ald.VARPositions = 0.4717 posizioni
aad.VARLimit = 3155 USD
ald.PositionLimit = 6688.6 USD
ald.VolumeLimit = 6.6886 lotti
ald.VolumeStep = 0.01 lotti
ald.NominalMargin = 1000 margine richiesto (ho inserito questa linea)
ald.MinimalVolume = 0.01 lotti

Output:
ald.OperationVolume = 6.68

 
Hello.
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.
Best regards,
Ais.
 
Hello.
The revised sample of the operation volume computing:

double avd.OperationVolume    ;

double avd.VARLimit  = 200.00 ;
int    avi.VARPoints = 50     ;

//<init>
int    init
 (//<0>
){//<1>
 
avd.OperationVolume = amd.OperationVolume ( Symbol () , avd.VARLimit , avi.VARPoints ) ;

}//</init> 

//<amd.OperationVolume>
double amd.OperationVolume
 (//<3>
       string aas.Symbol    ,
       double aad.VARLimit  ,
       int    aai.VARPoints
){//<31>

double ald.VolumeStep      = MarketInfo ( aas.Symbol , MODE_LOTSTEP        )                        ;
double ald.MinimalVolume   = MarketInfo ( aas.Symbol , MODE_MINLOT         )                        ;
double ald.NominalLot      = MarketInfo ( aas.Symbol , MODE_LOTSIZE        )                        ;
double ald.NominalMargin   = MarketInfo ( aas.Symbol , MODE_MARGINREQUIRED )                        ;
double ald.NominalTick     = MarketInfo ( aas.Symbol , MODE_TICKVALUE      )                        ;
double ald.QuoteTick       = MarketInfo ( aas.Symbol , MODE_TICKSIZE       )                        ;
double ald.QuotePoint      = MarketInfo ( aas.Symbol , MODE_POINT          )                        ;

double ald.MinimalMargin   = ald.NominalMargin       * ald.MinimalVolume                            ;
double ald.MinimalTick     = ald.NominalTick         * ald.MinimalVolume                            ;
double ald.MinimalPoint    = ald.MinimalTick         * ald.QuotePoint    / ald.QuoteTick            ;
int    ali.PositionPoints  = MathRound               ( ald.MinimalMargin / ald.MinimalPoint )       ;

double ald.VARPositions    = aai.VARPoints * 1.0     / ali.PositionPoints                           ;
double ald.MarginLimit     = avd.VARLimit            / ald.VARPositions                             ;
double ald.VolumeLimit     = ald.MarginLimit         / ald.NominalMargin                            ;
 
double ald.OperationVolume = 0                                                                      ;

if   ( ald.VolumeLimit    >= ald.MinimalVolume )
     { int ali.Steps       = MathFloor ( ( ald.VolumeLimit - ald.MinimalVolume ) / ald.VolumeStep ) ;
       ald.OperationVolume = ald.MinimalVolume + ald.VolumeStep * ali.Steps                         ; }

string als.LotMeasure      , als.BaseCurrency                                                       ;

if   ( AccountLeverage () != NormalizeDouble ( ald.NominalLot / ald.NominalMargin , 1 ) )
     { als.BaseCurrency    = StringSubstr    ( aas.Symbol , 0 , 3 )                                 ;
       als.LotMeasure      = als.BaseCurrency                                                       ; }
else   als.LotMeasure      = AccountCurrency ()                                                     ;

Alert  ( " "                                                                                      ) ;
Alert  ( "ald.OperationVolume = " , ald.OperationVolume , " " , "lots"                            ) ;
Alert  ( "Output :"                                                                               ) ;
Alert  ( " "                                                                                      ) ;
Alert  ( "ald.MinimalVolume   = " , ald.MinimalVolume   , " " , "lots"                            ) ;
Alert  ( "ald.VolumeStep      = " , ald.VolumeStep      , " " , "lots"                            ) ;
Alert  ( "ald.VolumeLimit     = " , ald.VolumeLimit     , " " , "lots"                            ) ;
Alert  ( "ald.MarginLimit     = " , ald.MarginLimit     , " " , AccountCurrency ()                ) ;
Alert  ( "aad.VARLimit        = " , aad.VARLimit        , " " , AccountCurrency ()                ) ;
Alert  ( "ald.VARPositions    = " , ald.VARPositions    , " " , "positions"                       ) ;
Alert  ( "aai.VARPoints       = " , aai.VARPoints       , " " , "points"                          ) ;
Alert  ( "ali.PositionPoints  = " , ali.PositionPoints  , " " , "points"                          ) ;
Alert  ( "ald.MinimalPoint    = " , ald.MinimalPoint    , " " , AccountCurrency ()                ) ;
Alert  ( "ald.MinimalMargin   = " , ald.MinimalMargin   , " " , AccountCurrency ()                ) ;
Alert  ( "ald.NominalMargin   = " , ald.NominalMargin   , " " , AccountCurrency ()                ) ;
Alert  ( "ald.NominalLot      = " , ald.NominalLot      , " " , als.LotMeasure                    ) ;
Alert  ( "Processing :"                                                                           ) ;
Alert  ( " "                                                                                      ) ;
Alert  ( "aai.VARPoints       = " , aai.VARPoints       , " " , "points"                          ) ;
Alert  ( "aad.VARLimit        = " , aad.VARLimit        , " " , AccountCurrency ()                ) ;
Alert  ( "aas.Symbol          = " , aas.Symbol                                                    ) ;
Alert  ( "Input :"                                                                                ) ;
Alert  ( " "                                                                                      ) ;
Alert  ( "AccountLeverage ()  = " , AccountLeverage ()                                            ) ;
Alert  ( "AccountCurrency ()  = " , AccountCurrency ()                                            ) ;
 
return ( ald.OperationVolume )                                                                      ;

}//</amd.OperationVolume>
 



Best regards,
Ais.
 
Il calcolo della dimensione del lotto è il calcolo della perdita massima consentita. Il rischio è il prezzo aperto - lo stop loss iniziale (Acquisto: Ask-SL, Vendita: SL-Bid) La perdita massima è il rischio per la perdita per pip. Questo è quello che vuoi che sia il 2% del saldo del conto. Niente a che fare con il margine. Cerca di capire dove saranno la tua apertura e i tuoi stop, poi la dimensione del lotto segue da questo.
//+------------------------------------------------------------------+
//| 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;
        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.
}

 

Continui a postare questo codice più e più volte nel forum, e in questo caso hai inserito un thread-necro di 2 anni fa per farlo, ed è corretto solo per le coppie di valute che hanno la denominazione del conto come contro-valuta nella coppia di valute.

(Se la denominazione del conto = USD e la coppia di valute EURUSD allora il tuo codice è corretto... ma è sbagliato per USDJPY, EURJPY, ecc.)

Io continuo a farlo notare, tu continui a ignorarlo.

 

WHRoeder, hai una versione aggiornata di questo codice che sia valido per tutte le coppie di valute indipendentemente dalla denominazione del conto o dall'essere contro-valuta?


Grazie.

 
Per quanto ne so QUI troverete la sua ultima collezione completa di codice base. Scorrete fino al suo post con l'allegato.
 
  1. roy7:
    WHRoeder, hai una versione aggiornata di questo codice che sia valido per tutte le coppie di valute indipendentemente dalla denominazione del conto o dall'essere contro-valuta?

    Quel codice è valido per qualsiasi coppia.
    return(  MarketInfo(Symbol(), MODE_TICKVALUE)
          / MarketInfo(Symbol(), MODE_TICKSIZE) ); // Not Point.
    Restituisce il cambiamento della valuta del conto per un tick della coppia, qualsiasi coppia. Non sono necessari cambiamenti, a meno che i tuoi stop siano così grandi che tickValue cambia significativamente (cioè 2000 pip SL.)
  2. 1005phillip 2010.09.18 17:29
    Io continuo a farlo notare, tu continui ad ignorarlo.
    Perché ti sbagli.
  3. ForexCoder 2011.06.01 06:42
    Per quanto ne so QUI troverete la sua ultima collezione completa di codice base. Scorrere fino al suo post con l'allegato.
    AutoScroll
 

Grazie!