16+
Нейросетевая торговая система Meta Trader 4 + MATLAB. Пошаговая разработка. Издание второе

Бесплатный фрагмент - Нейросетевая торговая система Meta Trader 4 + MATLAB. Пошаговая разработка. Издание второе

Объем: 278 бумажных стр.

Формат: epub, fb2, pdfRead, mobi

Подробнее

Предисловие

Во второе издание включена глава ” Шаблон автоматической нейросетевой торговой системы на стандартных индикаторах». Используя данный шаблон, представляющий пошаговую инструкцию (с кодами скриптов и экспертов MT4 и Matlab) построения нейросетевой торговой системы, вы сможете приступить к созданию своей торговой стратегии на основе предложенной системы либо развивать нейросетевую систему самостоятельно.

По прочтению этой главы — вы самостоятельно создадите исполняемый файл ExpertPrimer. exe, который представляет собой обученную нейронную сеть. В главе «Нейросети Matlab+MT4» вы найдете инструкцию, как оформить интерфейс этой программы с помощью GUI Matlab. Ниже представлены индикаторы, скрипты и эксперты, которые вы будете использовать при создании своей первой нейронной сети.

А здесь вы можете посмотреть пример результата работы с шаблоном https://youtu.be/o9DAvnzCDlU. Как мы видим, после всей подготовительной работы по выстраиванию системы и на ее основе торговой стратегии, весь этот процесс занимает несколько минут. В конце видео показана для сравнения работа автоматической торговой системы готовой к реальной работе. По завершению тестирования на графике выводятся индикаторы, которые используются торговым экспертом. Одним из достоинств данной системы является то, что она кроме двух простейших индикаторов, использует в эксперте только ценовые данные. Все остальное делает нейросеть.

Почему я написал — первой? Эта нейросеть будет для вас шаблоном, который в дальнейшем вы сможете использовать для создания рабочей торговой системы, и на основе которой вы будете разрабатывать различные торговые стратегии. Например, вот какие индикаторы, скрипты и эксперты, я использую в системе, которую так же описываю в главе «Нейросети Matlab+MT4».

Ниже, как пример результативности работы данной системы приведен отчет по ее тестированию.

Обратим внимание на тот факт, что тестирование проводилось в динамике. Т.е. в процессе совершенствования торговой стратегии, основанной на нейросистеме и в течение длительного времени примерно четырех лет.

В главе «Критические ошибки при разработке нейросетевой системы» я попытался рассказать о «подводных камнях» при ее подготовке. И выделить особенно важный аспект — проведения тестов нейронной системы. Некоторую часть главы «Нейросети Matlab+MT4» мне также пришлось посвятить этой проблеме на примере рабочей нейросетевой системы — так как этот процесс неотъемлем от разработки торговой стратегии.

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

Видеоуроки, облегчающие понимание обучения, тренировки и тестирования нейросетей и видеоролики примеров работы с пользовательскими индикаторами можно посмотреть на канале https://www.youtube.com/channel/UCScAAn_sRRaKHdNIxl0aI9A?view_as=subscriber

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

Книга написана с учетом интересов всех категорий трейдеров, а так же тех читателей, которые готовятся заняться трейдингом. Хочется обратить внимание на тот факт, что в данной книге вы не найдете никакого теоретического материала по проблемам нейросетей и самого трейдинга. В любой литературе посвященной этим двум направлениям есть список трудов различных уважаемых авторов. Мне так же хотелось бы снабдить эту книгу таким же списком. Однако, увы, я этого не могу сделать, так как максимально постарался уйти от какой либо теории и психологии, которым в основном посвящена литература о трейдинге. Однако это не значит, что в свое время я не изучал подобную литературу и, что от нее нет пользы. Вот не полный список авторов, труды которых мною изучались — Чарльз Лебо и Дэвид В. Лукас, Юрий Жваколюк, Д. Ю. Пискулов, В. С. Сафонов, Шерри Де Ковни и Кристин Такки, Анна Эрлих, Александр Элдер, Джон Дж. Мэрфи. Но для понимания и практического применения материала представленного мною, в принципе, достаточно теоретической информации, которая подается на сайтах дилинговых компаний и официального сайта Matlab. То есть, любой читатель имеющий представление о трейдинге может выполнить пошаговую инструкцию из моей книги и получить готовую автоматическую нейросетевую систему торговли. Причем, при кажущейся сложности системы в итоге вы прейдете к пониманию, что конечный результат в плане применения программных кодов поразительно легок, но в тоже время самодостачен и функционален. Ведь основная нагрузка в данной системе происходит при обучении нейросетей. Но и здесь, вникнув в процесс, вы обнаружите, что настроив систему, обучение не занимает много времени, а можно даже сказать, что занимает мало времени. Однако нам все равно придется немного пофилософствовать в следующем разделе на тему логического обоснования обучения нейросетей на принятие решения. От этого обоснования во многом зависит конечный результат.

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

Видео с визуализацией работы исполняемых файлов нейронных сетей совместно с MT4 также можно посмотреть по ссылкам https://youtu.be/5GwhRnSqT78 — при обучении и компиляции использовалась программа Matlab, https://youtu.be/cIegQGJKbhY- при обучении и компиляции использовалась программа NeuroSolutions 6.

