R : i primi 30 minuti (dall’installazione al primo Trading-System) (1 Viewer)

GiuliaP

The Dark Side
Il pacchetto-base legge dati dall’universo ascii (txt, csv etc.) ma con un concetto diverso dai software classici, ad esempio l’istruzione:

read.table()

legge indifferentemente da un file sul tuo pc, dalla tua clipboard, oppure da internet.
In pratica ciò permette di accedere allo sterminato universo di dati pubblici presenti sul web (es. files times&sales sul CME), permettendoti di manipolarli secondo i tuoi scopi (es. cambiare il formato delle date)

Alcuni packages contengono accessi diretti facilitati ad enormi database finanziari, come yahoo.finance, google finance, FRED, Oanda, Bloomberg, IB, con modalità non sempre possibili con i classici software di AT.

Esempio, supponiamo di voler ottenere da yahoo.finance 1 year Target Price, P/E Ratio, Book Value di 4 titoli petroliferi: XOM quotata al NYSE, ENI quotata in Italia, BP a Londra e Petrochina a Hong Kong. Dopo aver richiamato la libreria è sufficiente una sola istruzione:

Codice:
[COLOR=red]library(quantmod)[/COLOR]
[COLOR=red]getQuote("XOM;ENI.MI;BP.L;0857.HK",what=yahooQF(c("1 yr Target Price","P/E Ratio","Book Value")))[/COLOR]
[code]
 
[COLOR=blue]               Trade Time 1 yr Target Price P/E Ratio Book Value[/COLOR]
[COLOR=blue]XOM     2012-03-23 04:00:00             94.24     10.13     32.614[/COLOR]
[COLOR=blue]ENI.MI  2012-03-23 12:30:00             19.77     10.59     15.194[/COLOR]
[COLOR=blue]BP.L    2012-03-23 12:35:00              8.51    354.84      5.874[/COLOR]
[COLOR=blue]0857.HK 2012-03-23 03:59:00              9.97     90.49      0.828[/COLOR]
Per le SVM in R, aggiungo un link alle info di Cren: Data Mining Algorithms In R/Classification/SVM - Wikibooks, open books for an open world

Ottimo.

Toccherà darci un'occhiata.

Grazie.
 

i.p.i.s

Nuovo forumer
Ciao L. wb :)
Leggevo il libro di Laura Romanò: " La fisica in barca a vela " ( curiosità per i marinai ).
Ho eseguito una pausa per spulciare il forum e ho letto il post, mi è venuto in mente...

