Closed SamoPP closed 1 year ago
The index values of series
are not actually seconds at the end of the days in UTC. They're off by 5 hours.
y <- head(series)
x <- y
index(x) <- as.Date(index(x))
(.index(y) - .index(x)) / 3600 # difference of 5 hours
## [1] 5 5 5 5 5 5
## attr(,"tzone")
## [1] "UTC"
## attr(,"tclass")
## [1] "Date"
How did you create series
? It's in an old format because xts indexes no longer have .indexClass
and .indexTZ
attributes. Also tclass
and tclass
attributes are only on the index now, not the xts object itself.
Thanks. I was assuming some tzone nightmare was happening....
Well, I created the xts object many years ago by downloading available history at that time from Interactive Brokers using IBrokers, saved it to disk and then (almost) every day append to it what is new (from IB) and saved the appended xts to disk. This was read from disk using getSymbols.FI.
In that case, I would add a index(x) <- as.Date(index(x))
to your code that downloads the data from IB and appends it to the old object.
It may make sense to check and warn if the underlying index are not UTC dates when the tclass = "Date"
and tzone = "UTC"
. Can you share some of the code you're using to create the data you're appending? That would help me determine where it might make sense to add a check.
Also, you can use x <- xts:::.update_index_attributes(x)
to update the tclass
and tzone
attributes to use the current structure.
Thanks. Will do as suggested.
Below is the code (well, part of it - it's a big mess) that downloads and updates data from IB and updates xts object on disk:
instr <- getInstrument(symbol)
contract <- instr$IB
symbol <- instr$primary_id
startTimeForOneSymbol <- Sys.time()
i <- i + 1
if (averageTimeTakenForOneSymbol != 0) {
print(paste0("[INFO] START - Download from IB for symbol=", symbol, " i=", i, " of ", nSymbols, " . Estimated time left: ", averageTimeTakenForOneSymbol*(nSymbols - i + 1)))
} else {
print(paste0("[INFO] START - Download from IB for symbol=", symbol, " i=", i, " of ", nSymbols))
}
firstDateOnDisk <- NULL
dateOfFirstTrade <- NULL
bizDaysFromHeadTimeStampToFirstDayOnDisk <- NULL
existingSymbolDataOnDisk <- NULL
print(paste0("[INFO] Retreiving existing data for symbol=", symbol, " from disk folder=", file.path(pathToIBData, "TRADES")))
try(existingSymbolDataOnDisk <- getSymbols(symbol, src="FI", env=env, dir=file.path(pathToIBData, "TRADES"), auto.assign=FALSE, extension="rda", split_method="common"))
if (!is.null(existingSymbolDataOnDisk) & !inherits(existingSymbolDataOnDisk, "try-error")) {
if (tclass(existingSymbolDataOnDisk) != "Date") {
tclass(existingSymbolDataOnDisk) <- "Date"
}
lastDateOnDisk <- last(index(existingSymbolDataOnDisk))
nDaysToDownload <- businessDaysBetween("UnitedStates/NYSE", from=lastDateOnDisk, to=lastNYSEOpenDate, includeFirst=FALSE, includeLast=TRUE)
print(paste0("[INFO] We have existing data for symbol=", symbol, " in folder=", file.path(pathToIBData, "TRADES"), " with lastDateOnDisk=", lastDateOnDisk, " therefore using nDaysToDownload=", nDaysToDownload))
} else {
if (isTRUE(usereqHeadTimestamp)) {
# Do the reqHeadTimestamp thing to find nDaysToDownload
if (is.null(contract)) {
contract <- Contr_From_Instr(symbol)
}
#dateOfFirstTrade <- try(reqHeadTimeStamp(contract, insync=insync, ib=ib, maxAttempts=5))
dateOfFirstTrade <- try(getAndManageReqHeadTimeStamp(symbol=symbol, contract=contract, insync=insync, ib=ib, maxAttempts=5, tryLoadingFromDisk=TRUE, folder="/data_warehouse/data/sources/ib/HeadTimeStamp/"))
if (!is.null(dateOfFirstTrade) & !inherits(dateOfFirstTrade, "try-error") & (length(dateOfFirstTrade) > 0)) {
if (dateOfFirstTrade > 0) {
dateOfFirstTrade <- as.Date(dateOfFirstTrade, origin="1970-01-01")
print(paste0("[INFO] First trade for symbol=", symbol, " appeared on ", dateOfFirstTrade))
} else {
print(paste0("[INFO] First trade for symbol=", symbol, " is a negative number (dateOfFirstTrade=", dateOfFirstTrade, ") and therefore probably data does not exist. Setting dateOfFirstTrade <- NULL ."))
dateOfFirstTrade <- NULL
}
} else {
print(paste0("[INFO] Could not get date of first trade for symbol=", symbol, " . There was an eror calling reqHeadTimeStamp()."))
dateOfFirstTrade <- NULL
}
if (!is.null(dateOfFirstTrade)) {
nDaysToDownload <- max(maxDays, businessDaysBetween("UnitedStates/NYSE", from=dateOfFirstTrade, to=lastNYSEOpenDate, includeFirst=FALSE, includeLast=TRUE))
} else {
nDaysToDownload <- maxDays
print(paste0("[INFO] For symbol=", symbol, " dateOfFirstTrade is NULL. There was an error or something instead. Maybe data simply just doesn't exist yet. Setting nDaysToDownload <- ", maxDays, " (maxDays) ."))
}
print(paste0("[INFO] We do not have existing data for symbol=", symbol, " in folder=", file.path(pathToIBData, "TRADES"), " therefore using nDaysToDownload=", nDaysToDownload, " (based on reqHeadTimestamp)."))
} else {
nDaysToDownload <- maxDays
print(paste0("[INFO] We do not have existing data for symbol=", symbol, " in folder=", file.path(pathToIBData, "TRADES"), " therefore using nDaysToDownload=", nDaysToDownload, " (maxDays)."))
}
}
if (nDaysToDownload > 0) {
newSymbolData <- NULL
endDateTime <- paste(format(strptime(paste(to, "23:59:59"),"%Y-%m-%d %H:%M:%S"),"%Y%m%d %H:%M:%S"))
if (nDaysToDownload <= 365) {
duration <- paste0(nDaysToDownload, " D")
} else {
duration <- paste0(ceiling(nDaysToDownload/365), " Y")
}
if (is.null(contract)) {
contract <- Contr_From_Instr(symbol)
}
if (is.null(tws)) {
tws <- twsConnect(clientId=5)
}
print(paste0("[INFO] Retreiving IB data for symbol=", symbol, " with duration=", duration, ", endDateTime=", endDateTime, " ."))
newSymbolData <- try(reqHistoricalData(tws, contract, barSize="1 day", duration=duration, endDateTime=endDateTime, useRTH="1", whatToShow="TRADES"))
if (!is.null(newSymbolData) & !inherits(newSymbolData, "try-error")) {
print(paste0("[INFO] Received new data from IB for symbol=", symbol, " and we have NROW(newSymbolData)=", NROW(newSymbolData), " ."))
tclass(newSymbolData) <- "Date"
combinedSymbolData <- NULL
if (!is.null(existingSymbolDataOnDisk)) {
combinedSymbolData <- rbind(existingSymbolDataOnDisk, newSymbolData)
} else {
combinedSymbolData <- newSymbolData
}
# Remove rows with a duplicated timestamp, but keep the latest one
combinedSymbolData <- combinedSymbolData[!duplicated(index(combinedSymbolData), fromLast=TRUE ), ]
assign(symbol, combinedSymbolData, envir=env)
saveSymbols.common(symbol, base_dir=file.path(pathToIBData, "TRADES"), env=env)
print(paste0("[INFO] Saved symbol=", symbol, " to folder=", file.path(pathToIBData, "TRADES")))
} else {
print(paste0("[INFO] Not able to receive new data from IB for symbol=", symbol))
}
} else {
print(paste0("[INFO] Nothing to download from IB for symbol=", symbol, " since nDaysToDownload=", nDaysToDownload, " (shoul be nDaysToDownload > 0)."))
}
The problem is this block of code. It changes the tclass attribute to "Date" but it doesn't update the index to seconds since the epoch in UTC.
if (tclass(existingSymbolDataOnDisk) != "Date") {
tclass(existingSymbolDataOnDisk) <- "Date"
}
This is similar enough to #311 that I'm going to close it as a duplicate. Please continue any discussions in that issue.
Description
While subsetting xts object by dates (
series$IsNthTradingDayOfMonth[lastNthTradingDaysOfMonth]
) nothing is returned.Subestting using
series$IsNthTradingDayOfMonth[which(index(series) %in% lastNthTradingDaysOfMonth)]
works as expected.See code below for details.
What is it that I do not understand?
Expected behavior
I was assuming the subsetting using vector of dates would work.
Minimal, reproducible example
Session Info