
Parte SECONDA: Come controllare il rischio
La gestione della posizione è una delle componenti più importanti nel trading.
Mentre, infatti, la direzione del mercato è sempre predittiva, soggetta a interpretazioni o statistiche più o meno valide a seconda delle condizioni del mercato, la gestione della posizione è l’unico fattore che possiamo decidere noi. Per questo focalizzarsi su questo aspetto è di importanza fondamentale.
Capitolo 8: Tipi di immissione ordine
Quando effettuiamo degli acquisti o vendite su strumenti finanziari abbiamo a che fare con il book di negoziazione.
Il book di negoziazione è, in sostanza, la “lista in tempo reale” di tutti gli ordini di acquisto e vendita presenti in un mercato in un determinato momento. Lo possiamo immaginare come un grande tabellone elettronico che mostra chi vuole comprare, chi vuole vendere, a quale prezzo e con quale quantità.
§ 8.1 – Ordine al meglio
Gli ordini rappresentano il modo in cui entriamo o usciamo dal mercato.
I principali tipi di ordini sono: ordini al meglio e ordini pendenti (LIMIT e STOP).
Gli ordini al meglio (o market order) vengono eseguiti immediatamente al miglior prezzo disponibile in quel momento sul mercato. Sono ideali quando vogliamo entrare o uscire dal mercato senza ritardi. La controparte è che non abbiamo il controllo preciso sul prezzo di esecuzione, che può variare in base alla liquidità ed alla velocità del mercato.
Quello “al meglio” è il modo più semplice per operare: dato un book di negoziazione con prezzi bid (a sinistra del book) e ask (a destra del book) che formano l’offerta del mercato, entriamo, in caso di operazione in acquisto (o long) semplicemente acquistando subito il primo livello ask con la relativa quantità. Per l’operazione di vendita allo scoperto vale esattamente l’opposto.
§ 8.2 – Ordine pendente
Gli ordini pendenti, invece, vengono eseguiti solo al verificarsi di una determinata condizione di prezzo. Distinguiamo due tipi di ordine pendenti:
– Limit order in cui impostiamo un prezzo specifico a cui vogliamo comprare o vendere. L’ordine verrà eseguito solo se il mercato raggiungerà quel livello o uno migliore.
L’ordine LIMIT è utile per entrare a prezzi più vantaggiosi o per prendere profitto.
– Stop order in cui impostiamo un prezzo specifico che si attiva quando il prezzo raggiunge un certo livello, trasformandosi in un ordine al meglio. Viene spesso usato per entrare a breakout (seguendo il trend del prezzo) oppure per limitare le perdite (stop loss).
In sintesi, gli ordini al meglio privilegiano la velocità di esecuzione, mentre gli ordini pendenti permettono un maggiore controllo sul prezzo e sulla strategia operativa.
In ProRealTime gli ordini pendenti durano una sola candela, quindi vanno piazzati nuovamente se alla candela successiva servono ancora. In pratica se la condizione rimane vera, il codice viene rieseguito a ogni nuova barra. La precisazione importante è che non è lo stesso ordine che rimane pendente: l’ordine LIMIT/STOP precedente, se non eseguito, scade dopo una barra, e alla barra successiva il codice può generarne uno nuovo.
Questo permette di stabilire entro quante candele deve valere un ordine pendente (stop o limit).
Prendiamo questo esempio sul Dax in cui all’evento crossover si stabilisce un prezzo di entrata STOP e si immette un ordine valido solo per le successive tre candele:
once prezzoEntrata = 0
once conto = 0
if not onMarket and prezzoEntrata = 0 and close crosses over average[20] then
prezzoEntrata = high + 100 * pointSize
conto = conto + 1
endif
if prezzoEntrata > 0 and conto <= 3 then
buy 1 contract at prezzoEntrata STOP
endif
if onMarket then
prezzoEntrata = 0
endif
if conto >= 3 then
prezzoEntrata = 0
endifRiassumiamo la differenza tra gli ordini STOP e LIMIT.
Gli ordini STOP hanno come logica di entrare del breakout di un certo livello, ossia in favore di trend e vengono quindi effettuati a prezzi più alti (se long) o più bassi (se short).
Con gli ordini di entrata STOP si hanno prezzi di entrata meno convenienti di quello attuale, ma si entra a favore del trend.
Gli ordini LIMIT invece sono entrate a prezzi più convenienti di quelli attuali, ossia si attende che il prezzo sia ad un prezzo migliore di quello attuale.
Hanno una logica opposta a quelli STOP, ossia di entrare (prendiamo il caso long) non al superamento di un livello di resistenza, ma di acquisto su un livello inferiore, come un supporto. Entriamo quindi contro trend.
Vediamo schematizzata in questo grafico le differenze:

