Reputation: 325
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
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
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
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