Possible unexpected behaviour when index is `POSIXct`-class
Opened this issue · 0 comments
Description
If the Sys.timezone()
is different from xts::tzone()
and the index is POSIXct
POSIXt
class, then quantmod::specifyModel()
fails, and this affects quantmod::buildModel()
and quantmod::tradeModel()
. I believe this is unexpected because in both cases xts::tzone()
is UTC
.
I have created some synthetic OHLC
-data to reproduce the behavior, display the expected behavior and showing a manual fix.
Expected behavior
set.seed(1903)
# 0) create generic
# OHLC zoo object
open <- runif(n = 50,min = 10, max = 100)
ticker <- zoo::as.zoo(
cbind(
Open = open,
High = open + 1,
Low = open - 1,
Close = open + 0.5
)
)
# 1) daily index
zoo::index(ticker) <- seq(
from = Sys.Date(),
by = "+1 day",
length.out = nrow(ticker)
)
# 2) convert to xts
ticker <- xts::as.xts(
ticker
)
# 3) Specify and run model
# accordingly
model <- quantmod::buildModel(
x = quantmod::specifyModel(
quantmod::Next(quantmod::OpCl(ticker)) ~ quantmod::Lag(quantmod::OpHi(ticker))
),
method = "lm",
training.per = c(zoo::index(ticker)[1],zoo::index(ticker)[10])
)
#> Registered S3 method overwritten by 'quantmod':
#> method from
#> as.zoo.data.frame zoo
# 3.1) Trade modell
quantmod::tradeModel(
x = model
)
#> Warning in modelReturn(quantmodResults, trade.dates = trade.dates, leverage =
#> leverage, : Model results are all one direction.
#>
#> Model: lm1708018884.17448
#>
#> C.A.G.R.: 1272.66% H.P.R.: 48.44%
#>
#> Returns by period summary:
#>
#> weekly monthly quarterly yearly
#> Max. 9.61% 37.81% 40.81% 46.68%
#> 3rd Qu. 7.65% 20.99% 31.65% 46.68%
#> Mean 6.61% 14.72% 22.49% 46.68%
#> Median 6.30% 4.17% 22.49% 46.68%
#> 2rd Qu. 5.45% 3.17% 13.33% 46.68%
#> Min. 4.17% 2.18% 4.17% 46.68%
#>
#> Period to date returns:
#>
#> weekly monthly quarterly yearly
#> 4.17% 4.17% 4.17% 46.68%
Created on 2024-02-15 with reprex v2.1.0
Minimal, reproducible example
Where it fails
Here I change the index
to POSIXct
as this supports smaller granularity.
set.seed(1903)
# 0) create generic
# OHLC zoo object
open <- runif(n = 50,min = 10, max = 100)
ticker <- zoo::as.zoo(
cbind(
Open = open,
High = open + 1,
Low = open - 1,
Close = open + 0.5
)
)
# 1) daily index
zoo::index(ticker) <- seq(
from = as.POSIXct(Sys.Date(), tz = "UTC", origin = '1970-01-01'),
by = "+1 day",
length.out = nrow(ticker)
)
# 2) convert to xts
ticker <- xts::as.xts(
ticker
)
# 3) Specify and run model
# accordingly
model <- quantmod::buildModel(
x = quantmod::specifyModel(
quantmod::Next(quantmod::OpCl(ticker)) ~ quantmod::Lag(quantmod::OpHi(ticker))
),
method = "lm",
training.per = c(zoo::index(ticker)[1],zoo::index(ticker)[10])
)
# 3.1) Trade modell
quantmod::tradeModel(
x = model
)
#> Error in eval(expr, envir, enclos): object 'model' not found
Created on 2024-02-15 with reprex v2.1.0
Manual fix
I can fix this by either setting Sys.setenv(TZ = "UTC")
or changing the index
to a Date
-class. (But the latter fix is not desirable for if one is to apply the quantmod
-functions to, say, hourly data)
set.seed(1903)
# 0) create generic
# OHLC zoo object
open <- runif(n = 50,min = 10, max = 100)
ticker <- zoo::as.zoo(
cbind(
Open = open,
High = open + 1,
Low = open - 1,
Close = open + 0.5
)
)
# 1) daily index
zoo::index(ticker) <- seq(
from = as.POSIXct(Sys.Date(), tz = "UTC", origin = '1970-01-01'),
by = "+1 day",
length.out = nrow(ticker)
)
# 2) convert to xts
ticker <- xts::as.xts(
ticker
)
# 2.1) set TZ
Sys.setenv(TZ = "UTC")
# 3) Specify and run model
# accordingly
model <- quantmod::buildModel(
x = quantmod::specifyModel(
quantmod::Next(quantmod::OpCl(ticker)) ~ quantmod::Lag(quantmod::OpHi(ticker))
),
method = "lm",
training.per = c(zoo::index(ticker)[1],zoo::index(ticker)[10])
)
#> Registered S3 method overwritten by 'quantmod':
#> method from
#> as.zoo.data.frame zoo
# 3.1) Trade modell
quantmod::tradeModel(
x = model
)
#> Warning in modelReturn(quantmodResults, trade.dates = trade.dates, leverage =
#> leverage, : Model results are all one direction.
#>
#> Model: lm1708019051.06961
#>
#> C.A.G.R.: 1272.66% H.P.R.: 48.44%
#>
#> Returns by period summary:
#>
#> weekly monthly quarterly yearly
#> Max. 9.61% 37.81% 40.81% 46.68%
#> 3rd Qu. 7.65% 20.99% 31.65% 46.68%
#> Mean 6.61% 14.72% 22.49% 46.68%
#> Median 6.30% 4.17% 22.49% 46.68%
#> 2rd Qu. 5.45% 3.17% 13.33% 46.68%
#> Min. 4.17% 2.18% 4.17% 46.68%
#>
#> Period to date returns:
#>
#> weekly monthly quarterly yearly
#> 4.17% 4.17% 4.17% 46.68%
Created on 2024-02-15 with reprex v2.1.0
Session Info
R version 4.3.2 (2023-10-31 ucrt)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 11 x64 (build 22631)
Matrix products: default
locale:
[1] LC_COLLATE=English_Denmark.utf8 LC_CTYPE=English_Denmark.utf8
[3] LC_MONETARY=English_Denmark.utf8 LC_NUMERIC=C
[5] LC_TIME=English_Denmark.utf8
time zone: Europe/Copenhagen
tzcode source: internal
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] usethis_2.2.2
loaded via a namespace (and not attached):
[1] compiler_4.3.2 magrittr_2.0.3 cli_3.6.2 tools_4.3.2
[5] fs_1.6.3 glue_1.6.2 rstudioapi_0.15.0 vctrs_0.6.5
[9] lifecycle_1.0.4 rlang_1.1.3 purrr_1.0.2
Disclaimer: I recently moved to Windows, and I don't remember experiencing this issue
on Linux. So it might just be me who are missing something.