Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved column matching for OHLCVA #306

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Authors@R: c(
)
Depends: R (>= 3.2.0), xts(>= 0.9-0), zoo, TTR(>= 0.2), methods
Imports: curl
Suggests: DBI,RMySQL,RSQLite,timeSeries,XML,downloader,jsonlite(>= 1.1)
Suggests: DBI,RMySQL,RSQLite,timeSeries,XML,downloader,jsonlite(>= 1.1), tinytest
Description: Specify, build, trade, and analyse quantitative financial trading strategies.
LazyLoad: yes
License: GPL-3
Expand Down
157 changes: 78 additions & 79 deletions R/OHLC.transformations.R
Original file line number Diff line number Diff line change
Expand Up @@ -181,144 +181,143 @@ OHLCV <- function(x)
`Op` <-
function(x)
{
if(has.Op(x))
return(x[,grep('Open',colnames(x),ignore.case=TRUE)])
stop('subscript out of bounds: no column name containing "Open"')
col <- has.Op(x, which = TRUE)
if(!identical(col, integer(0))) {
return(x[, col])
} else {
stop('subscript out of bounds: Open column not found')
}
}

`has.Op` <-
function(x,which=FALSE)
{
colAttr <- attr(x, "Op")
if(!is.null(colAttr))
return(if(which) colAttr else TRUE)

loc <- grep('Open',colnames(x),ignore.case=TRUE)
if(!identical(loc,integer(0))) {
return(if(which) loc else TRUE)
} else FALSE
n <- which(colnames(x) %in% c("Op", "Open"))

if(identical(n,integer(0))) {
n <- grep('Open$', colnames(x), ignore.case = TRUE)
}

return(if(which) n else !identical(n,integer(0)))
}

`Hi` <-
function(x)
{
if(has.Hi(x))
return(x[,grep('High',colnames(x),ignore.case=TRUE)])
stop('subscript out of bounds: no column name containing "High"')
col <- has.Hi(x, which = TRUE)
if(!identical(col, integer(0))) {
return(x[, col])
} else {
stop('subscript out of bounds: High column not found')
}
}

`has.Hi` <-
function(x,which=FALSE)
{
colAttr <- attr(x, "Hi")
if(!is.null(colAttr))
return(if(which) colAttr else TRUE)

loc <- grep('High',colnames(x),ignore.case=TRUE)
if(!identical(loc,integer(0))) {
return(if(which) loc else TRUE)
} else FALSE
n <- which(colnames(x) %in% c("Hi", "High"))

if(identical(n,integer(0))) {
n <- grep('High$', colnames(x), ignore.case = TRUE)
}

return(if(which) n else !identical(n,integer(0)))
}

`Lo` <-
function(x)
{
if(has.Lo(x))
return(x[,grep('Low',colnames(x),ignore.case=TRUE)])
stop('subscript out of bounds: no column name containing "Low"')
col <- has.Lo(x, which = TRUE)
if(!identical(col, integer(0))) {
return(x[, col])
} else {
stop('subscript out of bounds: Low column not found')
}
}

`has.Lo` <-
function(x,which=FALSE)
{
colAttr <- attr(x, "Lo")
if(!is.null(colAttr))
return(if(which) colAttr else TRUE)

loc <- grep('Low',colnames(x),ignore.case=TRUE)
if(!identical(loc,integer(0))) {
return(if(which) loc else TRUE)
} else FALSE
n <- which(colnames(x) %in% c("Lo", "Low"))

if(identical(n,integer(0))) {
n <- grep('Low$', colnames(x), ignore.case = TRUE)
}

return(if(which) n else !identical(n,integer(0)))
}

`Cl` <-
function(x)
{
if(has.Cl(x))
return(x[,grep('Close',colnames(x),ignore.case=TRUE)])
stop('subscript out of bounds: no column name containing "Close"')
col <- has.Cl(x, which = TRUE)
if(!identical(col, integer(0))) {
return(x[, col])
} else {
stop('subscript out of bounds: Close column not found')
}
}
`has.Cl` <-
function(x,which=FALSE)
{
colAttr <- attr(x, "Cl")
if(!is.null(colAttr))
return(if(which) colAttr else TRUE)

loc <- grep('Close',colnames(x),ignore.case=TRUE)
if(!identical(loc,integer(0))) {
return(if(which) loc else TRUE)
} else FALSE
n <- which(colnames(x) %in% c("Cl", "Close"))

if(identical(n,integer(0))) {
n <- grep('Close$', colnames(x), ignore.case = TRUE)
}

return(if(which) n else !identical(n,integer(0)))
}

