Serve una formula di moneymanagement LOT size basata su SL e rischio del conto! - pagina 3

 

OK ragazzi! Questo codice è stato scritto da me ed è quello che uso nei miei EA. È abbastanza complesso perché, oltre al Risk% e StopLoss, tiene conto anche del Margin Risk% e corregge la dimensione del lotto in base a Minimum, Maximum e Step Size. Inoltre usa sempre il valore minimo del Bilancio corrente e del Patrimonio netto invece di usarne solo uno. Credo che sia più sicuro in questo modo.

Si prega di notare, tuttavia, che non utilizza lo spread nel calcolo, perché lo calcolo separatamente quando calcolo lo StopLoss da utilizzare. La funzione qui sotto, usa quindi una dimensione relativa dello stop loss. Nei miei EA l'argomento dblStopLossPips viene calcolato in anticipo in base a vari fattori come la strategia, lo spread, l'ATR, ecc.; quindi il valore finale passato alla funzione dblLotsRisk() è già un valore finale per calcolare la dimensione del lotto da utilizzare.

// 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:

Questo mi fa venire il mal di testa solo cercando di risolvere le parentesi!

Ad essere onesti, non ho assolutamente idea di cosa tu stia cercando di ottenere qui.

Non riesco a capire come MODE_STOPLEVEL o SPREAD siano rilevanti, sicuramente dovresti basare i tuoi calcoli sulla distanza dello stop-loss dal prezzo corrente?

Non dovrebbe fare differenza quale sia la valuta del conto, il calcolo dovrebbe essere lo stesso perché TICKVALUE è nella valuta del conto.

Nota bene, mettendo la tua linea di codice su 2 righe, il post non è così ampio e rende più facile la lettura senza scorrere a destra e a sinistra :)

Ho postato qualche pagina indietro, un'immagine in cui illustravo la mia formula per calcolare il lotto, ma il pipvalue o tickvalue o qualsiasi altra cosa è sempre un casino, quote->valuta base e altre cose che confondono, ma finora la mia formula ha fatto un buon lavoro, anche se non sono sicuro che sia corretta.

Lo SPREAD può essere irrilevante, ma lo stoplevel è necessario. Ho messo lo SL il più vicino possibile al prezzo di apertura dell'ordine che è lo stoplevel, ma a causa delle fluttuazioni e dei picchi, ho bisogno di regolarlo manualmente a volte, ecco perché ho messo una variabile STOPSLIP con cui posso regolare lo SL alla volatilità o altro.

FMIC:

OK ragazzi! Questo codice è stato scritto da me ed è quello che uso nei miei EA. E' abbastanza complesso perché, oltre al Risk% e allo StopLoss, tiene conto anche del Margin Risk% e corregge la dimensione del lotto in base a Minimum, Maximum e Step Size. Inoltre usa sempre il valore minimo del Bilancio corrente e del Patrimonio netto invece di usarne solo uno. Sento che è più sicuro in questo modo.

Si prega di notare, tuttavia, che non utilizza lo spread nel calcolo, perché lo calcolo separatamente quando calcolo lo StopLoss da utilizzare. La funzione qui sotto, utilizza quindi una dimensione relativa dello stop loss. Nei miei EA l'argomento dblStopLossPips viene calcolato in anticipo in base a vari fattori come la strategia, lo spread, l'ATR, ecc.; quindi il valore finale passato alla funzione dblLotsRisk() è già un valore finale per calcolare la dimensione del lotto da utilizzare.

Grazie, lo testerò e dirò il mio feedback!

Anche se non capisco perché hai messo così tante variabili lì, l'intero codice può essere inserito in 1 linea :)

 
Proximus:

Ho postato qualche pagina addietro un'immagine in cui illustravo la mia formula per calcolare il lotto, ma il pipvalue o tickvalue o qualsiasi altra cosa è sempre un casino, quote->valuta base e altre cose che confondono, ma finora la mia formula ha fatto un buon lavoro, anche se non sono sicuro che sia corretta.

Lo SPREAD può essere irrilevante, ma lo stoplevel è necessario. Ho messo lo SL il più vicino possibile al prezzo di apertura dell'ordine che è lo stoplevel, ma a causa delle fluttuazioni e dei picchi, ho bisogno di regolarlo manualmente a volte, ecco perché ho messo una variabile STOPSLIP con la quale posso regolare lo SL alla volatilità o altro.

Grazie, lo testerò e dirò il mio feedback!

Anche se non capisco perché hai messo così tante variabili, l'intero codice può essere inserito in 1 riga :)


