-1

I have the following recursive function:

 new.trend <- function(MergedData)
    {
      sig <- c(2,4,6,8,9,11,12,13,14,15,16,17,18,19,20,21,24)
      ret <- as.list(rep(NA,length(sig))) 

      for (i in sig) { #Calculates output variables based on active signals
        x <- MergedData[[i]]
        x <- xts(x[,-1], order.by=x[,1])
        dev20 <- (x[,4]-x[,5])/x[,4]*100
        dev50 <- (x[,4]-x[,6])/x[,4]*100
        ret <- lapply(ret, function(x) merge(merge(tail(dev20, n=1L), tail(dev50, n=1L), tail(RSI, n=1L))))
      }
      na.omit(do.call(merge, ret))
    }
    print(new.trend(MergedData))

Sig is calculated recursively, but for sake of post length I'm just inserting the calculated values for sig.

I'm having trouble because the above code returns only the last set of indices

[[1]]
           INR.LOW.1 INR.LOW.1.1      EMA
2017-02-22 -1585.909   -1584.359 31.86353

But I want it to return:

$JPY
           JPY.LOW.1 JPY.LOW.1.1      EMA
2017-02-22 -1585.909   -1584.359 31.86353

$CHF
           CHF.LOW.1 CHF.LOW.1.1      EMA
2017-02-22 -1585.909   -1584.359 31.86353

