Блог им. uralpro

Как быстро увеличить производительность алгоритма. Часть 1

biasnn

Основные принципы увеличения прибыльности алгоритмов автоматизированной торговли изложены в блоге Inovancetech. Представляю здесь перевод этой статьи. В ней использованы некоторые алгоритмы и результаты цикла про машинное обучение (часть 1, часть 2).

После построения алгоритма, вам нужно убедиться, что он робастен и будет генерировать прибыльные сигналы при реальной торговле. В данном посте мы представим 3 легких способа увеличить производительность вашей модели.

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

Тренировочный набор данных:

Это данные, которые вы используете для тренировки, или построения модели. Алгоритм будет пытаться найти взаимосвязь между входом ( вашими индикаторами) и выходом (где будет находится цена в следующем периоде — выше или ниже текущей). Обычно берут 60% имеющихся данных для этого набора.

Тестовый набор данных:

Мы будем использовать тестовый набор для определения производительности модели на данных, которые не использовались для тренировки. Этот набор мы применим для сравнения разных моделей ( или одной модели с разными параметрами),  необходимо, чтобы это был как можно более репрезентативный набор, учитывающий разные ситуации на рынках. Обычно, берут 20% от имеющихся данных для тестирования.

Проверочный набор данных:

Проверочные данные используются для определения, как хорошо наша окончательная модель будет работать на будущих периодах. Мы можем использовать данный набор единожды, как выборку «out-of sample», для избежания подгонок под эти последние данные. Если результат не соответствует требуемым показателям, вы должны использовать другой проверочный набор, чтобы убедиться в робастности модели. Последние 20% данных зарезервированы для проверочного набора.

1.Понимание вашей модели.

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

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

Мы получили представление, когда наши модели подвержены недооценке/подгонке, далее рассмотрим другие способы улучшения алгоритмов.

2. Создание индикаторов.

Использование правильных входных данных для модели чрезвычайно важно. Выражение «мусор на входе — мусор на выходе» соответствует действительности, это означает, что если мы не подали значимой информации на вход алгоритма, то никогда не найдем в ней каких-либо паттернов или связей.

Если вы говорите «я использую 14-периодный RSI для торговли», за этими словами может скрываться больше, чем сказано. Вы можете применять наклон RSI, или его локальные максимумы и минимумы, расхождение с ценовым рядом, и множество других факторов. Однако модель получает только одну часть информации — текущее значение RSI. Для создания индикатора, или вычисления, основанного на значении RSI, нам нужно дать алгоритму  больше информации, чем просто одно значение.

Используем наивный байесовский алгоритм, более стабильный, чем другие, склонные к подгонке, для создания сложных индикаторов, могущих улучшить производительность. Используем программу на языке R, применение наивного байесовского классификатора подробно разбирается в части 2 цикла про машинное обучение.

Во-первых, инсталлируем нужные библиотеки, устанавливаем входные данные и вычисляем основные входные параметры:

install.packages(“quantmod”)
library(quantmod)
install.packages(“e1071”)
library(e1071)

startDate = as.Date("2009-01-01")
endDate = as.Date("2014-06-01")
#Установим диапазон дат, который хотим исследовать

getSymbols("MSFT", src = "yahoo", from = startDate, to = endDate)
#Получаем наши данные

EMA5<-EMA(Op(MSFT),5)
RSI14<-RSI(Op(MSFT),14)
Volume<-lag(MSFT[,5],1)
#Вычисляем основные индикаторы. Отметим: у нас есть лаг в данных по объему, так как мы используем вчерашние данные в качестве входных для избежания подгонки данных, так как мы вычисляем индикаторы из цен открытия

PriceChange<- Cl(MSFT) - Op(MSFT)
Class<-ifelse(PriceChange>0,"UP","DOWN")
#Создаем переменную, которую хотим предсказывать

BaselineDataSet<-data.frame(EMA5,RSI14,Volume)
BaselineDataSet<-round(BaselineDataSet,2)
#Округляем входные данные до двух знаков после запятой, для использовании байесовского алгоритма

BaselineDataSet<-data.frame(BaselineDataSet,Class)
BaselineDataSet<-BaselineDataSet[-c(1:14),]
colnames(BaselineDataSet)<-c("EMA5","RSI14","Volume","Class")
#Создаем набор данных, удаляя периоды вычисления индикаторов

BaselineTrainingSet<-BaselineDataSet[1:808,];BaselineTestSet< -BaselineDataSet[809:1077,];BaselineValSet<-BaselineDataSet[1078:1347,]
#Разделяем данные на 60% тренировочного набора, 20% тестового набора и 20% проверочного набора

Затем строим основную модель:

BaselineNB<-naiveBayes(Class~EMA5+RSI14+Volume,data=BaselineTrainingSet)