Логическое обоснование обучения нейросетей на принятие решения

Прежде чем приступать к разработке любой торговой системы, мы задаемся вопросом — на каких принципах данная система будет функционировать? У нас есть два основополагающих принципа — использования флэтов и продолжение тенденции. Пока не будем рассматривать более узкие производные от них — внутри дневная торговля или нет, на фундаментальных данных, на новостях, на открытии рынков и т. д. Мне пришлось сталкиваться с описанием нейросетевых продуктов, где их авторы в примерах использования предлагали прогнозирование каких либо курсов — акций, валют и т. д. Приведем пример, используя платформу NeuroSolutions. Весь процесс повторять не обязательно, так как данную платформу мы в построении нашей системы использовать не будем, а я в данном случае использую ее как пример. Напишем скрипт для получения ценовых данных в MT4. Хочется обратить внимание на то, что при копировании программного кода из файла в формате PDF не сохраняется его стиль — все строки при переносе сохраняются без отступов. Так же могут быть скопированы номера страниц. Для текстовых редакторов эта проблема отсутствует.

//+-+

//|History.mq4 |

//| Copyright © 2009, Andrey Dibrov. |

//| "https://www.youtube.com/channel/UCScAAn_sRRaKHdNIxl0aI9A?view_as=subscriber"|

//+-+

#property copyright «Copyright © 2009, Andrey Dibrov.»

#property link “ https://www.youtube.com/channel/UCScAAn_sRRaKHdNIxl0aI9A?view_as=subscriber»

#property version «1.00»

#property strict

int file=FileOpen («history. csv», FILE_CSV|FILE_READ|FILE_WRITE,»;»);

//+ — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — +

//| Script program start function |

//+ — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — +

void OnStart ()

{

// — —

FileWrite (file,«Open; OpenD; HighD; LowD; CloseD; Max; Min; Date»);

if (file> 0)

{

Alert («Идет запись файла»);

for (int i=iBars (NULL,60) -1; i> =0; i — )

{

FileWrite (file,

iOpen (NULL,60,i),

iOpen (NULL,1440,iBarShift (NULL,1440,iTime (NULL,60,i))),

iHigh (NULL,1440,iBarShift (NULL,1440,iTime (NULL,60,i))),

iLow (NULL,1440,iBarShift (NULL,1440,iTime (NULL,60,i))),

iClose (NULL,1440,iBarShift (NULL,1440,iTime (NULL,60,i))),

iCustom (NULL,60,«Max», 0,1440,60,0,i),

iCustom (NULL,60,«Min», 0,1440,60,0,i));

TimeToStr (iTime (NULL,60,i)));

}

}

Alert («Файл записан»);

FileClose (file);

}

//+-+

Запустив данный скрипт — в папке …MQL4/Files каталога данных терминала, получим файл «history».

Откроем этот файл и добавим в начале десять столбцов In1—10 и один столбец Out.

Заполним эти столбцы Данными из столбца CloseD. Как Вы уже поняли, это данные дневных закрытий.

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

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

С помощью надстройки NeuroSolutions, выделив столбцы In1-In10, отформатируем их как входы.

А столбец Out как выход нейросети.

Аналогичным образом разобьем нашу матрицу построчно на обучающее множество.

И множество, которое мы будем использовать для анализа.

Теперь мы сформируем файлы для программы NeuroSolutions.

Откроем NeuroSolutions и нажмем кнопку NeuralBuilder.

Выберем модель нейросети Multilayer Perceptron.

Нажмем кнопку Browse…

И откроем файл с обучающими входами.

Далее откроем файл с обучающим выходом.

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

С помощью кнопки Start и запустим процесс обучения.

После завершения процесса обучения нажмем кнопку Testing.

В выпадающем списке выберем Production.

Выберем файл с данными для анализа.

Создадим текстовой файл Prod.

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

Откроем файл Prod и скопируем из него отклики нейросети.

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

Поместим эти данные на график.

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

график отклика нейросети, хоть и повторяет график цен, но на один шаг от него отстает. Причем это не зависит — прогнозируем ли мы ценовые данные или производные от них. Исходя из этого, мы можем вывести какой-то постулат. Например — «То, что для нас — вчера, для нейросети — сегодня». Согласитесь, что здесь, в принципе, ни о каком прогнозе речи идти не может. Однако, забегая вперед, отмечу, что данный вариант, при определенной доработке мы так же будем использовать. Но, мы бы, конечно, хотели бы использовать постулат — «То, что для нейросети сегодня, для нас — завтра». Машина времени, какая то. Но мы с Вами ведь понимаем, что все-таки, самая лучшая нейросеть — это наш мозг. И то, мы можем использовать этот постулат максимум с 50% успехом (если мы говорим о вероятности да или нет), а то и хуже. Но ведь есть еще и третий вариант постулата — «То, что для нейросети — вчера, для нас — сегодня». Разберем, что для нас означают эти постулаты в трейдинге:

первый — мы совершаем сделку и завтра получаем ответ от нейросети — открылись в правильном направлении или нет. Хотя мы это уже знаем и без нейросети;