And so on. The dput is attached here

 structure(list(EUR = structure(list(EUR.DATE = structure(1409202000, class = c("POSIXct", 
"POSIXt"), tzone = ""), EUR.HIGH = 1.3221, EUR.LOW = 1.316, EUR.OPEN = 1.3193, 
    EUR.CLOSE = 1.3182, EUR.20D = 1.3323, EUR.50D = 1.3465), .Names = c("EUR.DATE", 
"EUR.HIGH", "EUR.LOW", "EUR.OPEN", "EUR.CLOSE", "EUR.20D", "EUR.50D"
), row.names = 651L, class = "data.frame"), JPY = structure(list(
    JPY.DATE = structure(1409202000, class = c("POSIXct", "POSIXt"
    ), tzone = ""), JPY.HIGH = 103.92, JPY.LOW = 103.56, JPY.OPEN = 103.88, 
    JPY.CLOSE = 103.72, JPY.20D = 102.92, JPY.50D = 102.22), .Names = c("JPY.DATE", 
"JPY.HIGH", "JPY.LOW", "JPY.OPEN", "JPY.CLOSE", "JPY.20D", "JPY.50D"
), row.names = 651L, class = "data.frame"), GBP = structure(list(
    GBP.DATE = structure(1409202000, class = c("POSIXct", "POSIXt"
    ), tzone = ""), GBP.HIGH = 1.6614, GBP.LOW = 1.6567, GBP.OPEN = 1.6576, 
    GBP.CLOSE = 1.6586, GBP.20D = 1.6703, GBP.50D = 1.6919), .Names = c("GBP.DATE", 
"GBP.HIGH", "GBP.LOW", "GBP.OPEN", "GBP.CLOSE", "GBP.20D", "GBP.50D"
), row.names = 651L, class = "data.frame"), CHF = structure(list(
    CHF.DATE = structure(1409202000, class = c("POSIXct", "POSIXt"
    ), tzone = ""), CHF.HIGH = 0.9162, CHF.LOW = 0.9126, CHF.HIGH.1 = 0.9148, 
    CHF.OPEN = 0.9151, CHF.CLOSE = 0.9096, CHF50D = 0.9017), .Names = c("CHF.DATE", 
"CHF.HIGH", "CHF.LOW", "CHF.HIGH.1", "CHF.OPEN", "CHF.CLOSE", 
"CHF50D"), row.names = 651L, class = "data.frame"), AUD = structure(list(
    AUD.DATE = structure(1409202000, class = c("POSIXct", "POSIXt"
    ), tzone = ""), AUD.HIGH = 0.9374, AUD.LOW = 0.9332, AUD.OPEN = 0.9337, 
    AUD.CLOSE = 0.9357, AUD.20D = 0.9308, AUD.50D = 0.9359), .Names = c("AUD.DATE", 
"AUD.HIGH", "AUD.LOW", "AUD.OPEN", "AUD.CLOSE", "AUD.20D", "AUD.50D"
), row.names = 651L, class = "data.frame"), CAD = structure(list(
    CAD.DATE = structure(1409202000, class = c("POSIXct", "POSIXt"
    ), tzone = ""), CAD.HIGH = 1.0869, CAD.LOW = 1.0837, CAD.OPEN = 1.0865, 
    CAD.CLOSE = 1.0861, CAD.20D = 1.0925, CAD.50D = 1.0808), .Names = c("CAD.DATE", 
"CAD.HIGH", "CAD.LOW", "CAD.OPEN", "CAD.CLOSE", "CAD.20D", "CAD.50D"
), row.names = 651L, class = "data.frame"), NZD = structure(list(
    NZD.DATE = structure(1409202000, class = c("POSIXct", "POSIXt"
    ), tzone = ""), NZD.HIGH = 0.8408, NZD.LOW = 0.8364, NZD.OPEN = 0.8374, 
    NZD.CLOSE = 0.8383, NZD.20D = 0.8439, NZD.50D = 0.8596), .Names = c("NZD.DATE", 
"NZD.HIGH", "NZD.LOW", "NZD.OPEN", "NZD.CLOSE", "NZD.20D", "NZD.50D"
), row.names = 651L, class = "data.frame"), SEK = structure(list(
    SEK.DATE = structure(1409202000, class = c("POSIXct", "POSIXt"
    ), tzone = ""), SEK.HIGH = 6.9859, SEK.LOW = 6.9279, SEK.CLOSE = 6.9495, 
    SEK.OPEN = 6.9717, SEK.20D = 6.8953, SEK.50D = 6.8358), .Names = c("SEK.DATE", 
"SEK.HIGH", "SEK.LOW", "SEK.CLOSE", "SEK.OPEN", "SEK.20D", "SEK.50D"
), row.names = 651L, class = "data.frame"), NOK = structure(list(
    NOK.DATE = structure(1409202000, class = c("POSIXct", "POSIXt"
    ), tzone = ""), NOK.HIGH = 6.1938, NOK.LOW = 6.166, NOK.OPEN = 6.1804, 
    NOK.CLOSE = 6.1795, NOK.20D = 7.5975, NOK.50D = 6.1876), .Names = c("NOK.DATE", 
"NOK.HIGH", "NOK.LOW", "NOK.OPEN", "NOK.CLOSE", "NOK.20D", "NOK.50D"
), row.names = 651L, class = "data.frame"), CZK = structure(list(
    CZK.DATE = structure(1409202000, class = c("POSIXct", "POSIXt"
    ), tzone = ""), CZK.HIGH = 21.1434, CZK.LOW = 20.9375, CZK.OPEN = 20.9924, 
    CZK.CLOSE = 21.11, CZK.20D = 20.9924, CZK.50D = 21.11), .Names = c("CZK.DATE", 
"CZK.HIGH", "CZK.LOW", "CZK.OPEN", "CZK.CLOSE", "CZK.20D", "CZK.50D"
), row.names = 651L, class = "data.frame"), HUF = structure(list(
    HUF.DATE = structure(1409202000, class = c("POSIXct", "POSIXt"
    ), tzone = ""), HUF.HIGH = 240.3, HUF.LOW = 236.56, HUF.HIGH.1 = 237, 
    HUF.LOW.1 = 239.06, HUF.20D = 235.57, HUF.50D = 231.14), .Names = c("HUF.DATE", 
"HUF.HIGH", "HUF.LOW", "HUF.HIGH.1", "HUF.LOW.1", "HUF.20D", 
"HUF.50D"), row.names = 651L, class = "data.frame"), ILS = structure(list(
    ILS.DATE = structure(1408597200, class = c("POSIXct", "POSIXt"
    ), tzone = ""), ILS.HIGH = 3.5505, ILS.LOW = 3.5185, ILS.HIGH.1 = 3.545, 
    ILS.LOW.1 = 3.526, ILS.20D = 3.4654, ILS.50D = 3.4442), .Names = c("ILS.DATE", 
"ILS.HIGH", "ILS.LOW", "ILS.HIGH.1", "ILS.LOW.1", "ILS.20D", 
"ILS.50D"), row.names = 651L, class = "data.frame"), PLN = structure(list(
    PLN.DATE = structure(1409202000, class = c("POSIXct", "POSIXt"
    ), tzone = ""), PLN.HIGH = 3.2101, PLN.LOW = 3.1767, PLN.HIGH.1 = 3.1831, 
    PLN.LOW.1 = 3.2036, PLN.20D = 3.1475, PLN.50D = 3.0943), .Names = c("PLN.DATE", 
"PLN.HIGH", "PLN.LOW", "PLN.HIGH.1", "PLN.LOW.1", "PLN.20D", 
"PLN.50D"), row.names = 651L, class = "data.frame"), RUB = structure(list(
    RUB.DATE = structure(1406178000, class = c("POSIXct", "POSIXt"
    ), tzone = ""), RUB.HIGH = 35.1463, RUB.LOW = 34.9402, RUB.HIGH.1 = 35.0165, 
    RUB.LOW.1 = 35.0413, RUB.20D = 34.4608, RUB.50D = 34.4596), .Names = c("RUB.DATE", 
"RUB.HIGH", "RUB.LOW", "RUB.HIGH.1", "RUB.LOW.1", "RUB.20D", 
"RUB.50D"), row.names = 651L, class = "data.frame"), TRY = structure(list(
    TRY.DATE = structure(1409202000, class = c("POSIXct", "POSIXt"
    ), tzone = ""), TRY.HIGH = 2.1727, TRY.LOW = 2.1536, TRY.LOW.1 = 2.154, 
    TRY.HIGH.1 = 2.1581, TRY.20D = 2.1599, TRY.50D = 2.1372), .Names = c("TRY.DATE", 
"TRY.HIGH", "TRY.LOW", "TRY.LOW.1", "TRY.HIGH.1", "TRY.20D", 
"TRY.50D"), row.names = 651L, class = "data.frame"), ZAR = structure(list(
    ZAR.DATE = structure(1409202000, class = c("POSIXct", "POSIXt"
    ), tzone = ""), ZAR.HIGH = 10.6868, ZAR.LOW = 10.6034, ZAR.HIGH.1 = 10.6129, 
    ZAR.LOW.1 = 10.6511, ZAR.20D = 10.6612, ZAR.50D = 10.6554), .Names = c("ZAR.DATE", 
"ZAR.HIGH", "ZAR.LOW", "ZAR.HIGH.1", "ZAR.LOW.1", "ZAR.20D", 
"ZAR.50D"), row.names = 651L, class = "data.frame"), BRL = structure(list(
    BRL.DATE = structure(1406523600, class = c("POSIXct", "POSIXt"
    ), tzone = ""), BRL.HIGH = 2.2348, BRL.LOW = 2.2222, BRL.HIGH.1 = 2.2294, 
    BRL.LOW.1 = 2.2225, BRL.20D = 2.2209, BRL.50D = 2.2271), .Names = c("BRL.DATE", 
"BRL.HIGH", "BRL.LOW", "BRL.HIGH.1", "BRL.LOW.1", "BRL.20D", 
"BRL.50D"), row.names = 651L, class = "data.frame"), CLP = structure(list(
    CLP.DATE = structure(1405573200, class = c("POSIXct", "POSIXt"
    ), tzone = ""), CLP.HIGH = 565.75, CLP.LOW = 557.75, CLP.HIGH.1 = 559.51, 
    CLP.LOW.1 = 564.54, CLP.20D = 553.43, CLP.50D = 553.42), .Names = c("CLP.DATE", 
"CLP.HIGH", "CLP.LOW", "CLP.HIGH.1", "CLP.LOW.1", "CLP.20D", 
"CLP.50D"), row.names = 651L, class = "data.frame"), COP = structure(list(
    COP.DATE = structure(1405918800, class = c("POSIXct", "POSIXt"
    ), tzone = ""), COP.HIGH = 1868.5, COP.LOW = 1866.7, COP.OPEN = 1866.7, 
    COP.CLOSE = 1868.5, COP.20D = 1867.79, COP.50D = 1889.27), .Names = c("COP.DATE", 
"COP.HIGH", "COP.LOW", "COP.OPEN", "COP.CLOSE", "COP.20D", "COP.50D"
), row.names = 651L, class = "data.frame"), MXN = structure(list(
    MXN.DATE = structure(1409202000, class = c("POSIXct", "POSIXt"
    ), tzone = ""), MXN.HIGH = 13.1309, MXN.LOW = 13.0689, MXN.HIGH.1 = 13.0844, 
    MXN.LOW.1 = 13.0856, MXN.20D = 13.1462, MXN.50D = 13.0548), .Names = c("MXN.DATE", 
"MXN.HIGH", "MXN.LOW", "MXN.HIGH.1", "MXN.LOW.1", "MXN.20D", 
"MXN.50D"), row.names = 651L, class = "data.frame"), PEN = structure(list(
    PEN.DATE = structure(1406696400, class = c("POSIXct", "POSIXt"
    ), tzone = ""), PEN.HIGH = 2.7935, PEN.LOW = 2.7866, PEN.LOW.1 = 2.7873, 
    PEN.HIGH.1 = 2.7895, PEN.20D = 2.7846, PEN.50D = 2.7885), .Names = c("PEN.DATE", 
"PEN.HIGH", "PEN.LOW", "PEN.LOW.1", "PEN.HIGH.1", "PEN.20D", 
"PEN.50D"), row.names = 651L, class = "data.frame"), CNY = structure(list(
    CNY.DATE = structure(1403758800, class = c("POSIXct", "POSIXt"
    ), tzone = ""), CNY.HIGH = 6.2337, CNY.LOW = 6.2243, CNY.OPEN = 6.229, 
    CNY.CLOSE = 6.2248, CNY.20D = 6.2336, CNY.50D = 6.2355), .Names = c("CNY.DATE", 
"CNY.HIGH", "CNY.LOW", "CNY.OPEN", "CNY.CLOSE", "CNY.20D", "CNY.50D"
), row.names = 651L, class = "data.frame"), IDR = structure(list(
    IDR.DATE = structure(1404709200, class = c("POSIXct", "POSIXt"
    ), tzone = ""), IDR.HIGH = 11870, IDR.LOW = 11683, IDR.HIGH.1 = 11829, 
    IDR.LOW.1 = 11710, IDR.20D = 11906, IDR.50D = 11722), .Names = c("IDR.DATE", 
"IDR.HIGH", "IDR.LOW", "IDR.HIGH.1", "IDR.LOW.1", "IDR.20D", 
"IDR.50D"), row.names = 651L, class = "data.frame"), INR = structure(list(
    INR.DATE = structure(1402462800, class = c("POSIXct", "POSIXt"
    ), tzone = ""), INR.HIGH = 59.36, INR.LOW = 59.325, INR.HIGH.1 = 59.0025, 
    INR.LOW.1 = 59.7634, INR.20D = 1041.23, INR.50D = 1037), .Names = c("INR.DATE", 
"INR.HIGH", "INR.LOW", "INR.HIGH.1", "INR.LOW.1", "INR.20D", 
"INR.50D"), row.names = 651L, class = "data.frame"), KRW = structure(list(
    KRW.DATE = structure(1407474000, class = c("POSIXct", "POSIXt"
    ), tzone = ""), KRW.HIGH = 1028.73, KRW.LOW = 1021.58, KRW.HIGH.1 = 3.1748, 
    KRW.LOW.1 = 3.1745, KRW.20D = 3.1805, KRW.50D = 3.2027), .Names = c("KRW.DATE", 
"KRW.HIGH", "KRW.LOW", "KRW.HIGH.1", "KRW.LOW.1", "KRW.20D", 
"KRW.50D"), row.names = 651L, class = "data.frame")), .Names = c("EUR", 
"JPY", "GBP", "CHF", "AUD", "CAD", "NZD", "SEK", "NOK", "CZK", 
"HUF", "ILS", "PLN", "RUB", "TRY", "ZAR", "BRL", "CLP", "COP", 
"MXN", "PEN", "CNY", "IDR", "INR", "KRW"))
Nikitau
  • 371
  • 3
  • 16
  • These seems to be way more code here than necessary to clearly demonstrate your specific question. Why not simplify some things. Create a **minimal** [reproducible example](http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) – MrFlick Mar 03 '17 at 19:28
  • @MrFlick Thanks. I removed the unnecessary calculations behind sig. – Nikitau Mar 03 '17 at 19:40
  • Much better, but it's still not reproducible because it's unclear where the RSI function comes from. But I think you just need to change the `ret <- lapply(ret, merge(...))` to `ret[[i]] <- merge(...)`. Even better would be to replace the `for()` loop with an `lapply()`. – MrFlick Mar 03 '17 at 19:45
  • @MrFlick Oops thanks for that! I've removed it because it's not really that important. And thanks for the suggestion! I've tried replacing it with `ret[[i]] <- merge(..)`, but since sig doesn't match up with indices in ret, I get blocks of `NULL` dataframes in the list. – Nikitau Mar 03 '17 at 19:49
  • @MrFlick I also took your advice and tried creating a `lapply()` function with `trend_calc <- function(MergedData) { dev20 <- tail((x[,4]-x[,5])/x[,4]*100, 1L) dev50 <- tail((x[,4]-x[,6])/x[,4]*100, 1L) return(cbind(dev20, dev50, RSI)) }` and `signal_trend <- lapply(MergedData[sig], trend_calc)` but this seemed to return the last set of values as well. – Nikitau Mar 03 '17 at 20:43
  • Your recent attempt doesn't define `x` or `RSI` inside `trend_calc`. I think you want `trend_calc <- function(x) {...}`. But please make sure that your sample work by running them in a fresh R session each time so you are sure they are reproducible. – MrFlick Mar 03 '17 at 21:02