table(predict(BaselineNB,BaselineTestSet),BaselineTestSet[,4],dnn=list('predicted','actual')) 

nnnb

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

Давайте создадим более сложные индикаторы и посмотрим, удастся ли уменьшить недооценку:

EMA5Cross<-EMA5-Op(MSFT)
RSI14ROC3<-ROC(RSI14,3,type="discrete")
VolumeROC1<-ROC(Volume,1,type="discrete")
#Исследуем расстояние между 5- периодной ЕМА и ценой открытия, и одно- и трехпериодный индикатор ROC на нашем индикаторе RSI  и объемах, соответственно

FeatureDataSet<-data.frame(EMA5Cross,RSI14ROC3,VolumeROC1)
FeatureDataSet<-round(FeatureDataSet,2)
#Округляем значение индикатора

FeatureDataSet<-data.frame(FeatureDataSet, Class)
FeatureDataSet<-FeatureDataSet[-c(1:17),]
colnames(FeatureDataSet)<-c("EMA5Cross","RSI14ROC3","VolumeROC1","Class")
#Создаем и называем набор данных

FeatureTrainingSet<-FeatureDataSet[1:806,]; FeatureTestSet< -FeatureDataSet[807:1075,]; FeatureValSet<-FeatureDataSet[1076:1344,]
#Создаем тренировочный, тестовы и проверочный наборы

И наконец, создаем нашу модель:

FeatureNB<-naiveBayes(Class~EMA5Cross+RSI14ROC3+VolumeROC1,data=FeatureTrainingSet)

Посмотрим, удалось ли уменьшить недооценку:

table(predict(FeatureNB,FeatureTestSet),FeatureTestSet[,4],dnn=list('predicted','actual')) 

nnnb1

У нас получилось увеличить аккуратность предсказания с 7% до 53% с использованием только относительно простых методов! Разберитесь как это произошло, просто наблюдайте за изменением этих индикаторов и переводите такие наблюдения в значения, которые понимает алгоритм, и вы сможете улучшить производительность стратегии еще больше.

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

Другие стратегии, применяемые в алгоритмической торговле и биржевых роботах смотрите на моем сайте.

★9
24 комментария
Что такое ошибка?
avatar
anatolyutkin, имеется в виду ошибка предсказания цены
avatar
uralpro, Но ведь торговый алгоритм--это достаточно хитрое предсказание. Как определить ошибку? Например, алго: при пересечении вверх SMA(10) входим лонг, при пересечении вниз выходим. Как для него определить ошибку?
avatar
очень просто — на тестовой выборке определяете, пошла ли цена вверх после пересечения вверх или вниз после пересечения вниз в вашем торговом периоде, считаете количество совпадений и общее количество сигналов и делите одно на другое
avatar
uralpro, имеется ввиду, пошла ли цена вверх в ожидаемый (предсказываемый) период времени после пересечения?
avatar
Marcello, да, верно
avatar
uralpro, То есть это процент прибыльных сделок что-ли? Но существуют прибыльные алгоритмы с этим процентом, меньшим 50. Они все недооценены?
avatar
anatolyutkin, вы неправильно понимаете значение слова «недооценка». Этот термин определяет только качество сигнала стратегии. И где речь идет об абсолютных процентах? По-моему только оценивается в плане «больше-меньше». Кроме того, мы говорим об автоматизированной торговле, где алгоритмов с процентом угадывания мене 50% практически не бывает, иначе невозможно получить на них прибыль статистически. Вы, наверное, имеете в виду ручную торговлю, где такое возможно, если прибыль выходит больше в среднем по значению, чем убытки
avatar
uralpro, У вас в тексте есть слова «большая ошибка». И не говорится, большая по сравнению с чем. Как понять фразу «Если у вас большая ошибка в тренировочном и большая ошибка в тестовом наборе, вы с большой вероятностью имеете дело с недооценкой,»?

У меня есть роботы с угадайкой 40-50 процентов. Не понимаю, как автоматизация/ее отсутствие влияют на параметры алгоритма. Автоматизация--это вроде техническая вещь.
avatar
anatolyutkin, а можно задать вопрос — с какой частотой у вас происходят сделки в подобных алгоритмах, в среднем?
avatar
uralpro, Это таймфреймовые трендовухи.
avatar
anatolyutkin, не подумайте ничего дурного, мне просто интересно оценить стат. значимость такого алгоритма
avatar
uralpro, Их же много всяких разных. Ну пусть одна сделка раз в три дня.

