English 中文 Español Deutsch 日本語 Português 한국어 Français Italiano Türkçe
Создание цифровых фильтров, не запаздывающих по времени

Создание цифровых фильтров, не запаздывающих по времени

MetaTrader 5Индикаторы | 10 января 2014, 09:49
14 483 43
Konstantin Gruzdev
Konstantin Gruzdev

Введение

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


Обычный подход

Этот подход основан на классических методах сглаживания временных рядов. Об этом есть множество статей, как на этом ресурсе, так и на других. Результаты получаем тоже классические:

  1. Смена тенденции проявляется с запаздыванием;
  2. За увеличение реакции индикатора (цифрового фильтра) приходится платить снижением качества сглаживания;
  3. Попытки реализации не запаздывающих индикаторов приводят к их перерисовке на последних отсчетах (барах).

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


Основная проблема

Не секрет, что большинство торговых систем с течением времени перестают работать. Или то, что индикаторы только на некоторых участках показательны. Объяснение этому простое: рыночные котировки нестационарны. Простое определение стационарности процесса есть в Википедии:

Стационарность — свойство процесса не менять свои характеристики со временем. Имеет смысл в нескольких разделах науки.

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

Несмотря на очевидность этого факта, огромное количество индикаторов строятся на основе теории анализа стационарных временных рядов. Примером таких индикаторов являются скользящие средние и их модификации. Есть, правда, попытки создания адаптивных индикаторов. Вроде как они должны в той или иной степени учитывать нестационарность биржевых котировок, но что-то чуда не происходит. Попытки "наказать" маркетмейкера, используя известные на сегодня способы анализа нестационарных рядов (вейвлеты, эмпирические моды и другие), тоже не приводят к успеху. Похоже на то, что упускается некий ключевой фактор.

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

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


Кластерный фильтр

Кластерный фильтр (англ. cluster — гроздь, сгусток, пучок) - совокупность цифровых фильтров, аппроксимирующих исходную последовательность. Кластерный фильтр не стоит путать с кластерными индикаторами.

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

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

Рисунок 1. Схема простого кластерного фильтра

Рисунок 1. Схема простого кластерного фильтра

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


Порядок построения кластерных фильтров

Любой кластерный фильтр может быть создан в три этапа:

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

2. На втором этапе под каждую модель создается один или несколько цифровых фильтров. Самое общее условие объединения фильтров в кластер служит то, что они принадлежат моделям, описывающих аппроксимируемую последовательность.

3. Итак, мы можем иметь от одного и более фильтров в кластере. Соответственно, на каждом новом отсчете у нас есть величина самого отсчета и одно или более значений фильтров. Таким образом, на каждом отсчете у нас есть вектор или искусственный шум из нескольких значений (минимум два). Все, что теперь нужно сделать, так это выбрать наиболее подходящее значение.


Пример простого кластерного фильтра

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

1. Описание принятой модели. Будем исходить из следующих предположений:

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

2. Подбираем цифровые фильтры. Для простоты возьмем два фильтра:

  • Первый фильтр у нас будет простое скользящее среднее (Simple Moving Average), рассчитываемое по последним двум ценам закрытия. На мой взгляд, это хорошо вписывается в третье условие нашей модели.
  • Так как процесс у нас нестационарный, то попробуем ввести дополнительный фильтр в надежде, что это как-то поможет уловить изменения характеристик временного ряда. С видом умного шамана я выбрал экспоненциальное скользящее среднее (Exponential Moving Average). Выбрал только по причине того, что EMA быстрее MA и не должна давать запаздывание на тренде и лучше реагирует на шум. EMA тоже будем рассчитывать по последним двум ценам закрытия.

3. Выбираем наиболее подходящее значение для кластерного фильтра.