второй — мы получаем информацию от нейросети, совершаем сделку и завтра видим, правильная рекомендация была или нет;

третий — мы получаем информацию от нейросети — когда нам надо совершить ту или иную сделку.

Первый вариант, естественно мы отбрасываем сразу. А вот второй и третий для торговли подходят. Однако второй вариант — вариант как бы заглядывания в будущее. Утрировано этот вариант торговли заключается в том, что мы получаем сигнал от нейросети в определенный момент времени — например по закрытию дня с прогнозом как закроется следующий день. Реализовать его для чисто механической торговли на данном этапе сложно. Ну, а если представить, что им получит возможность воспользоваться большинство торговцев — то он сразу же потеряет свою актуальность. Смысл третьего варианта, заключается в том, что мы отслеживаем отклик нейросети на протяжении торговой сессии и покупаем либо продаем его интерпретируя. И здесь нам надо понять основное. Какой из вариантов мы сможем реализовать зависит от того как мы будем обучать нейросеть. И согласитесь, что третий вариант реализовать все-таки легче. Если во втором — мы будем использовать, какую либо информацию с прицелом на получение результата на следующий день — его закрытия (день выбран как пример, естественно может быть какой либо другой период), то в третьем варианте мы используем информацию, пришедшую за шаг до принятия решения — куда двинется цена в этот момент времени.

Шаблон автоматической нейросетевой торговой системы на стандартных индикаторах

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

Запустим скрипт «ScriptIn».

//+ — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — +

//| ScriptIn.mq4 |

//| Copyright © 2019, Andrey Dibrov. |

//|"https://www.youtube.com/channel/UCScAAn_sRRaKHdNIxl0aI9A?view_as=subscriber" |

//+ — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — +

#property copyright «Copyright © 2019, Andrey Dibrov.»

#property link "https://www.youtube.com/channel/UCScAAn_sRRaKHdNIxl0aI9A?view_as=subscriber"

#property show_inputs

extern string Date=«2004.07.01 00:00»;

extern string DateOut=«2010.12.31 23:00»;

//+ — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — +

//| script program start function |

//+ — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — +

int start ()

{

int handle=FileOpen («In. csv», FILE_CSV|FILE_READ|FILE_WRITE,»;»);

int handleOut=FileOpen («Out. csv», FILE_CSV|FILE_READ|FILE_WRITE,»;»);

Alert («Идет запись файлов»);

for (int i=iBars (NULL,0) -1; i> =0; i — )

{

string Date1=TimeToStr (iTime (NULL,0,i));

if (DateOut> =Date1 && Date <=Date1)

{

if (iHigh (NULL,0,i)> iBands (NULL,0,20,2,0,PRICE_CLOSE, MODE_MAIN, i) && iLow (NULL,0,i) <iBands (NULL,0,20,2,0,PRICE_CLOSE, MODE_MAIN, i) && ((iHigh (NULL,0,i+1) <iBands (NULL,0,20,2,0,PRICE_CLOSE, MODE_MAIN, i+1) && iLow (NULL,0,i+1) <iBands (NULL,0,20,2,0,PRICE_CLOSE, MODE_MAIN, i+1)) ||

(iHigh (NULL,0,i+1)> iBands (NULL,0,20,2,0,PRICE_CLOSE, MODE_MAIN, i+1) && iLow (NULL,0,i+1)> iBands (NULL,0,20,2,0,PRICE_CLOSE, MODE_MAIN, i+1))))

{

FileWrite (handle,

iWPR (NULL,0,14,i+3),

iStochastic (NULL,0,5,3,3,MODE_SMA,1,MODE_MAIN, i+3),

iRVI (NULL,0,10,MODE_MAIN, i+3),

iRSI (NULL,0,14,PRICE_CLOSE, i+3),

iOsMA (NULL,0,12,26,9,PRICE_CLOSE, i+3),

iMACD (NULL,0,12,26,9,PRICE_CLOSE, MODE_MAIN, i+3),

iWPR (NULL,0,14,i+2),

iStochastic (NULL,0,5,3,3,MODE_SMA,1,MODE_MAIN, i+2),

iRVI (NULL,0,10,MODE_MAIN, i+2),

iRSI (NULL,0,14,PRICE_CLOSE, i+2),

iOsMA (NULL,0,12,26,9,PRICE_CLOSE, i+2),

iMACD (NULL,0,12,26,9,PRICE_CLOSE, MODE_MAIN, i+2),

iWPR (NULL,0,14,i+1),

iStochastic (NULL,0,5,3,3,MODE_SMA,1,MODE_MAIN, i+1),

iRVI (NULL,0,10,MODE_MAIN, i+1),

iRSI (NULL,0,14,PRICE_CLOSE, i+1),

iOsMA (NULL,0,12,26,9,PRICE_CLOSE, i+1),

iMACD (NULL,0,12,26,9,PRICE_CLOSE, MODE_MAIN, i+1),

iWPR (NULL,0,14,i),

iStochastic (NULL,0,5,3,3,MODE_SMA,1,MODE_MAIN, i),

iRVI (NULL,0,10,MODE_MAIN, i),

iRSI (NULL,0,14,PRICE_CLOSE, i),

iOsMA (NULL,0,12,26,9,PRICE_CLOSE, i),

iMACD (NULL,0,12,26,9,PRICE_CLOSE, MODE_MAIN, i));

FileWrite (handleOut, iClose (NULL,1440,iBarShift (NULL,1440,iTime (NULL,0,i))) -iOpen (NULL,0,i));

}}}
FileClose (handle); FileClose (handleOut); Alert («Файлы записаны»); return (0)

}

