Тестирование доходности акций для правила скользящего среднего в r

Я пытаюсь протестировать доходность акций с учетом правила скользящей средней за 10 месяцев. Правило таково: если цена выше 10-месячной средней - покупайте, если ниже 10-месячной средней - сохраняйте значение постоянным.

Я знаю, как это сделать в Excel очень легко, но у меня проблемы с R.

Ниже мой подход в R:

#Downloand financial data
library(Quandl)

SPY <- Quandl("YAHOO/INDEX_GSPC", type = "xts", collapse = "monthly")
head(SPY)

#Calculate log returns
SPY$log_ret <- diff(log(SPY$Close))

#Calculate moving average for Closing price
SPY$MA.10 <- rollapply(SPY$Close, width = 10, FUN = mean)

#Create binary rule to determine when to buy and when to hold
#1 = Buy
SPY$Action <- ifelse(SPY$MA.10 < SPY$Close, 1, 0)

#Create default value in a new column to backtest returns
SPY$Hit <- 100

#Calculate cumulative returns
SPY$Hit <-ifelse(SPY$Action == 1, SPY[2:n, "Hit"] * 
                (1 + SPY$log_ret), lag.xts(SPY$Hit, k=1))

Возврат вычисляется правильно для действия, равного 1, но когда действие не равно 1, я обнаружил, что SPY$Hit отстает только на 1 раз, затем по умолчанию используется значение 100, в то время как я хотел бы, чтобы оно удерживало значение из последнего действия. == 1 раз.

Эта формула очень хорошо работает в MS Excel и ее очень легко реализовать, но кажется, что проблема в R заключается в том, что я не могу сохранить постоянное значение из последнего действия == 1, как я могу это сделать, чтобы я мог видеть, как хорошо эта простая торговая стратегия будет работать?

Пожалуйста, дайте мне знать, если я могу уточнить это, спасибо.

Sample of the desired output:
      Action Return    Answer
 [1,]      0   0.00 100.00000
 [2,]      1   0.09 109.00000
 [3,]      1   0.08 117.72000
 [4,]      1  -0.05 111.83400
 [5,]      1  -0.03 108.47898
 [6,]      0  -0.02 108.47898
 [7,]      0   0.01 108.47898
 [8,]      0   0.06 108.47898
 [9,]      1  -0.03 105.22461
[10,]      0   0.10 105.22461
[11,]      1  -0.05  99.96338

person santorch    schedule 01.04.2017    source источник
comment
Можете ли вы объяснить, что такое SPY[2:n, Hit]?   -  person Evan Friedland    schedule 02.04.2017
comment
Это сдвиг значений таким образом, что они начинаются со 2-го значения столбца SPY$Hit. Например, поскольку данные начинаются с октября 1950 года, второй точкой данных будет ноябрь 1950 года, на что указывает SPY[2:n, Hit].   -  person santorch    schedule 03.04.2017


Ответы (2)


Вот мое предположение, дайте мне знать, что вы думаете.

# Looping
Hit <- matrix(100, nrow = nrow(SPY))
for(row in 11:nrow(SPY)){ # 11 since you have NA's from your moving average
  if(SPY$Action[row] == 1){ 
    Hit[row] = Hit[row-1] * (1 + SPY$log_ret[row]) # here we needed row-1
  } else {
    Hit[row] = Hit[row-1]
  }
}
SPY$Hit <- Hit

cbind(SPY$Action, SPY$Hit)

Для вашего образца:

x <- data.frame(Action = c(0,1,1,1,1,0,0,0,1,0,1))
x$Return <- c(0,0.09,0.08,-0.05,-0.03,-0.02,0.01,0.06,-0.03,0.10,-0.05)

x$Answer <- matrix(100, nrow = nrow(x))
for(row in 2:nrow(x)){ # 11 since you have NA's from your moving average
  if(x$Action[row] == 1){ 
    x$Answer[row] = x$Answer[row-1] * (1 + x$Return[row])
  } else {
    x$Answer[row] = x$Answer[row-1]
  }
}
x
       Action Return    Answer
1       0   0.00 100.00000
2       1   0.09 109.00000
3       1   0.08 117.72000
4       1  -0.05 111.83400
5       1  -0.03 108.47898
6       0  -0.02 108.47898
7       0   0.01 108.47898
8       0   0.06 108.47898
9       1  -0.03 105.22461
10      0   0.10 105.22461
11      1  -0.05  99.96338
person Evan Friedland    schedule 02.04.2017
comment
Это близко, но не работает. Кажется, когда я запускаю этот код, он просто умножает строку * (1 + SPY$log_ret) и сбрасывает расчет для создания исходной матрицы 100. Та же проблема, что и раньше. Я ищу значение индекса 100, чтобы зафиксировать совокупную доходность, когда действие == 1. Имеет ли это смысл? - person santorch; 03.04.2017
comment
Не могли бы вы опубликовать действительно небольшой пример, может быть, 5 или 6 строк, где я могу увидеть желаемый результат? - person Evan Friedland; 03.04.2017
comment
Я разместил желаемые результаты в качестве редактирования исходного вопроса, дайте мне знать, если это сработает. - person santorch; 03.04.2017
comment
Пожалуйста, смотрите правки. Я пытался отредактировать исходный код, но не смог запуститься из-за превышения вызовов API... Дайте мне знать, что вы думаете. - person Evan Friedland; 03.04.2017

В Excel есть 2 способа добиться этого: 1. Перейдите к команде «Данные», найдите «Анализ данных», найдите «Скользящее среднее». В диалоговом окне вам нужно указать диапазон входных данных, интервал (в вашем случае 10), затем выходные адреса ячеек. . После нахождения результата напишите эту формулу,

=if(A2 >B2, "Купить", "Держать") Где A2 удерживает цену, B2 удерживает значение скользящей средней за 10 месяцев.

  1. В любом месте в ячейках номера листа по горизонтали от 1 до 10 (номер месяца). В нижней строке введите значение месяца от 1 до 10. В нижней строке вычислите среднее значение за 10 месяцев.

И, наконец, напишите написанную выше формулу, чтобы найти Купить или удержать.

person Community    schedule 02.04.2017