Vediamo un esempio di ordine pendente STOP in cui si entra sopra il massimo della candela precedente più 1 tick, oppure sotto il minimo meno 1 tick:
if not onMarket then
buy 1 contract at high[1] + (1 * pointSize) STOP
sellShort 1 contract at low[1] - (1 * pointSize) STOP
endifFacciamo notare che in ProRealTime mentre gli ordini vengono eseguiti all’inizio della candela successiva a quella che ha generato il segnale, gli ordini pendenti che vengono eseguiti come stop loss o take profit di una posizione possono anche essere eseguiti all’interno di una candela.
§ 8.3 – Ordini breakout temporali
Come abbiamo visto, le entrate di tipo STOP sono usate principalmente per entrate a breakout su specifici punti di prezzo.
Per “breakout” infatti si intende la violazione di un livello chiave (supporto o resistenza) che porta il prezzo fuori da un trading range che aveva ingabbiato il prezzo per un certo periodo.
Quando il prezzo supera la resistenza si parla di breakout rialzista, quando rompe il supporto di breakout ribassista.
In questo esempio vediamo come spesso, nel trading reale, i breakout sono breakout di un punto temporale specifico, ossia dei massimi e minimi di una specifica barra temporale.
In questo esempio compriamo/vendiamo il breakout del massimo/minimo della barra oraria delle ore 09:00:
if intraDayBarIndex = 0 then
massimo = 0
minimo = 0
endif
if time = 090000 then // salva barra delle 09:00
massimo = high
minimo = low
endif
if time > 090000 and not onMarket then
if close < massimo then
buy 1 contract at massimo + pointSize STOP
endif
if close > minimo then
sellshort 1 contract at minimo - pointSize STOP
endif
endif§ 8.4 – Ordini box-breakout temporali
Dal punto di vista operativo oltre che operare su singole barre che rappresentano degli specifici ed importanti punti temporali, può essere utile identificare dei veri e propri box-range temporali in cui operare.
In questo esempio individuiamo il massimo ed il minimo del box temporale che va dalle 9.00 alle 12.00 per poi utilizzarli in un orario che vogliamo.
In sostanza usiamo i valori salvati del box che si crea dalle ore 09:00 alle 12:00 per poi utilizzare questi valori in un momento che vogliamo, nell’esempio nella fascia temporale dalle 14:30 alle 17:00.
beginTime = 143000
endTime = 170000
if time = 090000 then
massimo = high
minimo = low
endif
if (time >= 090000) and (time <= 120000) then
massimo = max(massimo,high)
minimo = min(minimo,low)
endif
if time >= beginTime and time <= endTime and not onMarket then
if close < massimo then
buy 1 contract at massimo STOP
else
buy 1 contract at massimo LIMIT
endif
if close > minimo then
sellShort 1 contract at minimo STOP
else
sellShort 1 contract at minimo LIMIT
endif
endifQuesto è un esempio completo di un sistema in cui si trada il breakout del massimo/minimo di un determinato numero di barre (ossia di una zona temporale):
defParam cumulateOrders = false
positionSize = 1
startTime = 080000
endTime = 180000
period = 10
distance = 5
stopLoss = 60
takeProfit = 10
// Condizione oraria operativa
timeCondition = time >= startTime AND time <= endTime
highestLevel = highest[period](high)
lowestLevel = lowest[period](low)
if not onMarket and timeCondition then
buy positionSize contract at highestLevel + distance * pointSize STOP
sellshort positionSize CONTRACT AT lowestLevel - distance * pointSize STOP
endif
set stop pLoss stopLoss
set target pProfit takeProfitIn generale questa è la scrittura per trovare massimi e minimi di un box temporale orario, qui dalle ore 09:00 alle 10:00. Poiché ci interessa la barra che apre a una determinata ora, è appropriato usare openTime. La logica è questa: alle 09:00 inizializziamo il box; nelle barre successive aggiorniamo massimo e minimo; quando arriva la barra delle 10:00, il range 09:00–10:00 è terminato.
if intradaybarindex = 0 then // eliminiamo i valori del giorno prima
myHighest = 0
myLowest = 999999
endif
if openTime = 090000 then // calcoliamo il range sulla barra dalle 09:00 alle 10:00
myHighest = high
myLowest = low
endif
if openTime > 090000 and openTime < 100000 then // formazione del range temporale
myHighest = max(myHighest,high)
myLowest = min(myLowest,low)
endifCon questa formula che possiamo sempre riutilizzare (basta cambiare gli orari) fissiamo:
– una fascia temporale in cui individuare massimi e minimi,
– un orario operativo.
La strategia costruisce un range temporale utilizzando il massimo e il minimo delle barre comprese tra le 09:00 e le 10:00. Alle 09:00 vengono inizializzati myHighest e myLowest con il massimo e il minimo della prima barra del periodo. Fino alle 10:00 i due valori vengono aggiornati, ottenendo così il massimo e il minimo dell’intero box. Dalle 11:00 alle 12:00 la strategia cerca il breakout del box temporale.
La separazione tra periodo di costruzione del box (09:00–10:00) e periodo di trading (11:00–12:00) è particolarmente istruttiva:
defParam cumulateOrders = false
startHour = 110000
endHour = 120000
pointsDistance = 15 * pointSize
cTime = time >= startHour and time <= endHour // orario per acquistare/vendere un breakout
if intradayBarindex = 0 then
myHighest = 0
myLowest = 999999
endif
if openTime = 090000 then
myHighest = high
myLowest = low
endif
if openTime > 090000 and openTime < 100000 then // formazione del range/box temporale
myHighest = max (myHighest,high)
myLowest = min (myLowest,low)
endif
if cTime and not onMarket then // breakout long 11:00 - 12:00
buy 1 contract at (myHighest + pointsDistance) STOP
set stop pLoss 100
set target pProfit 100
endif
if cTime and not onMarket then // breakout short 11:00 - 12:00
sellShort 1 contract at (myLowest - pointsDistance) STOP
set stop pLoss 100
set target pProfit 100
endifCompletiamo questa panoramica sui box temporali con lo studio di alcune uscite.
Nell’esempio riportato sotto, alle 09:00 vengono inizializzati il massimo e il minimo della barra. Dalle 09:00 alle 10:00 questi valori vengono aggiornati per costruire il range del box temporale.
Vediamo poi come identificare delle barre precedenti a quella attuale per individuare correttamente le barre di uscita (usiamo in questi esempi un timeframe di 1 ora):
if openTime = 090000 then
myHighest = high
myLowest = low
endif
if openTime >= 090000 and openTime <=100000 then
myHighest = max (myHighest,high)
myLowest = min (myLowest,low)
endif
if openTime = 090000 then
A) uscita sotto il minimo della barra oraria precedente dalle 8 alle 9:
myExit = lowest[1](low)
B) uscita sotto il minimo delle ultime due barre orarie precedenti dalle 7 alle 9:
myExit = lowest[2](low)
C) uscita sotto il minimo della barra oraria precedente a quella attuale, dalle 7 alle 8:
myExit = lowest[1](low[1])
endifCapitolo 9: Gestire la posizione
Dal momento che i mercati finanziari seguono flussi non prevedibili, il controllo del rischio diventa l’aspetto più importante del trading a cui non si dedica, specialmente all’inizio, mai abbastanza attenzione.
In pratica non si conosce né si stima mai correttamente il rischio, con tutte le conseguenze operative che poi ne derivano.
Possiamo considerare diversi livelli di gestione-controllo del rischio. Ne distinguiamo per semplicità tre:
– la selezione accurata dei criteri di entrata,
– la corretta determinazione del peso della posizione,
– l’uso diretto di criteri di protezione una volta entrati in posizione, di cui ci occupiamo in questo capitolo.
§ 9.1 – Usare gli stop loss
Lo stop loss è un ordine automatico che chiude una posizione quando il prezzo raggiunge un livello prestabilito, limitando le perdite massime accettabili. Lo stop loss è uno degli strumenti di gestione del rischio più importanti nel trading.
I mercati si muovono in modo casuale. Senza uno stop loss, una posizione in perdita può erodere progressivamente il capitale, generando perdite molto superiori a quelle inizialmente tollerabili e compromettendo la possibilità di continuare ad operare.
In ProRealTime abbiamo diversi modi per uscire dalla posizione e settare gli stop loss. I due più conosciuti sono:
1) l’uso dell’istruzione SELL (per uscire da posizioni long) ed EXITSHORT (per uscire da posizioni short):
sell 1 contract at market // uscita da una posizione long
exitShort 1 contract at market // uscita da una posizione short 2) il secondo modo per uscire dalla posizione è attraverso l’istruzione SET (a cui va sempre agganciato uno stop loss).
Possiamo definire lo stop in punti, in percentuale, valore monetario:
SET STOP pLoss // La posizione sarà chiusa non appena la perdita sarà pari ad una certa quantità di punti dal prezzo di entrata, spese di intermediazione non incluse (come in tutti i tipi di stop loss).
SET STOP %LOSS // La posizione sarà chiusa non appena la perdita raggiungerà una certa percentuale dal prezzo di entrata.
SET STOP $LOSS // La posizione sarà chiusa non appena la perdita raggiungerà un certo importo (nella valuta dello strumento).
* Per disattivare uno Stop loss nel codice, bisogna utilizzare la seguente istruzione:
SET STOP pLOSS 0, SET STOP %LOSS 0, SET STOP $LOSS 0Oppure possiamo definire lo stop come vogliamo.
Ecco un esempio basato sulla volatilità:
atrPeriod = 14
atrMult = 2
myATR = averageTrueRange[atrPeriod](close)
if not onMarket and (condizione di ingresso) then
buy 1 contract at market
SET STOP LOSS myATR * atrMult
endifQui invece inseriamo lo stop loss sul minimo a 10 candele:
SL = Lowest[10](Low)
// Impostazione dell'ordine di uscita al prezzo calcolato
SET STOP PRICE SLAbbiamo visto come settare uno stop loss, ma dove lo piazziamo?
Se usiamo l’analisi tecnica classica lo stop dovrebbe essere piazzato, nel caso di operazione long, sotto un livello tecnico rilevante (supporto, swing low, media mobile …), così da essere invalidato solo se la posizione che abbiamo preso è effettivamente sbagliata.
Nel caso dei trading system tuttavia si possono benissimo usare vari tipi di stop, sia tecnici, ma anche puramente percentuali (quando perdiamo, ad esempio, lo 0.5% usciamo dalla posizione), a punti, monetari …
Ci sono varie regole generali sul rapporto rischio-rendimento che ci forniscono indicazioni di dove piazzare gli stop loss. Una regola di base è la seguente: prima di entrare in un’operazione, verificare che il potenziale guadagno (target) sia almeno il doppio del rischio (stop). Un rapporto 1:2 o 1:3 è considerato accettabile.
Un’altra regola generale è quella di legare la size dello stop loss alla grandezza del capitale: se il capitale totale è 10.000€ e si accetta un rischio massimo del 2% per operazione (200€), la size va calcolata di conseguenza in base alla distanza dello stop.
Al di là del tipo di stop che scegliamo, una regola essenziale che dovrebbe essere sempre seguita è quella di non spostare mai lo stop loss. Modificarlo per allontanarlo mentre il prezzo si avvicina, sperando in un’inversione, è uno degli errori più gravi e diffusi: definita una strategia non dovrebbe poi essere cambiata in corso. Alterare i parametri di rischio a operazione avviata invalida la pianificazione iniziale e mina la disciplina, pilastro fondamentale del trading.
§ 9.2 – Stop Loss Esempi
Riportiamo qui una carrellata di esempi operativi tratti dall’utilizzo personale e dal forum di ProRealCode (https://www.ProRealCode.com/forums/) che possono essere utili per avere un’idea della grande varietà di stop loss che si possono inserire in una strategia.
Chiudere una posizione quando si verifica una candela ribassista con chiusura inferiore allo 0.5% dell’apertura:
if longOnMarket and close < open and close < open * 0.995 then
sell at market
endifStop loss posto a -0.3% dal valore di ingresso:
SL = close * 0.997 // = close x (1 - 0.003) Inserire uno stop loss dinamico sotto il minimo di 5 candele:
set stop loss abs(close - lowest[5](low)) E’ importante ricordare che: “set” vuole una differenza di prezzo in quanto indica una distanza dello stop, definisce la distanza dello stop dal prezzo di entrata. “Sell” invece vuole il prezzo dello stop, il livello preciso al quale deve essere posizionato l’ordine.
Come inserire uno stop loss sotto l’ultima candela oppure sotto una media:
if mieCondizioni then
buy 1 contract at market
SL = close - low[1] // stop sotto il minimo della candela precedente
SL = abs (close - average[20]) // stop sotto la media a 20 periodi
set stop loss SL
endif Qui fissiamo lo stop loss come minimo di due condizioni, una monetaria e l’altra tecnica, usando la funzione MIN, che confronta valori numerici:
SL = MIN(10 * pointSize, close - average[20](close))Qui usciamo se dopo essere trascorse 5 barre dall’apertura della posizione non si è raggiunto un determinato profitto:
if longOnMarket and (barIndex - tradeIndex(1)) > 5 and (close - tradePrice(1)) < 10 * pointSize then
sell at market
endifUsciamo se dopo 3 barre non si sono guadagnati almeno 35 punti:
if longOnMarket and (barIndex - tradeIndex(1)) = 3 then
if (close - tradePrice(1)) < 35 * pointSize then
sell at market
endif
endifUn altro modo di uscire da una posizione è quella di usare la volatilità, qui vediamo un esempio con l’average true range:
cLong = close crosses over average[20](close)
if cLong and not onMarket then
myATR = AverageTrueRange[10]
mySL = myATR
myTP = myATR * 2
buy 1 contract at market
SET STOP pLOSS mySL / pointSize
SET TARGET pPROFIT myTP / pointSize
endifQui vediamo come disattivare uno stop loss
if time < 110000 then
// nessuno stop
else
set stop pLOSS 20
endifPer vedere altri esempi sugli stop loss rimandiamo al capitolo sulle nuove istruzioni di ProRealTime.
§ 9.3 – Target Profit
Il Target Profit (TP) è un ordine condizionato che chiude automaticamente una posizione aperta nel momento in cui il prezzo raggiunge un livello predefinito di guadagno.
Quando apriamo una posizione (long o short), possiamo definire in anticipo il livello di prezzo a cui vogliamo uscire in profitto. ProRealTime invia l’ordine al broker non appena il mercato tocca quel livello.
I principali vantaggi di usare un target profit sono:
– Automazione completa. Una volta impostato, il TP lavora anche quando non siamo a schermo. Questo è particolarmente utile quando operiamo su molti mercati con orari differenti.
– Gestione delle emozioni. Una volta che abbiamo fissato l’obiettivo prima dell’apertura della posizione, eliminiamo la tentazione di spostare il target in corso d’opera.
– Definizione del rapporto rischio/rendimento. Impostare insieme Stop Loss e Take Profit prima dell’entrata permette di calcolare esattamente il risk/reward ratio di ogni operazione, elemento fondamentale per una solida gestione del capitale.
Lo svantaggio principale di fissare un target di prezzo è che limitiamo il potenziale rialzista del mercato.
Per ovviare a questo si dovrebbero introdurre nella strategia tecniche di rientro in posizione che ci consentano, una volta usciti in profitto, di poter rientrare a determinate condizioni se il trend dovesse proseguire.
La scrittura in ProRealTime è uguale in tutte le forme a quella degli stop loss, chiaramente scriviamo PROFIT al posto di LOSS nell’istruzione.
if condizioneLong then
buy 1 contract at market
endif
SET TARGET pPROFIT 100 // target a 100 punti
oppure
SET TARGET %PROFIT 2 // target al 2% dal prezzo§ 9.4 – Tipi di trailing profit
Il Trailing Profit è una tecnica avanzata di gestione delle posizioni che consente di proteggere i guadagni accumulati mentre si lascia correre un trade in direzione favorevole.
Il trailing profit permette di mantenere almeno una parte del profitto realizzato fissando due livelli:
– il livello di attivazione (il punto dove si attiva il trailing profit)
– il livello di ritracciamento (con il quale decidiamo quanto spazio dare al possibile ritracciamento)
In generale con il trailing profit (lo chiamiamo per semplicità TRP) abbiamo i seguenti vantaggi operativi:
– si evita di chiudere troppo presto un trade vincente,
– si protegge parte del capitale guadagnato in caso di inversione improvvisa.
Gli aspetti negativi invece riguardano la difficoltà di fissare correttamente i livelli di ritracciamento, rischiando di uscire prematuramente da un trend.
Questo accade prevalentemente quando ci sono dei trend forti con un’alta volatilità.
Per questo motivo solo l’utilizzo di backtest approfonditi consente di valutare correttamente se aggiungere un TRP ad una strategia o meno e di che tipo.
Ci sono infatti moltissimi tipi di trailing profit, qui vediamo i due più comuni.
Il primo tipo di trailing profit che prendiamo in considerazione è quello classico.
La logica di questo trailing è la seguente: non appena il profitto raggiunge una soglia prefissata, lo stop viene spostato al prezzo di entrata più un delta prefissato, mettendosi così in guadagno garantito. Da quel momento in poi, ogni volta che il prezzo avanza nella direzione del trade di un ulteriore delta, lo stop di uscita viene aggiornato di conseguenza, mantenendo sempre la stessa distanza dal prezzo corrente.
Vediamo i due codici in punti ed in percentuale in modo da poter essere copiati ed utilizzati in una strategia (chiaramente i nomi delle variabili si possono cambiare).
Questo primo algoritmo muove lo stop solo quando il mercato copre una determinata ampiezza di punti (reach), spostandolo in avanti di un ammontare prestabilito (keep). Le variabili: rL, rS, kL e kS sono da ottimizzare per trovare i valori migliori.
pointToReachLong = rL * pointSize // es. rL (reachLong) = 50 punti
pointToReachShort = rS * pointSize
pointToKeepLong = kL * pointSize
pointToKeepShort = kS * pointSize
if not onMarket then
myNewSL = 0
endif
if longOnMarket then
if myNewSL = 0 and high - tradePrice(1) > pointToReachLong then
myNewSL = tradePrice(1) + pointToKeepLong
endif
if myNewSL > 0 and high - myNewSL > pointToReachLong then
myNewSL = myNewSL + pointToKeepLong
endif
endif
if shortOnMarket then
if myNewSL = 0 and tradePrice(1) - low > pointToReachShort then
myNewSL = tradePrice(1) - pointToKeepShort
endif
if myNewSL > 0 and myNewSL - low > pointToReachShort then
myNewSL = myNewSL - pointToKeepShort
endif
endif
// Se la variabile "myNewSL" contiene un valore valido (> 0), inseriamo gli ordini condizionali d'uscita
if myNewSL > 0 then
sell at myNewSL stop
exitshort at myNewSL stop
endifIl codice usa high e low come punti di attivazione. Sostituendoli con close, lo stop si aggiornerà esclusivamente sulla base del prezzo di chiusura della candela. Questo elimina i falsi segnali dovuti a picchi o spike improvvisi durante la formazione della barra, al costo di una minore tempestività nelle uscite.
Questo è lo stesso codice riportato sopra, ma in percentuale.
pointToReachLong = close * rL / 100 // es. se close=5000 e rL=0.5 → 25 punti prezzo
pointToReachShort = close * rS / 100
pointToKeepLong = close * kL / 100
pointToKeepShort = close * kS / 100
if not onMarket then
myNewSL = 0
endif
if longOnMarket then
if myNewSL = 0 and high - tradePrice(1) > pointToReachLong then
myNewSL = tradePrice(1) + pointToKeepLong
endif
if myNewSL > 0 and high - myNewSL > pointToReachLong then
myNewSL = myNewSL + pointToKeepLong
endif
endif
if shortOnMarket then
if myNewSL = 0 and tradePrice(1) - low > pointToReachShort then
myNewSL = tradePrice(1) - pointToKeepShort
endif
if myNewSL > 0 and myNewSL - low > pointToReachShort then
myNewSL = myNewSL - pointToKeepShort
endif
endif
if myNewSL > 0 then
sell at myNewSL stop
exitshort at myNewSL stop
endif Il secondo tipo di trailing profit che prendiamo in considerazione è quello MFT (“max favorable excursion”).
Questo tipo di trailing profit non aggiunge una quantità di punti al prezzo di entrata per mantenere un profitto, ma sottrae una quantità prefissata di punti dal massimo punto raggiunto di guadagno. Questa è la versione in punti:
pointToReachLong = rL * pointSize // es. 100 punti pointToReachShort = rS * pointSize
pointToKeepLong = kL * pointSize
pointToKeepShort = kS * pointSize
if not onMarket then
maxPrice = 0
minPrice = 999999
priceExit = 0
endif
if longOnMarket then
maxPrice = MAX(maxPrice,high)
if maxPrice-tradePrice(1) > pointToReachLong then
priceExit = maxPrice - pointToKeepLong
endif
endif
if shortOnMarket then
minPrice = MIN(minPrice,low)
if tradePrice(1) – minPrice > pointToReachShort then
priceExit = minPrice + pointToKeepShort
endif
endif
if onMarket and priceExit > 0 then
sell at priceExit STOP
exitShort at priceExit STOP
endifRiportiamo anche per questo secondo tipo di trailing la versione in percentuale.
Qui utilizziamo tradePrice(1) al posto di close per la stabilità dei punti. TradePrice(1) rappresenta il prezzo esatto a cui è stato eseguito l’ultimo ordine d’ingresso. Trattandosi di un valore fisso, le distanze in punti pointToReachLong e pointToKeepLong vengono calcolate una volta sola e rimangono identiche per tutta la durata dell’operazione.
La differenza fondamentale è che rL, rS, kL e kS vengono calcolati rispetto al prezzo di entrata, che rimane fisso, anziché rispetto al close corrente, che cambia ad ogni barra.
pointToReachLong = tradePrice(1) * rL / 100
pointToReachShort = tradePrice(1) * rS / 100
pointToKeepLong = tradePrice(1) * kL / 100
pointToKeepShort = tradePrice(1) * kS / 100
if not onMarket then
maxPrice = 0
minPrice = 999999
priceExit = 0
endif
if longOnMarket then
maxPrice = MAX(maxPrice,high)
if maxPrice - tradePrice(1) > pointToReachLong then
priceExit = maxPrice-pointToKeepLong
endif
endif
if shortOnMarket then
minPrice = MIN(minPrice,low)
if tradePrice(1) - minPrice > pointToReachShort then
priceExit = minPrice + pointToKeepShort
endif
endif
if onMarket and priceExit > 0 then
sell at priceExit STOP
exitShort at priceExit STOP
endif§ 9.5 – Stop a Breakeven
Uscire a breakeven (a pareggio) dopo una prima fase favorevole è un’alternativa da considerare rispetto all’uso di un trailing stop. Con il trailing stop proteggiamo una parte del profitto accumulato, riducendo però lo spazio di ritracciamento del prezzo e col rischio di uscire prematuramente dal trend. Al contrario, spostando lo stop a breakeven offriamo al mercato la massima libertà di movimento: la posizione si chiuderà solo con il raggiungimento del target finale oppure a pareggio, senza incassare profitti intermedi.
In un trading system, la scelta tra un’uscita a breakeven e un trailing profit non dovrebbe basarsi solo sulle preferenze personali, ma soprattutto sui risultati di un’accurata analisi statistica in fase di backtest.
Va notato che, sebbene sia una prassi meno comune, è possibile combinare questi due approcci impostandoli su soglie differenti: possiamo attivare lo stop a breakeven al raggiungimento di X punti per azzerare il rischio, e innescare un trailing profit solo a partire da Y punti per iniziare a bloccare progressivamente i guadagni accumulati.
Ecco un modo di scrivere del codice per un’uscita a breakeven.
Separiamo per una maggiore chiarezza long e short e riportiamo le formule in punti e percentuale:
Qui il metodo in punti:
pointToReachBreakevenL = 100 * pointSize
pointToReachBreakevenS = 50 * pointSize
once myExit = 0
if not onMarket then
myExit = 0
endif
if longOnMarket and myExit = 0 and (close - tradePrice(1)) >= pointToReachBreakevenL then
myExit = tradePrice(1)
elsIf shortOnMarket and myExit = 0 and (tradePrice(1) - close) >= pointToReachBreakevenS then
myExit = tradePrice(1)
endif
if myExit > 0 then
sell at myExit STOP
exitShort at myExit STOP
endifUtilizzando close: (close – tradePrice(1) il breakeven viene attivato solo quando una chiusura di barra raggiunge la soglia. Se invece vogliamo che basti il prezzo durante la formazione della barra che raggiunga 100 punti (caso long) e 50 punti (caso short) dobbiamo sostituire rispettivamente close con high e low.
Oppure in percentuale:
pointToReachBreakevenL = tradePrice(1) * 0.5 / 100
pointToReachBreakevenS = tradePrice(1) * 0.3 / 100
once myExit = 0
if not onMarket then
myExit = 0
endif
if longOnMarket and myExit = 0 and (close - tradePrice(1)) >= pointToReachBreakevenL then
myExit = tradePrice(1)
elsIf shortOnMarket and myExit = 0 and (tradePrice(1) - close) >= pointToReachBreakevenS then
myExit = tradePrice(1)
endif
if myExit > 0 then
sell at myExit STOP
exitShort at myExit STOP
endif§ 9.6 – Splittare la posizione
Un altro modo, oltre al trailing profit, di assicurarsi (sempre dopo aver raggiunto certi livelli di prezzo) almeno una parte del profitto atteso consiste nel dividere in due (o più parti) l’uscita.
Lo split della posizione in due parti è una tecnica di gestione del rischio molto usata nel trading: invece di chiudere tutta la posizione si chiude metà della posizione con un obiettivo di breve termine e si lascia aperta l’altra metà puntando ad un obiettivo più ampio.
Cosa significa praticamente: apriamo un’operazione (ad esempio con 2 contratti) e quando raggiungiamo un certo profitto prefissato allora:
– chiudiamo 1 contratto al primo obiettivo,
– lasciamo aperto 1 contratto per cercare di prendere un movimento più ampio.
Vale quanto detto per il trailing profit: solo test accurati ci consentono di stabilire se questa tecnica porta un reale vantaggio all’interno di una determinata strategia.
E’ interessante notare che, sebbene in pratica si splittano per lo più posizioni vincenti, possiamo anche splittare una posizione perdente, ossia uscire con metà posizione su due differenti livelli di stop loss.
Per utilità pratica riportiamo i codici di diversi scenari di utilizzo dello split.
In questi codici splittiamo una posizione in guadagno in punti e nel secondo esempio in percentuale.
once partialcloseGain = 1 // Splittare in PUNTI posizione VINCENTE
once perCent = 0.5 // chiudere il 50%
once pointsGain = 100 // 100 punti split
once minLotSize = 0.5 // IG minimum Size
once flag = 1
if not onMarket then
flag = 1
endif
if longOnMarket then
tempGain = (close - positionPrice) / pointSize
elsif shortOnMarket then
tempGain = (positionPrice - close) / pointSize
endif
// Calcoliamo la quantità teorica da chiudere e verifichiamo che la rimanente sia >= min
exitQuantity = ABS(CountOfPosition) * perCent
leftQty = MAX(MinLotSize, ABS(countOfPosition) - exitQuantity)
closeQuantity = MAX(0, ABS(countOfPosition) - leftQty)
if partialcloseGain and longOnMarket AND tempGain >= pointsGain and flag then
sell closeQuantity contracts at market
flag = 0
endif
if partialcloseGain and shortOnMarket and tempGain >= pointsGain and flag then
exitShort closeQuantity contracts at market
flag = 0
endifCosa fa questo codice:
– partialcloseGain abilita o disabilita la funzione,
– perCent stabilisce la percentuale della posizione da chiudere: con 0.5 viene chiuso il 50%,
– pointsGain definisce la soglia di profitto necessaria per attivare lo split,
– minLotSize stabilisce la quantità minima che deve rimanere aperta,
– flag viene utilizzato come controllo di esecuzione, in modo che lo split venga effettuato una sola volta per ogni operazione.
In percentuale:
once partialcloseGain = 1 // Splittare in % posizione VINCENTE
once perCent = 0.5 // chiudere il 50%
once percentGain = 2 // 2% split
once minLotSize = 0.5 // IG minimum Size
once flag = 1
if not onMarket then
flag = 1
endif
if longOnMarket then
tempGain = ((close - positionPrice) / positionPrice) * 100
elsif shortOnMarket then
tempGain = ((positionPrice - close) / positionPrice) * 100
endif
exitQuantity = ABS(CountOfPosition) * perCent
leftQty = MAX(minLotSize, ABS(countOfPosition) - exitQuantity)
closeQuantity = MAX(0, ABS(countOfPosition) - leftQty)
if partialcloseGain and longOnMarket and tempGain >= percentGain and flag then
sell closeQuantity contracts at market
flag = 0
endif
if partialcloseGain and shortOnMarket and tempGain >= percentGain and flag then
exitShort closeQuantity contracts at market
flag = 0
endifCosa fa questo codice:
– partialcloseGain abilita o disabilita la funzione,
– perCent stabilisce la percentuale della posizione da chiudere: con 0.5 viene chiuso il 50%,
– percentGain indica la percentuale di profitto necessaria per attivare lo split. In questo esempio, 2 significa +2% rispetto al prezzo di entrata,
– minLotSize definisce la quantità minima che deve rimanere aperta,
– flag impedisce che lo stesso split venga eseguito più volte durante la stessa operazione.
In questi codici, che sono la versione speculare di quelli sopra riportati, splittiamo una posizione in perdita (sempre in punti e poi percentuale):
once partialcloseLoss = 1 // Splittare in PUNTI posizione PERDENTE
once perCent = 0.5 // chiudere il 50%
once pointsLoss = 100 // 100 punti split
once minLotSize = 0.5 // IG minimum Size
once flag = 1
if not onMarket then
flag = 1
endif
if longOnMarket then
tempGain = (close - positionPrice) / pointSize
elsif shortOnMarket then
tempGain = (positionPrice - close) / pointSize
endif
exitQuantity = ABS(CountOfPosition) * perCent
leftQty = MAX(minLotSize, ABS(countOfPosition) - exitQuantity)
closeQuantity = MAX(0, ABS(countOfPosition) - leftQty)
if partialcloseLoss and longOnMarket and tempGain <= -pointsLoss and flag then
sell closeQuantity contracts at market
flag = 0
endif
if partialcloseLoss and shortOnMarket and tempGain <= -pointsLoss and flag then
exitShort closeQuantity contracts at market
flag = 0
endifIn percentuale:
once partialcloseLoss = 1 // Splittare in % posizione PERDENTE
once perCent = 0.5 // chiudere il 50%
once percentLoss = 2 // 2% split
once minLotSize = 0.5 // IG minimum Size
once flag = 1
if not onMarket then
flag = 1
endif
if longOnMarket then
tempGain = ((close - positionPrice) / positionPrice) * 100
elsif shortOnMarket then
tempGain = ((positionPrice - close) / positionPrice) * 100
endif
exitQuantity = ABS(CountOfPosition) * perCent
leftQty = MAX(minLotSize, ABS(countOfPosition) - exitQuantity)
closeQuantity = MAX(0, ABS(countOfPosition) - leftQty)
if partialcloseLoss and longOnMarket and tempGain <= -percentLoss and flag then
sell closeQuantity contracts at market
flag = 0
endif
if partialcloseLoss and shortOnMarket and tempGain <= -percentLoss and flag then
exitShort closeQuantity contracts at market
flag = 0
endif§ 9.7 – Nuove istruzioni di PRT
Vediamo ora delle nuove istruzioni che sono state inserite recentemente in ProRealTime per semplificare il modo di scrivere dei codici.
La prima che vediamo è: SET STOP BREAKEVEN.
Set Stop Breakeven sposta lo stop loss al prezzo di carico della posizione, cioè al livello di ingresso, quando il mercato ha già sviluppato un certo profitto. In pratica serve a eliminare il rischio di trasformare un trade in guadagno in un trade in perdita.
È una funzione molto usata quando il prezzo si muove nella direzione attesa e si vuole “mettere in sicurezza” la posizione senza chiuderla subito. Praticamente è un modo semplice di scrivere uno stop a breakeven.
currentPosition = positionPrice*positionPerf/pointSize
if longOnMarket and currentPosition > 15*pointSize then
set stop breakeven
endif
graph currentPositionUna seconda importante istruzione è: SET STOP PRICE.
Set Stop Price permette di impostare uno stop a un prezzo assoluto, invece che a una distanza in punti, percentuale o valuta rispetto all’ingresso.
Con set stop price diciamo: se il prezzo arriva qui, esci.
Questa istruzione è diversa da uno stop dinamico basato sulla distanza dall’entry, perché lavoriamo direttamente sul livello di prezzo scelto.
Vediamo diversi esempi di set stop price dato che è la funzione più utilizzata:
Qui usciamo al prezzo di entrata più un certo numero di ticks:
set stop price (tradePrice + 10*pointSize)Qui fissiamo uno stop loss sul minimo inferiore delle ultime 5 barre:
if buyCondition and not longOnMarket then
buy 1 contract at market
set stop price lowest[5](low)
endifQui vediamo due uscite dalla posizione basate su indicatori tecnici: un’uscita in stop su una banda di Bollinger (1) ed una su una media mobile (2).
Si esce quando il prezzo tocca i determinati livelli degli indicatori.
if buyCondition and not longOnMarket then
buy 1 contract at market
1) set stop price bollingerLow[20]
2) set stop price average[20,0]
endifStop sul minimo assoluto delle ultime tre candele meno tre punti:
Set Stop Price lowest[3](low) - 3 * pointSize Oppure fissiamo una condizione:
SL = low -30*pointSize
set stop price SLUna terza istruzione è: SET TARGET BREAKEVEN.
Set Target Breakeven non è molto utilizzato, in pratica sposta il target di profitto al prezzo di ingresso della posizione quando il trade va in profitto di una certa quantità:
if longOnmarket then
if high - tradeprice >= 15 * pointSize then
set target breakeven
endif
endifLa differenza con un trailinig profit è che set target breakeven non segue la posizione, ma fa solo uno spostamento iniziale.
L’ultima istruzione che vediamo è: SET TARGET PRICE.
Set Target Price imposta il take profit a un prezzo preciso dell’asset.
Non stiamo dicendo “voglio guadagnare tot punti”, ma “voglio uscire esattamente a questo livello di prezzo”.
Questa istruzione è molto utile quando il target coincide con un livello tecnico, come una resistenza, un massimo precedente o un prezzo psicologico.
if close crosses over average[20] then
buy 1 contract at market
TP = highest[20](high) + 5 * pointSize
endif
set target price TPEcco il link alla documentazione di ProRealCode: https://www.prorealcode.com/topic/new-trading-instructions-better-management-of-your-orders/.
§ 9.8 – Stop di inattività
Lo stop di inattività è una regola di uscita che chiude la posizione se il mercato non raggiunge un determinato livello di profitto entro un intervallo di tempo prestabilito, misurato in numero di barre. L’obiettivo di questo stop è evitare che il capitale rimanga bloccato in operazioni ‘stagnanti’: se un trade rimane aperto troppo a lungo senza generare il guadagno atteso, la posizione viene liquidata automaticamente.
In questo esempio se dopo 10 barre non siamo ancora in guadagno usciamo dal trade:
barsInTrade = barIndex - tradeIndex
if longOnMarket and barsInTrade >= 10 and positionPerf <= 0 then
sell at market
endif
if shortOnMarket and barsInTrade >= 10 and positionPerf <= 0 then
exitShort at market
endif§ 9.9 – Calcolo uscita ottimale da un trade
Questa formula ci consente di calcolare il numero di barre ottimali per uscire dalle posizioni long e short, sia quando, dopo un numero determianto di barre, siamo in guadagno sia quando siamo in perdita.
La formula va presa come un’indicazione sulla durata ottimale delle posizioni.
Il codice ci dice che in media dopo n candele in profitto o in perdita non conviene più stare dentro al trade, ma è meglio liquidare la posizione al meglio.
Chiaramente è un dato statistico sulle operazioni passate che ci fornisce delle informazioni operative per valutare meglio il sistema.
// PARAMETRI DI TEMPO (NUMERO DI CANDELE)
once maxLongWinBars = 20
once maxShortWinBars = 10
once maxLongLossBars = 5
once maxShortLossBars = 8
// PERFORMANCE E CONTEGGIO CANDELE
// positionPerf restituisce la performance decimale (es. 0.02 = +2%, -0.01 = -1%)
posProfit = positionPerf
numberCandles = barIndex - tradeIndex(1)
// CONDIZIONI DI USCITA
L1 = longOnMarket and posProfit > 0 and numberCandles >= maxLongWinBars
S1 = shortOnMarket and posProfit > 0 and numberCandles >= maxShortWinBars
L0 = longOnMarket and posProfit < 0 and numberCandles >= maxLongLossBars
S0 = shortOnMarket and posProfit < 0 and numberCandles >= maxShortLossBars
// ESECUZIONE DEGLI ORDINI
if L1 or L0 then
sell at market
endif
if S1 or S0 then
exitShort at market
endifCapitolo 10 : Il Money Management
Il money management rappresenta l’insieme delle regole con cui gestire il capitale all’interno delle strategie di trading. Non riguarda quindi quando entrare o uscire, ma quanto rischiare e come dimensionare le posizioni.
È uno degli aspetti più importanti, perché anche una buona strategia può diventrare inefficace senza una corretta gestione del rischio, come è altrettanto vero che il money management non può trasformare una strategia tecnicamente perdente in vincente.
Il money management è uno degli aspetti più critici del trading, e spesso è ciò che distingue i trader di lungo periodo da chi esaurisce il capitale in poco tempo.
Possiamo suddividere la gestione di un sistema di trading in due grandi aree, strettamente collegate tra loro:
Position Management: riguarda la gestione della posizione una volta che il trade è stato aperto. Comprende tutte le regole che determinano come proteggere, gestire e chiudere la posizione, come stop loss, take profit, trailing stop, breakeven, uscite parziali e uscite temporali.
Money Management e Position Sizing: riguardano invece la gestione del capitale e della dimensione delle posizioni. Il Money Management definisce le regole con cui viene controllato il rischio complessivo del sistema, ad esempio il rischio massimo per trade, il capitale massimo esposto e la gestione del drawdown. Il Position Sizing traduce queste regole in una decisione operativa: quanti contratti o quale quantità acquistare o vendere in ogni singola operazione.
Il Money Management stabilisce le regole del rischio, mentre il Position Sizing determina la dimensione concreta della posizione necessaria per rispettarle.
Tra le tecniche di Position Sizing rientrano, ad esempio, i sistemi che modificano la quantità operata in funzione dell’andamento delle operazioni precedenti, come Martingala e Antimartingala, mentre il dimensionamento può anche essere calcolato in funzione del rischio monetario associato allo stop loss.
Un concetto fondamentale del Money Management è il Drawdown (DD). Esistono diverse definizioni di drawdown; una delle più note è quella proposta da Ryan Jones, secondo la quale il drawdown rappresenta la diminuzione del capitale dal precedente massimo raggiunto fino al minimo successivo, prima che venga raggiunto un nuovo massimo.
Il drawdown è un parametro molto importante per valutare il comportamento storico di una strategia e per comprendere quale livello di perdita il sistema ha dovuto affrontare in passato. Tuttavia, rappresenta soltanto una misura storica del rischio e non una garanzia sul rischio futuro: un sistema che in passato ha registrato un determinato drawdown potrebbe infatti sperimentrare in futuro un drawdown superiore.
Per questo motivo, il drawdown storico dovrebbe essere considerato come un riferimento per la gestione del rischio, e non come un limite massimo che il sistema non potrà mai superare.
Il Money Management e il Position Sizing stabiliscono quindi:
– quanto capitale allocare per ogni operazione
– quanto si è disposti a perdere per trade
– come aumentare o ridurre la size nel tempo
– come proteggere il capitale durante i periodi negativi
In pratica, queste regole servono a mantenere il capitale sotto controllo, limitando l’esposizione al rischio e contribuendo a evitare perdite eccessive.
Conoscere in anticipo quanto si rischia in ogni operazione aiuta inoltre a ridurre l’impatto delle decisioni emotive. Avere regole di gestione del capitale definite e applicarle in modo coerente può infatti contribuire a evitare comportamenti impulsivi, come aumentrare eccessivamente la size dopo una perdita o mantenerla troppo elevata durante un periodo di drawdown.
§ 10.1 – Martingala
Esaminiamo ora due tecniche famose di position sizing che possono servire a comprendere il rischio: martingala ed antimartingala.
Nel position sizing la martingala e l’antimartingala sono tecniche di Position Sizing (dimensionamento della posizione) e gestione del capitale. A differenza delle regole di uscita (come breakeven o trailing stop), non agiscono sui livelli di prezzo, ma variano la dimensione del lotto (size) da applicare alle operazioni successive in base all’esito (in perdita o in profitto) dei trade precedenti.
La martingala è una tecnica di gestione in cui, dopo una perdita, si aumenta l’esposizione — classicamente raddoppiando la size — con l’obiettivo di recuperare le perdite precedenti con una sola operazione vincente.
In teoria può sembrare efficace, ma comporta un rischio molto elevato perché una serie negativa può far crescere rapidamente l’esposizione e consumare il capitale disponibile impedendo di continuare ad operare.
Per questo motivo, nel trading reale la martingala viene considerata una tecnica molto aggressiva e potenzialmente pericolosa, soprattutto se non esistono limiti rigidi alla size massima o al numero di raddoppi consecutivi.
È molto comune che i trader alle prime armi applichino, spesso in modo inconsapevole, la tecnica della martingala. Questo approccio consiste nel raddoppiare la posizione dopo ogni perdita per tentrare di recuperare rapidamente i capitali, esponendo il conto a rischi estremamente elevati.
Si riportano di seguito alcune formule operative, tratte dalle soluzioni sviluppate da Roberto Gozzi (moderatore del forum italiano di ProRealCode), utili per effettuare test e valutazioni all’interno dei propri sistemi trading.
Questo primo codice non è una vera Martingala in quanto non raddoppia ad ogni perdita la posizione, ma si ferma al primo raddoppio, che rimane costante fino a un’operazione in guadagno.
Formula contratti: 1 → 2 → 2 → 2 → …
once positionSize = 1
minPositionSize = 1
maxPositionSize = 2
if strategyProfit < strategyProfit[1] then
positionSize = 2
elsif strategyProfit > strategyProfit[1] then
positionSize = 1
endif
// Limita la size tra 1 e 2 contratti
positionSize = min(maxPositionSize, max(minPositionSize, positionSize))Martingala originale con raddoppio costante ad ogni perdita:
Formula contratti: 1 → 2 → 4 → 8 → …
once positionSize = 1
minPositionSize = 1
maxPositionSize = 100
if not onMarket and onMarket[1] then
if strategyProfit < strategyProfit[1] then // trade perdente
positionSize = positionSize * 2
elsif strategyProfit > strategyProfit[1] then // trade vincente
positionSize = 1
endif
endif
positionSize = min(maxPositionSize, max(minPositionSize, positionSize))§ 10.2 – AntiMartingala
L’antimartingala segue il principio opposto: anziché aumentrare l’esposizione dopo una perdita, la si incrementa dopo una vincita e la si riduce durante le fasi sfavorevoli. L’obiettivo è sfruttare i trend positivi limitando i danni quando il mercato si muove contro le nostre posizioni. Trattandosi di un approccio coerente con le logiche di trend following, l’antimartingala favorisce la crescita del capitale nei momenti favorevoli. Ciononostante, l’applicazione dell’antimartingala necessita di un rigoroso controllo del rischio, poiché fasi di forte volatilità o repentine inversioni di trend possono compromettere i profitti accumulati.
Antimartingala con raddoppio dopo la prima vincita e mantenimento costante del raddoppio fino alla prima perdita.
Formula contratti: 1 → 2 → 2 → 2 → …
once positionSize = 1
minPositionSize = 1
maxPositionSize = 2
if strategyProfit > strategyProfit[1] then
positionSize = 2
elsif strategyProfit < strategyProfit[1] then
positionSize = 1
endif
// Limita la size tra 1 e 2 contratti
positionSize = min(maxPositionSize, max(minPositionSize, positionSize))
Antimartingale originale con raddoppio costante ad ogni guadagno:
Formula contratti: 1 → 2 → 4 → 8 → …
once positionSize = 1
minPositionSize = 1
maxPositionSize = 100
if not onMarket and onMarket[1] then
if strategyProfit > strategyProfit[1] then // trade vincente
positionSize = positionSize * 2
elsif strategyProfit < strategyProfit[1] then // trade perdente
positionSize = 1
endif
endif
positionSize = min(maxPositionSize, max(minPositionSize, positionSize))Possiamo anche scrivere il codice che raddoppia la posizione solo dopo la prima vincita (1 → 2 → 2 → 2 → …) in questo modo:
ANTIMARTINGALA con raddoppio della posizione dopo il primo guadagno e mantenimento del raddoppio fino ad una perdita.
once positionSize = 1 //starting number of contracts
once minPositionSize = 1 //minimum lot size required by the broker
once maxPositionSize = 2
once increase = 1 //number of lots to increment
//once decrease = 1 //number of lots to decrement
if strategyProfit > strategyProfit[1] then
positionSize = positionSize + increase
elsIf strategyProfit < strategyProfit[1] then
positionSize = positionSize - increase
endif
positionSize = min(maxPositionSize, max(minPositionSize,positionSize)) //check both maximum and minimumQuesto codice invece implementa “raddoppio solo dopo il primo guadagno”, ma non mantiene il 2 dopo vincite consecutive.
Formula contratti: 1 → 2 → 1 …
ANTIMARTINGALA con raddoppio della posizione solo dopo il primo guadagno.
once positionSize = 1
once minPositionSize = 1
once maxPositionSize = 2
once increase = 1
// once decrease = 1
once flag = 1
if strategyProfit < strategyProfit[1] then
positionSize = positionSize - increase
flag = 1
elsIf strategyProfit > strategyProfit[1] then
if flag = 1 then
positionSize = positionSize + increase
flag = 0
else
positionSize = minPositionSize
endif
endif
positionSize = min(maxPositionSize, max(minPositionSize,positionSize))In un software come ProRealTime, martingala e antimartingala possono essere studiate, simulate e confrontate tramite backtest, così da osservare l’impatto di una progressione della size sui risultati storici della strategia.
In sintesi: la martingala tende a privilegiare il recupero delle perdite, ma al prezzo di un rischio sempre crescente; l’antimartingala, invece, tende a premiare la continuità dei guadagni e soprattutto a ridurre il rischio durante le perdite.
§ 10.3 – Come interrompere una strategia
Abbiamo visto come arrestare definitivamente una strategia tramite l’istruzione QUIT. Tuttavia in alcuni contesti di risk management è preferibile una sospensione temporanea. Qualora una strategia accumuli un drawdown mensile superiore alla soglia di tolleranza, il seguente snippet consente di disattivare il sistema per il resto del mese corrente, ripristinando l’operatività a partire dal mese successivo.
once strategyON = 1
once beginMonthProfit = 0
if openMonth <> openMonth[1] then
strategyON = 1
beginMonthProfit = strategyProfit
endif
floatingMonthProfit = (strategyProfit - beginMonthProfit) / pointValue
if floatingMonthProfit <= -(1000*positionSize) then
strategyON = 0
endif
//graph strategyON coloured("Red")
//graph floatingMonthProfitEcco una spiegazione dettagliate del codice:
– openMonth <> openMonth[1]: individua la prima barra del nuovo mese. Quando cambia il mese, la variabile strategyON torna a 1 (riabilitando il sistema) e viene registrato il profitto totale cumulato fino a quel momento (beginMonthProfit),
– floatingMonthProfit: calcola il guadagno o la perdita del mese in corso facendone la differenza rispetto al valore di inizio mese,
– if floatingMonthProfit <= -(1000 * positionSize): verifica se le perdite del mese hanno raggiunto o superato il limite impostato (nell’esempio: 1000 punti. In tal caso, imposta strategyON = 0.
Qui arrestiamo una strategia utilizzando un controllo settimanale:
once strategyON = 1
once beginWeekProfit = 0
if openDayOfWeek < openDayOfWeek[1] then
strategyON = 1
beginWeekProfit = strategyProfit
endif
floatingWeekProfit = (strategyProfit - beginWeekProfit) / pointValue
if floatingWeekProfit <= -(300*positionSize) then
strategyON = 0
endif
//graph strategyON coloured("Red")
//graph floatingMonthProfit§ 10.4 – Calcolo dell’equity
Per controllare il valore globale del nostro conto possiamo utilizzare questa formula, che serve a calcolare la equity reale, cioè il valore del conto includendo anche il profit/loss delle posizioni ancora aperte.
Il codice che riportiamo ha un obiettivo molto chiaro: calcolare l’Equity Reale sommando al capitale iniziale (capital), i profitti consolidati dei trade chiusi (strategyProfit) e il guadagno/perdita latente della posizione attualmente aperta (floatingPosition).
once capital = 10000
if longOnMarket then
floatingPosition = (((close-positionPrice)*pointValue)*countOfPosition)/pointSize
elsif shortOnMarket then
floatingPosition = (((positionPrice-close)*pointValue)*countOfPosition)/pointSize
else
floatingPosition = 0
endif
equity = capital + strategyProfit + floatingPosition
graph equityOltre ad una formula per il calcolo dell’equity può essere utile per analizzare la gestione del proprio sistema conoscere i profitti della strategia a livello settimanale e mensile.
§ 10.5 – Calcolare il profitto settimanale
Ecco un codice che restituisce il profitto settimanale. Il profitto viene aggiornato alla prima barra della nuova settimana.
once equity = 0
once profittoSettimanale = 0
if week <> week[1] then
profittoSettimanale = strategyProfit - equity
equity = strategyProfit
endif
graph profittoSettimanaleSe vogliamo invece vedere il profitto corrente della settimana:
once equity = 0
once profittoSettimanale = 0
if week <> week[1] then
equity = strategyProfit
endif
profittoSettimanale = strategyProfit - equity
graph profittoSettimanale§ 10.6 – Calcolare il profitto mensile
Ecco un codice che restituisce il profitto mensile. Il profitto viene aggiornato alla prima barra del nuovo mese.
once equity = strategyProfit
once performanceLastMonth = 0
if month <> month[1] then
performanceLastMonth = strategyProfit - equity
equity = strategyProfit
endif
graph performanceLastMonthSe vogliamo invece vedere il profitto corrente del mese:
once equity = 0
if month <> month[1] then
equity = strategyProfit
endif
performanceCurrentMonth = strategyProfit - equity
graph performanceCurrentMonthPer riassumere: performanceLastMonth si aggiorna al cambio del mese e fotografa il mese appena concluso, mentre performanceCurrentMonth usa il valore di strategyProfit all’inizio del mese e misura l’andamento del mese in corso.
§ 10.7 – Drawdown
Quando si sviluppa o si valuta un trading system in ProRealTime, uno degli aspetti più importanti da analizzare non è soltanto il profitto generato, ma anche il rischio sostenuto per ottenere quei risultati. Il parametro più utilizzato per misurare questo rischio è il drawdown.
Il drawdown rappresenta la diminuzione del capitale rispetto al suo massimo precedente. In altre parole, misura la perdita temporanea che il sistema subisce durante una fase negativa prima di tornare a nuovi massimi.
Ad esempio, se il capitale di un sistema sale da 10.000 € a un picco di 15.000 € per poi scendere a 13.500 €, il drawdown sarà di 1.500 €, ossia il 10% rispetto al massimo storico. Questo valore aiuta a stimare le perdite temporanee da sostenere durante le fasi sfavorevoli del mercato.
Comprendere e monitorare il drawdown è quindi fondamentale per valutare correttamente le prestazioni di una strategia e per definire aspettative realistiche sulle possibili perdite che potrebbero verificarsi durante l’operatività reale.
In termini pratici, il drawdown massimo rappresenta la peggiore fase di perdita attraversata dal sistema prima di recuperare, quindi misura la pressione psicologica e finanziaria che il metodo può imporre al capitale.
La robustezza di un sistema si misura non solo nel rendimento complessivo, ma nella capacità di mantenere il drawdown su livelli compatibili con la tolleranza al rischio che il trader può accettare.
Il backtest non mira a massimizzare i profitti assoluti, bensì a valutare la stabilità e l’efficienza della gestione nel tempo.
Ecco la formula per ProRealTime per calcolare il drawdown assoluto corrente, cioè la distanza tra il massimo storico raggiunto da strategyProfit e il valore attuale:
once maxEquity = 0
equity = strategyprofit // equity rappresetna il profitto cumulato della strategia
if equity > maxEquity then
maxEquity = equity // memorizza il massimo storico dell'equity
endif
drawdown = maxEquity - equity // calcola la distanza dal massimo storico
graph drawdownSe invece vogliamo sapere qual è stato il peggior drawdown mai raggiunto dalla strategia, dobbiamo conservare anche il massimo drawdown.
Questa è la formula del peggior drawdown raggiunto:
once maxEquity = 0
once maxDD = 0
equity = strategyprofit
if equity > maxEquity then
maxEquity = equity
endif
drawdown = maxEquity - equity
if drawdown > maxDD then
maxDD = drawdown
endif
graph drawdown as "Current DD"
graph maxDD as "Max DD"§ 10.8 – DD e RU
Come vedremo nella parte pratica sulla costruzione di un trading system, il rapporto del massimo guadagno (run up) e del DD è una metrica fondamentale.
Per misurare il rapporto tra rendimento e rischio si ricorre spesso al Recovery Factor:
Più questo valore è alto, migliore è il rapporto tra rendimento ottenuto e rischio sopportato. Questo indice mostra chiaramente quanto rende una strategia in rapporto al rischio necessario per attuarla.
Per intenderci: un valore pari a 2 significa che il sistema ha guadagnato il doppio della sua massima perdita storica. PIù il dato è alto, più la strategia risulta attraente; se è basso, significa che il sistema genera poco profitto a fronte di cali di capitale troppo marcati.
Valutare un trading system basandosi esclusivamente sul rendimento assoluto è fuorviante: questo dato non esprime né l’efficienza del modello né la sua reale sostenibilità operativa. Una strategia capace di generare profitti elevati a fronte di un massimo drawdown eccessivo può apparire interessante sulla carta, ma risulta spesso inapplicabile nella pratica a causa del rischio elevato, dell’impatto sul capitale e dello stress psicologico durante i periodi di calo.
Invece di rilevare il drawdown semplicemente sullo strategyProfit, la formula sviluppata da Roberto Gozzi, moderatore del forum di PRT, tiene conto sia dell’equity che del profitto delle posizioni ancora aperte. In questo modo, l’algoritmo calcola in tempo reale l’equity complessiva, il massimo drawdown e il max run-up, restituendo un rapporto finale tra le due metriche per valutare l’efficienza globale del sistema.
once capital = 10000
once minPoint = capital
once maxPoint = 0
once maxRU = 0
once maxDD = 0
//------------------------------------------
// Equity
equity = capital + strategyProfit
tempProfit = positionPerf * positionPrice / pointSize
tempEquity = equity + tempProfit
//------------------------------------------
// DrawDown
maxPoint = max(MaxPoint,TempEquity)
DD = maxPoint - tempEquity
maxDD = max(MaxDD,DD)
//
//------------------------------------------
// RunUp
minPoint = min(MinPoint,TempEquity)
RU = tempEquity - minPoint
maxRU = max(maxRU,RU)
//------------------------------------------
// DD/RU ratio
DDRUratio = (maxDD / maxRU) * 100§ 10.9 – Position Sizing
Quando si parla di trading, la maggior parte dei principianti dedica l’80% del tempo a cercare il punto di ingresso perfetto. Tuttavia, ciò che distingue un trader amatoriale da un professionista costante non è quando si entra a mercato, ma quanto si scommette su ogni singola operazione. Il position sizing (la gestione della dimensione della posizione) è il vero pilastro della sopravvivenza finanziaria: è l’unica leva in grado di proteggere il capitale dalle inevitabili serie negative e di trasformare una strategia profittevole in un modello di guadagno sostenibile nel tempo.
Il modo più semplice per gestire un trading system è impiegare una size fissa. Con questo approccio infatti la dimensione della posizione rimane costante nel tempo: un trader che decide di operare con 2 contratti continuerà a utilizzare 2 contratti sia durante le fasi di profitto sia durante i periodi di perdita.
once positionSize = 2
if mieCondizioni then
buy positionSize contracts at market
endifIl principale vantaggio del Fixed Size è la sua semplicità. Per questi motivi viene spesso utilizzato nelle fasi iniziali di sviluppo e validazione di un trading system, poiché consente di analizzare la performance della strategia in modo neutrale e facilmente confrontabile.
Di contro, questo metodo non sfrutta la crescita del capitale.
Quando la strategia accumula profitti significativi, la dimensione della posizione rimane invariata, precludendo i benefici dell’interesse composto (è il meccanismo in cui gli interessi-guadagni maturati in ciascun periodo non vengono prelevati, ma si sommano al capitale iniziale).
Allo stesso modo, durante le fasi di drawdown, il rischio monetario per operazione resta costante anziché ridursi automaticamente per proteggere il conto.
§ 10.10 – Fixed Fractional (Ralph Vince)
Il concetto di Fixed Fractional è stato reso popolare nel mondo del trading da Ralph Vince all’inizio degli anni ’90, in particolare attraverso libri fondamentali come “Portfolio Management Formulas” (1990) e “The Mathematics of Money Management” (1992).
Il metodo è legato al Criterio di Kelly (sviluppato nel 1956 da John L. Kelly Jr. dei Bell Labs nell’ambito della teoria dell’informazione), che Vince ha adattato alle serie di trade storiche con il concetto di optimal f.
Anziché rischiare una cifra monetaria fissa (es. 500 € a operazione), il trader rischia una percentuale fissa del capitale attuale su ciascun trade (ad esempio l’1% o il 2%). Calcolando la dimensione della posizione in percentuale rispetto al capitale, la size cresce nelle fasi profittevoli e si riduce automaticamente durante i drawdown.
Il calcolo si basa sulla seguente formula:
Position Size = (Capitale × Percentuale di Rischio) / Rischio per Contratto
– Capitale: il capitale disponibile al momento dell’operazione (capitale iniziale più profitti realizzati).
– Percentuale di Rischio: la frazione fissa del capitale che si intende rischiare per ogni operazione.
– Rischio per Contratto: la distanza dello Stop Loss in punti moltiplicata per il valore monetario di un singolo punto. Il risultato viene arrotondato per difetto al numero intero di contratti.
Vediamo un esempio:
Con un capitale di 50.000 €, una percentuale di rischio del 2%, uno stop di 50 punti e un valore punto di 10 €, il rischio massimo consentito sarà:
50.000 × 2% = 1.000 €
Poiché ogni contratto rischia:
50 × 10 = 500 €
la dimensione della posizione sarà:
1.000 / 500 = 2 contratti
Se il capitale crescerà a 75.000 €, la size aumenterà automaticamente a 3 contratti mantenendo invariato il rischio percentuale.
once initialCapital = 50000
once riskPercent = 0.02 // 2%
once stopPoints = 50
once pointValue = 10
capital = initialCapital + strategyProfit
riskPerContract = stopPoints * pointValue
positionSize = INT((capital * riskPercent) / riskPerContract)
if positionSize < 1 then
positionSize = 1
endifUno dei principali vantaggi del Fixed Fractional è la protezione del capitale durante i drawdown: poiché la size diminuisce quando il capitale si riduce, il rischio resta proporzionato alle risorse disponibili. Nei periodi di crescita, invece, la size aumenta progressivamente, sfruttando l’effetto della capitalizzazione composta.
Per questo motivo il Fixed Fractional viene spesso considerato uno dei modelli di money management più solidi, particolarmente adatto ai trader che desiderano mantenere un controllo rigoroso del rischio e una crescita sostenibile nel lungo periodo. Il risultato dipende però dalla percentuale scelta: percentuali elevate rendono il metodo aggressivo.
§ 10.11 – Fixed Ratio (Ryan Jones)
Il Fixed Ratio è un metodo di money management sviluppato da Ryan Jones e presentato nel libro The Trading Game (1999). Il suo obiettivo è aumentrare la dimensione delle posizioni in modo progressivo e controllato, in funzione dei profitti accumulati.
A differenza del Fixed Fractional, che calcola la size come percentuale del capitale disponibile, il Fixed Ratio utilizza un parametro chiamato Delta: il profitto richiesto per passare da 1 a 2 contratti.
La size non dipende quindi dalla percentuale di rischio né dalla distanza dello stop, ma esclusivamente dal profitto cumulato e dal valore del Delta.
L’idea fondamentale del Fixed Ratio è che la size non debba aumentrare in proporzione diretta al profitto.
Il passaggio a ogni livello successivo richiede infatti un profitto progressivamente maggiore:
– per passare da 1 a 2 contratti è necessario raggiungere un profitto pari a 1 × Delta;
– per passare da 2 a 3 contratti sono necessari 2 × Delta;
– per passare da 3 a 4 contratti sono necessari 3 × Delta;
La crescita è quindi relativamente rapida all’inizio e rallenta man mano che la posizione aumenta. Il valore del Delta determina il carattere del metodo: un Delta elevato rende la crescita più lenta e prudente, mentre un Delta contenuto la rende più aggressiva.
Supponiamo di utilizzare un Delta di 1.000 €. Le soglie di profitto cumulato, che seguono i numeri triangolari (1, 3, 6, 10, 15…), diventano:
1 contratto → 0 €
2 contratti → 1.000 €
3 contratti → 3.000 €
4 contratti → 6.000 €
5 contratti → 10.000 €
6 contratti → 15.000 €
Con un profitto cumulato di 3.500 €, ad esempio, il sistema opera con 3 contratti: ha superato la soglia dei 3.000 €, ma non quella dei 6.000 € necessaria per arrivare a 4. Il meccanismo funziona anche al contrario: se il profitto scende sotto la soglia del livello corrente, la size si riduce al livello precedente.
Per ricavare direttamente il numero di contratti dal profitto si può utilizzare la formula:
N = (1 + √(1 + 8 × Profitto / Delta)) / 2, arrotondato per difetto.
Con profitto pari a zero o negativo la size resta a 1 contratto.
Esempio: con un Delta di 1.000 € e un profitto realizzato di 3.500 €, si ottiene (1 + √(1 + 8 × 3,5)) / 2 = (1 + √29) / 2 ≈ 3,19, quindi la size è di 3 contratti. Per passare a 4 contratti servono 6.000 € di profitto; se invece il profitto scende sotto i 3.000 €, la size torna a 2 contratti.
Uno dei principali vantaggi del Fixed Ratio è che la size aumenta soltanto quando il sistema di trading ha generato risultati sufficienti a giustificare un rischio maggiore, con un ritmo che rallenta all’aumentrare dei contratti. Per questo rappresenta un approccio intermedio tra il Fixed Size, che mantiene la size statica, e il Fixed Fractional, più legato alla capitalizzazione composta. È adatto ai trader che vogliono far crescere la size in modo graduale mantenendo un controllo strutturato del rischio.
In ProRealTime il calcolo si traduce nel codice seguente. Il Delta va espresso nella stessa unità di strategyProfit (in valuta).
once delta = 1000
once maxContracts = 10
profit = strategyProfit
if profit > 0 then
positionSize = INT((1 + SQRT(1 + 8 * profit / delta)) / 2)
else
positionSize = 1
endif
if positionSize > maxContracts then
positionSize = maxContracts
endifNota: la versione proposta è semplificata e simmetrica, la size aumenta e si riduce non appena il profitto supera o scende sotto una soglia. Si tratta di un adattamento a scopo didattico del metodo di Ryan Jones, per la cui formulazione originale si rimanda a The Trading Game.