//+ — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — +

В результате работы скрипта мы получим в папке /MQL4/Files каталога данных MT4 два файла In. csv и Out. csv. Исходя из имен этих файлов — первый является файлом входов нейросети. Выборку данных мы делаем с использованием технического индикатора Bollinger Bands. Т.е. записываем значения индикаторов с глубиной три часа в момент, когда максимум часа выше средней линии, а минимум ниже. Также максимум и минимум предыдущего часа либо одновременно выше средней линии или ниже. Файл Out. csv — файл, в который мы записали, соответственно с использованием индикатора Bollinger Bands выборку разницы закрытия дня и открытия текущего часа. Таким образом, мы тренируем нейросеть на направление движения цены и ее амплитуду. Эти данные мы записываем с помощью скрипта, так как нам необходимы значения (закрытие дня), которые с помощью эксперта мы записать не сможем. А вот для того, что бы получить достоверный результат при тестировании нейросети — тестовое множество нам надо записать с помощью эксперта.

Запустим в тестере стратегий эксперт «ExpertPrimer», как показано на рисунке выше.

//+ — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — +

//| ExpertPrimer.mq4 |

//| Copyright © 2019, Andrey Dibrov. |

//|"https://www.youtube.com/channel/UCScAAn_sRRaKHdNIxl0aI9A?view_as=subscriber" |

//+ — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — +

#property copyright «Copyright © 2019, Andrey Dibrov.»

#property link "https://www.youtube.com/channel/UCScAAn_sRRaKHdNIxl0aI9A?view_as=subscriber"

extern string DateTren=«2004.07.01 00:00»;

extern string DateTest=«2010.12.31 23:00»;

int handleTest=FileOpen («Test. csv», FILE_TXT|FILE_WRITE|FILE_SHARE_READ,»;»);

int handleDate=FileOpen («Date. csv», FILE_TXT|FILE_WRITE|FILE_SHARE_READ,»;»);

//+ — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — +

//| Expert initialization function |

//+ — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — +

int OnInit ()

{

// — —

// — —

return (INIT_SUCCEEDED);

}

//+ — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — +

//| Expert deinitialization function |

//+ — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — +

void OnDeinit (const int reason)

{

// — —

FileClose (handleTest);

FileClose (handleDate);

}

//+ — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — +

//| Expert tick function |

//+ — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — +

void OnTick ()

{

// — —

string Date=TimeToStr (iTime (NULL,0,0));

if (handleTest> 0 && handleDate> 0 && DateTest <Date)

{

FileWrite (handleTest,

iWPR (NULL,0,14,3),

iStochastic (NULL,0,5,3,3,MODE_SMA,1,MODE_MAIN,3),

iRVI (NULL,0,10,MODE_MAIN,3),

iRSI (NULL,0,14,PRICE_CLOSE,3),

iOsMA (NULL,0,12,26,9,PRICE_CLOSE,3),

iMACD (NULL,0,12,26,9,PRICE_CLOSE, MODE_MAIN,3),

iWPR (NULL,0,14,2),

iStochastic (NULL,0,5,3,3,MODE_SMA,1,MODE_MAIN,2),

iRVI (NULL,0,10,MODE_MAIN,2),

iRSI (NULL,0,14,PRICE_CLOSE,2),

iOsMA (NULL,0,12,26,9,PRICE_CLOSE,2),

iMACD (NULL,0,12,26,9,PRICE_CLOSE, MODE_MAIN,2),

iWPR (NULL,0,14,1),

iStochastic (NULL,0,5,3,3,MODE_SMA,1,MODE_MAIN,1),

iRVI (NULL,0,10,MODE_MAIN,1),

iRSI (NULL,0,14,PRICE_CLOSE,1),

iOsMA (NULL,0,12,26,9,PRICE_CLOSE,1),

iMACD (NULL,0,12,26,9,PRICE_CLOSE, MODE_MAIN,1),

iWPR (NULL,0,14,0),

iStochastic (NULL,0,5,3,3,MODE_SMA,1,MODE_MAIN,0),

iRVI (NULL,0,10,MODE_MAIN,0),

iRSI (NULL,0,14,PRICE_CLOSE,0),

iOsMA (NULL,0,12,26,9,PRICE_CLOSE,0),

iMACD (NULL,0,12,26,9,PRICE_CLOSE, MODE_MAIN,0));

FileWrite (handleDate, Date);

}

}

//+ — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — +

В папке /tester/files каталога данных MT4 мы получим также два файла Date. csv и Test. csv. В первом мы записали дату и почасово время тестового множества. Во втором непосредственно значения, по которым мы будем получать отклик нейросети.

Файлы Date. csv и Test. csv мы перенесем в папку …\MQL4\Files.