Итак, на каждом новом отсчете будем иметь значение самого отсчета (цена закрытия), значение MA и EMA. Цену закрытия будем игнорировать, исходя из второго условия нашей модели. Далее выбираем значение МА или ЕМА, исходя из последнего условия модели, то есть из условия следования тренду:

  • Для возрастающего тренда, т.е. CF(i-1)>CF(i-2), выбираем один из следующих четырех вариантов:

    если CF(i-1)<MA(i) и CF(i-1)<EMA(i), то CF(i)=MIN(MA(i),EMA(i));

    если CF(i-1)<MA(i) и CF(i-1)>EMA(i), то CF(i)=MA(i);

    если CF(i-1)>MA(i) и CF(i-1)<EMA(i), то CF(i)=EMA(i);

    если CF(i-1)>MA(i) и CF(i-1)>EMA(i), то CF(i)=MAX(MA(i),EMA(i)).


  • Для нисходящего тренда, т.е. CF(i-1)<CF(i-2), выбираем один из следующих четырех вариантов:

    если CF(i-1)>MA(i) и CF(i-1)>EMA(i), то CF(i)=MAX(MA(i),EMA(i));

    если CF(i-1)>MA(i) и CF(i-1)<EMA(i), то CF(i)=MA(i);

    если CF(i-1)<MA(i) и CF(i-1)>EMA(i), то CF(i)=EMA(i);

    если CF(i-1)<MA(i) и CF(i-1)<EMA(i), то CF(i)=MIN(MA(i),EMA(i)).


Здесь:

  • CF(i) – значение кластерного фильтра на текущем баре;
  • CF(i-1) и CF(i-2) – значения кластерного фильтра на предыдущих барах;
  • MA(i) – значение простой скользящей средней на текущем баре;
  • EMA(i) – значение экспоненциальной скользящей средней на текущем баре;
  • MIN – минимальное значение;
  • MAX – максимальное значение;


Программный код и результат работы кластерного фильтра

Код индикатора с нашим кластерным фильтром не сложнее кода скользящего среднего. Поэтому здесь его разбирать не имеет смысла, там нет какого-то ноу-хау. Исходник приложен к статье.

Не теряя времени, пример работы нашего индикатора можно посмотреть на видео:


Видео 1. Результат работы простого кластерного фильтра

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

Видео 2. Сравнение простого кластерного фильтра и JJMA

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


Эффект опережающего сглаживания

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

Для демонстрации был сделан индикатор GMomentum test. Он содержит две индикаторных линии:

  • Синяя - классический моментум.
  • Красная - классический моментум, сглаженный кластерным цифровым фильтром, в котором реализован более сложный алгоритм.

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

Какого-то особого аргумента в пользу выбора Momentum для статьи у меня нет, просто линия моментума достаточно сильно зашумлена и поэтому работа фильтра, на мой взгляд, наиболее показательна. В общем, запускаете индикатор GMomentum test и изучаете, как ведет себя красная линия в сравнении с синей.

Для начала рассмотрим один любопытный момент. Для этого при запуске индикатора необходимо установить параметр "Filter" в "Test No.1 Advance". В этом режиме настройки фильтра таковы, что достаточно часто проявляется эффект, который можно назвать опережающим. При тестировании вы не увидите сглаживания всей исходной линии моментума. Фильтр выискивает участки, где есть вероятность получить опережающий эффект. Не удивительно, что это получается не всегда. Но достаточно часто, чтобы можно было это заметить.

На графике ниже представлен один из показательных участков работы фильтра.

Рисунок 2. Опережающий эффект при сглаживании линии моментума

Рисунок 2. Опережающий эффект при сглаживании линии моментума

Стоит отметить, что это только видимость опережающей фильтрации. Эта видимость возникает исключительно из-за присутствующих шумовых движений самой линии моментума, а не потому, что фильтр опередил время. Подобные исследования других индикаторов (от простого MA до JJMA) подтверждают, что эффект опережающего сглаживания можно наблюдать на каждом из них. И чем меньше установленный период, тем чаще это проявляется. Последние наработки показывают, что эффект можно усилить. Все зависит только от способа формирования вектора вероятных значений и его анализа.


Эффект кобры

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

Видео 3. Опережающее сглаживание и эффект кобры