`Vo` <-
function(x)
{
#vo <- grep('Volume',colnames(x))
#if(!identical(vo,integer(0)))
if(has.Vo(x))
return(x[,grep('Volume',colnames(x),ignore.case=TRUE)])
stop('subscript out of bounds: no column name containing "Volume"')
col <- has.Vo(x, which = TRUE)
if(!identical(col, integer(0))) {
return(x[, col])
} else {
stop('subscript out of bounds: Volume column not found')
}
}
`has.Vo` <-
function(x,which=FALSE)
{
colAttr <- attr(x, "Vo")
if(!is.null(colAttr))
return(if(which) colAttr else TRUE)

loc <- grep('Volume',colnames(x),ignore.case=TRUE)
if(!identical(loc,integer(0))) {
return(if(which) loc else TRUE)
} else FALSE
n <- which(colnames(x) %in% c("Vo", "Vol", "Volume"))

if(identical(n,integer(0))) {
n <- grep('Volume$', colnames(x), ignore.case = TRUE)
}

return(if(which) n else !identical(n,integer(0)))
}

`Ad` <-
function(x)
{
if(has.Ad(x))
return(x[,grep('Adjusted',colnames(x),ignore.case=TRUE)])
stop('subscript out of bounds: no column name containing "Adjusted"')
col <- has.Ad(x, which = TRUE)
if(!identical(col, integer(0))) {
return(x[, col])
} else {
stop('subscript out of bounds: Adjusted column not found')
}
}
`has.Ad` <-
function(x,which=FALSE)
{
colAttr <- attr(x, "Ad")
if(!is.null(colAttr))
return(if(which) colAttr else TRUE)

loc <- grep('Adjusted',colnames(x),ignore.case=TRUE)
if(!identical(loc,integer(0))) {
return(if(which) loc else TRUE)
} else FALSE
n <- which(colnames(x) %in% c("Ad", "Adj", "Adjusted"))

if(identical(n,integer(0))) {
n <- grep('Adjusted$', colnames(x), ignore.case = TRUE)
}

return(if(which) n else !identical(n,integer(0)))
}

`OpCl` <-
function(x)
{
xx <- Delt(Op(x),Cl(x))
colnames(xx) <- paste("OpCl",deparse(substitute(x)),sep='.')
xx
}

`OpOp` <-
function(x)
{
xx <- Delt(Op(x))
colnames(xx) <- paste("OpOp",deparse(substitute(x)),sep='.')
xx
}