Запустим Matlab, нажмем Ctrl+N и в открывшемся окне вставим ниже представленный код и сохраним его как скрипт Primer. m в папке «Matlab» на рабочем столе. Путь к этой папке укажем в соответствии с ее расположением на жестком диске нашего компьютера. То же самое сделаем и в отношении других файлов используемых при обучении нейросети.

Input= xlsread («C:\Users\Администратор\AppData\Roaming\MetaQuotes\Terminal\287469DEA9630EA94D0715D755974F1B\MQL4\Files\In. csv’,«In’)»;

Out= xlsread («C:\Users\Администратор\AppData\Roaming\MetaQuotes\Terminal\287469DEA9630EA94D0715D755974F1B\MQL4\Files\Out. csv’,«Out’)»;

Test= xlsread («C:\Users\Администратор\AppData\Roaming\MetaQuotes\Terminal\287469DEA9630EA94D0715D755974F1B\MQL4\Files\Test. csv’,«Test’)»;

[~, ~, Date] = xlsread («C:\Users\Администратор\AppData\Roaming\MetaQuotes\Terminal\287469DEA9630EA94D0715D755974F1B\MQL4\Files\Date. csv’,«Date’);

trainFcn = ’trainlm’;

hiddenLayerSize = 10;

net = fitnet (hiddenLayerSize, trainFcn);

net.divideParam.trainRatio = 70/100;

net.divideParam.valRatio = 15/100;

net. divideParam. testRatio = 15/100;

[net, tr] = train (net, Input, Out);

Net=net (Test)»;

xlswrite («C:\Users\Администратор\Desktop\Matlab\Indicator. csv’,Date,»», «1A»);

xlswrite («C:\Users\Администратор\Desktop\Matlab\Indicator. csv’,Net,»», «1B»);

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

Файл net.mat (обученную нейросеть) сохраним в папке Primer, которую предварительно создадим в папке Matlab. Отмечу, что папку Matlab мы назначим рабочим каталогом программы. Потом вы, конечно же, можете все настроить, как вам будет удобнее.

Так же в папке Matlab, скрипт создаст файл Indicator. csv. Это отклик нейросети, который мы будем использовать как индикатор для разработки торговой стратегии.

Откроем этот файл. В ячейке C5 вставим формулу, которую вы видите в строке формул на рисунке выше. Заполним этой формулой колонку «С». Скопируем данные и через специальную вставку заполним ячейки данной колонки значениями формул.

Сохраним файл в формате csv.

Данный файл скопируем и вставим в папки /MQL4/Files и /tester/files. Для удобства я рекомендую ярлыки этих папок разместить рядом с папкой Matlab.

Запустим индикатор 1.mq4.

//+ — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — +

//| 1.mq4 |

//| Copyright © 2009, Andrey Dibrov. |

//|"https://www.youtube.com/channel/UCScAAn_sRRaKHdNIxl0aI9A?view_as=subscriber" |

//+ — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — +

#property copyright «Copyright © 2009, Andrey Dibrov.»

#property link "https://www.youtube.com/channel/UCScAAn_sRRaKHdNIxl0aI9A?view_as=subscriber"

#property indicator_separate_window

#property indicator_buffers 2

#property indicator_color1 Red

#property indicator_color2 Blue

string File_Name=«Indicator. csv»;

double Buf_0 [];

double Buf_1 [];

double Str0;

double Str1;

datetime Date0;

datetime Date1;

int Handle;

int i;

//+ — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — +

//| Custom indicator initialization function |

//+ — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — +

int init ()

{

SetIndexBuffer (0,Buf_0);

SetIndexBuffer (1,Buf_1);

IndicatorBuffers (2);

IndicatorDigits (4);

SetIndexStyle (0,DRAW_LINE, STYLE_SOLID,1);

SetIndexStyle (1,DRAW_LINE, STYLE_SOLID,1);

SetLevelValue (0,0.5);

return (0);

}

//+ — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — +

//| |

//+ — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — +

int start ()

{

Handle=FileOpen (File_Name, FILE_CSV|FILE_READ,»;»);

while (i==0)

{

Date0=StrToTime (FileReadString (Handle));

i++;

}

FileClose (Handle);

i=iBarShift (NULL, PERIOD_H1,Date0);

Handle=FileOpen (File_Name, FILE_CSV|FILE_READ,»;»);

while (i> =0)

{

Date1=StrToTime (FileReadString (Handle));

Str0=StrToDouble (FileReadString (Handle));

Str1=StrToDouble (FileReadString (Handle));

Buf_0 [i] =Str0;

Buf_1 [i] =Str1;

i — ;

}

FileClose (Handle);

return (0);

}

//+ — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — +

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

С помощью эксперта «ExpertPrimerReal» протестируем отклик нейросети.

//+ — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — +

//| ExpertPrimerReal.mq4|

//| Copyright © 2019, Andrey Dibrov. |

//|"https://www.youtube.com/channel/UCScAAn_sRRaKHdNIxl0aI9A?view_as=subscriber" |

//+ — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — +

#property copyright «Copyright © 2019, Andrey Dibrov.»

#property link "https://www.youtube.com/channel/UCScAAn_sRRaKHdNIxl0aI9A?view_as=subscriber"

extern int H1;

extern int H2;

