Reputation: 425
I want to count how many positive and negative returns for each month in 10 years time and include them in the dtf
. This is because I want to calculate the probability of getting positive and negative returns. I'm not sure how to include the counting process in my for loop.
For example: The average monthly returns for July in 10 years is 2.18%, and the number of positive returns are 8 out of 10 which is 80% and so the probability of obtaining negative returns will be 20%. Since the 10 years average monthly return for July is in positive, 2.18%, I would like the probability of positive return (80%) to be shown in dtf
instead of negative one (20%).
Another example: Same thing goes to May. Since the average monthly return in 10 years time for May is negative (-1.23%), and the probability of getting positive returns in 10 years is 60% (6 out of 10) while for the negative one is 40% (4 out of 10), I would like the negative probability (40%) to be shown in dtf
instead of the positive 60%.
Same thing goes to each and every month, and therefore, there will be a 3rd column in dtf
showing the probability of getting positive/negative returns.
I tried to include if loop
in my for loop
but it doesn't work. I attached my code below with the dtf
with only 2 column (Month and AverageMonthlyRet).
library(quantmod)
#obtian the historical stock price
prices <- getSymbols("^GSPC", src = 'yahoo', from = "2009-07-01", to = "2019-08-01",
periodicity = "monthly", auto.assign = FALSE, warnings = FALSE)[,4]
#calculate the log return and convert back to simple return
return <- diff(log(prices))
r <- na.omit(exp(return)-1)
monthlyRet <- as.numeric(r[,1])
#loop through all the months in 10 years
AverageMonthlyRet <- c()
for (j in 1:12){
Group <- c()
for (i in seq(j,length(monthlyRet),12)){
Group[i] <- monthlyRet[i]
}
AverageMonthlyRet[j] <- mean(Group, na.rm=TRUE)
}
AverageMonthlyRet <- round(AverageMonthlyRet,4)
#create a data frame to store the result
Month <- c("Aug","Sep","Oct","Nov","Dec","Jan","Feb","Mar","Apr","May","Jun","Jul")
dtf <- data.frame(Month, AverageMonthlyRet)
Upvotes: 2
Views: 531
Reputation: 388982
Using base R, we can count the proportion of sign
for each month, merge
by "Month"
with dtf
and select the appropriate value based on sign
of AverageMonthlyRet
.
tmp <- as.data.frame(do.call(rbind, tapply(sign(r), format(index(r), "%b"),
function(x) c(table(x)))))
tmp$Month <- rownames(tmp)
df1 <- merge(dtf, tmp)
df1$selected <- ifelse(sign(df1$AverageMonthlyRet) == 1, df1$`1`, df1$`-1`)
df1
# Month AverageMonthlyRet -1 1 selected
#1 Apr 0.0122 1 9 9
#2 Aug -0.0078 5 5 5
#3 Dec 0.0061 3 7 7
#4 Feb 0.0234 2 8 8
#5 Jan 0.0115 4 6 6
#6 Jul 0.0218 2 8 8
#7 Jun 0.0030 4 6 6
#8 Mar 0.0171 4 6 6
#9 May -0.0123 4 6 4
#10 Nov 0.0162 2 8 8
#11 Oct 0.0189 4 6 6
#12 Sep 0.0086 4 6 6
Upvotes: 1
Reputation: 1116
Here is a proposed solution, based on my understanding of your question. Comments are given in the code.
The main idea is to add some counter variables that you increment in the loop depending on the results of some if/else
tests. They store the probability of negative or positive income. Then with an additional test you determine of you want to keep the positive or negative income probability.
There are ways to write it more concisely, but this longer version show all the details and ideas. If you know that the income is never null, you can just compute one counter because you know that one probability, e.g. positive, will always be 100 - other probability. In my version, null income is possible and thus you might have positive probability + negative probability being smaller than 100.
library(quantmod)
#obtian the historical stock price
prices <- getSymbols("^GSPC", src = 'yahoo', from = "2009-07-01", to = "2019-08-01",
periodicity = "monthly", auto.assign = FALSE, warnings = FALSE)[,4]
#calculate the log return and convert back to simple return
return <- diff(log(prices))
r <- na.omit(exp(return)-1)
monthlyRet <- as.numeric(r[,1])
#loop through all the months in 10 years
AverageMonthlyRet <- c()
#Added: Array to store the probability for each month
Probability <- c()
for (j in 1:12){
Group <- c()
#Added: Counter, for each month, of positive or negative income
connt_pos=0
count_neg=0
for (i in seq(j,length(monthlyRet),12)){
Group[i] <- monthlyRet[i]
#Added: Increment the counters based on the sign of monthlyRet[i]
if(monthlyRet[i]>0){
connt_pos <- connt_pos+1
}
else if(monthlyRet[i]<0){
count_neg <- count_neg+1
}
}
AverageMonthlyRet[j] <- mean(Group, na.rm=TRUE)
#Added: Depending if the average monthly retrn is positive or negative
#compute the probability of positive or negative income (in %)
prob=0
if(AverageMonthlyRet[j]>0)
{
prob=connt_pos/(length(monthlyRet)/12)*100
}
else if (AverageMonthlyRet[j]<0){
prob=count_neg/(length(monthlyRet)/12)*100
}
#Added: Store the result
Probability[j] <- prob
}
AverageMonthlyRet <- round(AverageMonthlyRet,4)
#create a data frame to store the result
Month <- c("Aug","Sep","Oct","Nov","Dec","Jan","Feb","Mar","Apr","May","Jun","Jul")
#Added: Add the new probability column to the final data frame
dtf <- data.frame(Month, AverageMonthlyRet,Probability)
Upvotes: 1