Friends. I cannot simplify this much, and I think the loop is unavoidable. As a recovering C programmer I want to avoid loops and in cases like this I almost allways can by using an apply function. But I suspect in this case there is nothing I can do. It is a finance example where a price series is compared to a moving average. If the price goes above the average, plus a bit, buy the security. If we are holding the security and the price dips below the moving average sell it. P is the series of prices m is the moving average series S <- P>(m*1.005) S[S]<-1 Now S is my signal it is 1 when P > m plus a margin of 0.005 x m But now I need to control when S goes from 1 to 0. As far as I can tell this is the only way... for(i in 2:length(S)){ if(S[i]==0 && S[i-1] == 1){ ## Was long, now short. SHould I be short? Is P>m still? if(P[i] > m[i]){ ## Stay long S[i] <- 1 } } } As I mentioned I am a recovering C programmer, so I have a buit in loop reflex, but I am struggling to adapt. But this one has me beat! Can anyone help? cheers W [[alternative HTML version deleted]]
#Use the indexes of S in a sapply function. N <- 10 S <- sample(c(0,1), size=N, replace=TRUE) v1 <- sapply(c(1:N-1), function(i) S[i]&&S[i+1]) # Then v2 <- (P > m) # And I guess you can fill up the rest. Beware of the boundary condition (the NA in v1) Cheers, jcb! _______________________ http://twitter.com/jcborras On Fri, Apr 8, 2011 at 5:30 AM, Worik R <worikr at gmail.com> wrote:> Friends. > > I cannot simplify this much, and I think the loop is unavoidable. ?As a > recovering C programmer I want to avoid loops and in cases like this I > almost allways can by using an apply function. ?But I suspect in this case > there is nothing I can do. > > It is a finance example where a price series is compared to a moving > average. ?If the price goes above the average, plus a bit, buy the > security. ?If we are holding the security and the price dips below the > moving average sell it. > > P is the series of prices > > m is the moving average series > > S <- P>(m*1.005) > S[S]<-1 > > Now S is my signal it is 1 when P > m plus a margin of 0.005 x m > > But now I need to control when S goes from 1 to 0. ?As far as I can tell > this is the only way... > > for(i in 2:length(S)){ > ?if(S[i]==0 && S[i-1] == 1){ > ? ?## Was long, now short. ?SHould I be short? ?Is P>m still? > ? ?if(P[i] > m[i]){ > ? ? ?## Stay long > ? ? ?S[i] <- 1 > ? ?} > ?} > } > > As I mentioned I am a recovering C programmer, so I have a buit in loop > reflex, but I am struggling to adapt. ?But this one has me beat! ?Can anyone > help? > > cheers > W > > ? ? ? ?[[alternative HTML version deleted]] > > ______________________________________________ > R-help at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. >
2011/4/8 Juan Carlos Borr?s <jcborras at gmail.com>:> #Use the indexes of S in a sapply function. > > N <- 10 > S <- sample(c(0,1), size=N, replace=TRUE) > v1 <- sapply(c(1:N-1), function(i) S[i]&&S[i+1])You can achieve the same v1 using v1.2 <- S[2:N-1] & S[2:N] .. or if you insist on having NA as the first element, -- c(NA, v1.2) Vectorization is more efficient than loops but this need not be true for the *apply functions.> > # Then > v2 <- (P > m) > > # And I guess you can fill up the rest. Beware of the boundary > condition (the NA in v1) > > Cheers, > jcb! > _______________________ > http://twitter.com/jcborras > > On Fri, Apr 8, 2011 at 5:30 AM, Worik R <worikr at gmail.com> wrote: >> Friends. >> >> I cannot simplify this much, and I think the loop is unavoidable. ?As a >> recovering C programmer I want to avoid loops and in cases like this I >> almost allways can by using an apply function. ?But I suspect in this case >> there is nothing I can do. >> >> It is a finance example where a price series is compared to a moving >> average. ?If the price goes above the average, plus a bit, buy the >> security. ?If we are holding the security and the price dips below the >> moving average sell it. >> >> P is the series of prices >> >> m is the moving average series >> >> S <- P>(m*1.005) >> S[S]<-1 >> >> Now S is my signal it is 1 when P > m plus a margin of 0.005 x m >> >> But now I need to control when S goes from 1 to 0. ?As far as I can tell >> this is the only way... >> >> for(i in 2:length(S)){ >> ?if(S[i]==0 && S[i-1] == 1){ >> ? ?## Was long, now short. ?SHould I be short? ?Is P>m still? >> ? ?if(P[i] > m[i]){ >> ? ? ?## Stay long >> ? ? ?S[i] <- 1 >> ? ?} >> ?} >> } >> >> As I mentioned I am a recovering C programmer, so I have a buit in loop >> reflex, but I am struggling to adapt. ?But this one has me beat! ?Can anyone >> help? >> >> cheers >> W >> >> ? ? ? ?[[alternative HTML version deleted]] >> >> ______________________________________________ >> R-help at r-project.org mailing list >> https://stat.ethz.ch/mailman/listinfo/r-help >> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html >> and provide commented, minimal, self-contained, reproducible code. >> > > ______________________________________________ > R-help at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. >
Kenn, I find your solution more elegant. 2011/4/8 Kenn Konstabel <lebatsnok at gmail.com>:> 2011/4/8 Juan Carlos Borr?s <jcborras at gmail.com>: >> #Use the indexes of S in a sapply function. >> >> N <- 10 >> S <- sample(c(0,1), size=N, replace=TRUE) >> v1 <- sapply(c(1:N-1), function(i) S[i]&&S[i+1]) > > You can achieve the same v1 using > > v1.2 <- ?S[2:N-1] & S[2:N] > > .. or if you insist on having NA as the first element, -- c(NA, v1.2) > > Vectorization is more efficient than loops but this need not be true > for the *apply functions. > >> >> # Then >> v2 <- (P > m) >>
Hi, this response uses the previous responses with an example: #Assume you have 100 observations n=100 #Simulate a time series of prices error=rnorm(n,0,3) raw.price=rpois(n,100) lag.price=c(rpois(1,100),raw.price[1:99]) price=lag.price+error #Say you want the moving average based on this #and the four preceding prices #define the moving average lag MA.lag=4 #Create an index vector from MA.lag+1 #(the first time for which you can compute the MA) #until the end index=matrix((MA.lag+1):n) #Define a function that computes the moving average #by taking the mean over the observations #from (x-MA.lag) to x MA=function(x){mean(price[(x-MA.lag):x])} #apply this function over all rows of the 'index' matrix #which yields the moving averages mov.av=apply(index,1,MA) #Now apply the previous solutions #First, create a T/F vector whether the price is greater #than the moving average S=price[(MA.lag+1):n]>mov.av #Now create an indicator whether the relation between #price and moving average changes v1 <- sapply(2:(n-MA.lag),function(i)S[i]!=S[i-1]) #Output a data frame; when True, column 'signal' #indicates that the system recommends a transaction data=data.frame(price[(MA.lag+2):n],mov.av[-1],S[-1],v1) names(data)=c('price','moving.average','price.greater.ma','signal') data HTH, Daniel -- View this message in context: http://r.789695.n4.nabble.com/Avoiding-a-loop-tp3435070p3435559.html Sent from the R help mailing list archive at Nabble.com.
Use 'diff' to determine where the changes are:> S <- sample(0:1,30,TRUE) > S[1] 0 0 1 1 0 1 1 1 1 0 0 0 1 0 1 0 1 1 0 1 1 0 1 0 0 0 0 0 1 0> which(diff(S) == -1)[1] 4 9 13 15 18 21 23 29>then use the indices for the other processing. On Thu, Apr 7, 2011 at 10:30 PM, Worik R <worikr at gmail.com> wrote:> Friends. > > I cannot simplify this much, and I think the loop is unavoidable. ?As a > recovering C programmer I want to avoid loops and in cases like this I > almost allways can by using an apply function. ?But I suspect in this case > there is nothing I can do. > > It is a finance example where a price series is compared to a moving > average. ?If the price goes above the average, plus a bit, buy the > security. ?If we are holding the security and the price dips below the > moving average sell it. > > P is the series of prices > > m is the moving average series > > S <- P>(m*1.005) > S[S]<-1 > > Now S is my signal it is 1 when P > m plus a margin of 0.005 x m > > But now I need to control when S goes from 1 to 0. ?As far as I can tell > this is the only way... > > for(i in 2:length(S)){ > ?if(S[i]==0 && S[i-1] == 1){ > ? ?## Was long, now short. ?SHould I be short? ?Is P>m still? > ? ?if(P[i] > m[i]){ > ? ? ?## Stay long > ? ? ?S[i] <- 1 > ? ?} > ?} > } > > As I mentioned I am a recovering C programmer, so I have a buit in loop > reflex, but I am struggling to adapt. ?But this one has me beat! ?Can anyone > help? > > cheers > W > > ? ? ? ?[[alternative HTML version deleted]] > > ______________________________________________ > R-help at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. >-- Jim Holtman Data Munger Guru What is the problem that you are trying to solve?