Sunday, December 27, 2015

A trading system on Amazon

by Marcello Belguardi
Trading Systems
Italian version: here.


Introduction:

We may say that when a trading system is robust then it must behave equally well across different instruments and markets as well as on different timeframes; But the opposite is also true: if the trading system works quite well in different contexts then it could be, very likely, sub-optimal, that is, we could surely find something else that works better applied to the asset that we are currently analysing.

We could perhaps say, for example, that a stable system, able to identify the inherent characteristics of the asset graph, i.e. some property of the price series (that remain persistent in time), is therefore robust .

But which properties? Well... we do not know, at least initially, but if we observe the rules of the trading system and we notice that they tend to not change  (and there's no need to re-optimize along the way) that means that we have got it right: we managed to find some dynamic that the graph follows often and we have implicitly extracted a model, despite the fact that price, returns and everything else may be random, or anyway, not stationary.

With a lot of research (and a bit of luck) we can get there.

My work is mostly directed to this: finding simple trading rules suited to a certain entity in such a way that they still apply as time passes (a 10+ years period is ideal for this test on a daily timeframe) excluding or reducing the need for additional optimization, and, at the same time, always reserving a recent period - still part of the backtesting - but where the trading system operates in the dark (namely out-of-sample) that is on a price time series previously never used during the design of the algorithm: a time series long at least 4 years, in the context of a daily timeframe.

Therefore we would say: low complexity of the algorithm, minimal or absent optimization and backtesting period long enough will guarantee that the probability that the trading system continues to operate properly in the future is reasonably high (although we don't have 100% security: the old adage that says more or less that past performance does not guarantee future returns is still valid...).


Another aspect to consider: we tend to try to design trading systems that have rational rules; in the case of fundamental analysis, or also with classic technical analysis or the modern technical analysis the rules that we seek typically have logical assumptions. We pretend that a protocol works on the basis of human logic or common sense. However this has inherent limitations .

The reality however is that markets, and especially in the short term (and it's on the short or very short time that we focus on) behave, say, in an irrational way. The supply and demand drive the price movements and the resulting graph looks random, or at least so it's perceived. Also on the short-term the analysis of the fundamental data of an instrument can not give a good indication of the possible direction of prices.

For us humans it is difficult to extract a model of the signals of a trading protocol. At the same time we know that prices may contain, let's say, a series of signals . This can happen because, in my opinion, the market players, actions and reactions, have recurrent (and often not trivial) patterns. The same signals that when have an almost constant distribution can made a trading protocol.

I deduced that a technique to extract these signals may be the one of data mining;


We have an idea now of which possible not human technique can be used for algorithm design.
Let's now proceed to describe the trading system in question.


The system:

In the example that follows I will show that it's possible to find strange price patterns which, if satisfied, could give reliable buy and sell signals: we look for patterns designed to works for one specific asset and for that one only. We focus on the Amazon stock price series.

Test:

The proposed trading system applies only to Amazon (AMZN), and what follows is the equity curve since the year 1997. (Click to enlarge)


Piattaforma - ProRealtime

These the performances during the period:






Of the 458 trades we have a winning percentage of 67.25% on average since May 22, 1997 with a final profit of + 264.36%. Time on market 16.44%. The average trade is 57.72 USD which easily absorbs slippage and commissions of a professional broker. (The initial capital is 10,000 and in this case we do not re-invest the profits).

The drawdown is 897 USD, not that much;



That's all for now. Good trading.

This post is for demonstrative or educational purpose only. We do not recommend to use the above system or ideas with real money. Trading is not suitable for everyone and there is a high risk of losing money.



Sunday, November 8, 2015

Over-fitting o... Under-fitting?

Cultura Generale
by Marcello Belguardi

Ecco un esempio di underfitting: il modello statico del trading system ad un certo punto non è più in sincronia con le caratteristiche dinamiche della serie dei prezzi e la curva dell'equity disegna un andamento laterale.

Equity Line - Piattaforma Tradestation

 (...e qui, siccome il trading system è progettato bene, il sistema non perde ma, purtroppo, neppure guadagna; in genere la percentuale di trade vincenti diventa il 50%, il Win/Loss ratio circa 1 che produce un Profit Factor di circa 1, cioè il totale delle perdite è uguale al totale dei guadagni risultando in un profitto nullo.)

Tutti quelli che si cimentano con il trading sistematico conoscono questo tipo di problemi.

E' un fenomeno che è difficile da modellare, non ho trovato, per il momento, nessuna spiegazione esauriente, in termini più o meno statistici. (Si dice che si sta modellando il rumore invece del segnale... una definizione però che non mi accontenta.)

Noi sappiamo che un sistema smette di funzionare se è stato sovraottimizzato sul periodo in-sample, il lasso temporale cioè utilizzato per la progettazione dell'algoritmo.

Ciò spesso accade quando il numero di trades sul periodo in-sample sono troppo pochi per avere significatività statistica. Il risultato è un fitting geometrico invece di un fitting statistico su tale periodo e come risultato il sistema non supererà l'esame dell'out-of-sample, e difficilmente il sistema inizierà a funzionare in paper trading o nel trading reale. Di solito questo effetto viene chiamato overfitting.
Questo è facile da identificare. E per risolvere occorre dedicare un periodo temporale ampio sul quale effettuare la progettazione,  e contemporaneamente avere il coraggio di scartare tutti i trading systems che non superano l'esame dell'out-of-sample.

Ma quello sopra è un fenomeno differente: il sistema viene generato su un periodo in-sample molto lungo, dopodichè supera il periodo di out-of-sample e funziona in paper trading per un periodo, prima di entrare nella fase laterale (non dovuta dalla diminuzione della volatilità ma da una perdita effettiva di edge).

Tale indesiderato effetto potrebbe essere dovuto ad un cambiamento radicale, strutturale, delle dinamiche di quella serie storica, su quel preciso asset. Non è un problema legato alla progettazione del sistema che però, per sua natura, rappresenta un modello statico dei segnali che deve identificare.

Questa mancanza di dinamicità è il limite dei trading systems, dinamicità non sempre necessaria perchè i segnali sulle serie storiche hanno, in genere, una ricorrenza affidabile.

Per fortuna, secondo la mia esperienza, è un fenomeno non troppo frequente (in genere il sistema continua a funzionare bene)  ma dobbiamo comunque tenerne conto. Ogni precauzione, test, ricerca e validazione non è mai abbastanza se si ha l'ambizione di produrre un trading system di qualità disegnato per superare la prova del tempo.




Sunday, September 20, 2015

Scaling-In

Programmazione ProRealtime
by Marcello Belguardi

Supponiamo di avere a disposizione 10000 USD da investire sul prossimo trade e, per gestire un pò meglio il rischio, decidiamo di entrare inizialmente solo con 5000 USD; dopo aver verificato che la direzione è corretta decidiamo quindi di investire i rimanenti 5000 USD.

Cioè tentiamo di frazionare il capitale da investire; stiamo utilizzando una tecnica che prende il nome di scaling-in o piramidizzazione.*

Specificatamente potremmo decidere di entrare con il secondo lotto solo quando il guadagno alla chiusura di una certa barra è maggiore del Range medio (cioè  della media dei range High/Low calcolato su x barre).

Nell'esempio entreremo il 6 febbraio e piramidizzeremo l'11 febbraio perchè è proprio da quel momento che la condizione suddetta è verificata.

(Fare click sull'immagine per ingrandire)





Nella simulazione entriamo il 6 Febbraio perchè il segnale goLong scatta la sera prima. Sappiamo che i nostri due lotti sono di 5000 USD e calcoliamo l'equivalente numero di azioni sempre la sera del 5 Febbraio.

Calcoliamo inoltre la media dei range più recenti (senza prendere in considerazione gli eventuali gap)

Dopo l'ingresso misuriamo la differenza tra il prezzo di chiusura corrente ed il prezzo di ingresso (close - TRADEPRICE). Quando questa differenza è maggiore del range medio possiamo entrare con il nuovo lotto, perchè la condizione scalingIn è verificata ed inoltre sappiamo di essere già long a mercato.

Siamo inoltre sicuri che il cumulo di ordini è consentito dal programma perchè abbiamo settato la variabile globale cumulateorders = true.
(Se questa variabile fosse settata a false non verrebbe consentito lo scaling-in).

Questo lo script:

// Scaling-In example

defparam cumulateorders = true

goLong = (date=20150205)
nShares = Round(5000/close)

averageRange = Average[10](Range)

if goLong then
   buy nShares share at market TomorrowOpen
endif

scalingIn = (close - TRADEPRICE) >= averageRange
consentScaling = countofLongShares < nShares*2

if longonmarket and scalingIn and consentScaling then
   buy nShares share at market TomorrowOpen
endif


graph scalingIn and consentScaling as "2nd entry"


Naturalmente nulla impedirebbe allo script di continuare a cumulare ordini, in teoria indefinitivamente, questo perchè dal secondo ingresso in poi la condizione scalingIn è sempre verificata.

Introduciamo allora una nuova condizione che confronta il numero di azioni a mercato (countofLongShares) con il numero di azioni massimo che vogliamo investire (nShares*2), mettendo un freno al cumulo.

Notare che ProRealtime visualizza mediante un istogramma il numero di azioni (positions) correntemente a mercato. Le azioni vengono raddoppiate alla seconda entry.




Note:

*Ad essere precisi nell'esempio facciamo un Averaging up, cioè compriamo altre azioni che già possediamo ad un prezzo più alto. Tecnica utilizzata da trend e momentum followers.

Riferimenti:
http://thepatternsite.com/ScalingIn.html






Monday, August 31, 2015

Crystal Ball

Cultura Generale
by Marcello Belguardi

Dr. Howard Bandy* e' uno degli autori indipendenti piu' noti, autorevoli e preparati nel campo dei trading systems.
Ed e' uno dei miei autori preferiti.

Ho trovato questa serie di sue osservazioni frutto di una sua conversazione molto interessanti, rilevanti per chi fa trading sistematico.

Nel trading, come noto, tutto è probabile, non troppo certo e, spesso, difficilmente generalizzabile e dimostrabileper sua stessa natura.
Ciò nonostante Dr. Bandy è sempre molto sicuro delle sue teorie, come vedremo.

Ma il suo e' (per fortuna) un approccio scientifico e, di solito i sui scritti, qualunque sia l'argomento, hanno questo stile.

Segue la versione inglese originale e un tentativo di traduzione mia in italiano, per chi preferisce;

Trading removes inefficiencies.

Il trading elimina le inefficienze.

Trading opportunities are inefficiencies in price.  Trading systems are designed to identify patterns that precede profitable trading opportunities. If the markets ever are truly efficient, no trading system will be profitable over periods exceeding a few trades. Trading a profitable system definitely removes a portion of the inefficiency the model portion of that system identifies.  

Le opportunità di trading sono nelle inefficienze dei prezzi. I trading system sono progettati per identificare patterns che precedono opportunità di trading profittevoli. Se i mercati fossero davvero efficienti nessun trading system sarebbe profittevole oltre periodi che eccedono alcuni trades. Tradandolo, un trading system profittevole sicuramente rimuove una porzione delle inefficienze che il modello del sistema identifica.

All profitable trades are trend following.  The price at the sell must be higher than the price at the buy, without regard to the order of those transactions.  And without regard for the pattern that signaled the trade -- break out, mean reversion, seasonality, whatever.

Tutti i trade profittevoli sono trend following. Il prezzo alla vendita deve essere più alto del prezzo in acquisto, non importa l'ordine delle transazioni. E non importa quale sia il pattern che ha segnalato il trade (breakout, mean reversion, stagionalità, qualunque cosa).

Imagine a reliable wizard who has a crystal ball that identifies profitable trades before they begin. She has determined that a trend that is about to start, with the price rising from the entry point at $50 (where the price has been for the past several months) to the exit point at $60.  The trend will last a few days -- however many are required for the price to rise to $60 -- then the price will stabilize at $60 indefinitely.  This is the action expected as the price changes to reflect some fundamental value in the underlying company.  When the wizard announces the signal on her blog, traders being taking long positions.  The first buyers get the best price and remove the lowest priced shares from the offer book.  Later buyers must bid higher to get filled, they pay more.  After a week or so the price stabilizes at $60 and traders close their positions.

Immaginate che ci esista un mago attendibile che ha una sfera di cristallo capace di identificare i trades profittevoli prima che inizino. Il mago, ad esempio, riconosce che un trend sta per iniziare, prevedendo l'aumento del prezzo dal punto di ingresso a  50$ (dove il prezzo è rimasto per il passato parecchi mesi), fino al punto di uscita a 60$. Il trend durerà un paio di giorni - ma molti scambi sono necessari affinche'  il prezzo salga a 60$. Dopodiche' il prezzo si stabilizzera' a 60$ per un tempo indeterminato. Questo è l'effetto che ci si aspetta, in quanto le variazioni di prezzo in qualche modo riflettono il valore fondamentale della società sottostante. Quando il mago annuncia il segnale sul suo blog, i traders entrano sul mercato con le loro posizioni long. I primi compratori spuntano i migliori prezzi e rimuovoni le azioni a prezzo piu' basso dall book. I buyer che arrivano piu' tardi  devono fare un'offerta superiore per essere serviti, essi pagano di più. Dopo una settimana o giù di lì il prezzo si stabilizza a 60$ ed i traders chiudono le loro posizioni.

A few traders become very good friends with the wizard.  In a few months, she identifies a new signal.  Her new friends take all of the available shares and the price moves from $50 to $60 quickly, removing the inefficiency.
We are all culturing our own wizards.  We are all looking for patterns that precede profitable price movement.  If I develop or discover a profitable trading system, every trade I make removes a portion of the inefficiency.  My account is small and my trades are insignificant.  But if a high volume trader somehow identifies that same pattern as preceding a profitable price change, their trade removes a larger portion of the inefficiency.  It will be traded in large size and make it more difficult for my trade to be profitable.  Eventually my trade, based on that signal, will not cover frictional costs, and the inefficiency will have disappeared. 
It will probably never return.  Because the large trading house has coded the pattern into their trading program and they continue to evaluate the signals and their profitability.  If that pattern shows signs of returning to profitability, they begin trading it, and the inefficiency is removed before I see it.

Alcuni traders diventano molto amici del mago. Dopo pochi mesi, egli identifica un nuovo segnale. I suoi nuovi amici comprano tutte le azioni disponibili e il prezzo si muove da 50$ a 60$ rapidamente, eliminando l'inefficienza.
(Noi traders) facciamo crescere i nostri stessi maghi. Siamo tutti alla ricerca di modelli che precedano un movimento dei prezzi profittevole. Se io sviluppo o scopro un trading system profittevole, ogni trade che faccio rimuove una porzione dell'inefficienza. Il mio account è piccolo e miei trades sono insignificanti. Ma se un trader che opera con grandi volumi in qualche modo identifica lo stesso pattern che precede un variazione del prezzo profittevole, il suo trade elimina una porzione più grande della inefficienza. Saranno le grandi dimensioni del trade a rendere più difficile la reddittivita' del mio trade. Alla fine il mio trade, sulla base di quel segnale, non coprira' i costi , e l'inefficienza scomparira'.
Probabilmente non tornera' più. Perché la grande trading house avra' codificato il pattern nel loro sistema di trading e continuera'  a valutare i segnali e la loro redditività. Se quel pattern  mostrera' segni di ritorno alla redditività, essi ricominceranno nuovamente a tradarlo, e l'inefficienza verra' rimosso prima che io me ne accorga.

Howard Bandy


*Alcuni riferimenti ai suoi libri:
http://www.blueowlpress.com/


Thursday, August 13, 2015

SuperSmoother (road-tested)

Analisi Tecnica
by Marcello Belguardi

John Ehlers, il noto analista ed ingegnere americano, suggerisce di utilizzare il suo SuperSmooher filter al posto di qualunque altra media mobile perchè, avverte, a parità di smoothing ha un lag minore rispetto a tutte le altre medie.
Indica inoltre di utilizzare un periodo sempre superiore a 10 barre per evitare i problemi di aliasing che introdurrebbero elementi di distorsione tipici del campionamento dei segnali.

Ho voluto confrontare la sua media con le comuni altre disponibili su ProRealtime, partendo dalla più comune, la media mobile aritmetica SMA.

Notare che la piattaforma offre una dialog dove è possibile selezionare il tipo di media che ci interessa e molti altri parametri.  Basta selezionare da "Add Indicator" e tra gli indicatori scegliere la "Moving Average", che è quindi configurabile per tracciare molte differenti medie.




Le medie mobili, intese come filtri e per questo tipo di applicazione, devono essere molto liscie per evitare i falsi segnali e avere un ritardo minimo.

Ehlers nei suoi libri fa  l'analisi nel dominio delle frequenze osservandone la risposta in frequenza, come giusto fare per analizzare un qualunque filtro.

Comparare le medie sovrapponendole ed osservando ad occhio la lisciatura ed il ritardo è invece il metodo, pratico, che ho scelto, perchè sono più interessato direttamente alle caratteristiche grafiche.

Cominciamo i test su strada, dunque, partendo dal confronto con la media più semplice. Il SuperSmoother filter (SSM) è quello di colore blu.


SuperSmoother vs Simple Moving Average





Non ci sono molti dubbi: il SSM di Ehlers batte la SMA perchè è più liscia a parità di ritardo. Entrambe comunque seguono il grafico piuttosto da vicino. Il lookback della SSM è di 10, il minimo, ed assomiglia alla SMA quando il lookback della SMA è settato a 5.


SuperSmoother vs Exponential Moving Average


Ha sicuramente meno ritado questa media esponenziale ma è anche molto meno liscia. SI potrebbe preferire il SSM. Il periodo equivalente della EMA è 5.


SuperSmoother vs Weighted Moving Average



La media pesata WMA ha meno ritardo del SSM, una barra in meno, ma ha più falsi segnali. 


SuperSmoother vs Triangular Moving Average




Con una certa sorpresa la TRIMA, la media mobile triangolare, una delle medie meno usate,  si comporta invece egregiamente. Ritardo simile alla SSM di Ehlers con una capacità di filtraggio comparabile.


SuperSmoother vs Hull Moving Average




La media di Hull ha una lisciatura o capacità di filtraggio e ritardo simili alla SSM ma ha un comportamento singolare, cioè una amplificazione del segnale in prossimità delle cuspidi (overshooting). Varrebbe la pena fare qualche esame ulteriore, probabilmente la HMA è adatta ad applicazioni particolari.

SuperSmoother vs Moving Linear Regression



La regressione lineare con lookback 15 è molto simile alla media di Hull. Il ritardo è minimo ma il filtraggio è poco convincente.  Ridurre il ritardo è facile al costo di perdere la capacità di smoothing. Senza smoothing infatti otterremmo ovviamente la serie dei prezzi originale. Non avremmo più informazioni, dal punto di vista analitico, che il prezzo già non avrebbe.


SuperSmoother vs Exponential ZL Moving Average


La media esponenziale zero lag (cioè a ritardo nullo, almeno così dice il nome) in effetti anticipa lo SSM di almeno una barra. Ha qualche falso segnale, cioè non un perfetto smoothing, come si nota bene sul grafico nel periodo intorno a Gennaio / Febbraio ed in generale su alcune altre cuspidi.

SuperSmoother vs Double Exponential Moving Average 


La DEMA necessita di due parametri: in questo caso per esempio rispettivamente 4 e 3. E' più difficile l'analisi perchè la diversa combinazione di essi può rimodellare la linea in modo differente. Sembra anticipare la SSM, ma ha uno smoothing inferiore. Nulla da segnalare rispetto alle medie precedenti.


SuperSmoother vs Triple Exponential Moving Average 


La TEMA richiede 3 parametri, in questo caso 3;2;3 rispettivamente. Anticipa SSM di meno di una barra però presenta qualche discontinuità, per esempio a Febbraio.

SuperSmoother vs Butterworth Filter


Il filtro di Butterworth a 2 poli ha un andamento molto vicino all SSM. Stesso ritardo, ma, sulle cuspidi, presenta un overshooting minore del SSM. Difficile giudicare ma, secondo me, questo filtro presenta già quel tipo di distorsione che Ehlers ha cercato di evitare con il SSM.


Conclusioni


Il SuperSmoother passa questo tipo di esame, nonostante alcune medie siano davvero simili e, forse, l'esercizio di confrontarle possa sembrare inutile;  specialmente quando utilizzate come guida nel trading discrezionale, dove l'occhio non necessita di una eccessiva precisione perchè il cervello corregge automaticamente la figura visualizzata prima che noi si prendano delle decisioni.

Credo che piccole differenze potrebbero invece dare risultati molto differenti se utilizzate in un algoritmo.

Comunque di seguito presento l'utilizzo di due SSM a 10 periodi di cui il secondo ritardato di una barra ed utilizzato come indicatore di inizio, continuazione e fine trend,  evidenziati dagli incroci nei punti di svolta. Credo siano visivamente molto efficaci, molto di più che l'utilizzo due medie mobili con periodi differenti.






Di seguito posto il codice di questo indicatore. Il periodo di lookback dovrebbe essere sempre maggiore o uguale a 10 per evitare di peggiorare la capacità di filtraggio.


// Supersmoother Cross

if barindex > 1 then

a1 = EXP(-1.414*3.14159 / period)
b1 = 2*a1*COS(1.414*180 / period)
c2 = b1
c3 = -a1*a1
c1 = 1 - c2 - c3
Filt = c1*(Close + Close[1]) / 2 + c2*Filt[1] + c3*Filt[2]

endif

return Filt, Filt[1]

// input: period >= 10 to avoid aliasing noise





Tuesday, June 2, 2015

Custom & Built-In Stops

Programmazione ProRealtime
by Marcello Belguardi

La differenza tra una exit e uno stop è che la prima è l'uscita dalla posizione in guadagno, la seconda in perdita rispetto al prezzo di ingresso. E' importante distinguerle ai fini della programmazione.

Un'altra distinzione esiste tra i custom stop ed i built-in stop. La prima categoria comprende tutte le tecniche di uscita dalla posizione che possiamo programmare e  aggiornare ad ogni barra, con semplici comandi sell ed exit short, la seconda categoria si riferisce ai comandi di protezione stop offerti nativamente dalla piattaforma. Vediamo di chiarire il concetto con gli esempi che seguono (per il caso long). Iniziamo con alcuni custom stop.

Breakeven Stop

E' lo stop in pari, il tipo di stop più semplice. Si esce dalla posizione corrente appena il prezzo passa sotto il prezzo d'acquisto. Non c'e' sostanzialmente perdita salvo slippage e commissioni.
Ai fini della simulazione, come faccio di solito, utilizzo ingressi forzati ad una certa data.

Ingresso: in chiusura di barra il 20-02-2015 lo script gira e la condizione goLong è verificata. Ciò implica che si invia un ordine a mercato valido per il giorno dopo (il 20 è un venerdì quindi valido per il lunedì successivo, il 23). Il 23 si entra in posizione long in apertura a mercato.

Uscita: Il 23 in chiusura di barra quando lo script gira, si è a mercato, e la condizione if longonmarket è verificata. Il trading system invia quindi un ordine di vendita di tipo stop valido per il giorno dopo al prezzo di breakeven, che è il prezzo registrato di ingresso TRADEPRICE, che è 129.62 . Il giorno dopo, il 24 questo prezzo non viene toccato e l'ordine stop non scatta, e scade perchè è un ordine daily.
Il 24 però in chiusura di barra lo script viene ovviamente valutato nuovamente ed il sistema invia un ordine di vendita di tipo stop valido per il giorno dopo. Questa volta, il 25, scatta lo stop in pari.





Notare i triangolini che mostrano l'ingresso e l'uscita dalla posizione allo stesso prezzo (129.62$), di breakeven appunto.

Il codice per la simulazione è il seguente:

goLong = (date=20150220)

if goLong then

buy 1 share at market
endif

if longonmarket then

sell at TRADEPRICE stop
endif


NOTE:

TRADEPRICE (o TRADEPRICE(1)) è il prezzo di ingresso in posizione al trade più recente.

Tenete presente inoltre che le tre linee di codice seguenti sono equivalenti quando il timeframe è daily:

buy 1 share at market
buy 1 share at market NextBarOpen
buy 1 share at market TomorrowOpen

Classic Stop Loss

Complichiamo le cose: settiamo lo stop loss  di protezione. Se scatta c'e' una perdita perchè il mercato ci sta dando torto. Poniamo lo stop ad una distanza del 3%  dal prezzo. 

Stesso ingresso di prima il 23 Febbraio a 129.62$. Dalla chiusura del 24 Febbraio fino alla chiusura del 4 Marzo lo script viene fatto girare dal sistema ed un ordine stop è inviato per il giorno dopo. Ad ogni barra scade perchè è un ordine daily ed è quindi rinnovato in chiusura. Scatterà per la prima volta il 5 Marzo quando il prezzo perforerà al ribasso il prezzo di ingresso del 3%, a 125.73$, come previsto.




Questo il codice della simulazione, dovrebbe risultare autoesplicativo:

// stop loss %

goLong = (date=20150220)
percentStop = 3 // percent stop at 3%

if longonmarket then
stopLossPrice = (TRADEPRICE(1) - TRADEPRICE(1)*percentStop*0.01)
endif

if goLong then
buy 1 share at market TomorrowOpen
endif

if longonmarket then
sell at stopLossPrice stop
endif

Built-In Stop

Ci sono, inoltre, i comandi di stop loss predefiniti dalla piattaforma.

Esempio:

// built-in stop loss percentuale rispetto al prezzo di ingresso
SET STOP %LOSS 1.5
// built-in stop loss in dollari rispetto al prezzo di ingresso
SET STOP $LOSS 2

Perche quindi esistono questi comandi di stop se è possibile, come abbiamo visto, programmare gli stop utilizzando semplici comandi di sell per posizioni long (ed exit short per posizioni short) ?

I motivi sono due: il primo è che con gli ordini predefiniti si è protetti sin dalla barra di ingresso. Infatti l'ordine di stop che viene inserito nello script è attivo dalla barra seguente,  naturalmente se si è effettivamente entrati in posizione.
L'altro motivo è che questo tipo di stop va inteso attivo  per tutta la durata del trade (Good Until Cancel - GTC) e non solo per una barra come i precedenti ordini daily. E' insomma uno stop loss di protezione assoluta che andrebbe sempre inserito (in aggiunta agli stop custom). 

Quindi per ricapitolare: Gli stop inseriti come ordini sell o exit short che abbiamo visto all'inizio del post sono attivi non dalla prima barra in posizione ma dalla seconda, perchè la condizione onmarket che va inserita nel codice è testata in chiusura della barra in cui si è entrati in ingresso e vanno rinnovati ad ogni barra, eventualmente con condizioni differenti, per esempio per creare un trailing stop.

Gli ordini standard della piattaforma invece sono automaticamente attivi, statici per tutta la durata del trade, ed è la piattaforma che verifica che la posizione sia attiva prima di agganciare lo stop relativo e rinnovare lo stop ogni giorno.
Sono gli stop "di emergenza" per proteggerci da situazioni anomale.

Vediamo un esempio: l'ordine scatta il 24 Febbraio e il sistema entra in posizione il 25 in apertura di mercato. Si assiste ad un downtrend intraday quel giorno e lo stop ci farà uscire ad una distanza del 1.5 % dal prezzo di apertura.





Il codice relativo è il seguente:


// stop loss %

goLong = (date=20150224)

if goLong then
buy 1 share at market TomorrowOpen
endif

SET STOP %LOSS 1.5
//SET STOP $LOSS 2

Lo stop in dollari, commentato nel codice, ha un effetto simile consentendoci di uscire ad una distanza di 2 dollari dal prezzo di ingresso. I due stop sono mutualmente esclusivi.

Un'altra osservazione riguarda il fatto che lo stop built-in aggiunto non è contenuto in uno statement condizionale per esempio di tipo if/then.  In questo modo la riga di codice è sempre eseguita ad ogni run dello script, ad ogni chiusura di barra.

Gli esempi sono stati fatti per semplicità solo per posizioni long, ma è immediato scriverli anche per posizioni short.

Sunday, May 31, 2015

Timeframe daily su 10 anni

Funzionalità ProRealtime
by Marcello Belguardi

In ProRealtime è possibile visualizzare i grafici a 5/10 anni con timeframe daily (per poter per esempio backtestare i trading systems su periodi estesi) ma la funzionalità non è immediata. Appena infatti si seleziona il periodo ad esempio appunto 10 anni come in figura...




... gli unici timeframe più brevi disponibili sono quella mensile e settimanale. Se si seleziona quella daily si perde la visualizzazione sul periodo.



L'unico modo è selezionare il periodo in punti, per esempio 10000 punti come in figura, e poi lasciare daily come timeframe. Allora funziona.


 Se si vuole si può zoomare un'area e lavorare su quella. Esempio:



Si clicca sul grafico e si seleziona l'area.



Per tornare alla visualizzazione precedente la zoommata basta selezionare l'icona di reset visualizzazione in basso a sinistra.



IMA (Ideal Moving Average)

Programmazione ProRealtime
by Marcello Belguardi

La IMA (Ideal Moving Average) è una media con lag (ritardo) nullo e smoothing (lisciatura) perfetto. Sovrapposta al grafico e calcolata la rispettiva slope (pendenza) si riescono ad identificare con prontezza i turning point (i punti di svolta), i momenti cioè in cui i downtrend lasciano la via agli uptrend e viceversa.

Ideal Moving Average - Piattaforma Prorealtime


Si possono utilizzare i cross tra due IMA o tra una IMA ed il prezzo per individuare i punti di ingresso ed uscita da un trade. Con loopback (quante barre includere nell'indicatore) più ampi può funzionare come supporto o resistenza osservandone la posizione relativa ai prezzi. (la classica prezzo > media a 200 periodi per accertare un trend al rialzo primario).

Esiste un compromesso tra la smoothness di una media mobile ed il suo lag e numerosi sforzi sono stati fatti per avere il meglio delle due caratteristiche nello stesso indicatore.
Noi vorremmo utilizzare la media come filtro dei movimenti impulsivi dei prezzi per estrarne il trend di fondo eliminando cioè le alte frequenze, per così dire, il rumore. E vorremmo che oltre a questo andamento armonico la media non avesse ritardi. Cerchiamo un indicatore che dia il numero minimo di falsi segnali rimanendo liberi di selezionarne il periodo, il loopback.

Per questo motivo la IMA è una illusione, una provocazione, non esiste, proprio per via di questo tradeoff tra lag e smoothing; potremmo però tentare di tracciarla, a mano, su un grafico.
Se agganciassimo un ipotetico trading system ai relativi segnali probabilmente avremmo performance fenomenali.

Come ho fatto allora a raffigurarla con ProRealtime nella figura precedente se la IMA non esiste? Facile: con una media mobile triangolare con lookback 8 e poi centrata, cioè fatta scorrere indietro di 3 barre. Per cui l'indicatore non è tracciato sulle ultime 3 barre. Inoltre ho basato la media non sul close ma sul total price (O+H+L+C)/4.




ProRealtime, così come le altre piattaforme, chiede di accontentarci e offre diversi tipi di moving average: Simple, Exponential, Weighted, Wilder's, Triangular, End Point, Time Series, Zero Lag Exponential, Hull.

Inoltre abbiamo nativamente tra gli indicatori la DEMA (Double Smoothing) e la TEMA (Triple Smoothing).



John Ehlers, noto autore ed analista americano, ha studiato per decenni il problema ed ha elaborato  il Supersmoother concludendo che questa è la media definitiva, la migliore.

Vorrei in un prossimo post verificare quale di queste medie si avvicina, senza compromessi, alla IMA. Se ha ragione John Ehlers perchè utilizzare, d'ora in poi, le altre medie?


Saturday, May 30, 2015

Equity Indicator

Programmazione ProRealtime
by Marcello Belguardi

Qualche tempo fa ho codificato un indicatore che, date le regole di un generico trading system, produce in output la rispettiva equity. Lo riporto qui perchè credo sia un utile esercizio di programmazione e perchè dalla curva di equity si possono estrarre preziose informazioni. (Con la nuova versione di ProRealtime e l'introduzione delle "backtest variables" è molto più facile ed immediato produrre questo output come vedremo successivamente).

Per calcolare la curva dell’equity correttamente, dobbiamo prima osservare come in un trading system le condizioni di acquisto o vendita, cioè i decisori c1 e c2, funzionano in ProRealtime.

Ecco la sezione di codice del noto TS con incrocio di SMA (Simple Moving Average).

c1 = shortMA >= longMA
c2 = shortMA < longMA

In backtesting lo script viene ri-eseguito per ogni barra in chiusura.

Ad ogni barra quindi si assegnano c1 e c2 che comandano la posizione che verrà presa all’indomani.

La posizione corrente, non quella di domani, è indicata da c1[1] e c2[1], cioè quella determinata alla barra precedente. Questa ci è utile per calcolare l’equity, non c1 e c2 che indicano la posizione futura.

Se alla barra corrente c’è stato un ordine di acquisto o vendita, il gap dato dalla differenza dalla chiusura di ieri all’apertura di oggi ha il segno deciso due barre fa, che corrisponde cioè a c1[2] e c2[2].

Quindi l’equity in chiusura della barra corrente si calcola così: l’equity della barra corrente più la differenza tra la chiusura di ieri e l’apertura di oggi. I segni degli addendi dipendono dalle  posizioni long o short determinate nelle barre precedenti.




…per cui questo è lo script dell'indicatore per calcolare l’equity.



// SMA Cross (Eq)
// S,L: 3 to 31


shortMA = Average[S](close)
longMA = Average[L](close)

c1 = shortMA >= longMA
c2 = shortMA < longMA

if barindex > 0 then


if c1[1] then
thisBarGain = close - open
endif

if c2[1] then
thisBarGain = -(close - open)
endif

if c1[2] then
gapGain = open - close[1]
endif

if c2[2] then
gapGain = - (open - close[1])
endif

EQ = EQ[1] + thisBarGain + gapGain

endif


return EQ AS "SMA Cross (Eq)"






Abbiamo realizzato un indicatore che mima esattamente la curva dell’equity calcolata in backtesting da ProRealtime. (Naturalmente dobbiamo sostituire le variabili S ed L calcolate dall’ottimizzatore per avere la stessa curva). Esempio:















Facciamo un altro esperimento: utilizziamo ora  la pendenza della regressione lineare applicata alla curva dell’equity come rivelatore dei periodi nei quali il trading system guadagna o perde.

Se costruiamo un indicatore binario che indichi quando l’equity sale (1) e quando invece scende (0) vediamo l’effetto graficamente:

Ecco il risultato aggiunto sul grafico dell’esempio precedente:




Ho aggiunto l’oscillatore e per chiarezza anche la regressione linerare sulla curva dell’equity (può essere aggiunta graficamente mediante la finestra a tendina e aggiungendo l’indicatore Linear Regression di ProRealtime). 

 Cosa notiamo: l’indicatore “Equity Slope Oscillator” è 0 quando l’equity scende ed 1 quando l’equity sale; ci dà un informazione importante su come si sta comportando il trading system. 

Nota: Questo è il TS completo di riferimento, incrocio di medie mobili. S & L da ottimizzare da 3 a 31

// SMA Cross Trading System 
// S,L: 3 to 31

shortMA = Average[S](close)
longMA = Average[L](close)

c1 = shortMA >= longMA
c2 = shortMA < longMA

if c1 and not longonmarket then
 buy 10000 cash at market
endif

if c2 and not shortonmarket then
 sellshort 10000 cash at market
endif



Friday, May 29, 2015

Non solo ingressi market

Programmazione ProRealtime
by Marcello Belguardi

Ci sono due principali classi alle quali sembrano appartenere i trading systems:



  • Trend following, che comprende anche la sottoclasse dei breakout.
  • Reversal o controtrend, mean reverting, contrarian: tutti termini per indicare lo stesso concetto.

Analizzandole, le due tipologie di setup sono piuttosto differenti perchè:


  • il segnale di un sistema trend following indica una alta probabilità che la corrente direzione del trend persista. Il segnale arriva infatti dopo un turning point.
  • il segnale di un sistema reversal indica una alta probabilità che la corrente direzione del trend non persista e si esaurisca in fretta. Il segnale arriva infatti prima di un turning point.

Resta inteso ovviamente che quando si è in posizione il trade avrà successo se e solo se dal punto di ingresso al punto di uscita dalla posizione esisterà un trend composto da un numero sufficiente di barre che assecondi la direzione del trade long o short, sia che si sia entrati poco dopo l’inizio del trend (trend following) o prima dell’inizio del trend (reversal).

Senza addentrarci qui di quali specifiche soluzioni logiche si avvalgano le due differenti categorie di sistemi si può dire che oltre agli specifici setup esistono precise tipologie di ingressi o entry che possono confermare o non confermare i setup.


Oltre agli ingressi di tipo market, esistono infatti gli ingressi di tipo stop e limit. Vediamoli:


L’ordine di ingresso di tipo stop viene eseguito solo se almeno un prezzo sulla barra che segue l’ordine supererà un determinato ammontare in $ o euro (per posizioni long) o ne sia inferiore (per posizioni short).


L’ordine di ingresso di tipo limit viene eseguito solo se un prezzo sulla barra che segue l’ordine rimarrà inferiore ad un determinato ammontare (per posizioni long) o superiore ad esso (per posizione short).


Per esempio un sistema breakout che preveda un superamento di un certo prezzo affinchè si entri in posizione può trarre beneficio da un ordine di tipo stop.


Se si decide per esempio in un contesto daily che si entrerà in posizione long solo se l’apertura di domani è maggiore della chiusura di oggi (o del massimo di oggi), sarà sufficiente impostare un ordine stop con il valore della chiusura (o del massimo) di oggi.


Fortunatamente in ProRealtime questo meccanismo è implementabile perchè esiste un apposito comando. 


Analogamente, in un sistema reversal, per coadiuvare l’idea di anticipare il trend che verrà, si può pensare di entrare in posizione solo se il prezzo di domani sarà inferiore al prezzo di oggi, per esempio inferiore alla chiusura o al minimo di oggi. Questo è implementabile con Prorealtime perchè esiste l’apposito comando.


Iniziamo a vedere come funziona il normale ordine market. In questo caso non ci sono particolari condizioni sulla entry. Il nostro setup è un segnale scattato l’11 di marzo in chiusura di barra che dice di entrare il 12 di marzo in apertura a mercato.

Piattaforma ProRealtime

Il codice per la simulazione equivalente è il seguente:

data = Date

goLong = (data = 20150311)


IF  goLong THEN

BUY 1 CONTRACTS AT MARKET
ENDIF

graph goLong as "Long"



Questa volta invece, come anticipato, si vuole seguire una strategia trend following o breakout. Dato il segnale in chiusura di barra l’11 Marzo vorrei entrare sulla barra successiva solo se il prezzo supererà il massimo di oggi. Utilizzo un ordine stop con il seguente effetto:


Piattaforma ProRealtime

Notare nella figura il triangolino con il livello di ingresso. La simulazione ha il seguente codice:

data = Date

goLong = (data = 20150311)


if  goLong then

Buy 1 contracts at high stop
endif

graph goLong as "Long"



Terzo caso: la strategia è reversal e si vuole insistere nell’andare controtrend, per cui dato il segnale il 5 Marzo chiederò al sistema di entrare il 6 Marzo solo se il prezzo scenderà sotto il minimo del 5 marzo, con un ordine di tipo limit. Questo l’effetto:


Piattaforma ProRealtime


E questo il codice equivalente:

data = Date

goLong = (data = 20150305)


if  goLong then

Buy 1 contracts at low limit
endif

graph goLong as "Long"


Gli ordini di tipo stop e limit possono essere anche interpretati come filtri, perchè se il movimento sottostante non è confermato anche dalla entry non si entrerà, evitando così dannosi falsi segnali.

Per ora è tutto. Buon trading!