Простые методики прогнозирования направления японских свечей

Evgeniy Logunov | 18 августа, 2009

Введение

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

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

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

Внимание! Прилагаемые к статье советники предназначены только для работы в тестере.

В первом методе предполагается, что направление следующей свечи совпадёт с направлением предыдущей. Во втором - что направление следующей свечи будет противоположным направлению предыдущей. Преимущество этих методов - в их простоте. Они будут рассмотрены в разделе "Наивные методы".

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


Исходные данные для прогнозирования

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

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

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

// получение направления свечи
double GetCandleDirection(int shift) {
   double diff=Close[shift]-Open[shift];
   if (diff>0.0) {
      return (DIRECTION_UP);
   }
   else if (diff<0.0) {
      return (DIRECTION_DOWN);
   }
   else /*if (diff==0.0)*/ {
      return (DIRECTION_NONE);
   }
}

В функцию передаётся смещение свечи (shift). Функция вычисляет разность цен её открытия и закрытия, после чего в зависимости от знака полученного числа возвращает значение одной из трёх констант - DIRECTION_UP, DIRECTION_DOWN или DIRECTION_NONE. Эти константы обозначают случаи "направление вверх", "направление вниз" и "отсутствие движения", соответственно.

Следует подчеркнуть, что все рассматриваемые методы прогнозирования предусматривают один особый случай - если направление предыдущей свечи не определено (вызов GetCandleDirection(1) вернул значение DIRECTION_NONE) - в качестве прогноза следующей свечи будет возвращено также неопределённое направление. В таком случае, советники, написанные для тестирования методов, не совершали вход в рынок.

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

// определения возможных направлений свечей
#define DIRECTION_NONE 0
#define DIRECTION_UP 1
#define DIRECTION_DOWN -1

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


Направления свечей - поведение во времени.

Как показывает индикатор, направления свечей довольно часто меняют поведение: они то чередуются, то совпадают для нескольких свечей подряд. Ясно, что прогнозирование направления даже одной свечи - непростая задача.

Теперь перейдём к рассмотрению и детальному анализу предлагаемых методов.


Наивные методы

Начнём с рассмотрения первых двух методов:

  1. Направление следующей свечи совпадёт с направлением предыдущей.
  2. Направление следующей свечи будет противоположным направлению предыдущей.

Для проверки эффективности обоих методов написан советник (файл CandlePredTest_naive.mq4 в прилагаемом архиве) и проведено его тестирование.

Советник работает по ценам открытия. На каждом новом баре он закрывает все позиции, которые открыл (фиксирует прибыль или убытки), и открывает позицию в соответствии с предполагаемым направлением следующей (только что открытой) свечи. Прогнозирование направления следующей свечи осуществляет функция ModelPredict:

// предсказание по используемой модели
int ModelPredict() {
   if (modelState==STATE_NORMAL) {
      return (GetCandleDirection(1));
   }
   else /*if (modelState==STATE_REVERSE)*/ {
      return (-GetCandleDirection(1));
   }
}

Функция реализует два метода прогнозирования. Выбор происходит в зависимости от значения переменной modelState.

В случае, когда переменная modelState принимает значение STATE_NORMAL - прогнозирование выполняется в соответствии с первым методом: функция запрашивает направление предыдущей свечи при помощи вызова GetCandleDirection(1) и возвращает его в качестве направления следующей свечи.

Второй метод прогнозирования используется, если переменная modelState равна STATE_REVERSE. Предполагаемое в таком случае вычисление противоположного направления осуществляется сменой знака, т.е. функция ModelPredict возвращает значение -GetCandleDirection(1).

В функции ModelPredict не используется явное сравнение с константой STATE_REVERSE, соответствующей второму методу. В коде советника предполагается, что введённые пользователем данные всегда корректны и переменная modelState всегда принимает одно из двух значений - STATE_NORMAL или STATE_REVERSE. Для осуществления явного сравнения нужно убрать скобки комментария "/*" и "*/" из тела функции, тем самым добавив в код ещё один условный оператор if.

Переменная modelState отсутствует в списке параметров советника, однако её значение при старте советника копируется из внешней переменной initialModelState:

// состояние модели
extern int initialModelState=STATE_NORMAL;

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

// определения состояний модели
#define STATE_NORMAL 0
#define STATE_REVERSE 1

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

Для тестирования советника приняты следующие условия:

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

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

Чистая прибыль:


M1 M5 M15 M30 H1 H4 D1
USDCHF -9902 -9900 -9903 -9907 -9901 -9900 -9927
GBPUSD -9868 -9864 -9869 -9887 -9873 -9868 -9924
EURUSD -9921 -9957 -9949 -9941 -9934 -9910 -9879
USDJPY -9900 -9905 -9900 -9905 -9935 -9926 -9904
AUDUSD -9952 -9957 -9966 -9962 -9961 -9956 -10000
USDCAD -9901 -9903 -9901 -9900 -9902 -9904 -8272
EURGBP -9862 -9861 -9864 -9869 -9875 -9871 -5747
EURCHF -9862 -9865 -9865 -9874 -9869 -9862 -5750
EURJPY -9866 -9877 -9964 -9877 -9869 -9867 -10000
GBPJPY -9848 -9841 -9840 -9845 -9848 -9870 -9849
GBPCHF -9891 -9885 -9850 -9844 -9857 -9856 -9891
EURAUD -9865 -9863 -9868 -9874 -9861 -9891 -10000


Процент прибыльных сделок:


M1 M5 M15 M30 H1 H4 D1
USDCHF 19.55 27.82 31.50 38.18 39.86 43.29 43.95
GBPUSD 21.18 27.81 30.29 33.81 35.20 41.39 46.71
EURUSD 26.06 33.20 34.59 37.55 41.64 43.73 44.37
USDJPY 19.28 31.68 34.13 35.48 39.04 42.99 46.85
AUDUSD 19.71 21.30 26.25 27.20 33.15 39.96 44.69
USDCAD 21.88 25.13 27.59 31.79 33.07 39.48 46.40
EURGBP 21.78 28.90 31.49 34.55 35.24 42.11 47.04
EURCHF 28.70 27.86 27.85 31.13 32.90 39.08 47.65
EURJPY 23.69 30.62 35.81 38.89 39.06 44.04 48.16
GBPJPY 10.11 19.47 33.48 37.39 37.75 43.09 47.42
GBPCHF 23.17 23.95 30.84 33.50 36.03 42.43 47.90
EURAUD 1.65 7.35 16.55 22.24 27.65 36.11 44.64

Тестирование первого метода показало неудовлетворительные результаты. По всем инструментам независимо от периода происходит слив депозита; при этом количество прибыльных сделок возрастает с увеличением периода, но не превышает 50%.

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

Чистая прибыль:


M1 M5 M15 M30 H1 H4 D1
USDCHF -9900 -9912 -9902 -9917 -9915 -9901 +83
GBPUSD -9864 -9866 -9869 -9874 -9870 -9911 -5565
EURUSD -9920 -9917 -9923 -9947 -9922 -9886 +4249
USDJPY -9906 -9901 -9906 -9900 -9900 -9928 +2003
AUDUSD -9955 -9956 -9957 -9956 -9969 -9947 +1203
USDCAD -9900 -9900 -9900 -9900 -9901 -9906 -3129
EURGBP -9868 -9862 -9862 -9863 -9867 -9902 -9867
EURCHF -9863 -9861 -9863 -9862 -9869 -9869 -6556
EURJPY -9861 -9864 -9866 -9868 -9897 -9886 -10000
GBPJPY -9850 -9887 -9905 -9857 -9969 -9848 -9964
GBPCHF -9846 -9841 -9842 -9842 -9886 -9914 -9850
EURAUD -9870 -9866 -9874 -9910 -9872 -9872 -2411


Процент прибыльных сделок:


M1 M5 M15 M30 H1 H4 D1
USDCHF 18.38 27.41 33.76 37.46 42.28 46.71 52.15
GBPUSD 18.59 27.71 34.07 39.01 43.79 47.33 49.39
EURUSD 23.37 33.88 41.05 43.80 43.56 48.16 52.56
USDJPY 16.88 30.39 38.13 40.29 43.94 46.62 49.34
AUDUSD 18.84 22.52 25.39 29.83 36.36 43.51 49.84
USDCAD 22.44 24.04 27.07 31.06 35.69 43.51 49.84
EURGBP 20.52 28.89 35.18 38.82 42.41 45.82 45.55
EURCHF 27.43 31.82 32.80 35.05 36.74 43.89 46.04
EURJPY 18.79 28.15 37.09 39.80 43.05 44.15 46.92
GBPJPY 10.02 19.76 31.92 38.06 41.84 44.32 47.53
GBPCHF 19.87 27.24 33.72 35.70 39.74 47.59 46.11
EURAUD 1.43 7.66 17.24 26.95 34.46 41.29 47.07