extern int H3;

extern int H4;

extern int Loss1;

extern int Profit1;

extern int Loss0;

extern int Profit0;

int MagicBuy1;

int MagicSell0;

int TicketBuy1;

int TicketSell0;

datetime Count=1;

double Buf_0 [100000];

double Buf_1 [100000];

string File_Name=«Indicator. csv»;

int K;

int i;

//+ — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — +

//| Expert initialization function |

//+ — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — +

int OnInit ()

{

// — —

int Handle=FileOpen (File_Name, FILE_CSV|FILE_READ,»;»);

while (Count> 0)

{

Count=StrToTime (FileReadString (Handle));

Buf_0 [i] =StrToDouble (FileReadString (Handle));

Buf_1 [i] =StrToDouble (FileReadString (Handle));

i++;

}

// — —

return (INIT_SUCCEEDED);

}

//+ — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — +

//| Expert deinitialization function |

//+ — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — +

void OnDeinit (const int reason)

{

// — —

}

//+ — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — +

//| Expert tick function |

//+ — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — +

void OnTick ()

{

// — —

for (i=1; i <=OrdersHistoryTotal (); i++)

{

if (OrderSelect (i-1,SELECT_BY_POS, MODE_HISTORY) ==true)

{

if (TicketBuy1==OrderTicket ()) MagicBuy1=0;

if (TicketSell0==OrderTicket ()) MagicSell0=0;

}

}

// — — — — -Buy0

if (MagicBuy1==0 && K> 0 && Buf_0 [K-1] <Buf_1 [K-1] && Buf_0 [K]> Buf_1 [K] && TimeHour (TimeCurrent ())> H1 && TimeHour (TimeCurrent ()) <H2 && H1 <H2)

{

bool send1=OrderSend (Symbol (),OP_BUY,1,Ask,3,Bid-Loss1*Point, Ask+Profit1*Point, NULL,1,0,Red);

for (i=1; i <=OrdersTotal (); i++)

{

if (OrderSelect (i-1,SELECT_BY_POS) ==true)

{

TicketBuy1=OrderTicket ();

MagicBuy1=OrderMagicNumber ();

}

}

}

if (MagicBuy1==1 && K> 0 && Buf_0 [K-1]> Buf_1 [K-1] && Buf_0 [K] <Buf_1 [K])

{

bool close1=OrderClose (TicketBuy1,1,Bid,2,Blue);

}

// — — — — -Sell0

if (MagicSell0==0 && K> 0 && Buf_0 [K-1]> Buf_1 [K-1] && Buf_0 [K] <Buf_1 [K] && TimeHour (TimeCurrent ())> H3 && TimeHour (TimeCurrent ()) <H4 && H3 <H4)

{

bool send0=OrderSend (Symbol (),OP_SELL,1,Bid,3,Ask+Loss0*Point, Bid-Profit0*Point, NULL,3,0,Green);

for (i=1; i <=OrdersTotal (); i++)

{

if (OrderSelect (i-1,SELECT_BY_POS) ==true)

{

TicketSell0=OrderTicket ();

MagicSell0=OrderMagicNumber ();

}

}

}

if (MagicSell0==3 && K> 0 && Buf_0 [K-1] <Buf_1 [K-1] && Buf_0 [K]> Buf_1 [K])

{

bool close0=OrderClose (TicketSell0,1,Ask,2,Blue);

}

K++;

}

//+ — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — +

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

// — — — — -Buy0

if (MagicBuy1==0 && K> 0 && Buf_0 [K-1] <Buf_1 [K-1] && Buf_0 [K]> Buf_1 [K] && TimeHour (TimeCurrent ())> H1 && TimeHour (TimeCurrent ()) <H2 && H1 <H2)

{

bool send1=OrderSend (Symbol (),OP_BUY,1,Ask,3,0,0,NULL,1,0,Red);

for (i=1; i <=OrdersTotal (); i++)

{

if (OrderSelect (i-1,SELECT_BY_POS) ==true)

{

TicketBuy1=OrderTicket ();

MagicBuy1=OrderMagicNumber ();

}

}

}

if (MagicBuy1==1 && K> 0 && Buf_0 [K-1]> Buf_1 [K-1] && Buf_0 [K] <Buf_1 [K])

{

bool close1=OrderClose (TicketBuy1,1,Bid,2,Blue);

}

// — — — — -Sell0

if (MagicSell0==0 && K> 0 && Buf_0 [K-1]> Buf_1 [K-1] && Buf_0 [K] <Buf_1 [K] && TimeHour (TimeCurrent ())> H3 && TimeHour (TimeCurrent ()) <H4 && H3 <H4)

{

bool send0=OrderSend (Symbol (),OP_SELL,1,Bid,3,0,0,NULL,3,0,Green);

for (i=1; i <=OrdersTotal (); i++)

{

if (OrderSelect (i-1,SELECT_BY_POS) ==true)

{

TicketSell0=OrderTicket ();

MagicSell0=OrderMagicNumber ();

}

}

}

if (MagicSell0==3 && K> 0 && Buf_0 [K-1] <Buf_1 [K-1] && Buf_0 [K]> Buf_1 [K])

