2016-07-07 60 views
5

Ho scaricato citazioni da yahoo con quantmod, calcola rendite trimestrali e voglio unire ritorni e quotazioni in un oggetto xts. In questo nuovo oggetto vorrei vedere solo la data in cui ho sia un ritorno sia un ritorno trimestrale (tipicamente l'ultimo giorno del trimestre). Quello che vedo è però questo:Unisci gli oggetti xts con intervalli di tempo diversi

2011-06-29 appears two time

Ecco il codice:

library(quantmod) 

#Define stocks 
tickers<-c("DBK.DE","DTE.DE") 
stock<-tickers 
StartDate<-'2011-6-25' 
EndDate<-'2016-06-25' 

PF <- getSymbols(tickers, src='yahoo', from=StartDate, to=EndDate) 

# combine the adjusted close values in one (xts) object 
dataset <- Ad(get(PF[1])) 
for (i in 2:length(PF)) { 
    dataset <- merge(dataset, Ad(get(PF[i]))) 
} 

#Getting Quarterly Returns 
QReturns<-as.xts(as.data.frame(lapply(dataset,quarterlyReturn))) 

#Here is where I suspect the problem 
Quarterly_Portfolio<-merge.xts(dataset,QReturns) 

Qualche idea?

risposta

5

Mentre FXQuantTrader's answer risolve il problema, non esegue correttamente la diagnosi o l'indirizzo della causa principale.

Non c'è niente di sbagliato nell'unione di due oggetti xts che hanno classi di indice diverse, perché tutti gli oggetti xts memorizzano l'indice come POSIXct internamente. Ad esempio:

d <- Sys.Date() 
merge(date=xts(1,d), posixct=xts(2,as.POSIXct(d,tz="UTC"))) 
      date posixct 
# 2016-07-09 1  2 

Il problema è dovuto al fatto che i due oggetti xts hanno fusi orari diversi. Notare che dataset ha un fuso orario UTC, poiché un indice Data non può avere un fuso orario.

R> str(dataset) 
An ‘xts’ object on 2011-06-27/2016-06-24 containing: 
    Data: num [1:1305, 1:2] 33.5 34.3 34.6 35.1 36 ... 
- attr(*, "dimnames")=List of 2 
    ..$ : NULL 
    ..$ : chr [1:2] "DBK.DE.Adjusted" "DTE.DE.Adjusted" 
    Indexed by objects of class: [Date] TZ: UTC 
    xts Attributes: 
List of 2 
$ src : chr "yahoo" 
$ updated: POSIXct[1:1], format: "2016-07-09 08:21:12" 

Ma QReturns ha un 'vuoto' TZ attributo (il che significa che il fuso orario locale viene utilizzato).

R> str(QReturns) 
An ‘xts’ object on 2011-06-30/2016-06-24 containing: 
    Data: num [1:21, 1:2] 0.047 -0.354 0.118 0.267 -0.215 ... 
- attr(*, "dimnames")=List of 2 
    ..$ : NULL 
    ..$ : chr [1:2] "quarterly.returns" "quarterly.returns.1" 
    Indexed by objects of class: [POSIXct,POSIXt] TZ: 
    xts Attributes: 
NULL 

QReturns assomiglia a questo, perché hai chiamato as.xts su un data.frame, e as.xts.data.frame specifica dateFormat = "POSIXct" per impostazione predefinita. Se imposti dateFormat = "Date", non avrai alcun problema con la fusione di questi due oggetti.

Si noti inoltre che è una pratica scorretta chiamare i metodi direttamente (merge.xts). Dovresti semplicemente chiamare lo standard merge e lasciare che il sistema S3 gestisca l'invio del metodo.

QReturns <- as.xts(as.data.frame(lapply(dataset,quarterlyReturn)),dateFormat="Date") 
Quarterly_Portfolio <- merge(dataset,QReturns) 
head(Quarterly_Portfolio) 
#   DBK.DE.Adjusted DTE.DE.Adjusted quarterly.returns quarterly.returns.1 
# 2011-06-27   33.5422   7.820    NA     NA 
# 2011-06-28   34.2747   7.786    NA     NA 
# 2011-06-29   34.6194   7.909    NA     NA 
# 2011-06-30   35.1193   8.085  0.04701838   0.03388747 
# 2011-07-01   36.0286   7.992    NA     NA 
# 2011-07-04   35.7787   7.995    NA     NA 

io personalmente eviterei questo tutti insieme, non la conversione da XTS a data.frame di nuovo a XTS nel calcolo QReturns. È possibile chiamare lapply direttamente su un oggetto xts, quindi unire nuovamente i risultati utilizzando do.call(merge, ...).

QReturns <- do.call(merge, lapply(dataset, quarterlyReturn)) 
Quarterly_Portfolio <- merge(dataset, QReturns) 

tuo getSymbols e "combinare" passi può essere effettuata anche in modo più compatto:

PF <- new.env() 
getSymbols(tickers, from=StartDate, to=EndDate, env=PF) 
# combine the adjusted close values in one (xts) object 
dataset <- do.call(merge, eapply(PF, Ad)) 
+0

Wow. Grazie mille. –

+0

Interessante. Grazie per la condivisione – FXQuantTrader

3

tuo problema sorge perché hanno diversi tipi di oggetti di tempo:

> class(index(dataset)) 
[1] "Date" 
> class(index(QReturns)) 
[1] "POSIXct" "POSIXt" 

si desidera convertire alla stessa classe quando si utilizza merge.xts. Si potrebbe provare questo, con l'aiuto della pratica lubridate funzione di floor_date, che arrotonda giù un tempo POSIXct alla data più vicina, quando ci sono non zero ore attaccati ai valori oggetto POSIXct:

require(lubridate) 
index(dataset) <- floor_date(as.POSIXct(index(dataset)), "day") 
Quarterly_Portfolio<-merge.xts(dataset,QReturns) 

> head(Quarterly_Portfolio) 
      DBK.DE.Adjusted DTE.DE.Adjusted quarterly.returns quarterly.returns.1 
2011-06-27   33.5422   7.820    NA     NA 
2011-06-28   34.2747   7.786    NA     NA 
2011-06-29   34.6194   7.909    NA     NA 
2011-06-30   35.1193   8.085  0.04701838   0.03388747 
2011-07-01   36.0286   7.992    NA     NA 
2011-07-04   35.7787   7.995    NA     NA 

In alternativa, invece di floor_date è anche possibile utilizzare la base R round.POSIXt in questo modo: as.POSIXct(round.POSIXt(as.POSIXct(index(dataset)), "day"))

+0

Thx un sacco funziona perfettamente ora –