Sì, il codice potrebbe essere messo tutto in una riga, ma credetemi, non è MAI un buon modo di scrivere codice, a meno che non stiate cercando di spremere fino all'ultimo ciclo di CPU dal vostro codice per essere il più veloce del pianeta.

Questo è il motivo per cui "GumRai" si è lamentato di avere il mal di testa cercando di fare testa o croce con l'altro codice. Semplicemente non era molto leggibile o facilmente comprensibile e questo rende molto difficile il debug.

Il mio modo può essere più prolisso, ma è più facile da eseguire il debug e mantenere, nonché più leggibile e più facile da capire da altri come te.

Ma sentitevi liberi di compattare tutto in una riga. Ma non lamentatevi se non dà gli stessi risultati. Lascerò a voi il compito di debuggare QUELLO.

 

Scusate se riapro questo thread ma è fondamentale confermare qualcosa, quindi questa è la funzione che mi è venuta in mente (la sto mettendo pubblica, potete ringraziarmi dopo):

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


Questa funzione dovrebbe restituire le unità di lotto basate sul rischio del conto, e calcolate tramite un conto in EUR, dato che l'EUR è sempre la valuta di base.

Unità di lotto significa = la dimensione reale del denaro di una posizione, quindi per un conto di 100 € con un rischio dell'1% dovrebbe restituire 1€ che, in base allo STOPLOSS, per esempio, uno stoploss di 100 pipette dovrebbe essere di 1000 unità di lotto (0.01 LOT IN MT4 EQUIVALENTE)

È fondamentale che la valuta del conto sia l'EURO, nient'altro.

Una volta chiamata la LOTUNITTORISK(), divideremo i risultati per 100.000 per ottenere la dimensione reale del lotto in formato MT4 (1000 unità di cassa 0.01 LOT in MT4)

RISKPERCENT =è un int e può essere 1,2,3,4 la % di rischio che rischiamo

STOPSIZE = è un int ed è il numero di pipette (pip/10 su broker a 5 cifre) che è la nostra dimensione di stop loss, quindi per esempio 60 pipette SL è un 6 pip SL

Voglio sapere se la funzione calcola correttamente i LOT UNITS, per favore testatela e se trovate qualche errore aiutatemi :)

Mille grazie!

 
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. Posizionate lo stop dove deve essere - dove la ragione del commercio non è più valida. Per esempio, facendo trading sul rimbalzo di un supporto, lo stop va sotto il supporto.
  2. Saldo del conto * percentuale = RISCHIO = (OrderOpenPrice - OrderStopLoss)*DIR * OrderLots * DeltaPerlot (Nota OOP-OSL include lo SPREAD)
  3. NON usare TickValue da solo - DeltaPerlot
  4. Devi anche controllare FreeMargin per evitare lo stop out
 
WHRoeder:
  1. Posizionate lo stop dove deve essere - dove la ragione del commercio non è più valida. Per esempio, facendo trading sul rimbalzo di un supporto, lo stop va sotto il supporto.
  2. Saldo del conto * percentuale = RISCHIO = (OrderOpenPrice - OrderStopLoss)*DIR * OrderLots * DeltaPerlot (Nota OOP-OSL include lo SPREAD)
  3. NON usare TickValue da solo - DeltaPerlot
  4. Devi anche controllare FreeMargin per evitare lo stop out

1) La funzione restituisce solo il LOT SIZE in unità monetaria non in unità MT4 nient'altro, quando metto gli ordini allora rispettivamente lo STOPSIZE sarà aggiunto /sottratto da Bid in caso di BUY e Ask in caso di sell.It è proprio come MT4 gestisce il TP e SL.

BUY aperto a ASK, chiuso a BID

VENDITA aperto a BID, chiuso a ASK

2) Non posso usare OrderOpenprice man perché nessun ordine viene aperto prima che questa funzione venga calcolata. Gli spread non sono inclusi, gli spread saranno gestiti quando aggiungo/sottraggo lo STOPSIZE dopo che l'ordine è aperto.

Ma prima dobbiamo determinare la dimensione del lotto, è logico.

3) Non capisco questo.

4) Ovviamente, ma sottolineo ancora una volta che la funzione di collocamento degli ordini viene eseguita dopo questo, e ha poco a che fare con questa funzione.L'unico scopo di questa funzione è quello di determinare la dimensione del lotto, nient'altro.


TickValue /  TickSize

Non è corretto, se li divido allora ottengo il numero sbagliato, forse per i conti USD dovrebbe essere fatto così, ma il suo è un conto EUR.

 
Proximus:

BUY aperto a ASK, chiuso a BID SELL aperto a BID, chiuso a ASK

2) Non posso usare OrderOpenprice

3) Non capisco questo.