"...E' buffo. Quei gabbiani che non hanno una meta ideale e che
viaggiano solo per viaggiare, non arrivano da nessuna parte, e vanno piano.
Quelli invece che aspirano alla perfezione, anche senza intraprendere alcun
viaggio, arrivano dovunque, è in un baleno.
( da " Il Gabbiano Jonathan Livingston di Richard Bach. )

mmdm :-(

lirica ma verissima analogia tra la volatilità dei gabbiani e quella dei mercati
 

Il Conte Pedro

Not so easy
Proseguiamo con l'educational e vediamo se ci ho capito qualcosa di questo R :D

Ho recuperato la versione originale di questo TS: http://www.investireoggi.it/forum/ts-giorno-e-notte-vt61406.html
e l'ho implementata in R con i dati di Yahoo (Skarso :bow: non me ne voglia, è solo per provare, ovviamente ci vanno dati più affidabili di quelli di Yahoo).

Il TS originale, SOLO versione giorno, era:

Fase di apertura del mercato:
- se il giorno del mese è 31,1,2,3 compra e chiudi la posizione alla chiusura del giorno stesso (Turn of the month)
- se Chiusura DJ-Apertura DJ del giorno precedente è maggiore di zero o giorno del mese è 17 vendi e chiudi la posizione alla chiusura del giorno stesso

L'ho corretto mettendo, al posto del giorno 31, il giorno di fine mese (mitico R per la gestione delle date!)

Codice:
#
## TS Giorno e Notte
#
# volendo riprodurlo è sufficiente copiare le sole istruzioni in rosso
# richiamiamo le librerie
[COLOR=Red]require(quantmod)
require(PerformanceAnalytics)
[/COLOR] #
# scarichiamo gli storici dell'FTSE MIB e del DJIA
#
[COLOR=Red]getSymbols("FTSEMIB.MI;^DJI", from="2000-01-01")
[/COLOR]#
# otteniamo le aperture e le chiusure ritardate di un giorno del DJIA
[COLOR=Red]djia_delayed_opens <- Lag(Op(DJI))
djia_delayed_closes <- Lag(Cl(DJI))
djia_delayed <- merge(djia_delayed_opens, djia_delayed_closes)
[/COLOR]#
# otteniamo le aperture e le chiusure dell'FTSE MIB
[COLOR=Red]ftsemib_opens <- Op(FTSEMIB.MI)
ftsemib_closes <- Cl(FTSEMIB.MI)
ftsemib <- merge(ftsemib_opens, ftsemib_closes)
[/COLOR]#
# sincronizziamo i dati
[COLOR=Red] xx <- na.omit(merge(ftsemib,djia_delayed))[/COLOR]
#
# se giorno del mese e' ultimo giorno del mese oppure 1,2,3 compra
# se chiusura DJ-Apertura DJ del giorno precedente è maggiore di zero oppure se il giorno del mese è 17 vendi
# Nota. Mi sfugge perche':
# 1) devo usare .indexDate(xx[,0])+2 per avere una serie shiftata avanti di un giorno
# 2) nella condizione booleana devo mettere xx[,1]!=xx[,1] che ovviamente e' falso, quindi di fatto non influisce nella condizione, per avere una serie temporale corretta
[COLOR=Red]ret <- ifelse(xx[,1]!=xx[,1] | .indexmday(xts(xx[,1], as.Date(.indexDate(xx[,0])+2)))==1 | .indexmday(xx)==1 | .indexmday(xx)==2 | .indexmday(xx)==3, log(xx[,2]/xx[,1]), ifelse(xx[,4]>xx[,3] | .indexmday(xx)==17, log(xx[,1]/xx[,2]), 0))
[/COLOR]#
# e ora la performance
[COLOR=Red]charts.PerformanceSummary(ret,ylog=TRUE,main="TS giorno",colorset="red")
table.AnnualizedReturns(ret)
[/COLOR]
Questi i risultati:

Annualized Return 0.2308
Annualized Std Dev 0.1589
Annualized Sharpe (Rf=0%) 1.4525

1332767406schermata032456013alle15.09.37.png


Idee, pareri, suggerimenti?
Soprattutto: vi sembra implementanto in maniera corretta in R, oppure ho scritto delle fesserie?
 

surcontre

Nuovo forumer
Il TS originale, SOLO versione giorno, era:
......
Fase di apertura del mercato:
- se il giorno del mese è 31,1,2,3 compra e chiudi la posizione alla chiusura del giorno stesso (Turn of the month)
- se Chiusura DJ-Apertura DJ del giorno precedente è maggiore di zero o giorno del mese è 17 vendi e chiudi la posizione alla chiusura del giorno stesso

L'ho corretto mettendo, al posto del giorno 31, il giorno di fine mese (mitico R per la gestione delle date!)
......
Ciao, Pedro
la prima parte del listato, quella che arriva alla matrice dei prezzi sincronizzati, mi sembra ottima.
Invece mi sembra un po' troppo complicata l'istruzione che perviene al vettore dei rendimenti (io non l'ho capita): forse sarebbe meglio spezzarla in più sotto-condizioni, con maggior chiarezza. Ad esempio all'inizio noto una cosa che mi lascia perplesso:
ret <- ifelse(xx[,1]!=xx[,1] | ........
chiaramente x[,1] non può mai essere diverso da se stesso.

Anche se il tuo scopo era di mostrare le potenzialità del linguaggio e non una particolare strategia, aggiungo un paio di cose sul modello:
Usare i prezzi Open degli indici di borsa in genere è rischioso (non solo con FTSEMIB) perché poco rappresentativi di ciò che accade , nella realtà, su futures o ETF che replicano l'indice.
Ad esempio, negli ultimi anni la correlazione tra i log-rendimenti dell'indice FTSEMIB e dell'etf ETFMIB è di circa 0.97 se presa Close/Close, crolla a circa 0.51 se presa Open/Close
Il ToM, nella versione originale semplice, è una delle poche strategie, verificate dal mondo accademico, che superano i vari test anti data-dredging. Andare a introdurre nel modello altri gradi di libertà come la scelta dei giorni, oppure se il comportamento del Dow etc. mi sembra un modo quasi sicuro per fare data-snooping.
Tutto sommato, trattandosi di una strategia mensile i dati disponibili sono pochi (anche se lo testi su 100 anni) ed è sempre possibile trovare il modo di 'condizionarlo' per escludere (tutti o una parte) i rendimenti negativi. Se però le condizioni che introduci non hanno motivazioni fondamentali 'forti' il risultato che ne esce tipicamente è una forma di trading quasi random.
Happy trading e complimenti
 

Il Conte Pedro

Not so easy
ret <- ifelse(xx[,1]!=xx[,1] | ........
chiaramente x[,1] non può mai essere diverso da se stesso.

Questa parte l'ho dovuta introdurre come ho scritto nei commenti, perché, se la lascio, questo sottoblocco
Codice:
xx[,1]!=xx[,1] | .indexmday(xts(xx[,1], as.Date(.indexDate(xx[,0])+2)))==1 | .indexmday(xx)==1 | .indexmday(xx)==2 | .indexmday(xx)==3
dà ancora una serie temporale:
Codice:
...
2012-03-16           FALSE
2012-03-19           FALSE
2012-03-20           FALSE
2012-03-21           FALSE
2012-03-23           FALSE
mentre questo sottoblocco senza quella condizione (che è sempre FALSE, quindi non altera il risultato):
Codice:
.indexmday(xts(xx[,1],  as.Date(.indexDate(xx[,0])+2)))==1 | .indexmday(xx)==1 |  .indexmday(xx)==2 | .indexmday(xx)==3
non dà più una serie temporale:
Codice:
   [1]  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE
  [45] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE  TRUE  TRUE
Comunque mi rendo conto di due cose:

  1. Io sono uno sviluppatore software, questo linguaggio mi piace perché è potentissimo avendo delle ottime librerie dedicate, ovviamente come tutti i linguaggi va imparato a fondo per evitare di scrivere spaghetti-code come ho fatto io
  2. Io non capisco niente di trading :D per cui prima di usare uno strumento come questo per creare un TS da usare con soldi reali, devo studiare di più
Scherzi a parte, avete visto con quante righe di codice si replica quel TS originariamente fatto con maggior fatica in Excel?
 

Cren

Forumer storico
...questo linguaggio mi piace perché è potentissimo avendo delle ottime librerie dedicate, ovviamente come tutti i linguaggi va imparato a fondo per evitare di scrivere spaghetti-code come ho fatto io
Ciao, anche io sto cercando di perfezionarmi per quanto mi è possibile con R.

Propongo a te, surcontre, all in, faor72 e altri gentili frequentatori che avranno la pazienza di smanettare un pochino con R di condividere qui listati e suggerimenti :)

Inviterei anche GiuliaP, se solo volesse degnarsi di condividere qualche listato con noi comuni mortali contravvenendo al suo personalissimo codice deontologico che le vieta di pubblicare certo materiale :D
 
Ultima modifica:

Il Conte Pedro

Not so easy
Spiego solo brevemente quel pezzo di codice incriminato:
Codice:
ret <- ifelse(xx[,1]!=xx[,1] | .indexmday(xts(xx[,1], as.Date(.indexDate(xx[,0])+2)))==1 | .indexmday(xx)==1 | .indexmday(xx)==2 | .indexmday(xx)==3, log(xx[,2]/xx[,1]), ifelse(xx[,4]>xx[,3] | .indexmday(xx)==17, log(xx[,1]/xx[,2]), 0))
La prima condizione dell'ifelse:
xx[,1]!=xx[,1] | .indexmday(xts(xx[,1], as.Date(.indexDate(xx[,0])+2)))==1 | .indexmday(xx)==1 | .indexmday(xx)==2 | .indexmday(xx)==3
serve ad avere un time series di booleani dove il giorno del mese è l'ultimo (as.Date(.indexDate(xx[,0])+2)))==1 cioè converto in data, sommo 2, e qui non capisco perchè devo sommare 2 per avanzare di un giorno, però ho visto che è così, riconverto in time series shiftata quindi avanti di un giorno e a questo punto verifico se il giorno del mese shiftato avanti di uno è il primo, quindi il giorno originale era l'ultimo giorno del mese) oppure il 1,2,3.

Se la condizione del primo ifelse è vera, compro e rivendo in chiusura, quindi il valore da usare è log(xx[,2]/xx[,1]).

Se la condizione è falsa, allora verifico l'altra condizione: se il DJIA del giorno precedente ha chiuso più alto dell'apertura (xx[,4]>xx[,3]), oppure il giorno è il 17 (.indexmday(xx)==17), allora vendo in apertura e ricompro in chiusura, quindi il valore da usare è log(xx[,1]/xx[,2]).
 
Ultima modifica:

Il Conte Pedro

Not so easy
Propongo a te, surcontre e altri gentili frequentatori che avranno la pazienza di smanettare un pochino con R di condividere qui listati e suggerimenti :)

Per quanto mi sarà possibile, volentieri. Ma solo relativamente a questioni di scrittura del codice, perché non sono assolutamente ferrato per dare altro tipo di indicazioni.
 

tex65

Forumer storico
Per quanto mi sarà possibile, volentieri. Ma solo relativamente a questioni di scrittura del codice, perché non sono assolutamente ferrato per dare altro tipo di indicazioni.

Ti e vi ascolto con interesse, soprattutto le idee (anche con rendimenti minimi), purtroppo non ho ne tempo ne competenze di linguaggi di programmazione adeguati per aiutare, seguiterò ad ascoltare in silenzio.
grazie a tutti! :up:
 

Users who are viewing this thread

Alto