{

bool close0=OrderClose (TicketSell0,1,Ask,2,Blue);

}

Уберем из кода скрипта Стоп Лоссы и Тейк Профиты.

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

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

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

После всех наших предыдущих действий у нас уже есть натренированная нейросеть, и мы мажем создать цепочку MT4-Matlab-MT4.

Назначим текущей папкой Matlab, ранее созданную нами папку Primer. Создадим в ней скрипт под именем «ExpertPrimer. m».

r=0;

Bar1=0;

Bar=23;

Open1=0;

Open2 =zeros (2,2);

% — — — — — — загружаем нейросети — — — — — — — — — — — — — — — — — — — — —

load('net.mat’);

% =========================================================================

tic

% — — — — — — скрипт работает 5 часов — — — — — — — — — — — — — — — — — — —

while toc <18000

% — — — — — — -загружаем данные от MT4 — — — — — — — — — — — — — — — — — — —

if Bar1~=Bar

try

Input=dlmread («C:\Users\Администратор\AppData\Roaming\MetaQuotes\Terminal\287469DEA9630EA94D0715D755974F1B\tester\files\Input_mat. txt’)»;

catch

continue;

end

% — — — — — — получаем отклик нейросетей — — — — — — — — — — — — — — — — — —

Buf=net (Input);

% — сглаживаем отклик по пяти значениям и записываем данные в матрицу — — —

try

if Bar1~=Bar

% % Open1=Buf;

r=r+1;

Open2 (r,1) =Buf;

if r> =5

Open2 (r,2) = (Open2 (r,1) +Open2 (r-1,1) +Open2 (r-2,1) +Open2 (r-3,1) +Open2 (r-4,1)) /5;

end

end

catch

continue;

end

if r> 1

Order (1,1) =Open2 (r-1,1);

Order (1,2) =Open2 (r-1,2);

Order (2,1) =Open2 (r,1);

Order (2,2) =Open2 (r,2);

end

% — — — — — — записываем сигнал в файл — — — — — — — — — — — — — — — — — — —

try

dlmwrite («C:\Users\Администратор\AppData\Roaming\MetaQuotes\Terminal\287469DEA9630EA94D0715D755974F1B\tester\files\Open. txt’,Order,’delimiter’,»», ’newline’,’pc’);

catch

continue;

end

end

% =========================================================================

Bar1=Bar;

try

Bar=dlmread («C:\Users\Администратор\AppData\Roaming\MetaQuotes\Terminal\287469DEA9630EA94D0715D755974F1B\tester\files\Bar. txt’);

catch

continue;

end

pause (0.2);

end

Внесем некоторые изменения в программный код эксперта «ExpertPrimerReal», адаптировав его для работы со скриптом «ExpertPrimer. m».

//+ — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — +

//| ExpertPrimerReal.mq4 |

//| Copyright © 2019, Andrey Dibrov. |

//|"https://www.youtube.com/channel/UCScAAn_sRRaKHdNIxl0aI9A?view_as=subscriber" |

//+ — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — +

#property copyright «Copyright © 2019, Andrey Dibrov.»

#property link "https://www.youtube.com/channel/UCScAAn_sRRaKHdNIxl0aI9A?view_as=subscriber"

extern int H1;

extern int H2;

extern int H3;

extern int H4;

extern int Loss1;

extern int Profit1;

extern int Loss0;

extern int Profit0;

int MagicBuy1;

int MagicSell0;

int TicketBuy1;

int TicketSell0;

int handleInput;

int handleBar;

int Con;

int Bar;

int Order;

double Order1;

double Order2;

double Order3;

double Order4;

//datetime Count=1;

//double Buf_0 [100000];

//double Buf_1 [100000];

//string File_Name=«Indicator. csv»;

int K;

int i;

//+ — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — +

//| Expert initialization function |

//+ — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — +

int OnInit ()

{

// — —

//int Handle=FileOpen (File_Name, FILE_CSV|FILE_READ,»;»);

// while (Count> 0)

// {

//Count=StrToTime (FileReadString (Handle));

//Buf_0 [i] =StrToDouble (FileReadString (Handle));

//Buf_1 [i] =StrToDouble (FileReadString (Handle));

// i++;

//}

// — —

return (INIT_SUCCEEDED);

}

//+ — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — +

//| Expert deinitialization function |

//+ — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — +

void OnDeinit (const int reason)

{

// — —

}

//+ — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — +

//| Expert tick function |

//+ — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — +

void OnTick ()

{

// — —

handleInput=FileOpen («Input_mat. txt», FILE_TXT|FILE_WRITE|FILE_SHARE_READ,»;»);

FileWrite (handleInput,

iWPR (NULL,0,14,3),

iStochastic (NULL,0,5,3,3,MODE_SMA,1,MODE_MAIN,3),

iRVI (NULL,0,10,MODE_MAIN,3),

iRSI (NULL,0,14,PRICE_CLOSE,3),

iOsMA (NULL,0,12,26,9,PRICE_CLOSE,3),

iMACD (NULL,0,12,26,9,PRICE_CLOSE, MODE_MAIN,3),

iWPR (NULL,0,14,2),

iStochastic (NULL,0,5,3,3,MODE_SMA,1,MODE_MAIN,2),

iRVI (NULL,0,10,MODE_MAIN,2),

iRSI (NULL,0,14,PRICE_CLOSE,2),

iOsMA (NULL,0,12,26,9,PRICE_CLOSE,2),

iMACD (NULL,0,12,26,9,PRICE_CLOSE, MODE_MAIN,2),

iWPR (NULL,0,14,1),

iStochastic (NULL,0,5,3,3,MODE_SMA,1,MODE_MAIN,1),

iRVI (NULL,0,10,MODE_MAIN,1),

iRSI (NULL,0,14,PRICE_CLOSE,1),

iOsMA (NULL,0,12,26,9,PRICE_CLOSE,1),

iMACD (NULL,0,12,26,9,PRICE_CLOSE, MODE_MAIN,1),

iWPR (NULL,0,14,0),

iStochastic (NULL,0,5,3,3,MODE_SMA,1,MODE_MAIN,0),

iRVI (NULL,0,10,MODE_MAIN,0),

iRSI (NULL,0,14,PRICE_CLOSE,0),

iOsMA (NULL,0,12,26,9,PRICE_CLOSE,0),

iMACD (NULL,0,12,26,9,PRICE_CLOSE, MODE_MAIN,0));

FileClose (handleInput);

handleBar=FileOpen («Bar. txt», FILE_TXT|FILE_WRITE|FILE_SHARE_READ,»;»);

FileWrite (handleBar, TimeHour (TimeCurrent ()));

FileClose (handleBar);

Order=FileOpen («Open. txt», FILE_CSV|FILE_READ|FILE_SHARE_READ,»»);

Order1=StrToDouble (FileReadString (Order));

Order2=StrToDouble (FileReadString (Order));

Order3=StrToDouble (FileReadString (Order));

Order4=StrToDouble (FileReadString (Order));

FileClose (Order);

Comment (Order1,»», Order2,»», Order3,»», Order4);

for (i=1; i <=OrdersHistoryTotal (); i++)

{

if (OrderSelect (i-1,SELECT_BY_POS, MODE_HISTORY) ==true)

{

if (TicketBuy1==OrderTicket ()) MagicBuy1=0;

if (TicketSell0==OrderTicket ()) MagicSell0=0;

}

}

Con++;

// — — — — -Buy0

if (MagicBuy1==0 && Order==1 && handleInput==1 && Bar==Bars && Con> =3 && Order1 <Order2 && Order3> Order4 && TimeHour (TimeCurrent ())> H1 && TimeHour (TimeCurrent ()) <H2 && H1 <H2)

{

bool send1=OrderSend (Symbol (),OP_BUY,1,Ask,3,Bid-Loss1*Point, Ask+Profit1*Point, NULL,1,0,Red);

for (i=1; i <=OrdersTotal (); i++)

{

if (OrderSelect (i-1,SELECT_BY_POS) ==true)

{

TicketBuy1=OrderTicket ();

MagicBuy1=OrderMagicNumber ();

}}}
if (MagicBuy1==1 && Order==1 && handleInput==1 && Bar==Bars && Con> =3 && Order1> Order2 && Order3 <Order4)
{
bool close1=OrderClose (TicketBuy1,1,Bid,2,Blue)

}

// — — — — -Sell0

if (MagicSell0==0 && Order==1 && handleInput==1 && Bar==Bars && Con> =3 && Order1> Order2 && Order3 <Order4 && TimeHour (TimeCurrent ())> H3 && TimeHour (TimeCurrent ()) <H4 && H3 <H4)

{

bool send0=OrderSend (Symbol (),OP_SELL,1,Bid,3,Ask+Loss0*Point, Bid-Profit0*Point, NULL,3,0,Green);

for (i=1; i <=OrdersTotal (); i++)

{

if (OrderSelect (i-1,SELECT_BY_POS) ==true)

{

TicketSell0=OrderTicket ();

MagicSell0=OrderMagicNumber ();

}}}
if (MagicSell0==3 && Order==1 && handleInput==1 && Bar==Bars && Con> =3 && Order1 <Order2 && Order3> Order4)
{
bool close0=OrderClose (TicketSell0,1,Ask,2,Blue)

}
K++

if (Bar <Bars)

{

Con=0;

}

Bar=Bars;

}

//+ — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — +

Запустим, данный эксперт с установками как показано на рисунке выше. Поскольку эксперт обращается из MT4 к Matlab и, наоборот, через временные файлы, ордера мы должны выставлять не на первом тике открытия часа. Иначе сигнал от нейросети у нас будет запаздывать на один час. При совершении сделок это условие мы обеспечиваем при помощи переменной «Con».

Поставим, эксперт на паузу и запустим «ExpertPrimer. m» в Matlab.

Снимем эксперт в MT4 с паузы.

В верхнем левом углу графика эксперт выводит отклик нейросети.

В папке …tester/files будут созданы три файла Bar. txt, Input_mat. txt и Open. txt. С помощью файла Input_mat. txt эксперт MT4 передает входные данные для нейросети, а в файле Open. txt скрипт Matlab передает отклик нейросети эксперту MT4.

Бесплатный фрагмент закончился.

Купите книгу, чтобы продолжить чтение.