Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Создание, тестирование и оптимизация торговых систем с использованием программы Metastok и языка R. Учебное пособие

.pdf
Скачиваний:
1
Добавлен:
08.09.2026
Размер:
2 Мб
Скачать
☆
getSymbols(paste0('SPFB.',RTS), src='Finam',
from= Sys.Date() - 365,
to= Sys.Date())
price = merge.zoo(SPFB.RTS[,4])
Во многих пакетах для тестирования уже заложены данные класса
data.frame. Например, в библиотеке TTR имеется встроенный фрейм
данных ttrc. Для того чтобы вывести на экран первые пять строк этого фрейма данных и определить его класс, достаточно выполнить следую­щие команды:
library(TTR)
data(ttrc)
head(ttrc)
class(ttrc)
Для удобства работы с финансовыми временными рядами рекомен­дуется преобразовывать фрейм данных в объекты класса
xts (eXtensible
Time-Series). Для этого можно использовать библиотеку xts и выпол-
нить следующую команду:
library(xts)
qxts<-
xts(ttrc[,-1],order.by=ttrc[,1])
Для очистки оперативной памяти можно использовать команду
rm(list=ls())
2.4. Выгрузка данных из программы R/Rstudio
Приведем некоторые простейшие приемы сохранения результатов работы, полученных во время сессии R:
sink(file= <имя файла>) – выводит результаты выполне-
ния последующих команд в режиме реального времени в файл с задан­ным именем; для прекращения действия этой команды необходимо вы­полнить команду
sink() без параметров;
save(file= <имя файла>, <список сохраняемых объектов>)
– сохраняет указанные объекты в двоичном файле
XDR-формата, с которым можно работать в любой операционной системе;
load(file= <имя файла>) – восстанавливает сохраненные
объекты в текущей среде;
save.image(file= <имя файла>) – сохраняет все объ-
екты, созданные в ходе работы, в виде специфичного для R rda-файла.
41
Для записи данных в текстовый файл можно использовать функцию
write.table(). Например, запишем матрицу A в файл с именем MyData.csv, в качестве разделителя значений используем символ табу-
ляции:
write.table(A, file="MyData.csv", sep="\t")
В среде R можно генерировать пиксельное изображение необходи­мого качества почти для любого разрешения дисплея или устройства пе­чати, а также сохранить полученные графические окна в файлах разного формата.
Для сохранения графика, построенного с использованием функции
plot(), можно выполнить следующий скрипт:
jpeg(file="saving_plot.jpeg")
plot(…)
dev.off()
В RStudio для сохранения построенных графиков в буфер обмена можно использовать команду
Следующий код позволяет загрузить котировки акций компании
ple
(AAPL) с сервера Yahoo Finance, затем сохранить данные в файл Ap-
Plots – Copy to Clipboard… .
Ap-
ple.rds в бинарном формате и загрузить данные из файла в перемен-
ную
Apple:
library(quantmod)
library(xts)
getSymbols("AAPL",src='yahoo')
saveRDS(AAPL, file="Apple.rds")
Apple = readRDS("Apple.rds")
Бинарный формат позволяет использовать исходные данные в раз­ных операционных системах.
2.5. Проведение технического анализа
Все объекты данных (а следовательно, и переменные) в R можно раз­делить на следующие классы (Шитиков, 2017):
numeric – объекты, к которым относятся целочисленные
(integer) и действительные числа (double);
logical – логические объекты, которые принимают только два
значения: FALSE (сокращенно F) и TRUE (T);
character – символьные объекты (значения переменных зада-
ются в двойных либо одинарных кавычках).
42
В языке R можно создавать имена для различных объектов (функций или переменных) как на латинице, так и на кириллице, но следует учесть, что
а (кириллица) и a (латиница) – это два разных объекта. Кроме того,
среда R чувствительна к регистру, т. е. строчные и заглавные буквы в ней различаются. Имена переменных (идентификаторы) в R должны начи­наться с буквы (или точки чёркивания. При помощи команды
.) и состоять из букв, цифр, знаков точки и под-
?<имя>
можно проверить, существует ли переменная или функция с указанными именем. Для проверки класса объекта достаточно выполнить команду
class(<объект>).
Выражение (expression) языка R представляет собой сочетание та-
ких элементов, как оператор присваивания (=, <-, ->), арифметические (+,
–, /, *, %/%, %%, ^) или логические операторы (==, !=, <, >, <=, >=, &, |, !), имена объектов и имена функций. Результат выполнения выражения,
как правило, сразу отображается в командном или графическом окне. Од­нако при выполнении операции присваивания результат сохраняется в соответствующем объекте и на экран не выводится
.
Построение графиков временных рядов. Загрузим котировки че-
тырех компаний General Electrics (GE), Кока-кола (KO), Apple (AAPL), McDonald’s (MCD) и индекс
Value Line Index (^VLIC) с сервера Yahoo
Finance за 2018 год. Для построения графика с пятью кривыми необходимо:
1. Подключить библиотеку:
library("quantmod")
2. Загрузить исходные данные:
symbols = c('^VLIC','GE','KO','AAPL','MCD') getSymbols(symbols, src='yahoo', from="2018-02-01",
to="2019-02-01")
3. Выбрать необходимые значения:
VLICad = VLIC$VLIC.Close; GEad = GE$GE.Close; KOad = KO$KO.Close; AAPLad = AAPL$AAPL.Close; MCDad = MCD$MCD.Close
4. Вычислить кумулятивную сумму ежедневных доходностей и
удалить первое слагаемое во временных рядах:
vl = cumsum((Delt(VLICad)*100)[-1,]) ge = cumsum((Delt(GEad)*100)[-1,]) ko = cumsum((Delt(KOad)*100)[-1,]) ap = cumsum((Delt(AAPLad)*100)[-1,]) md = cumsum((Delt(MCDad)*100)[-1,])
43
5. Предварительно сделать настройки осей графика:
lim = c(min(vl,ge,ko,ap,md), max(vl,ge,ko,ap,md))
6. Построить график для индекса и добавить на него четыре кривые
и легенду:
plot(vl,main="",ylim=lim,
xlab="",ylab="Доходность, %")
lines(ge, col="green"); lines(ko, col="red") lines(ap, col="violet"); lines(md, col="yellow") legend(x="topleft",
cex=0.4,c("VLIC","GE","KO","AAPL","MCD"),
lty=1, col=c("black", "green", "red", "violet",
"yellow"))
В результате выполнения скрипта на экране появится график, при-
веденный на рис. 26.
Рис. 26. График индекса VLIC и котировки компании GE, KO, AAPL, MCD
Построение линейной регрессионной модели для временного
ряда.
eral Reserve Bank
Загрузим временной ряд индекса Доу Джонса (DJIA) с сервера Fed-
за период с 2017 по 2018 год.
Для построения регрессионной модели
и проверки ее качества необ-
ходимо:
1. Подключить библиотеку:
library("quantmod")
2. Загрузить исходные данные:
getSymbols("DJIA", src="FRED")
44
3. Выбрать необходимые значения:
serie = DJIA["2017/2018"] price = as.numeric(serie) time = index(serie)
4. Построить линейную регрессию:
x=1:length(price) model = lm(price~x) reg = model$coef[1]+model$coef[2]*x
5. Построить график индекса Доу Джонса и добавить на него мо-
дельную кривую:
plot(x=time, y=price, main="Dow Jones",
type="l", xlab="Дата", ylab="Пункты")
lines(time, reg, col=2, lwd=2)
6. Познакомиться с оценками коэффициентов выборочного уравне­ния регрессии, значениями стандартных ошибок, вероятностями откло­нения гипотез о равенстве полученных оценок истинным значениям, а также коэффициентом детерминации:
summary(fit)
В результате выполнения скрипта на экране появится график, при-
веденный на рис. 27.
Рис. 27. Котировки индекса Доу Джонса и линейная регрессия (красная линия)
45
Применение индикатора технического анализа к графику коти-
ровок
. Загрузим котировки Microsoft (MSFT) c сервера yahoo. Построим свечной график цены для полученных данных за 2018–2019 гг., периодич­ность – 1 неделя, тема графика – белая. К полученному графику применим два индикатора – Полосы Боллинджера (BBands), схождение и расхожде­ние скользящих средних (MACD) с установками по умолчанию.
Для построения индикаторов необходимо:
1. Подключить необходимые (предварительно установленные)
библиотеки:
library(quantmod) library(TTR)
2. Загрузить исходные данные:
getSymbols("MSFT", src = "yahoo")
3. Построить график за 2018–2019 гг. с необходимыми настройками:
candleChart(to.weekly(MSFT["2018/2019"]), theme="white", up.col='green', dn.col='red',
name="Microsoft (MSFT)")
4. Наложить на график два индикатора с настройками по умолчанию:
addMACD() addBBands()
Рис. 28. График цены и два индикатора технического анализа
46
В результате выполнения скрипта на экране появится график, при­веденный на рис. 28. Полосы Боллинджера (BBands) построены в основ­ном окне с установками: окно усреднения – 20 периодов, множитель сигма – 2. Индикатор схождение и расхождение скользящих средних (MACD) отображен в дополнительном окне (под графиком цены), с уста­новками: короткая скользящая средняя – 12, длинная скользящая средняя
– 26, сглаживающая скользящая
средняя – 9 периодов.
График плотности вероятности случайной величины. Загрузим
временной ряд котировок Apple(AAPL) с сервера YahooFinance. Вычис­лим логарифмические доходности и построим для них график функции плотности. Проверим гипотезу о нормальности распределения доходно­стей с использованием теста Шапиро–Уилка. Для этого необходимо:
1. Подключить библиотеку:
library(quantmod)
2. Загрузить исходные данные:
getSymbols("AAPL", src="yahoo", from="2018-02-01", to="2019-02-01")
3. Вычислить дневные логарифмические доходности:
apRd= periodReturn(AAPL$AAPL.Close, pe­riod="daily", type="log")
4. Построить оценку функции плотности распределения для вычис­ленных доходностей, например с использованием непараметрического метода – ядерного сглаживания (Kernel Density Estimation):
dsd = density(apRd)
5. Сделать настройки графика и вывести график эмпирической функции плотности на экран:
yl=c(min(dsd$y), max(dsd$y)) plot(dsd, main="Функция плотности", ylim=yl,
xlab="x")
6. Оценить математическое ожидание, дисперсию по эмпирическим наблюдениям, сгенерировать случайную величину, подчиняющую нормаль­ному закону распределения и нанести точки на график функции плотности:
a=seq(min(apRd), max(apRd), 0.001) s = dnorm(a, mean(apRd), sd(apRd)) points(a, s, type="l", lty=2, col="red") legend("bottomright", col=c("black", "red"),
lwd=1, lty=c(1,2),
legend=c("Оценка","Модель"))
47
7. Выполнить тест Шапиро–Уилка:
shapiro.test(as.vector(apRd))
В результате работы скрипта на экране отобразится график (рис. 29).
Рис. 29. График плотности вероятности для логарифмических доходностей
2.6. Создание и тестирование торговых систем
Библиотеки PerformanceAnalytics, quantstat, quantmod, TTR позво­ляют производить испытания и сравнительный анализ запрограммиро­ванных торговых стратегий.
Создание и тестирование реверсной торговой системы. Создадим
реверсную торговую систему CrossMACD_RSI, которая подает сигналы для входа и выхода в позицию при двух индикаторов технического ана­лиза: схождения/расхождения скользящих средних MACD и индекса от­носительной силы RSI (табл. 3).
Таблица 3
Пример торговой системы
Длинная позиция Короткая позиция
сигнальная линия MACD выше MACD и RSI больше 60 сигнальная линия MACD ниже MACD и RSI меньше 40
Открываем Закрываем
сигнальная линия MACD ниже MACD и RSI меньше 40 сигнальная линия MACD выше MACD и RSI больше 60
48
В качестве примера будем использовать цены закрытия (Close) акций
компании Microsoft (MSFT) за период с 5 января 2018 по 5 января 2019.
Для создания торговой системы необходимо:
1.
Подключить необходимые (предварительно установленные)
библиотеки:
library(PerformanceAnalytics) library(quantmod)
2. Загрузить исходные данные, установить требуемый временной
интервал для тестирования, обработать пропуски в данных:
getSymbols("MSFT", src = "yahoo", from="2018-02-
01",to="2019-02-01")
MSFT<- MSFT[, "MSFT.Close"] MSFT[is.na(MSFT),] # обработка пропусков MSFT <- na.locf(MSFT)
3. Вычислить ежедневные доходности:
ret_MSFT <- Delt(MSFT)
4. Вычислить значения технических индикаторов MACD и RSI:
macd<- MACD(MSFT, nFast = 12, nSlow = 26, nSig = 9,
maType = "SMA", percent = FALSE)
rsi<- RSI(MSFT, n=14, maType = "SMA")
5. Записать условия формирования сигналов для открытия и закры-
тия соответствующих позиций (табл. 3):
signal<- NULL signal<-
ifelse ((macd$signal>macd$macd) & (rsi$SMA>
60), 1, ifelse((macd$signal<macd$macd) & (rsi$SMA<
40), -1, 0))
signal[is.na(signal)] <- 0
6. Открыть позицию на следующий торговый день после сигнала:
trade_return<- ret_MSFT *lag(signal, na.pad =
FALSE)
7. Вычислить доходность по позициям и годовую доходность:
cumm_return<-Return.cumulative(trade_return) annual_return<-Return.annualized(trade_return)
49
8. Построить графики кривой доходности, прибылей/убытков по
позициям, кривой просадок:
charts.PerformanceSummary(trade_return)
В результате выполнения этой команды на экране появится три тре-
буемых графика (рис. 30).
Рис. 30. График доходности (сверху); график прибылей и убытков
по позициям (по центру); график просадок торговой стратегии (снизу)
9. Вывести в консоль максимальный просадок стратегии:
maxDrawdown(trade_return)
Рассчитать показатель эффективности торговой стратегии (ко-
10.
эффициент Шарпа), а также коэффициент Шарпа в процентах годовых. Для этого выполним команды со следующими параметрами:
SharpeRatio(as.ts(trade_return), Rf = 0, p=0.95,
FUN = "StdDev")
SharpeRatio.annualized(trade_return, Rf=0)
50
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]