Машинное обучение в трейдинге: теория, модели, практика и алготорговля - страница 7
Вы упускаете торговые возможности:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Регистрация
Вход
Вы принимаете политику сайта и условия использования
Если у вас нет учетной записи, зарегистрируйтесь
Спасибо, попробовал. Видно что вы много сделали для отбора предикторов, ибо нейронка легко на них обучилась, и сохранила результат также на проверочном датасете.
Результаты ниже относятся к обучению на R1.F3
1) С Rattle вышел забавный результат. НН со стандартной конфигурацией показала ошибки train/validate/testing - 30%/29%/33%. Ошибка на R2.F3 - 35%. Но всё это просто удачный случай на самом деле, в другой конфигурации она бы легко недо- или переобучилась, тут просто повезло.
2) Потом я взял простой грубый подход с обучением без контроля, 200 скрытых нейронов, сеть обучалась пока результат не перестал улучшаться. Ошибки train/validate/testing/R2.F3 - 2%/30%/27%/45%. Ну это понятно, сеть переобучилась.
3) Обучение с контролем. Это отличается от деревьев, но с нейронкой так вообще всегда надо делать чтоб её не переобучить. Суть в том чтобы иногда приостанавливать обучение, и сверять результаты train/validate/testing. Золотого правила сверки результатов я не знаю, но вполне нормальный подход это обучать на train датасете, потом смотреть на ошибки в validate и testing датасетах, прекратить обучение когда ошибки в validate/testing перестанут понижаться. Это даёт какую-то гарантию от переобучения. R2.F3 во время всего этого процесса считается недоступным, и тест на нём делается только после конца обучения. В этом случае ошибки train/validate/testing/R2.F3 - 27%/30%/31%/37%. Тут опять наблюдается переобученность, но небольшая. Можно было остановить процесс обучения пораньше, после того как ошибка train стала заметно меньше ошибок validate/testing, но это уже гадание... могло помочь, а могло бы и нет.
У "R1.F1" целевая переменная имеет три значения, Rattle так не умеет с нейронкой, и нужно писать свой код на R, я этот датасет пропустил.
"R1.F4" "R1.F5" "R1.F6" давали в нейронке в Rattle примерно такие-же результаты для всех 4 ошибок, мне кажется адекватный подход с нейронкой тоже даст примерно теже результаты, я с ними дальше не занимался.
Я имею аналогичные цифры для леса и ada.
А теперь, если вернуться к нашим "баранам" - как отбросить из произвольного перечня предикторов шум? У меня имеется некий эмпирический алгоритм, который отобрал мои 27 предикторов из 170. Кроме этого я его использовал для анализа чужих наборов предикторов и тоже удачно. На основании этого опыта я утверждаю, что все методы из R, которые в своих алгоритмах используют "важность" переменных, не могут очистить набор предикторов от шума.
Обращаюсь ко всем читателям ветки: готов сделать соответствующий анализ, если исходные данные будут представлены в виде RData или экселевском файле, не требующем обработки.
Кроме этого.
В аттаче прилагаю ряд статей, которые якобы решают проблему очистки первоначального набора предикторов от шума, причем с гораздо большим качеством. К сожалению в данный момент у меня нет времени попробовать. Может быть кто-нить попробует и выложит результат?
В аттаче прилагаю ряд статей, которые якобы решают проблему очистки первоначального набора предикторов от шума, причем с гораздо большим качеством. К сожалению в данный момент у меня нет времени попробовать. Может быть кто-нить попробует и выложит результат?
Я правильно понял что в вашем файле ALL_cod.RData можно использовать для обучения также Rat_DF1 (указав нужный таргет), а затем для проверки использовать Rat_DF2 и Rat_DF3? Я приатачил свой код на R для тех кому интересно, он реализует обучение нейронной сети с контролем ошибки. Для выбора другой целевой переменной можно просто заменить в файле автозаменой "Short_Long.75" на что-то из "Short_Long.35", "Flet_Long", "Short_Flet", "Flet_In". Так удобней чем подставлять разные датасеты.
mmm Данные о времени могут быть нужны, так рынки по сессиям различно работают.
Посмотрите, какой у меня набор фичей для форекса:
> names(sampleA)
[1] "lag_diff_2" "lag_diff_3" "lag_diff_4" "lag_diff_6" "lag_diff_8" "lag_diff_11" "lag_diff_16"
[8] "lag_diff_23" "lag_diff_32" "lag_diff_45" "lag_diff_64" "lag_diff_91" "lag_diff_128" "lag_diff_181"
[15] "lag_diff_256" "lag_diff_362" "lag_diff_512" "lag_diff_724" "lag_mean_diff_2" "lag_mean_diff_3" "lag_mean_diff_4"
[22] "lag_mean_diff_6" "lag_mean_diff_8" "lag_mean_diff_11" "lag_mean_diff_16" "lag_mean_diff_23" "lag_mean_diff_32" "lag_mean_diff_45"
[29] "lag_mean_diff_64" "lag_mean_diff_91" "lag_mean_diff_128" "lag_mean_diff_181" "lag_mean_diff_256" "lag_mean_diff_362" "lag_mean_diff_512"
[36] "lag_mean_diff_724" "lag_max_diff_2" "lag_max_diff_3" "lag_max_diff_4" "lag_max_diff_6" "lag_max_diff_8" "lag_max_diff_11"
[43] "lag_max_diff_16" "lag_max_diff_23" "lag_max_diff_32" "lag_max_diff_45" "lag_max_diff_64" "lag_max_diff_91" "lag_max_diff_128"
[50] "lag_max_diff_181" "lag_max_diff_256" "lag_max_diff_362" "lag_max_diff_512" "lag_max_diff_724" "lag_min_diff_2" "lag_min_diff_3"
[57] "lag_min_diff_4" "lag_min_diff_6" "lag_min_diff_8" "lag_min_diff_11" "lag_min_diff_16" "lag_min_diff_23" "lag_min_diff_32"
[64] "lag_min_diff_45" "lag_min_diff_64" "lag_min_diff_91" "lag_min_diff_128" "lag_min_diff_181" "lag_min_diff_256" "lag_min_diff_362"
[71] "lag_min_diff_512" "lag_min_diff_724" "lag_sd_2" "lag_sd_3" "lag_sd_4" "lag_sd_6" "lag_sd_8"
[78] "lag_sd_11" "lag_sd_16" "lag_sd_23" "lag_sd_32" "lag_sd_45" "lag_sd_64" "lag_sd_91"
[85] "lag_sd_128" "lag_sd_181" "lag_sd_256" "lag_sd_362" "lag_sd_512" "lag_sd_724" "lag_range_2"
[92] "lag_range_3" "lag_range_4" "lag_range_6" "lag_range_8" "lag_range_11" "lag_range_16" "lag_range_23"
[99] "lag_range_32" "lag_range_45" "lag_range_64" "lag_range_91" "lag_range_128" "lag_range_181" "lag_range_256"
[106] "lag_range_362" "lag_range_512" "lag_range_724" "symbol" "month" "day" "week_day"
[113] "hour" "minute" "future_lag_2" "future_lag_3" "future_lag_4" "future_lag_6" "future_lag_8"
[120] "future_lag_11" "future_lag_16" "future_lag_23" "future_lag_32" "future_lag_45" "future_lag_64" "future_lag_91"
[127] "future_lag_128" "future_lag_181" "future_lag_256" "future_lag_362" "future_lag_512" "future_lag_724"
Я беру и данные от скользящих средних, и максимумы, и минимумы, и размах цен в окне. И время, и дни и даже месяцы )
Мои алгоритмы могут реально оставить из 114 предикторов 10 или даже 5. Это нормально. В таких данных сильная корреляция между ПРЕДИКТОРАМИ и следовательно присутствует сильная избыточность.
Расскажу про свой метод отбора информативных признаков кратко. Код прилагается.
Есть две стороны вопроса - как отбирать поднаборы и как мерять релевантность отобранных предикторов выходной переменной.
Первый вопрос. Я решаю его путем стохастического перебора комбинаций предикторов, применяя метод Имитации отжига. Похож по результату работы на генетику и недетерминированный градиентный спуск. Плюс в том, что выбирается из локальных минимумов и работает по принципу, который есть в природе. Может работать с негладкой поверхностью ошибки, но тут все условно.
Для многих задач сторонники метода считают его лучше, чем генетика, например. Реализуется через пакет в R стандартно почти. Фишка в том, что он для непрерывных данных, а у меня индексы предикторов, так вот я делаю непрерывный вектор длиной в общее количество предикторов и при пробитии заданного порога любым скаляром индекс предиктора обращается в единицу.
Второй вопрос - еще более тонкий. Фитнесс-функция.
Как померить, что предиктор (и набор предикторов) влияют на выход. Зависимость может быть нелинейна. Стандартная регрессия может крупно лажать на некоторых нелинейных задачах. При этом я не говорю про обучение черного ящика и использование встроенного оценщика важности. Я про отдельную методу.
Надо понимать, что зависимость может быть весьма сложной и включать в себя взаимодействия, избыточности, нелинейность опять же. Все эти штуки могут быть применимы и к категориальным данным, и к нумерикам.
Я остановил выбор на категориальных данных, так как под них есть хорошие средства из Теории информации. Если сказать совсем просто: есть вход и выход. Если состояние выхода хотя-бы чуть чуть зависит от входа (вероятностно), то они зависимы. Есть такая штука - взаимная информация. Она это и меряет.
Теперь глубже. ВИ меряет нечто на наблюдаемом распределении на выборке конечного размера. Это конечно точечная оценка.
Поэтому нужно оценить статистические границы информации при случае независимой пары вход-выход. Это делаемся самописной функцией численными методами.
Еще глубже. Если у нас два и более предиктора - что с ними делать?
Во-первых, они сами могут быть связаны и чем сильнее связаны, тем больше будет избыточность в их наборе. Эта избыточность меряется т.н. мультиинформацией. Но мультиинформация это тоже точечная оценка на выборке. Для нее также высчитывается квантиль распределения численно через еще одну самописную функцию.
Во-вторых, количество уровней категорий предикторов может быть таким большим (скажем, 2 ^ 15), что нельзя ничего сказать про зависимость на этих уровнях. Очень мало наблюдений приходится на уровень.
И наконец, когда все это сделано и соединено воедино, получаем возможность измерить произвольного вида зависимость на произвльном числе предикторов и выходе, на произвольном размере выборки с заданной заранее статистической значимостью. Сами базовые функции из Теории информации берутся из пакета.
Все это в приложенном файле. Конечно, без 100 грамм там разобраться не просто. Там еще полный код для создания правил торговли и их валидации. Все для вашей информации и углубления знаний.
В принципе результат таков обычно:
[1] "1.69%"
> final_vector <- c((sao$par >= threshold), T)
> names(sampleA)[final_vector]
[1] "lag_diff_23" "lag_diff_45" "lag_mean_diff_2" "lag_mean_diff_8" "lag_max_diff_11" "lag_max_diff_181" "lag_min_diff_3" "lag_min_diff_724"
[9] "lag_sd_724" "lag_range_32" "symbol" "future_lag_181"
После полутора суток работы и перебора десятков тысяч комбинаций предикторов функция выдает значение фитнесс-функции - это значимая взаимная информация пенализированная на наличие избыточности в наборе предикторов. И сами предикторы.
Все это, повторюсь, категориально и позволяет строить человеко-читаемые правила. Позволяет трактовку найденной закономерности.
Вот, например, выше у меня 1.7% от полной детерминированности (что для форекса неплохо) и куча входов, которые в совокупности значимо на уровне доверия 0.1 (я так поставил эксперимент) определяют состояние выхода (бинарного). То есть, явно информация в форексных данных присутствует. Вопрос - доказан экспериментально.
После этого можно оценивать на валидации прибыльность и кодить торговую систему.
Алексей
Я правильно понял что в вашем файле ALL_cod.RData можно использовать для обучения также Rat_DF1 (указав нужный таргет), а затем для проверки использовать Rat_DF2 и Rat_DF3? Я приатачил свой код на R для тех кому интересно, он реализует обучение нейронной сети с контролем ошибки. Для выбора другой целевой переменной можно просто заменить в файле автозаменой "Short_Long.75" на что-то из "Short_Long.35", "Flet_Long", "Short_Flet", "Flet_In". Так удобней чем подставлять разные датасеты.
Да. Именно для удобства в rattle.
Еще один нюанс.
Все целевые переменные получены из двух ЗЗ: ЗЗ(35) и ЗЗ(25). И вот здесь один очень неприятный нюанс, который перекликается с Вашим.
Целевая переменная - это последовательность 0 и 1, что соответствует плечу ЗЗ. Но мы ВСЕГДА предсказываем отдельный элемент плеча ЗЗ, а не само плечо. Поэтому говорить, что мы предсказываем тренды, неправильно. Правильно говорить, что предсказывается элемент тренда. А если сложить все предсказанные элементы тренда, то тренд скорее всего и не получится.
Спасибо за feature_selector_modeller.zip, буду разбираться.
Обращаюсь ко всем читателям ветки: готов сделать соответствующий анализ, если исходные данные будут представлены в виде RData или экселевском файле, не требующем обработки.
Я приатачил файл, это набор данных с форекса. Внутри RData с двумя датасетами, для тренировки и для валидации. Физически данные в двух датасетах идут друг за другом, они поделены на два файла просто для удобства тестирования модели. Модель на этом датасете обучить можно, я вручную отсеивал предикторы и обучал нейронку, в итоге минимальная ошибка на валидационном датасете была 46%, что на самом деле не прибыльно. О реальном профите можно думать если ошибка упадёт меньше 40%. Попробуйте отсеять предикторы из этого файла пожалуйста.
Целевая переменная - это последовательность 0 и 1, что соответствует плечу ЗЗ. Но мы ВСЕГДА предсказываем отдельный элемент плеча ЗЗ, а не само плечо. Поэтому говорить, что мы предсказываем тренды, неправильно. Правильно говорить, что предсказывается элемент тренда. А если сложить все предсказанные элементы тренда, то тренд скорее всего и не получится.
Я пробовал разные целевые переменные. С одной стороны, можно предсказывать цену на один бар вперёд, и тогда целевая переменная будет 1 или 0 в зависимости если цена за следующий бар выросла или упала. На маленьких таймфреймах я результата так и не добился, похоже что цена закрытия это довольно случайное число на них. Но на H1 и выше уже есть какой-то положительный результат.
Другой вариант это зигзаг, или другие трендовые индикаторы. У меня с ним получались какие-то положительные результаты, но при условии что результат нейронки проходил через фильтр. Например брать среднее от результатов за последние бары, или использовать результаты только выше какого-то порогового значения. Я считаю что это всё не стоит применять, тут больше гадания чем точных вычислений. Проблема в том что от модели требуется давать только сигналы на покупку следующих 10-20 баров, а она иногда среди них даёт сигнал на продажу. В таком случае сделка переворачивается, платится комиссия и спред, и так несколько раз за тренд. Поэтому нужно либо добиться высокой точности, либо сглаживать результат чтоб не было таких переворотов на всего один бар. То есть да, как вы и сказали предсказывается только элемент тренда, а сам тренд из таких элементов сложить не очень получается.
Я пробовал разные целевые переменные. С одной стороны, можно предсказывать цену на один бар вперёд, и тогда целевая переменная будет 1 или 0 в зависимости если цена за следующий бар выросла или упала. На маленьких таймфреймах я результата так и не добился, похоже что цена закрытия это довольно случайное число на них. Но на H1 и выше уже есть какой-то положительный результат.
У меня результаты стабильно противоположные. Я легко прогнозирую движение цены на несколько минут вперед (до часа) с точностью 55% (Ask to Ask). Лучший результат для 23 минут. Это бинарная классификация на валидационных выборках.
А при повышении горизонта прогноза точность медленно падает вплоть до 51% на 12 часов вперед. И эта зависимость есть на всей истории. Но точность должна быть еще выше, чтобы выйти в плюс (преодолеть расстояние Ask - Bid).
Обсудим потом еще.
Спасибо за feature_selector_modeller.zip, буду разбираться.
Я приатачил файл, это набор данных с форекса. Внутри RData с двумя датасетами, для тренировки и для валидации. Физически данные в двух датасетах идут друг за другом, они поделены на два файла просто для удобства тестирования модели. Модель на этом датасете обучить можно, я вручную отсеивал предикторы и обучал нейронку, в итоге минимальная ошибка на валидационном датасете была 46%, что на самом деле не прибыльно. О реальном профите можно думать если ошибка упадёт меньше 40%. Попробуйте отсеять предикторы из этого файла пожалуйста.
Ясно, спасибо, буду искать другие исходные данные.
Подождите. Я тоже прогоню ваши данные на предмет зависимостей.
Один вопрос пока я не начал. Ваши данные включают в себя все бары подряд, или было прореживание баров перед составлением выборок?