user3612816
user3612816

Reputation: 325

Get trading strategy vector of long positions based on crossing a threshold

This is somewhat of a simple manner, yet I couldn't really find a quick (1,2,3)-liner to solve it. I have a vector of rolling mean of 10 day returns - the strategy is simple: go long when the rolling mean crosses the zero barrier from below and sell when it crosses the barrier from above. To be more precise, let us say the rolling mean returns are stored in vector Returns.

which(Returns > 0)
[1]    3    4    5    9   10   11   14   18   27   28   29   36   37   38   47   48

Based on this I would be long at times 4,5,6 (at 3 we only get the entrance signal and at 6 we exit), 10,11,12,15,19 and so on. How can I get this vector? I have experimented with diff, another which and several other combinations but nothing really solves the problem. Any help will be greatly appreciated.

Edit (based on the first answer):

Initiate_Long_Position  <- which(ifelse(goLong  == TRUE, 1,0) == 1) 
Terminate_Long_Position <- which(ifelse(goShort  == TRUE, 1,0) == 1) 

if (length(Terminate_Long_Position) > length(Initiate_Long_Position) ){
  Terminate_Long_Position <- Terminate_Long_Position[-1]
}

Days_Long_Returns <- rep(0, dim(ticker)[1])
Daily_returns <- returns(Cl(ticker))
for (i in 1:length(Initiate_Long_Position)){
  Days_Long_Returns[(Initiate_Long_Position[i]+1):(Terminate_Long_Position[i])] <-
  Daily_returns[(Initiate_Long_Position[i]+1):(Terminate_Long_Position[i])]
}

I have added +1 to Initiate_Long_Position[i] in the foor loop as we only get the next period return after the signal to go long is observed, whereas selling is done in "real time". Am I missing something, i.e are returns properly indexed so that we are not looking into the future of using the returns i-1 at time i?

Upvotes: 0

Views: 105

Answers (3)

Georgery
Georgery

Reputation: 8117

You need the zoo-package and the dplyr-package

library(zoo) # to compute rolling means
library(dplyr) # to compute lagged vectors

a <- c(-5:5, 5:-5) # create a sample vector

# rolling mean over the last 3 observations
myRollmeans <- rollmean(a, 3, fill = NA, align = "right")
goLong <- lag(myRollmeans) < 0 & myRollmeans >= 0
goShort <- lag(myRollmeans) > 0 & myRollmeans <= 0

data.frame(myRollmeans, goLong, goShort)

Results in

       myRollmeans goLong goShort
1           NA     NA      NA
2           NA     NA      NA
3    -4.000000  FALSE      NA
4    -3.000000  FALSE   FALSE
5    -2.000000  FALSE   FALSE
6    -1.000000  FALSE   FALSE
7     0.000000   TRUE   FALSE
8     1.000000  FALSE   FALSE
9     2.000000  FALSE   FALSE
10    3.000000  FALSE   FALSE
11    4.000000  FALSE   FALSE
12    4.666667  FALSE   FALSE
13    4.666667  FALSE   FALSE
14    4.000000  FALSE   FALSE
15    3.000000  FALSE   FALSE
16    2.000000  FALSE   FALSE
17    1.000000  FALSE   FALSE
18    0.000000  FALSE    TRUE
19   -1.000000  FALSE   FALSE
20   -2.000000  FALSE   FALSE
21   -3.000000  FALSE   FALSE
22   -4.000000  FALSE   FALSE

Upvotes: 1

Antonios
Antonios

Reputation: 1939

I tried to make an example of returns as I am not familiar with trading

Returns<-c(-1,-2,-1,1,2,4,1,-2,-3,-2,-1,1,2,4,5,3,2,-1)
LagReturns<-lag(Returns,1)
position=rep("0",length(Returns))
mask1=Returns*LagReturns<0&Returns<0
mask2=Returns*LagReturns<0&Returns>0
position[mask1]="sell"
position[mask2]="long"

in my understanding when zero is not crossed you take no position ("0") when Returns from negative become positive you take position long ("long") and when from positive negative you take position sell ("sell")

Upvotes: 0

chinsoon12
chinsoon12

Reputation: 25225

You can use rle on the sign of Returns to get a sequence of above 0 or below 0 returns. After that, it is a case of identifying when to go long or short. If there is a need to remove the entry signal, you can use diff on TIME and remove those more than 2.

set.seed(23L)
(Returns <- rnorm(50))

#generate sequence of positive and or negative returns
runs <- rle(sign(Returns))

#identify the time to go long or short
trades <- data.frame(
    TIME=seq_along(Returns),
    RETURN=Returns,
    DIRN=rep(runs$values, runs$lengths),
    RUNS=rep(runs$lengths, runs$lengths))
longs <- trades[trades$DIRN==1 & trades$RUNS >= 2,]
shorts <- trades[trades$DIRN==-1 & trades$RUNS >= 2,]

reference: Find consecutive sequence of zeros in R

Upvotes: 0

Related Questions