Гэп - доходная стратегия или 50/50?
- Введение
- Какой рынок выбрать?
- Работа с группой символов
- Собираем данные
- Теперь вместе с CGraphic
- Выбор файлов при помощи системного диалога "Открыть файл"
- Статистика по остальным ценным бумагам
- Заключение
Введение
Проверка на рынках ценных бумаг гэпов на таймфрейме D1. Как часто рынок продолжает двигаться в сторону гэпа? А может быть рынок после гэпа разворачивается? На эти вопросы я постараюсь ответить в статье, а для визуализации результатов будут использованы пользовательские графики CGraphic. Выбор файлов с символами производится с помощью системной DLL-функции GetOpenFileName.
Какой рынок выбрать?
Сразу скажу, что гэп интересует меня исключительно на таймфрейме D1.
Очевидно, что самое большое количество гэпов не на Forex символах, а на ценных бумагах. Хотя бы потому, что ценные бумаги торгуются с утра и до вечера, а ночью торги по ним закрыты. Конкретно меня в поисках гэпа интересуют акции: по акциям есть довольно глубокая история. А вот фьючерсы не сильно подходят, так как часто они имеют время жизни 3 или 6 месяцев — этого недостаточно для исследования истории на таймфрейме D1.
Проверить сколько баров на текущем символе и на таймфрейме D1 есть на сервере можно при помощи скрипта "TestLoadHistory.mq5" из раздела справки "Организация доступа к данным". Пример проверки количества баров D1 на символе "ABBV":
Рис. 1. Символ "ABBV"
Порядок действий:
- Сначала нужно сохранить скрипт из справки. Для этого в редакторе кода MetaEditor 5 создаётся новый скрипт (справка: "Создание скрипта"), имя скрипту лучше сразу дать "TestLoadHistory.mq5". Теперь нужно выделить текст скрипта из справки и вставить скопированный текст в скрипт "TestLoadHistory.mq5" (при этом текст из справки должен заменить весь текст в скрипте).
- Скомпилировать получившийся скрипт (после компиляции скрипт станет виден в терминале в окне "Навигатор".
- Запустить скрипт в терминале MetaTrader 5. Раз проверка затевалась для символа "ABBV", значит нужно подготовить график: открыть график символа "ABBV" и сменить таймфрейм на D1. Из окна "Навигатор" взять скрипт и бросить на открытый график символа "ABBV". В параметрах скрипта задать имя символа "ABBV", выбрать таймфрейм D1 и поставить дату 1970 год:
Рис. 2. Запуск скрипта "TestLoadHistory.mq5"
Результат работы скрипта:
TestLoadHistory (ABBV,D1) Start loadABBV,Dailyfrom1970.03.16 00:00:00 TestLoadHistory (ABBV,D1) Loaded OK TestLoadHistory (ABBV,D1) First date 2015.09.18 00:00:00 - 758 bars
— история начинается с 2015 года и в истории есть 758 баров D1. Это достаточное количество для анализа.
Работа с группой символов
Чтобы анализировать и рассчитывать какие-то критерии, необходимо обеспечить сравнение символов из одной группы символов. Как правило, символы в терминале MetaTrader 5 уже распределены по группам (правый клик в окне "Обзор рынка" и пункт "Символы" или сочетание клавиш "Ctrl" + "U"):
Рис. 3. Символы группы NASDAQ(SnP100)
На рисунке выделена группа "NASDAQ(SnP100)" — в эту группу входит символ "ABBV". Самый удобный способ работать с группой символов — это обеспечить запуск скрипта на символе из этой группы. Таким образом для перебора каждой группы необходимо будет вручную из каждой группы открыть график одного символа и потом запустить на графике служебный скрипт "Symbols on symbol tree.mq5" — этот скрипт собирает все символы группы (названия символов) в отдельный файл.
Скрипт "Symbols on symbol tree.mq5" работает по такому алгоритму: получить путь в дереве символов "SYMBOL_PATH"; из полученного пути выделить конечную группу символов (для данного примера это будет группа "NASDAQ(SnP100)"; выбрать все символы из этой группы и сохранить выбранные символы в файл. Название файла — это путь в дереве символов, в котором все символы "/" и "\" заменены на "_" (замена производится скриптом автоматически, и название файла также получается автоматически). После замены символов для группы символов NASDAQ(SnP100)" будет получено такое имя файла: "Stock Markets_USA_NYSE_NASDAQ(SnP100)_.txt".
Зачем нужно каждую группу помещать в отдельный файл? Впоследствии можно будет просто считывать названия символов из файлов групп без перебора всех-всех символов и проводить исследования направления гэпа. В общем, служебный скрипт "Symbols on symbol tree.mq5" убирает рутину ручного отбора символов из конкретной группы символов.
Скрипт "Symbols on symbol tree.mq5"
Подробно остановлюсь на работе скрипта.
ВНИМАНИЕ: только распечатка текста "Everything is fine. There are no errors" во вкладке Эксперты гарантирует, что скрипт отработал без ошибок, и полученный файл с символами можно использовать для дальнейшей работы!
Для сокращения кода файловых операций подключается класс CFileTxt, и работу с тестовым файлом ведёт m_file_txt — объект класса CFileTxt. Скрипт делает свою работу в семь шагов:
//+------------------------------------------------------------------+ //| Symbols on symbol tree.mq5 | //| Copyright © 2018, Vladimir Karputov | //| http://wmua.ru/slesar/ | //+------------------------------------------------------------------+ #property copyright "Copyright © 2018, Vladimir Karputov" #property link "http://wmua.ru/slesar/" #property version "1.000" //--- #include <Files\FileTxt.mqh> CFileTxt m_file_txt; // file txt object //--- string m_file_name=""; // File name //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { //--- STEP 1 string current_path=""; if(!SymbolInfoString(Symbol(),SYMBOL_PATH,current_path)) { Print("ERROR: SYMBOL_PATH"); return; } //--- STEP 2 string sep_="\\"; // A separator as a character ushort u_sep_; // The code of the separator character string result_[]; // An array to get strings //--- Get the separator code u_sep_=StringGetCharacter(sep_,0); //--- Split the string to substrings int k_=StringSplit(current_path,u_sep_,result_); //--- STEP 3 //--- Now output all obtained strings if(k_>0) { current_path=""; for(int i=0;i<k_-1;i++) current_path=current_path+result_[i]+sep_; } //--- STEP 4 string symbols_array[]; int symbols_total=SymbolsTotal(false); for(int i=0;i<symbols_total;i++) { string symbol_name=SymbolName(i,false); string symbol_path=""; if(!SymbolInfoString(symbol_name,SYMBOL_PATH,symbol_path)) continue; if(StringFind(symbol_path,current_path,0)==-1) continue; int size=ArraySize(symbols_array); ArrayResize(symbols_array,size+1,10); symbols_array[size]=symbol_name; } //--- STEP 5 int size=ArraySize(symbols_array); if(size==0) { PrintFormat("ERROR: On path \"%s\" %d symbols",current_path,size); return; } PrintFormat("On path \"%s\" %d symbols",current_path,size); //--- STEP 6 m_file_name=current_path; StringReplace(m_file_name,"\\","_"); StringReplace(m_file_name,"/","_"); if(m_file_txt.Open("5220\\"+m_file_name+".txt",FILE_WRITE|FILE_COMMON)==INVALID_HANDLE) { PrintFormat("ERROR: \"%s\" file in the Data Folder Common folder is not created",m_file_name); return; } //--- STEP 7 for(int i=0;i<size;i++) m_file_txt.WriteString(symbols_array[i]+"\r\n"); m_file_txt.Close(); Print("Everything is fine. There are no errors"); //--- } //+------------------------------------------------------------------+
Алгоритм работы скрипта:
- STEP 1: для текущего символа определяется SYMBOL_PATH — путь в дереве символов;
- STEP 2: полученный путь разбирается на подстроки с разделителем "\";
- STEP 3: заново собираем текущий путь, но уже без последней подстроки, так как последняя подстрока — это название символа;
- STEP 4: цикл по всем-всем доступным символам; если у символа путь в дереве символов совпадает с текущим путём, выделяем название символа и добавляем в массив найденных символов;
- STEP 5: проверяем размер массива найденных символов;
- STEP 6: формируем имя файла (удаляем из имени символы "/" и "\", создаём файл;
- STEP 7: записываем в файл наш массив найденных символов и закрываем файл.
Обратите внимание на STEP 6: файл создаётся в папке "5220" в каталоге общих файлов (используется флаг FILE_COMMON).
Также необходимо проследить, что работа скрипта прошла без ошибок: во вкладке "Эксперты" должна появиться надпись "Everything is fine. There are no errors. Create file:". И в следующей строке будет распечатано имя файла — можно скопировать это имя и вставить в скрипт "Getting gap statistics ...". Ниже пример удачного создания файла:
On path "Stock Markets\USA\NYSE/NASDAQ(SnP100)\" 100 symbols
Everything is fine. There are no errors. Create file:
Stock Markets_USA_NYSE_NASDAQ(SnP100)_
В результате получим файл (в данном примере Stock Markets_USA_NYSE_NASDAQ(SnP100)_), в котором в каждой новой строке стоит один символ. Первые пять строк этого файла:
AAPL ABBV ABT ACN AGN
Собираем данные
Получение исторических данных OHLC по символам и расчёт статистики выполняет главный скрипт "Getting gap statistics.mq5". По каждому символу заполняется структура SGapStatistics:
struct SGapStatistics { string name; // symbol name int d1_total; // total number of D1 bars int gap_total; // total number of gaps int gap_confirmed; // gap was confirmed };
name — имя символа
d1_total — количество баров D1 по символу
gap_total — количество обнаруженных гэпов
gap_confirmed — количество подтверждённых гэпов (например, день открылся гэп вверх и день закрылся как бычий бар)
Для получения цен OHLC по каждому символу самая подходящая функция — это "CopyRates". Использоваться будет третья форма — по начальной и конечной датам требуемого интервала времени. В качестве начального времени берётся расчетное текущее время торгового сервера TimeTradeServer плюс одни сутки, а конечная дата — это 1 января 1970 года.
Остаётся решить вопрос, как обработать ошибку (в результате запроса возвращается "-1") или как определить, что в результате запроса были возвращены не все данные (например, ещё не всё данные выкачаны с сервера). Можно пойти простым путём (запрос — пауза N — секунд — снова запрос) или правильным. Правильный путь базируется на доработке скрипта "TestLoadHistory.mq5" из раздела справки "Организация доступа к данным".
Результаты выполнения запроса скрипта перечислены ниже:
switch(res) { case -1 : Print("Неизвестный символ",InpLoadedSymbol); break; case -2 : Print("Запрошенных баров больше, чем можно отобразить на графике"); break; case -3 : Print("Выполнение было прервано пользователем"); break; case -4 : Print("Индикатор не должен загружать собственные данные"); break; case -5 : Print("Загрузка окончилась неудачей"); break; case 0 : Print("Все данные загружены"); break; case 1 : Print("Уже имеющихся данных в таймсерии достаточно"); break; case 2 : Print("Таймсерия построена из имеющихся данных терминала"); break; default : Print("Результат выполнения не определен"); }
— то есть результат выполнения меньше нуля — это ошибка. Тогда схема работы будет такая: открываем файл с символами и по каждому символу делаем запрос. Суммируем отрицательные результаты. Если есть хоть один отрицательный результат — выводим сообщение о наличии проблем при запросах. Пользователю в таком случае нужно будет запустить скрипт ещё раз (вероятно, история уже загрузится или построится к тому моменту). Если ошибок нет, то получаем данные OHLC и считаем количество гэпов.
Скрипт "Getting gap statistics.mq5"
Этот скрипт выводит статистику по гэпам во вкладку "Эксперты" терминала. Здесь и далее будет формулировка "Подтверждение гэпа". Подтверждённый гэп означает, что дневной бар закрылся в сторону гэпа, а не подтверждённый гэп — когда дневной бар закрылся в сторону, противоположную гэпу:
Рис. 4. Подтверждённый и не подтверждённый гэпы
Имеет один входной параметр "File name" — это как раз имя файла, который был сформирован вспомогательным скриптом "Symbols on symbol tree.mq5" (если Вы ещё помните, этот файл создаётся в общем папке в директории 5220). Имя файла вводится без указания директории и расширения, например, так:
Рис. 5. Входной параметр скрипта "Getting gap statistics"
Таким образом, для получения статистики необходимо выполнить несколько шагов:
- Определится с группой символов, для которой будет выполняться подсчёт гэпов
- Из выбранной группы выбрать любой символ и открыть график выбранного символа
- На открытый график поместить скрипт "Symbols on symbol tree.mq5" — в результате будет создан файл со всеми символами из выбранной группы символов. Необходимо убедиться в отсутствии ошибок во время работы скрипта: во вкладке "Эксперты" должна появится надпись "Everything is fine. There are no errors".
- На график поместить скрипт "Getting gap statistics.mq5"
В итоге во вкладке "Эксперты" будет такая статистика по количеству гэпов. Вид для первых пять символов:
[name] [d1_total] [gap_total] [gap_confirmed] [ 0] "AAPL" 7238 3948 1640 [ 1] "ABBV" 759 744 364 [ 2] "ABT" 762 734 374 [ 3] "ACN" 759 746 388 [ 4] "AGN" 761 754 385
Теперь вместе с CGraphic
Выводить всю информацию во вкладку "Эксперты" не очень информативно, поэтому следующий скрипт "Getting gap statistics CGraphic.mq5" для вывода графиков будет использовать пользовательские графики CGraphic. Скрипт имеет входные параметры:
- "File name" — имя файла с символами (этот файл должен быть создан заранее при помощи служебного скрипта "Symbols on symbol tree.mq5")
- "Log CheckLoadHistory" — выводить/не выводить результаты загрузки истории по символам во вкладку "Эксперты"
- "Log Statistics" — выводить/не выводить статистику по гэпам во вкладку "Эксперты"
Результата работы — графика количества (в процентах) подтверждённых гэпов:
Рис. 6. Результат работы скрипта "Getting gap statistics CGraphic.mq5"
На рисунке обозначены цифрами:
- "1" — название линии подтверждённых гэпов
- "2" — шкала процентов
- "3" — название файла, из которого брались символы
На графике видно, что значения по гэпам колеблются около отметки 50% плюс минус 6% (и то, 6% — это максимум), хотя есть три выброса менее 42%. Эти три выброса с подтверждением гэпов менее 42% означают, что у трёх символов с вероятностью 58% дневной бар будет идти против гэпа.
Теперь можно проверить другую группу символов — Stock Markets\RussiaMICEX20. Результат работы скрипта "Getting gap statistics CGraphic.mq5" для группы Stock Markets\RussiaMICEX20:
Рис. 7. Статистика по гэпам для группы Stock Markets\RussiaMICEX20
Здесь есть два аномальных выброса. Но в текущей версии связать рисунок и символ нельзя. Значит необходимо немного улучшить скрипт.
Скрипт "Getting gap statistics CGraphic 2.mq5
Изменения: в версии 2.0 во вкладку "Эксперты" будет выводится статистика по подтверждённым гэпам в процентах. Благодаря этому, при включённой настройке "Log Statistics" для группы Stock Markets\RussiaMICEX20 легко можно найти два аномальных символа:
[name] [d1_total] [gap_total] [gap_confirmed] [confirmed_per] *** [14] "NVTK.MM" 757 737 347 47.08 [15] "PIKK.MM" 886 822 282 34.31 [16] "ROSN.MM" 763 746 360 48.26 [17] "RSTI.MM" 775 753 357 47.41 [18] "RTKM.MM" 753 723 324 44.81 [19] "SBER.MM" 762 754 400 53.05 [20] "SBER_p.MM" 762 748 366 48.93 [21] "SNGS.MM" 762 733 360 49.11 [22] "TATN.MM" 765 754 370 49.07 [23] "SNGS_p.MM" 751 708 305 43.08 [24] "URKA.MM" 765 706 269 38.10 [25] "VTBR.MM" 763 743 351 47.24 [26] "RASP.MM" 778 756 354 46.83
Для символов "PIKK.MM" 34% и для "URKA.MM" 38% подтверждённых гэпов означает, что на этих символах, с вероятностью 66% и 62% соответственно, дневной бар закроется против гэпа.
Ограничение количества символов (инструментов) в файле
При анализе различных групп символов я нашёл группы, в которых содержатся более тысячи символов. Оказалось, что работать с таким большим набором очень неудобно: такое огромное количество символов довольно долго добавляется в окно "Обзор рынка", а итоговый график становится нечитаемым — слишком много данных, которые очень плотно расположены друг к другу.
Поэтому решил модернизировать скрипт "Symbols on symbol tree.mq5" — написать версию "Symbols on symbol tree 2.mq5". В версии 2 максимальное количество символов в файле не более 200, и в имя файла добавляется номер части. Например, в группе символов "Stock Markets\USA\NYSE/NASDAQ(SnP100)\" находится 100 символов — значит будет всего одна часть, и имя файла выглядит так: "Stock Markets_USA_NYSE_NASDAQ(SnP100)_part_0.txt".
Выбор файлов при помощи системного диалога "Открыть файл"
Поработав несколько дней со скриптами из данной статьи, пришло понимание, что вносить название файла во входные параметры скрипта "Getting gap statistics CGraphic 2.mq5" очень неудобно. Приходится делать несколько манипуляций: открыть общую папку всех терминалов, скопировать название файл и потом вставить скопированное имя файла в скрипт.
Поэтому выбор файла сделан при помощи системной DLL-функции GetOpenFileName. Для этого подключаю файл "GetOpenFileNameW.mqh". Функция "OpenFileName" из этого файла возвращает полный путь выбранного *.txt файла, например, это может быт такой длинный путь: "C:\Users\barab\AppData\Roaming\MetaQuotes\Terminal\Common\Files\5220\Stock Markets_USA_NYSE_NASDAQ(SnP100)_part_0.txt". Остаётся выделить их этого пути имя файла.
Скрипт "Getting gap statistics CGraphic 3.mq5" использует DLL функцию GetOpenFileName:
Рис. 8. Запрос на разрешение DLL при запуске скрипта "Getting gap statistics CGraphic 3.mq5"
, а вот так выбирается файл при помощи системного диалога "Открыть файл":
Рис. 9. Выбор файла
Статистика по остальным ценным бумагам
Теперь можно собрать статистику по гэпам для других групп символов.
Группа Stock Markets\USA\NYSE\NASDAQ(ETFs)
символы группы разбиты на семь файлов:
Рис. 10. Группа Stock Markets\USA\NYSE\NASDAQ(ETFs), часть 0
Рис. 11. Группа Stock Markets\USA\NYSE\NASDAQ(ETFs), часть 1
Рис. 12. Группа Stock Markets\USA\NYSE\NASDAQ(ETFs), часть 2
Рис. 13. Группа Stock Markets\USA\NYSE\NASDAQ(ETFs), часть 3
Рис. 14. Группа Stock Markets\USA\NYSE\NASDAQ(ETFs), часть 4
Рис. 15. Группа Stock Markets\USA\NYSE\NASDAQ(ETFs), часть 5
Рис. 16. Группа Stock Markets\USA\NYSE\NASDAQ(ETFs), часть 6
Группа "Stock Markets\United Kngdom\LSE Int. (ADR/GDR)\"
Рис. 17. Группа "Stock Markets\United Kngdom\LSE Int. (ADR/GDR)\"
Группа "Stock Markets\United Kngdom\LSE (FTSE350)\"
В данной группе 350 символов, поэтому символу разделены в два файла.
Рис. 18. Группа "Stock Markets\United Kngdom\LSE (FTSE350)\", часть 0
Рис. 19. Группа "Stock Markets\United Kngdom\LSE (FTSE350)\", часть 1
Группа "Stock Markets\Germany\XETRA (IBIS)\Dax100\"
Рис. 20. Группа "Stock Markets\Germany\XETRA (IBIS)\Dax100\"
Группа "Stock Markets\France\Eurnext (CAC40)\"
Рис. 21. Группа "Stock Markets\France\Eurnext (CAC40)\"
Заключение
При исследовании нескольких рынков ценных бумаг я увидел, что после гэпа вероятность продолжения движения и вероятность разворота у многих близка к 50%, то есть ловля гэпа — это 50/50. Но при этом есть ценные бумаги, у которых вероятности значительно выше 65% (причём это могут как вероятность продолжения, так и вероятность разворота). И именно в этих ценных бумагах можно опираться на торговлю по гэпам.
К статье прикреплён архив со скриптами, описываемыми в статье:
Название скрипта | Описание |
---|---|
Symbols on symbol tree.mq5 | Служебный скрипт. Определяет группу в дереве символов и сохраняет все символы из этой группы в файл, в общую папку, в директорию 5220 |
Symbols on symbol tree 2.mq5 | Служебный скрипт. Определяет группу в дереве символов и сохраняет все символы из этой группы в файл, в общую папку, в директорию 5220. Разбивает группу символов в файлы по 200 символов. |
Getting gap statistics.mq5 | Скрипт загружает символы из файла, который создал служебный скрипт и выводит во вкладку "Эксперты" статистику по гэпам |
Getting gap statistics CGraphic.mq5 | Скрипт загружает символы из файла, который создал служебный скрипт и выводит статистику по гэпам в виде графика, используются пользовательские графики CGraphic |
Getting gap statistics CGraphic 2.mq5 | Скрипт загружает символы из файла, который создал служебный скрипт и выводит статистику по гэпам в виде графика, используются пользовательские графики CGraphic. Статистика во вкладку "Эксперты" выводится и в процентах тоже. |
Getting gap statistics CGraphic 3.mq5 | Скрипт загружает символы из файла, который создал служебный скрипт и выводит статистику по гэпам в виде графика, используются пользовательские графики CGraphic. Статистика во вкладку "Эксперты" выводится и в процентах тоже. Для выбора файла с символами используется системный диалог "Открыть файл" |
GetOpenFileNameW.mqh | Включаемый файл, обеспечивающий работу системным диалогом "Открыть файл" |
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Эта статья именно о сборе статистики куда закроется дневной бар, который был открыт с гэпом.
Если нужна статистика движения после гепа на нескольких барах - то каждый может изменить код под свои потребности.
Про статью всё понятно, я же её не критикую, а говорю только о том, что она не дает окончательного ответа на вышеприведенное утверждение.
Мне, к примеру, весьма не просто дополнить Ваш код, что бы получить более развернутую картину, поэтому я и сообщил, что не хватает этой информации, в надежде, что Вы согласитесь со мной и дополните свой труд кодом, который даст окончательный ответ о гэпах.
Про статью всё понятно, я же её не критикую, а говорю только о том, что она не дает окончательного ответа на вышеприведенное утверждение.
Мне, к примеру, весьма не просто дополнить Ваш код, что бы получить более развернутую картину, поэтому я и сообщил, что не хватает этой информации, в надежде, что Вы согласитесь со мной и дополните свой труд кодом, который даст окончательный ответ о гэпах.
Я писал статью на основе акций - а там что ни день, то гэп. Поэтому не вижу практического смысла найти гэп, а потом ждать несколько баров: так как в эти несколько баров может быть ещё несколько гэпов.
Так как раз такие неперекрытые сразу гэпы могут представлять интерес, из моих наблюдений - там формируются уровни сопротивления/поддержки - наблюдаю я на USDRUB_TOM.
Так как раз такие неперекрытые сразу гэпы могут представлять интерес, из моих наблюдений - там формируются уровни сопротивления/поддержки - наблюдаю я на USDRUB_TOM.
А у меня нет такого символа, поэтому в данном случае помочь не смогу.
А у меня нет такого символа, поэтому в данном случае помочь не смогу.
Жаль, что Вас не интересует Московская биржа.