Ошибки, опережающие тенденцию

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

Давайте посмотрим, как работает алгоритм при фильтрации вот таких опережающих тенденцию ошибок. Для этого при запуске индикатора необходимо установить параметр "Filter" в "Test No.2 Smoothing". Работа кластерного фильтра во время этого теста разделена на две части.

В коротком имени индикатора "GMomentum(Параметр 1, Параметр 2)", отображаемом в подокне графика, в скобках есть два параметра. Если второй параметр равен -1, то происходит попытка исправить (сгладить) ошибки, опережающие тенденцию. Если второй параметр равен или выше нуля, то подключаются настройки для получения опережающего сглаживания.

На видео ниже можно увидеть работу фильтра при изменении его чувствительности от минимума до приемлемого значения и обратно. В индикаторе для управления чувствительностью (при активном окне индикатора) нажимайте клавиши Up и Down, чтобы добиться подобного эффекта как на видео.

Видео 4. Фильтрация ошибок, опережающих тенденцию.

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

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

На следующем видео обратите внимание на то, что фильтр "съедает" сильные пики исходной линии моментума и практически без запаздывания отрисовывает тенденцию, которая, к слову, близка к движению цены и более гладкая. Объяснение, почему это так, есть в статье про индикаторы Уильяма Блау.

Видео 5. Сглаживание пиков исходной линии моментума.

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


Импульсная характеристика

Исследования характеристик моментума со встроенным фильтром могут оказаться весьма занятными. Например, импульсная характеристика хорошо демонстрирует, как и куда исчезают пики на линии индикатора. Для теста необходимо установить параметр "Filter" в "Test No.3 Impulse". Во время теста на каждом 1024 баре подается единичный импульс. После старта индикатора найдите этот момент на графике. Он должен выглядеть так:

Рисунок 3. Импульсная характеристика моментума

Рисунок 3. Импульсная характеристика моментума

При запуске индикатора фильтр отключен. Поэтому вы увидите два пика на синей и красной линии. Один пик будет в момент единичного импульса и равен ему, другой - направлен в обратную сторону через указанное количество периодов. Именно так выглядит импульсная характеристика "голого" моментума. Далее, с помощью клавиш Up и Down постепенно увеличивайте или уменьшайте чувствительность фильтра. У вас должно получиться нечто подобное:

Видео 6. Импульсная характеристика моментума

Как видите, фильтр постепенно под корень "съедает" второй пик и абсолютно не трогает первый. Фильтр полностью исправляет то, что натворил моментум и в точности воссоздает исходную картину: единичный импульс в чистом поле. Нет никакого запаздывания. Нет искажения амплитуды единичного импульса и его формы. Что это? Работа идеального фильтра?


Идеальный фильтр

Есть один существенный фактор, который не позволяет сходу считать рассматриваемый фильтр идеальным. Но об этом чуть ниже.

Существует фиксированная идея, что идеального фильтра не может быть. Что все фильтры (индикаторы) запаздывают. Тогда как объяснить полученные результаты? Все они представлены как то, что можно наблюдать. Хитрая работа программиста? Пожалуй, можно схитрить в коде с единичным импульсом. Но ведь это все проявляется на любых котировках. При этом нет необходимости как-то настраивать или перенастраивать индикатор под каждый торговый инструмент.

Когда мы строим фильтр из физических объектов (конденсатор, индуктивность и т.п.), идеального фильтра не может быть. Об этом хорошо позаботилась сама природа. Но когда мы имеем дело с цифровым миром, то разве построение идеального фильтра не возможно? Естественно, что ответ нужно давать, пренебрегая физическими ограничениями вычислительных систем (точность, скорость расчета и т.п.).

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


Заключение

Надеюсь, что материал, представленный в статье, разрушит некоторые стереотипы в отношении построения цифровых фильтров (индикаторов).

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

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

Прикрепленные файлы |
clusterfilter.mq5 (6.67 KB)
Последние комментарии | Перейти к обсуждению на форуме трейдеров (43)
[Удален] | 13 янв. 2014 в 14:52
vlad1949:

Набор наукоподобных слов без абсолютно никакого смысла. Где здесь кластеры? Где вероятные будущие значения?


 После вашей критики перечитал еще раз статью и понял что вы сильно ошибаетесь.

Автор фильтра не только смог доступно объяснить о своей разработке, но и предоставить наглядно в роликах как это работает.

И надо сказать очень впечатляюще выглядит, сами посмотрите если открытие будет происходить на 1-2 бара раньше(хотя бы по МАшкам), уже будет большой + к профиту.

Lizar: получается этот фильтр можно будет прикрутить к любому индикатору?

Konstantin Gruzdev
Konstantin Gruzdev | 13 янв. 2014 в 16:47
-_-FART:

 Lizar: получается этот фильтр можно будет прикрутить к любому индикатору?

Можно. Надо пробовать, может не получится также интересно, как с моментумом.
[Удален] | 14 янв. 2014 в 11:03

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

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

Konstantin Gruzdev
Konstantin Gruzdev | 14 янв. 2014 в 20:53
GT788:

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

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

Можно и это посмотреть. Отметил себе, займусь этим, но не сейчас. 
Евгений
Евгений | 14 июн. 2020 в 11:15

Так а почему бы не использовать метод локальной аппроксимации https://chaos.phys.msu.ru/loskutov/PDF/Los_Kotl_Zhur.pdf ?

Он же позволяет не только предсказывать данные, но и фильтровать. И, теоретически, задержки у такого фильтра быть не должно вообще!

Идея очень похожа. Только тут не надо переключаться между разными фильтрами для разных участков временного ряда. Здесь ищутся в истории участки похожие на последние отсчёты ряда, а потом эти найденные участки усредняются по ансамблю. Это и есть результат фильтрации. Главное, чтобы было достаточно данных в истории, иначе просто может не найтись похожих участоков.

Оффлайновые графики и новый MQL4 Оффлайновые графики и новый MQL4
В новом MQL4 изменился формат хранения исторических данных и появилась соответствующая структура MqlRates для удобного хранения значений Time, Open, Low, High, Close и Volume. За многие годы трейдеры написали на MQL4 свои программы, которые собирают и записывают собственные данные в HST-файлы для создания оффлайновых графиков. Каждый трейдер может быть уверен - все ранее скомпилированные EX4-файлы будут работать в новом терминале MetaTrader 4 так же, как и раньше.
Рецепты MQL5 - Разработка мультивалютного индикатора волатильности на MQL5 Рецепты MQL5 - Разработка мультивалютного индикатора волатильности на MQL5
В этой статье рассмотрим разработку мультивалютного индикатора волатильности. Начинающие разработчики на MQL5 могут столкнуться с некоторыми сложностями при разработке мультивалютных индикаторов, но после прочтения этой статьи все станет намного проще. Основные вопросы при разработке мультивалютного индикатора относятся к синхронизации данных других символов по отношению к текущему символу, решению проблемы отсутствия части данных индикатора, определению начала "истинных" баров таймфрейма. Все это будет подробно рассматриваться в статье.
SQL и MQL5: Работаем с базой данных SQLite SQL и MQL5: Работаем с базой данных SQLite
Данная статья рассчитана на программистов, проявившим интерес к использованию SQL в своих проектах. В статье читателям представляется функциональность SQLite, а также рассматриваются ее преимущества. Статья не требует знание функций SQLite, но минимальные знания SQL приветствуются.
Основы программирования на MQL5 - Списки Основы программирования на MQL5 - Списки
Новая версия языка программирования торговых стратегий - MQL [MQL5] - имеет более эффективный и мощный инструментарий по сравнению с предыдущей [MQL4]. И это преимущество прежде всего относится к средствам объектно-ориентированного программирования. В данной статье рассматривается возможность использования такого пользовательского типа данных, относящегося к сложному, как узлы и списки. Приводится пример использования списков при программировании практических задач в MQL5.