Если честно, мне нравится концепция недооцененности/переподгонки. Нравится существование оптимума. Но хотелось бы деталей и конкретных примеров, потому что пока это выглядит лишь затравкой и не более. В качестве примера удобно взять что-то, имеющее смысл, но что не жалко. Поэтому я и предложил пересечения МА. Это простая трендовуха, эксплуатирует трендовость. Вот как понять--она переподогнана или недооценена?
avatar
anatolyutkin, Просто угадайка в качестве метрики, имхо, не пляшет. Просто в силу того, что не определяет финрез, а важен именно финрез.
avatar
anatolyutkin, я вот не силен в таких стратегиях с одной-двумя сделками в неделю. Я не смог бы проверить их статистику — просто недостаточно данных. Со своей стороны могу рассуждать только об алгоритмах с не менее чем десятком сделок в день. Насколько недооценена стратегия, можно определить на длинных выборках. Критерий недооценки, как и переоценки — неустойчивость результатов на выборках out-of-sample. По идее. вам без разницы, недооценена система или переоценена, в любом случае это плохо. Как правило, переоцененные системы имеют большое количество настраиваемых параметров и сложны, недооцененные — наоборот.
avatar
uralpro, Есть и десяток сделок в день, но там угадайка, конечно, 50+%.

Простая/сложная--это слова. Имхо, есть то, что я называю край эджа. Пример: smart-lab.ru/blog/186186.php Это искусственный процесс. СБ, но с доп условием--смещено в контру при сильном отклонении. Вот код:

var: s(10),x(0);
x=2*Random(1)-1;
if s[1]-s[2]<-0.9 then x=x+0.8;
if s[1]-s[2]>0.9 then x=x-0.8;
s=s[1]+x;

И тут есть явный максимум эджа--0.8 средняя сделка и 90% угадайка. Все, что лучше--переподгонка, все, что хуже--недооценка.
Но тут процесс известен. На рынке--не так. И как понять, где край эджа? С опытом оно приходит, конечно, но может есть формальные способы находить оптимум?
avatar
anatolyutkin, ну а вероятность прибыльных сделок разве не есть критерий оценки? То, что вы называете прибыльной системой с процентом угадывания менее 50%, на самом деле система с количеством правильных сигналов все-таки более 50%, просто когда вы следуете за трендом, то считаете, что вошли по одному сигналу в начале, а на самом деле сигнал действует продолжительное время, то есть дискретизировав его по времени вы получите набор прибыльных и убыточных сигналов, с процентом угадывания более 50%.
avatar
uralpro, Это правильно, да. Ну теперь объясните еще, что такое большая/маленькая угадайка. Как понять фразу «Если у вас большая ошибка в тренировочном и большая ошибка в тестовом наборе, вы с большой вероятностью имеете дело с недооценкой,»?
avatar
anatolyutkin, это означает, что соотношение прибыльных и убыточных (дискретизированных) сигналов на тренировочной и тестовой выборке менее 50% для недооценки, а для переоценки — более 50% на тренировочной и менее 50% — на тестовой
avatar
uralpro,
1) Ну тут же распределение некое должно быть. Условно, если 30% на тренировочной и 30% на тестовой--это явная недоподгонка. Если 50 и 50--хз. Если 70 и 70--явная переподгонка.

2) Сами эти цифры (30, 70) зависят от системы. Мне известны системы с угадайкой 80+% при соотношении средний убыток/средний выигрыш=1:1. Но они не есть переподгонка, они просто юзают сильную неэффективность (это редкие события, конечно, частые события мне такие неизвестны). И наоборот, есть системы с частыми событиями и угадайкой 52-53% при win/loss=1:1. Их можно подточить до 55%, но это будет точно переподгонка, нарушающая их суть.
Зависимость правильных цифр от конкретной системы делает создание адекватной методы как минимум непростым, ибо не ясно, как формализовать что такое «конкретная система».
avatar
anatolyutkin, так и есть, соглашусь со всем этим. Думаю нет такой универсальной оценки для любой системы. Если система юзает сильную неэффективность (еще и редкую), то ее скорее всего нельзя оценивать статистическими понятиями. Это больше относится к высокочастотным системам с большой статистической выборкой по сигналам.
avatar
uralpro, Ну да, редким событиям вообще статистика не писана, так что ну их. А вот для высокочастотных можно попытаться оценить недо/переподгонку некими (полу)формальными методами. Это интересная тема. А то все получается, что система в работу отправляется тогда, когда работать над ней надоело :)
avatar
anatolyutkin, тут похоже другое. К примеру, после пересечения SMA(10) вверх ты ожидаешь, что через определенное число баров (скажем, 4) она не уйдет ниже точки пересечения. Если ты угадываешь в 50% случаев и тебе этого мало, то ищешь другое условие входа, после которого 4-й бар остается в прибыли. По сути, это подгонка под «тейк-профит» (намеренно взял в кавычки).
avatar
Marcello, Ну да, так и есть. Дискретизованное время. Там выше автор дал хорошее определение--см. коммент от 17:21:29.
avatar

теги блога uralpro

....все тэги



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