English 中文 Español Deutsch 日本語 Português
Технический индикатор своими руками

Технический индикатор своими руками

MetaTrader 5Примеры | 25 августа 2022, 07:36
2 978 3
Aleksej Poljakov
Aleksej Poljakov

Введение

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


Правило #1

Суть всех линейных индикаторов довольно проста и сводится к выполнению четырех шагов:

  1. Берем заранее определенное количество отсчетов цены;
  2. Умножаем их на какие-то коэффициенты;
  3. Суммируем полученные результаты;
  4. Получившееся значение выводим на график.

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

Индикаторы, которые устанавливаются на основной график, можно выразить простой формулой (в данном случае в качестве коэффициентов мы используем целые числа):

Для того, чтобы перевести коэффициенты в вещественные числа, нужно сделать простое преобразование:

Тогда основное правило для таких индикаторов сводится к простому утверждению: «сумма коэффициентов должна быть равна единице». То есть:

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

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

input string InpCoefficient="1,1,1,1,1";//переменная для коэффициентов индикатора

В качестве разделителя между коэффициентами мы будем использовать запятую.

Внутри функции OnInit() выполним следующие действия (в коде есть еще какой-то загадочный центр, его предназначение мы узнаем позже):

   string s[];                                                  //массив для подстрок с коэффициентами
   size=StringSplit(InpCoefficient,StringGetCharacter(",",0),s);//получаем подстроки и их количество
   
   ArrayResize(coeff,size);  //готовим массив для коэффициентов индикатора
   double denom=0,center=0;  //переменные для нормализации значений и вычисления центра индикатора
   for(int i=0; i<size; i++) // записываем коэффициенты
     {
      coeff[i]=StringToDouble(s[i]);
      denom=denom+coeff[i];
     }

   if(denom==0) //если нормировочный член равен 0, значит, что-то пошло не так
     {
      Alert("Wrong odds!");
      return(INIT_FAILED);
     }

   for(int i=0; i<size; i++) //нормируем коэффициенты и вычисляем центр индикатора
     {
      coeff[i]=coeff[i]/denom;
      center=center+coeff[i]*(i+1);
     }

   Print((int)MathRound(center));//выведем отсчет ближайший к центру индикатора

Ну, а теперь рассмотрим несколько примеров.

Первая последовательность. Возьмем пять отсчетов цены с одинаковыми коэффициентами: 1,1,1,1,1. Тогда у нас получится простая скользящая средняя. А формула индикатора в этом случае будет такой: (price[0] + price[1] + price[2] + price[3] + price[4])/5.

Вторая последовательность. Для получения этой последовательности мы возьмем пять скользящих средних с периодами от одного до пяти, и найдем их среднее. То есть наши исходные данные будут такими:

price[0]/1 +
(price[0] + price[1])/2 +
(price[0] + price[1] + price[2])/3 +
(price[0] + price[1] + price[2] + price[3])/4 +
(price[0] + price[1] + price[2] + price[3] + price[4])/5.

А их суммирование даст нам коэффициенты нашей последовательности – 137,77,47,27,12.

Третья последовательность. Для этой последовательности мы возьмем пять скользящих средних со сдвигом на один шаг назад. А потом найдем их среднее. То есть в результате у нас получится среднее из нескольких скользящих средних. Исходные данные:

(price[0] + price[1] + price[2] + price[3] + price[4])/5 +
(price[1] + price[2] + price[3] + price[4] + price[5])/5 +
(price[2] + price[3] + price[4] + price[5] + price[6])/5 +
(price[3] + price[4] + price[5] + price[6] + price[7])/5 +
(price[4] + price[5] + price[6] + price[7] + price[8])/5.

В результате у нас получится треугольное окно с коэффициентами – 1,2,3,4,5,4,3,2,1.

В качестве коэффициентов индикатора можно использовать различные математические последовательности. Вот пример еще нескольких индикаторов. Один из них построен на числах Фибоначчи: 34,21,13,8,5,3,2,1,1. Другой индикатор построен также на числах Фибоначчи, но из них построена симметричная конструкция: 1,1,2,3,5,3,2,1,1. А в основе третьего индикатора лежит ряд треугольника Паскаля: 1,8,28,56,70,56,28,8,1.

