Блог им. uralpro

Проверка стратегии GMR с применением языка R

7hPrY5P

В прошлой статье мы рассмотрели простую портфельную стратегию ротации глобальных рынков. Результаты, которые привел автор статьи, были впечатляющими, однако он не опубликовал алгоритм своих расчетов, а только его общее описание. Ilya Kipnis в своем блоге решил проверить указанную стратегию и воспроизвел алгоритм на языке программирования R.

Для проверки был взят несколько иной набор биржевых фондов, чем у автора оригинальной статьи, но поведение этих активов идентично исходным. Итак, используется 5 ETF: MDY, ILF, FEZ, EEM, и EPP, совместно с облигационным фондом TLT в качестве защитного актива. Каждый месяц происходит инвестирование в фонд, показавший больший ценовой импульс на исторических данных. Автору не удалось получить такой же доходности, которая была обещана в оригинале, но и воспроизведен алгоритм был не со 100% точностью — вместо изменяемого исторического периода, по которому принимается решение о выборе, он использовал фиксированный трехмесячный период, так как не до конца понял принцип его формирования.

Ниже приведен код на языке R для бэктеста:

require(quantmod)
require(PerformanceAnalytics)
 
symbols <- c("MDY", "TLT", "EEM", "ILF", "EPP", "FEZ")
getSymbols(symbols, from="1990-01-01")
prices <- list()
for(i in 1:length(symbols)) {
  prices[[i]] < - Ad(get(symbols[i]))
}
prices <- do.call(cbind, prices)
colnames(prices) <- gsub("\\.[A-z]*", "", colnames(prices))
returns <- Return.calculate(prices)
returns <- na.omit(returns)
 
logicInvestGMR <- function(returns, lookback = 3) {
  ep <- endpoints(returns, on = "months") 
  weights <- list()
  for(i in 2:(length(ep) - lookback)) {
    retSubset <- returns[ep[i]:ep[i+lookback],]
    cumRets <- Return.cumulative(retSubset)
    rankCum <- rank(cumRets)
    weight <- rep(0, ncol(retSubset))
    weight[which.max(cumRets)] <- 1
    weight <- xts(t(weight), order.by=index(last(retSubset)))
    weights[[i]] <- weight
  }
  weights <- do.call(rbind, weights)
  stratRets <- Return.portfolio(R = returns, weights = weights)
  return(stratRets)
}
 
gmr <- logicInvestGMR(returns)
charts.PerformanceSummary(gmr)

И в результате работы программы получены следующие показатели производительности стратегии:

> rbind(table.AnnualizedReturns(gmr), maxDrawdown(gmr), CalmarRatio(gmr))
                          portfolio.returns
Годовая доходность                 0.287700
Годовое ср.кв.отклонение           0.220700
Коэффициент Шарпа (Rf=0%)          1.303500
Наибольшая просадка                0.222537
Коэффициент Калмара                1.292991

Эквити бэктеста приведено в заглавии поста. Как видите, обещанные в оригинале 34% годовой доходности не получилось, но и результат в 28,7% очень даже неплох, так же как и солидный коэффициент Шарпа = 1,3. Скорее всего разница объясняется не совсем точным воспроизведением алгоритма, и мы сделаем вывод, что данная стратегия вполне применима для широкого круга инвесторов, в силу ее простоты и хорошей производительности.

Другие алгоритмы и их применение смотрите на моем сайте.

★3
2 комментария
спасибо
avatar

теги блога uralpro

....все тэги



UPDONW
Новый дизайн