Question

I am trying to do a very simple thing: transform OHLC currency data in such a way that I replace Hi with biggest value of high until that moment of time in a given day and replace Lo with smallest value of low until that moment of time in a given day.

require(quantmod)
require(FinancialInstrument)

Symbols <- "EURUSD"

base_dir <- "/home/samop/data/sources/truefx/" 
sec_dir <- paste0(base_dir, "sec/")

EURUSD.sec <- getSymbols(Symbols, src='FI', dir=sec_dir, extension='RData', split_method='days', from='2009-10-07', to='2011-09-15', days_to_omit="Saturday", auto.assign=FALSE)
EURUSD.min <- to.minutes(EURUSD.sec)

EURUSD.min.Lo.cumulative <- apply.daily(Lo(EURUSD.min), cummin)
EURUSD.min.Hi.cumulative <- apply.daily(Hi(EURUSD.min), cummax)

EURUSD.min.OHLC.cumulative <- cbind(Cl(EURUSD.min), EURUSD.min.Hi.cumulative, EURUSD.min.Lo.cumulative, Cl(EURUSD.min))

Which fails:

> EURUSD.min.Lo.cumulative <- apply.daily(Lo(EURUSD.min), cummin)
> EURUSD.min.Hi.cumulative <- apply.daily(Hi(EURUSD.min), cummax)
> EURUSD.mi.cumulative <- cbind(Op(EURUSD.min), EURUSD.min.Hi.cumulative, EURUSD.min.Lo.cumulative, Cl(EURUSD.min))
Error in merge.xts(..., all = all, fill = fill, suffixes = suffixes) : 
  (list) object cannot be coerced to type 'double'

Interesting enough:

> head(cummin(Lo(EURUSD.min["2011-09-15"])))
                    EURUSD.sec.Low
2011-09-15 00:00:59        1.37446
2011-09-15 00:01:59        1.37446
2011-09-15 00:02:58        1.37446
2011-09-15 00:03:59        1.37446
2011-09-15 00:04:57        1.37446
2011-09-15 00:05:59        1.37446
Warning message:
timezone of object (GMT) is different than current timezone (UTC). 
> apply.daily(Lo(EURUSD.min["2011-09-15"]), cummin)
Error in array(r, dim = d, dimnames = if (!(is.null(n1 <- names(x[[1L]])) &  : 
  length of 'dimnames' [1] not equal to array extent

So, cummin works but applied wrapped in xts::apply.daily fails...

Is there something smarter I can do here?

Note: I have downloaded data from TrueFX using this script: https://r-forge.r-project.org/scm/viewvc.php/pkg/FinancialInstrument/inst/parser/download.TrueFX.R?view=markup&revision=1349&root=blotter

Was it helpful?

Solution

apply.daily is an aggregation function, so it expects the function passed to it to return one observation per column. cummin returns a vector, which is why it doesn't work with apply.daily.

I think ave does what you want:

EURUSD.cumulative.Lo <- ave(Lo(EURUSD.min), .indexday(EURUSD.min), FUN=cummin)
EURUSD.cumulative.Hi <- ave(Hi(EURUSD.min), .indexday(EURUSD.min), FUN=cummax)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top