Коэффициенты для индикатора можно найти и в Энциклопедии целочисленных последовательностей. В 2014 году был проведен конкурс на самую красивую новую последовательность. Победили три последовательности - A229037, A235265, A235383. Потом одна из этих последовательностей даже получила собственное имя – «forest fire». Эта последовательность интересна тем, что она избегает линейных трендов. А вот как выглядят индикаторы, построенные на их основе.

В коэффициенты индикаторов можно преобразовывать и слова. Возьмем название самой популярной торговой платформы MetaTrader 5. В качестве коэффициентов возьмем порядковый номер каждой буквы. Тогда у нас получится последовательность: 13,5,20,1,20,18,1,4,5,18,5.
Эту торговую платформу выпускает MetaQuotes Software Corp. Опустим пробелы и точку. Получится последовательность: 13,5,20,1,17,21,15,20,5,19,19,15,6,20,23,1,18,5,3,15,18,16.

Индикаторы на основе этих последовательностей выглядят так.

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

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

В зависимости от центра и периода индикатора, мы можем отнести его к одному из трех типов. Пусть period — период индикатора.

  • Трендовый:            center < period/3
  • Сглаживающий:      period/3 <  center < 2*period/3
  • Контртрендовый:    2*period/3 <  center

    Правило #1а

    Как мы видели, выполняя правило #1, мы всегда получали вполне работоспособный технический индикатор. Но тут возникает вопрос: могут ли быть в индикаторе отрицательные коэффициенты? Тут вступает в действие дополнительное правило, которое звучит так: абсолютное значение любого коэффициента должно быть меньше их суммы. Или, в символьном виде для целочисленных и вещественных коэффициентов:

    Это ограничение связано с устойчивостью индикатора. Для примера возьмем несколько последовательностей, полученных из линейно-взвешенной скользящей средней: 5,4,3,2,1 – синяя линия, 5,4,3,2,-1 – зеленая, 5,4,3,-2,-1 – желтая и 5,4,-3,-2,-1 – красная.

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


    Небольшая пауза

    Правило для коэффициентов дает нам возможность не только создавать новые индикаторы, но и модифицировать классические варианты. Для примера возьмем экспоненциальную скользящую среднюю. Её формула проста и всем известна:

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

    То есть у нас получилась геометрическая прогрессия бесконечной длины.

    Небольшое замечание: то, что в обиходе мы называем периодом EMA, на самом деле является периодом простой скользящей средней, центр которой совпадает с центром EMA.

    Давайте попробуем ограничить длину прогрессии. Тогда у нас получится фильтр, который мы будем называть геометрическим. Самая интересная особенность этого фильтра заключается в том, что его поведение зависит как от коэффициента сглаживания, так и от его периода. При этом по мере увеличения периода геометрический фильтр становится всё более похожим на классическую EMA. Например, возьмем коэффициент экспоненциального сглаживания равным a = 0.1. Тогда период EMA можно рассчитать так:

    А теперь сравним поведение EMA и геометрического фильтра с тем же коэффициентом сглаживания, но с периодом равным 10.

    Теперь попробуйте постепенно увеличивать период геометрического фильтра, и вы увидите, как он постепенно приближается к EMA.

    Кроме геометрической прогрессии есть еще и арифметическая. В терминале MetaTrader арифметическая прогрессия реализована в виде линейно-взвешенной средней. Давайте внесем в нее небольшие изменения — введем шаг арифметической прогрессии. С его помощью мы сможем получить индикатор со значениями от SMA до LWMA.

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


    Оконные функции для чайников

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

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

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

    Пусть, iPeriod — период нашего будущего индикатора. Тогда, центр индикатора может принимать значения с 1 по iPeriod с шагом равным 0.5. То есть, iCenter может принимать значения 1, 1.5, 2, ... iPeriod.

       int period=MathMax(2,iPeriod),     //проверяем длину индикатора на мин. допустимое значение
           step=(int)MathRound(2*iCenter);//кол-во шагов по 0.5 до центра индикатора
    
       double center=0.5*step;      //центр индикатора
       if(center<1 || center>period)//проверяем имеет ли центр допустимое значение
          center=0.5*(period+1);
    

    Теперь нам остается определить ширину окна и найти его смещение. Это смещение позволяет совместить центр индикатора и оконной функции.

       int width=(int)(2*center),//ширина оконной функции
           shift=1;              //смещение для совмещения центров индикатора и окна
    
       if(2*center<=period)//если центр смещен к началу индикатора
         {
          width=2*period-(int)(2*center)+2;
          shift=period-(int)(2*center)+2;
         }

    Давайте ограничимся окном пятого порядка. Тогда нам потребуется задать до пяти коэффициентов C1 – C5. В качестве коэффициентов можно использовать любые числа. При этом должно обязательно выполняться условие – каждый следующий коэффициент должен быть меньше предыдущего. То есть C1 > C2 > C3 > C4 > C5. Выполнение этого условия необходимо для корректного расчета нормирующего значения.

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

    Окно Ханна: C1 = 1.

    Окно с линейным спадом коэффициентов: C1 = 5, C2 = 4, C3 = 3, C4 = 2, C5 = 1.

    Окно с числами Фибоначчи: C1 = 8, C2 = 5, C3 = 3, C4 = 2, C5 = 1.

    Кстати, при некоторых значениях коэффициентов у нас могут получаться оконные функции с частично отрицательными значениями. Это делает их похожими на классическое окно с плоским верхом: C1 = 3, C2 = 2.

    Оконные функции для продвинутых

    Для построения оконных функций можно использовать обобщенный адаптивный полином. Его формула выглядит так:

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

    С помощью этого полинома можно получить как уже известные оконные функции, так и нечто необычное. Например, при C0 = 1 у нас получится прямоугольное окно (SMA).

    Треугольное окно: C0 = 1, C1 = 1, P1 = 1.

    Окно Уэлча: C0 = 1, C1 = 1, P1 = 2.

    А можно получить и нечто необычное. Окно с числами Фибоначчи и линейным ростом степени (коэффициент C0 оставляем свободным, тогда он примет значение 19): C1 = 8, P1 = 1, C2 = 5, P2 = 2, C3 = 3, P3 = 3, C4 = 2, P4 = 4, C5 = 1, P5 = 5.


    Правило #2

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

    Работоспособный осциллятор проще всего сделать на основе двух индикаторов. Тогда формула осциллятора будет:

    При этом нужно соблюдать условие: индикаторы должны быть разными. Например, так выглядит осциллятор, построенный на прямоугольном и треугольном окнах: 1,1,1,1,1 и 1,2,3,2,1.

    Также можно использовать одну и ту же оконную функцию, но разной длины: 1,2,3,2,1 и 1,2,3,4,5,4,3,2,1.

    А может быть и тот же индикатор, но сдвинутый на несколько отсчетов назад: 5,4,3,2,1 и 0,0,0,5,4,3,2,1 (нули во второй последовательности осуществляют сдвиг на три отсчета):

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

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

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

    Параметры тестирования: символ EURUSD, таймфрейм H1, интервал тестирования 2021.01.01 - 2021.12.31.
    Результаты тестирования приведены в таблице. Для индикатора Crazy, учитывая его особенности, было сделано 5 тестов.

    TypeInd Total Net Profit
    Gross Profit
    Gross Loss
    Total Trades
    SMA -112.15
    338.69
    -450.84
    340
    TMA 4.64
    422.06
    -417.42
    372
    MT4 -39.43
    402.26
    -441.69
    444
    MT5 -45.27
    395.20
    -440.47
    438
    Crazy 1 -82.13
    432.68
    -514.81
    640
    Crazy 2 -91.15 469.24   -560.39 662
    Crazy 3  -57.01 454.13   -511.14 612
    Crazy 4  -39.16 487.40 -526.56  673
    Crazy 5 -21.45 471.97 -493.42 666

    Как мы можем видеть, ни один из вариантов впечатляющих результатов не показал. Хотя немного порадовал индикатор Crazy. Разница между наилучшей и наихудшей сделкой в 4 раза. Этот индикатор на самом деле сумасшедший.

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

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

    TypeInd Total Net Profit
    Gross Profit
    Gross Loss
    Total Trades
    SMA 45.64
    325.11
    -279.47
    138
    TMA 156.03
    466.26
    -310.23
    306
    MT4 -133.56
    296.25
    -429.81
    212
    MT5 -192.40
    273.05
    -465.45
    203
    Crazy 1 114.30
    564.00
    -449.70
    409
    Crazy 2 -93.57 421.01    -514.58 413
    Crazy 3  -31.83 445.27    -477.10 446
    Crazy 4  3.87 451.39 -447.52  431
    Crazy 5 -8.04 458.58 -466.62 409

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

    Заключение

    Как вы могли убедиться, разработка технического индикатора может оказаться довольно увлекательным занятием. Во вложении:

    1. Base Indicator — шаблон, позволяющий строить индикаторы по их коэффициентам.
    2. OEIS — индикатор, построенный на самых красивых последовательностях. Все последовательности имеют ограничения по периоду.
    3. Crazy — индикатор, использующий случайные коэффициенты.
    4. Arithmetic Geometric Filter — индикатор, построенный на арифметической и геометрической прогрессиях.
    5. Window Functions for Dummies — скрипт, позволяющий рассчитать оконную функцию на основе косинусного полинома. Скрипт сохраняет полученные коэффициенты в текстовом файле в папке Files.
    6. Window Functions for Advanced — скрипт, рассчитывающий коэффициенты индикатора с помощью обобщенного адаптивного полинома. Результат расчетов также сохраняется в файл.
    7. Basic Oscillator — шаблон для осциллятора, построенного по двум индикаторам.
    8. EA Indicator — эксперт, открывающий позиции по осцилляторам. Параметр Control определяет количество осцилляторов для анализа.


    Последние комментарии | Перейти к обсуждению на форуме трейдеров (3)
    Tretyakov Rostyslav
    Tretyakov Rostyslav | 25 авг. 2022 в 08:29
    Отличная статья. Спасибо.
    Aleksej Poljakov
    Aleksej Poljakov | 25 авг. 2022 в 14:15
    Tretyakov Rostyslav #:
    Отличная статья. Спасибо.

    Спасибо. В ближайшее время попробую подготовить материал по адаптирующимся индикаторам.

    Oleh Fedorov
    Oleh Fedorov | 2 сент. 2022 в 09:37

    Вот зачем такое название, а?

    Работа очень серьезная, мне было действительно интересно знакомиться с выкладками.

    Но вот название намекает, что тут - просто инструкция "А давайте откроем мастер и запишем параметры в нужные окошки"...

    Можно поменять? Что-нибудь по типу "Универсальный индикатор своими руками" или "Индикаторы и теория сигналов"?

    Или уже слишком сложно?

    Разработка торговой системы на основе стандартного отклонения Разработка торговой системы на основе стандартного отклонения
    Представляю вашему вниманию новую статью из серии, в которой мы учимся создавать торговые системы по показателям самых популярных технических индикаторов и пишем на их основе системы на языке MQL5 для использования в MetaTrader 5. В этой статье мы узнаем, как разработать торговую систему по индикатору стандартного отклонения.
    Нейросети — это просто (Часть 26): Обучение с подкреплением Нейросети — это просто (Часть 26): Обучение с подкреплением
    Продолжаем изучение методов машинного обучения. Данной статьей мы начинаем еще одну большую тему "Обучение с подкреплением". Данный подход позволяет моделям выстаивать определенные стратегии для решения поставленных задач. И мы рассчитываем, что это свойство обучения с подкреплением откроет перед нами новые горизонты построения торговых стратегий.
    DoEasy. Элементы управления (Часть 16): WinForms-объект TabControl — несколько рядов заголовков вкладок, режим растягивания заголовков под размеры контейнера DoEasy. Элементы управления (Часть 16): WinForms-объект TabControl — несколько рядов заголовков вкладок, режим растягивания заголовков под размеры контейнера
    В статье продолжим разработку элемента управления TabControl, и реализуем расположение заголовков вкладок со всех четырёх сторон элемента для всех режимов задания размера заголовков: "Normal", "Fixed" и "Fill To Right".
    Рыночная математика: прибыль, убыток, издержки Рыночная математика: прибыль, убыток, издержки
    В данной статье я покажу вам, как считать полную прибыль или убыток любого трейда, включая комиссию и своп. Составим точнейшую математическую модель, напишем по ней код и сравним ее с эталоном, а также попытаемся залезть под капот основной функции MQL5 для вычисления прибыли и докопаемся до сути всех необходимых величин из спецификации.