iqoption

Оптимизация портфеля на R

На 25% счета я стараюсь максимизировать доходность за счет активной торговли, а на 75% — минимизировать риск. И делаю ребалансировку между ними. Во вторую часть входит портфель акций, облигации и валюта.

Так получилось, что мой портфель акций сейчас состоит из следующих эмитентов:

(«BANE», «ALRS», «TGKA», «GMKN», «RUALR», «PHOR», «AKRN», «ROSN», «OFCB»)

Причин этому несколько — требование высокой ликвидности, хорошего роста за последние годы, маленькое среднеквадратичное отклонение доходностей. Есть также диверсификация по секторам: нефть, алмазы, электрогенерация, металлы, удобрения, банк.

Поставил перед собой задачу — оптимизировать доли каждого эмитента в портфеле с целью уменьшения отклонения доходности. Увеличивать саму доходность я не ставлю целью, так как понятно, что наиболее растущих акций в таком случае будет больше всего, а история не повторится. При этом моя цель в портфельных инвестициях — сбережение. А вот минимизация риска с учетом матрицы ковариаций — это интересно.

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

Optimal Weights:
  BANE   ALRS   TGKA   GMKN  RUALR   PHOR   AKRN   ROSN   OFCB 
0.0818 0.0623 0.1664 0.0500 0.1064 0.1169 0.0662 0.0500 0.3000 
То есть банка Открытие должно быть 30%, а Русала 10%. Максимальная просадка при этом 5%. 

Если же взять максимальную историю с 2012 года (для некоторых компаний есть история с 2007, но мне нужна история, которая есть для всех компаний), то получается:

Optimal Weights:
  BANE   ALRS   TGKA   GMKN  RUALR   PHOR   AKRN   ROSN   OFCB 
0.0921 0.1090 0.1107 0.0772 0.0500 0.1243 0.1238 0.1962 0.1168 
То есть теперь уже доля OFCB всего 12%, а Русала 5%. Максимальная просадка получается 17%.

На счет максимальной просадки понятно, а вот то, что доли так сильно меняются, меня разочаровало. Теперь не понятно, в каких долях держать эти инструменты — хоть в равных. 

Код на R:

#install.packages("PortfolioAnalytics")
#install.packages("tseries")
#install.packages("quantmod")
#install.packages("rusquant", repos="http://R-Forge.R-project.org")
#install.packages("DEoptim")
#install.packages("ROI")
# Установка пакетов. Она не требуется, если уже все установлено.

library(PortfolioAnalytics)
library(quantmod)
library(rusquant)
library(DEoptim)
library(ROI)
require(ROI.plugin.glpk)
require(ROI.plugin.quadprog)

rm(list = ls())
# Очистка среды R от лишних переменных в памяти, если требуется

fund.names <- c("BANE", "ALRS", "TGKA", "GMKN", "RUALR", "PHOR", "AKRN", "ROSN", "OFCB")
# Создаем массив из тикеров, для которых будем получать данные

if ( ! exists("BANE") ) {
  getSymbols(fund.names, src = "Finam", from = "2012-01-01")
  # Получение котировок
}

prices.data <- merge(BANE[,4], ALRS[,4], TGKA[,4], GMKN[,4], RUALR[,4], PHOR[,4], AKRN[,4], ROSN[,4], OFCB[,4])
returns.data <- CalculateReturns(prices.data)
returns.data <- na.omit(returns.data)
colnames(returns.data) <- fund.names
# Подготовка данных

pspec <- portfolio.spec(assets=fund.names)
pspec <- add.constraint(portfolio=pspec, type="weight_sum", min_sum=1, max_sum=1)
pspec <- add.constraint(portfolio=pspec, type="box", min=0.05, max=0.3)
pspec <- add.objective(portfolio=pspec, type="risk", name="var")
opt_minvar <- optimize.portfolio(R=returns.data, portfolio=pspec,optimize_method="ROI", trace=TRUE)
print(opt_minvar)
percentage <- opt_minvar$weights * 100
print(percentage)
# Оптимизация портфеля и вывод весов

portfolio.returns <- Return.portfolio(returns.data, weights = opt_minvar$weights)
print("Portfolio return mean:")
print(mean(portfolio.returns))
# Дневная доходность портфеля и среднее от нее

print(Return.annualized(returns.data, geometric=FALSE))
# Средняя годовая доходность

print("Table of drawdowns:")
print(table.Drawdowns(portfolio.returns, top = 5, digits = 4))
# Таблица просадок

print("Max drawdown:")
print(maxDrawdown(portfolio.returns))
# Максимальная просадка

chart.Drawdown(portfolio.returns, geometric = TRUE, legend.loc = "bottomleft", ylim=c(-0.2, 0.2))
# Просадки