1 Answers1

0

First of all: your example does not work as you have not provided RSI. So, I will just assume RSI <- dev50

Your problem is in this line:

ret <- lapply(ret, function(x) merge(merge(tail(dev20, n=1L), tail(dev50, n=1L), tail(RSI, n=1L))))

This is inside a for loop. Thus you are overwriting it every pass of the loop. Also you have double merge here, which is useless.

What you want to do is have one lapply instead of a loop and lapply:

new.trend <- function(MergedData) {
  sig <- c(2, 4, 6, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 24)

  ret <- lapply(sig, function(i) {
    x <- MergedData[[i]]
    x <- xts(x[, -1], order.by = x[, 1])
    dev20 <- (x[, 4] - x[, 5]) / x[, 4] * 100
    dev50 <- (x[, 4] - x[, 6]) / x[, 4] * 100
    RSI <- dev50
    merge(last(dev20), last(dev50), last(RSI))

  })
  ret
}

This will return you what you want:

new.trend(MergedData)

[[1]]
                    JPY.CLOSE JPY.CLOSE.1 JPY.CLOSE.2
2014-08-28 07:00:00 0.7713074    1.446201    1.446201

[[2]]
                     CHF.OPEN CHF.OPEN.1 CHF.OPEN.2
2014-08-28 07:00:00 0.6010272   1.464321   1.464321

[[3]]
                     CAD.CLOSE CAD.CLOSE.1 CAD.CLOSE.2
2014-08-28 07:00:00 -0.5892643   0.4879845   0.4879845

I also replaced tail(x, n = 1L) with last(x) as it gives the same effect in this case and easier to read. Removed pre-allocation of ret, as lapply already takes care of it.

Also, depending on you application this might be a better code: Make new.trend a simple function without nested lapply. And lapply sig over it. Thus your sig will not be hard-coded inside this function.

new.trend <- function(MergedData, sig) {
  x <- MergedData[[sig]]
  x <- xts(x[, -1], order.by = x[, 1])
  dev20 <- (x[, 4] - x[, 5]) / x[, 4] * 100
  dev50 <- (x[, 4] - x[, 6]) / x[, 4] * 100
  RSI <- dev50
  merge(last(dev20), last(dev50), last(RSI))
}

sig <- c(2, 4, 6, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 24)
lapply(sig, new.trend, MergedData = MergedData)
Jav
  • 2,203
  • 13
  • 22