`ClCl` <-
function(x)
{
Expand Down
Binary file added inst/tinytest/stock.rda
Binary file not shown.
121 changes: 121 additions & 0 deletions inst/tinytest/test_OHLCVA.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
## OHLC test-cases, including underlying supporting functions.

# Load stock test data (originating from getSymbols())
stock <- readRDS("stock.rda")
cols <- colnames(stock)

# Test is/has OHLC functions to be true.
expect_true(has.Op(stock))
expect_true(has.Hi(stock))
expect_true(has.Lo(stock))
expect_true(has.Cl(stock))
expect_true(has.Vo(stock))
expect_true(is.HLC(stock))
expect_true(all(has.HLC(stock)))
expect_true(is.OHLC(stock))
expect_true(all(has.OHLC(stock)))
expect_true(is.OHLCV(stock))
expect_true(all(has.OHLCV(stock)))

# Test which for has/OHLC functions.
expect_equal(has.Op(stock, which = TRUE), 1)
expect_equal(has.Hi(stock, which = TRUE), 2)
expect_equal(has.Lo(stock, which = TRUE), 3)
expect_equal(has.Cl(stock, which = TRUE), 4)
expect_equal(has.Vo(stock, which = TRUE), 5)
expect_equal(has.HLC(stock, which = TRUE), c(2,3,4))
expect_equal(has.OHLC(stock, which = TRUE), c(1,2,3,4))
expect_equal(has.OHLCV(stock, which = TRUE), c(1,2,3,4,5))

# Test return correct OHLC column(s).
expect_identical(colnames(Op(stock)), cols[1])
expect_identical(colnames(Hi(stock)), cols[2])
expect_identical(colnames(Lo(stock)), cols[3])
expect_identical(colnames(Cl(stock)), cols[4])
expect_identical(colnames(HLC(stock)), cols[c(2,3,4)])
expect_identical(colnames(OHLC(stock)), cols[c(1,2,3,4)])
expect_identical(colnames(OHLCV(stock)), cols[c(1,2,3,4,5)])

# Test sample matrix regression
data(sample_matrix, package = "xts")
sample <- as.xts(sample_matrix)
expect_equal(has.Op(sample, which = TRUE), 1)
expect_equal(has.Hi(sample, which = TRUE), 2)
expect_equal(has.Lo(sample, which = TRUE), 3)
expect_equal(has.Cl(sample, which = TRUE), 4)
expect_identical(colnames(Op(sample)), "Open")
expect_identical(colnames(Hi(sample)), "High")
expect_identical(colnames(Lo(sample)), "Low")
expect_identical(colnames(Cl(sample)), "Close")

# Test "Open" columns with column "Op".
colnames(stock) <- gsub("MSFT.Open", "Op", cols)
expect_true(has.Op(stock))
expect_equal(has.Op(stock, which = TRUE), 1)
expect_identical(colnames(Op(stock)), "Op")

# Test "High" columns with column "Hi".
colnames(stock) <- gsub("MSFT.High", "Hi", cols)
expect_true(has.Hi(stock))
expect_equal(has.Hi(stock, which = TRUE), 2)
expect_identical(colnames(Hi(stock)), "Hi")

# Test "Low" columns with column "Lo".
colnames(stock) <- gsub("MSFT.Low", "Lo", cols)
expect_true(has.Lo(stock))
expect_equal(has.Lo(stock, which = TRUE), 3)
expect_identical(colnames(Lo(stock)), "Lo")

# Test "Close" columns with column "Cl".
colnames(stock) <- gsub("MSFT.Close", "Cl", cols)
expect_true(has.Cl(stock))
expect_equal(has.Cl(stock, which = TRUE), 4)
expect_identical(colnames(Cl(stock)), "Cl")

# Test "Volume" columns with column "Vo".
colnames(stock) <- gsub("MSFT.Volume", "Vo", cols)
expect_true(has.Vo(stock))
expect_equal(has.Vo(stock, which = TRUE), 5)
expect_identical(colnames(Vo(stock)), "Vo")

# Test "Adjusted" columns with column "Ad".
colnames(stock) <- gsub("MSFT.Adjusted", "Ad", cols)
expect_true(has.Ad(stock))
expect_equal(has.Ad(stock, which = TRUE), 6)
expect_identical(colnames(Ad(stock)), "Ad")

# Test "Open" columns with symbol "OPEN".
colnames(stock) <- gsub("MSFT", "OPEN", cols)
expect_true(has.Op(stock))
expect_equal(has.Op(stock, which = TRUE), 1)
expect_identical(colnames(Op(stock)), colnames(stock)[1])

# Test "High" columns with symbol "HIGH".
colnames(stock) <- gsub("MSFT", "HIGH", cols)
expect_true(has.Hi(stock))
expect_equal(has.Hi(stock, which = TRUE), 2)
expect_identical(colnames(Hi(stock)), colnames(stock)[2])

# Test "Low" columns with symbol "LOW".
colnames(stock) <- gsub("MSFT", "LOW", cols)
expect_true(has.Lo(stock))
expect_equal(has.Lo(stock, which = TRUE), 3)
expect_identical(colnames(Lo(stock)), colnames(stock)[3])

# Test "Close" columns with symbol "CLOSE".
colnames(stock) <- gsub("MSFT", "CLOSE", cols)
expect_true(has.Cl(stock))
expect_equal(has.Cl(stock, which = TRUE), 4)
expect_identical(colnames(Cl(stock)), colnames(stock)[4])

# Test "Volume" columns with symbol "VOLUME".
colnames(stock) <- gsub("MSFT", "VOLUME", cols)
expect_true(has.Vo(stock))
expect_equal(has.Vo(stock, which = TRUE), 5)
expect_identical(colnames(Vo(stock)), colnames(stock)[5])

# Test "Adjusted" columns with symbol "ADJUSTED".
colnames(stock) <- gsub("MSFT", "ADJUSTED", cols)
expect_true(has.Ad(stock))
expect_equal(has.Ad(stock, which = TRUE), 6)
expect_identical(colnames(Ad(stock)), colnames(stock)[6])
5 changes: 5 additions & 0 deletions tests/tinytest.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@

if ( requireNamespace("tinytest", quietly=TRUE) ){
tinytest::test_package("quantmod")
}