Тестирование второго метода показало неоднозначные результаты. На всех периодах меньше D1 результаты примерно совпали с результатами, полученными для первого метода. На периоде D1 советник на четырёх инструментах из двенадцати получил прибыль; при этом количество прибыльных сделок близко к 50%, а в двух случаях достигает 52%.

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


Адаптивный метод

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

Эффективность этого метода проверялась при помощи тестирования советника (файл CandlePredTest_adaptive.mq4 в прилагаемом архиве).

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

// рабочая функция советника
int start() {
   // открытие позиций выполняется один раз на каждом баре
   if (!IsNewBar()) {
      return (0);
   }
   // закрываем все открытые позиции
   TradeClosePositions(DIRECTION_UP);
   TradeClosePositions(DIRECTION_DOWN);
   // обновляем состояние модели
   if (prediction!=DIRECTION_NONE) {
      ModelUpdate(prediction==GetCandleDirection(1));
   }
   // предсказываем цвет следующей свечи
   prediction=ModelPredict();
   if (prediction==DIRECTION_NONE) {
      return (0);
   }
   // открываем позицию в нужном направлении
   TradeOpenPosition(prediction,"");
   return (0);
}

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

Замену одного наивного метода прогнозирования другим осуществляет функция ModelUpdate, которой в качестве параметра передаётся флаг корректности прогноза (prediction==GetCandleDirection(1)).

// обновление состояния модели
void ModelUpdate(bool correct) {
   // если прогноз был ошибочным - изменить состояние модели
   if (!correct) {
      if (modelState==STATE_NORMAL) {
         modelState=STATE_REVERSE;
      }
      else /*if (modelState==STATE_REVERSE)*/ {
         modelState=STATE_NORMAL;
      }
   }
}

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

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

Тестирование советника проводилось в тех же условиях. Исключение составляет выбор значения переменной initialModelState, которое было фиксированным (STATE_NORMAL).

Чистая прибыль:


M1 M5 M15 M30 H1 H4 D1
USDCHF -9903 -9905 -9902 -9915 -9902 -9907 -3738
GBPUSD -9866 -9875 -9876 -9864 -9867 -9933 -6404
EURUSD -9924 -9924 -9931 -9920 -9920 -9903 -3779
USDJPY -9904 -9900 -9900 -9904 -9920 -9902 -6493
AUDUSD -9955 -9954 -9955 -9995 -9955 -9965 -8649
USDCAD -9903 -9902 -9901 -9911 -9900 -9904 -1525
EURGBP -9861 -9867 -9865 -9862 -9881 -9877 -9913
EURCHF -9861 -9862 -9872 -9881 -9870 -9875 -9258
EURJPY -9861 -9865 -9866 -9868 -9876 -9905 -9880
GBPJPY -9842 -9844 -9867 -9840 -9919 -10000 -9933
GBPCHF -9841 -9843 -9917 -9840 -9893 -9848 -9895
EURAUD -9866 -9869 -9863 -9872 -9867 -9904 -7656


Процент прибыльных сделок:


M1 M5 M15 M30 H1 H4 D1
USDCHF 19.22 26.82 32.29 35.71 40.29 44.15 47.93
GBPUSD 20.12 28.16 32.01 34.87 40.05 41.97 49.39
EURUSD 25.24 32.65 38.32 39.48 41.50 45.81 48.88
USDJPY 19.16 29.48 35.02 37.03 40.19 44.45 47.34
AUDUSD 19.63 21.67 25.76 28.16 32.11 41.11 46.76
USDCAD 22.84 24.46 27.39 29.79 34.44 42.26 48.46
EURGBP 21.44 29.45 33.05 36.55 38.19 41.86 46.23
EURCHF 27.51 29.98 30.92 34.44 34.09 40.87 44.27
EURJPY 21.24 28.56 35.58 38.78 40.50 44.23 47.12
GBPJPY 11.30 19.90 31.91 37.15 36.76 41.11 46.24
GBPCHF 22.00 26.81 32.13 34.38 36.99 43.11 47.16
EURAUD 1.50 6.56 15.14 22.25 31.63 37.96 47.70

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


Заключение

Результаты тестирования, приведённые в статье, показали низкую эффективность рассмотренных методов.