4) t, se li divido allora ottengo il numero sbagliato, forse per i conti USD dovrebbe essere fatto così, ma è un conto EUR.

  1. L'Ask è l'OrderOpenPrice per un acquisto
  2. Il Bid è l'OrderOpenPrice per una vendita. Perché non puoi usarlo, devi saperlo per passarlo a OrderSend?
  3. Devi usare tickvalue/ticksize. Il tickvalue da solo non ha senso.
  4. Devi dividere per ottenere le unità corrette (Change in price) * (tickValue) /(change in price) ti dà un valore. $10 per pip = $1 per punto = valore/cambio. Ricorda che il risultato è in valuta del conto quindi quando lo dividi per il tuo rischio ottieni un numero puro, di nuovo le unità annullano $rischio(BAL%)/$rischio(SL). Se devi fare il multiplo stai facendo qualcosa di sbagliato o i valori del broker sono incasinati.
 
WHRoeder:
Proximus:

BUY aperto a ASK, chiuso a BID SELL aperto a BID, chiuso a ASK

2) Non posso usare OrderOpenprice

3) Non capisco questo.

4) t, se li divido allora ottengo il numero sbagliato, forse per i conti USD dovrebbe essere fatto così, ma è un conto EUR.

  1. L'Ask è l'OrderOpenPrice per un acquisto
  2. Il Bid è l'OrderOpenPrice per una vendita. Perché non puoi usarlo, devi saperlo per passarlo a OrderSend?
  3. Devi usare tickvalue/ticksize. Tickvalue da solo non ha senso.
  4. Devi dividere per ottenere le unità corrette (Change in price) * (tickValue) /(change in price) ti dà un valore. $10 per pip = $1 per punto = valore/cambio. Ricorda che il risultato è in valuta del conto quindi quando lo dividi per il tuo rischio ottieni un numero puro, di nuovo le unità annullano $rischio(BAL%)/$rischio(SL). Se devi fare il multiplo stai facendo qualcosa di sbagliato o i valori del broker sono incasinati.


1,2 Lo so, ma mi rendo conto che è gestito da un'altra funzione che non ha niente a che vedere con questa

3) Da quanto ho capito il tickvalue è il valore di 1 pip nella valuta di base, quindi a seconda della coppia che uso si dovrà o dividere o moltiplicare per essa, nel caso di un conto EUR sembra che si debba moltiplicare non dividere.

Ecco una foto che lo illustra meglio:


Sulla EUR/USD per un trade con rischio del 3% dobbiamo aprire 1798 unità, arrotondate a 0.02 LOTTI in unità MT4 per ottenere questo risultato.

La dimensione dello STOPLOSS è determinata da un'altra funzione.

Sembra essere corretto come l'ho provato, ma non sono sicuro che la formula sia veramente precisa, questo è ciò che sto cercando di determinare qui, quindi per favore aiutatemi su questo.

 

Anch'io ho cercato di capire questo calcolo della dimensione del lotto basato su SL, rischio del conto E livello di chiamata del margine, specialmente quando il livello di chiamata del margine non è 100% ma è per esempio 120%. La migliore risposta che ho trovato è quella che WHRoeder ha condiviso qui nel suo codice whrea.mq4. Il codice whrea.mq4 aveva bisogno di qualche correzione ma WHRoeder ha già dato questa correzione qui nella sua risposta al commento di RaptorUK. Quindi la risposta completa al calcolo della dimensione del lotto c'è, ma è necessario un certo sforzo per comprendere appieno ciò che WHRoeder ha condiviso.

Ho allegato il codice che ho estratto e modificato da WHRoeder whrea.mq4 per compilare con l'ultima nuova build di MT4 per calcolare la dimensione del lotto per un trade lungo dove il Margin Call Level è superiore al 100%.

Tuttavia, non sono sicuro che moltiplicare per il MarginCallLevel % sia corretto per prendere in considerazione il Margin Call Level % per evitare un margin call. Se il MarginCallLevel è 100% allora entrambe le linee di codice sarebbero corrette, ma se il MarginCallLevel è 120%, moltiplicare per il MarginCallLevel % sarebbe un test Margin Call corretto? Se no, qual è il modo corretto di farlo? WHRoeder, puoi aiutarmi con questo? William, ho fatto del mio meglio.

Ecco il codice della sezione Margin Test per un trade lungo:

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.
File:
 

... in questa parte di codice c'è un problema con la nuova compilazione (errore ---> 'MarketInfo' - tipo di espressione switch illegale) forse era tutto OK fino all'aggiornamento a MT4 build 600+ ... ma da allora non funziona più.

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

Quindi, potresti per favore postare qualche versione più recente ... se ovviamente sei ancora in giro.