Search code examples
rxtsfinance

Aggregating a position value based on entry/exit values xts


Im trying to use entry/exit signals to generate a position/signal data column for analysis. I would like the the entry signals to be cumulative and the exit value to signal for the exit of all current entry positions. In addition I would like to be able to handle being given an exit signal without any current entry positions (of course, this should result in nothing). I cannot seem to reasonably incorporate this last function while preserving the cumulative properties.

I thought I could get there with this solution. I just couldnt get the last part to work for me.

Change value of some column in xts based on other columns values with lookback

Borrowing some arbitrary Enter/Exit data from the referenced question:

> Entry <- c(1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0)
> Exit <- c(0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1)

The desired solution would look like this:

> DesiredOutcome
      Entry Exit Signal
 [1,]     1    0      1
 [2,]     0    0      1
 [3,]     0    0      1
 [4,]     1    0      2
 [5,]     0    0      2
 [6,]     0    0      2
 [7,]     1    0      3
 [8,]     0    0      3
 [9,]     0    1      3
[10,]     0    0      0
[11,]     0    0      0
[12,]     0    1      0
[13,]     1    0      1
[14,]     0    0      1
[15,]     0    0      1
[16,]     1    0      2
[17,]     0    0      2
[18,]     0    0      2
[19,]     0    1      2
[20,]     0    0      0
[21,]     0    1      0
[22,]     1    0      1
[23,]     0    0      1
[24,]     0    1      1

Any help would be greatly appreciated!

UPDATE. As requested, here are some attempts at addressing the issue that were not very productive.

Instead of using Entry/Exit/Signal columns one column with nested ifelse statements were attempted to interrogate an indicator (s$Z203 in this case). Values less than -2 were entry, greater than 2 were exit.

s$position <- ifelse(s$Z203>=2,0, ifelse(s$Z203<=-2,s$position+1,s$position+lag(s$position)))

Using the multi-column approach i thought I could use simple arithmetic (as in the posted example) and avoid having to query previous lines of the xts object as it iterated through the data. Having several course columns to accomplish the procedure got me close, but still doesnt address the 1 exit trigger applying to all aggregated entry signals and ignoring an exit signal without any entry positions.


Solution

  • You're calculating the cumsum of Entry by group, where group is the cumsum of the lagged Exit column. There are lots of ways to "split, apply, combine." One of them is ave:

    > cbind(Entry, Exit, Signal=ave(Entry, cumsum(c(0, head(Exit, -1))), FUN=cumsum))
          Entry Exit Signal
     [1,]     1    0      1
     [2,]     0    0      1
     [3,]     0    0      1
     [4,]     1    0      2
     [5,]     0    0      2
     [6,]     0    0      2
     [7,]     1    0      3
     [8,]     0    0      3
     [9,]     0    1      3
    [10,]     0    0      0
    [11,]     0    0      0
    [12,]     0    1      0
    [13,]     1    0      1
    [14,]     0    0      1
    [15,]     0    0      1
    [16,]     1    0      2
    [17,]     0    0      2
    [18,]     0    0      2
    [19,]     0    1      2
    [20,]     0    0      0
    [21,]     0    1      0
    [22,]     1    0      1
    [23,]     0    0      1
    [24,]     0    1      1
    

    If you started with an xts you can do it like this

    x <- .xts(cbind(Entry, Exit), seq_along(Entry))
    x$Signal <- with(xx, ave(Entry, cumsum(c(0, lag(Exit, na.pad=FALSE))), FUN=cumsum))