![]() |
Здравствуйте, гость ( Вход | Регистрация )
![]() |
leonid553 |
![]()
Сообщение
#1
|
![]() Группа: Активный участник Сообщений: 2 002 Регистрация: 14.4.2006 Из: г.Самара Пользователь №: 28 Спасибо сказали: 11 раз(а) ![]() |
Yury V. Reshetov
Нейронная сеть Что такое нейронная сеть или Perceptron? Это алгоритм использующий уравнение линейного неравенства (линейного фильтра), с помощью которого можно причислить исследуемый объект к тому или иному классу или же наоборот исключить его из этого самого класса объектов. Само неравенство выглядит так: w1 * a1 + w2 * a2 + ... wn * an > d где: 1. wi - весовой коэффициент с индексом i; 2. ai - численное значение признака с индексом i исследуемого объекта; 3. d - пороговое значение, чаще всего равное 0. Дело в том, что геометрически плоскость описывается линейным уравнением. Например, в трехмерном пространстве относительно координат X, Y и Z уравнение плоскости имеет вид: A * X + B * Y + C * Z + D = 0 Координаты всех точек, расположенных по одну сторону от плоскости, в этом самом пространстве, удовлетворяют неравенству: A * X + B * Y + C * Z + D > 0 А координаты всех точек лежащих по другую сторону от плоскости, удовлетворяют неравенству: A * X + B * Y + C * Z + D < 0 Таким образом, если нам известно уравнение некой плоскости и координаты любых точек, то мы можем разделить множество всех точек пространства на два множества точек, разделяемых этой самой плоскостью. ПОСТАНОВКА ЗАДАЧИ Если мы разделим объекты на два класса: открываемые длинные позиции и короткие позиции, а в качестве признаков возьмем значения индикаторов или осцилляторов технического анализа, то остается лишь выяснить уравнение плоскости и попытаться с ее помощью произвести идентификацию. Постановка задачи ясна. Множества точек пересекаются в пространстве и провести четкую разделительную черту между ними невозможно. Единственным и приемлемым решением здесь является линия, которая будет отделять оба множества точек таким образом, чтобы с ее помощью большинство красных объектов оказалось по одну сторону, а синих по другую. На сей раз, мы имеем дело с задачей оптимизации, то есть поиском уравнения разделяющей плоскости или линии, способной максимально разделить два класса объектов друг от друга, но с вероятностью того, что часть точек, принадлежащих одному классу, будет ошибочно идентифицировано, как принадлежащих к классу другому. Попробуем теперь определиться с постановкой задачи, которую мы собираемся решить. Элементарно, что нужно знать трейдеру для прибыльной торговли - это направление движения котировок. То есть если котировки пойдут вверх, то следует открыть длинную позицию. Если вниз, то необходимо открывать позицию короткую. Следовательно, два класса объектов у нас уже есть, а именно, направление движения котировок. Для того, чтобы принять решение, следуя техническому анализу, трейдеры прибегают к исследованию так называемых технических индикаторов или осцилляторов. Мы также будем исследовать осциллятор. Поскольку технические осцилляторы - это гистограммы, значения которых отклоняются от горизонтальной линии, то соответственно и нейронная сеть нам понадобится с линейным фильтром. В качестве признаков объекта, будем брать паттерны, то есть значения осциллятора в четырех точках, взятые с шагом в семь периодов вглубь истории, начиная от текущего момента. Эскизы прикрепленных изображений |
![]() ![]() |
leonid553 |
![]()
Сообщение
#2
|
![]() Группа: Активный участник Сообщений: 2 002 Регистрация: 14.4.2006 Из: г.Самара Пользователь №: 28 Спасибо сказали: 11 раз(а) ![]() |
На вышеприведенном рисунке значения осциллятора обведены кружочками. Присвоим их идентификаторам a1, a2, a3 и a4 и будем подставлять в уравнение разделительной плоскости и сравнивать полученное значение с нулем, чтобы узнать, с какой стороны будет находиться паттерн. Осталось только получить само уравнение плоскости, которое будет разделять паттерны, предшествующие движению цены вверх, от паттернов, предшествующих движению цены вниз. Для этой цели будем использовать встроенный в торговый терминал MetaTrader4 генетический алгоритм, предназначенный для ускорения процессов оптимизации. Проще говоря, мы будем подбирать значения весовых коэффициентов линейного фильтра таким образом, чтобы в результате получить уравнение разделительной линии для максимального значения баланса оптимизацией стратегии на исторических данных. Для этой цели нам понадобится, как минимум, формулировка торговой стратегии, с помощью которой можно будет реализовать алгоритм и переложить его в код советника для MetaTrader4. Теоретически торговая система должна предусматривать сигналы, как для входа в рынок, так и для выхода из него. Впрочем, выходы по сигналам не являются обязательными и их можно исключить с помощью: Расстановки стоп-ордеров - takeprofit и stoploss; Разворотом позиции в противоположном направлении при получении сигнала о изменении направления тенденции рынка. Чтобы не усложнять торговую систему, мы будем использовать выходы по защитным стопам - stoploss и по сигналам разворотов. В этом случае нейросеть будет выдавать на выходе только два сигнала по значениям признаков объектов, а именно: Котировки вероятнее всего будут двигаться в сторону повышения; Котировки вероятнее всего будут двигаться в сторону понижения. Таким образом упрощается задача идентификации объектов для нейронной сети путем разделения их всего на два класса. Оптимизацию торговой системы также можно упростить, исключив из управления ордерами фиксацию прибылей по takeprofit, то есть избавить ее от подбора еще одного входного параметра. В этом случае достаточно воспользоваться трейлинг-стопами, то есть постепенными подтягиваниями stoploss в прибыльную сторону до тех пор, пока нейросеть не даст противоположный сигнал или пока она не ошибется. Любая ошибка нейросети приведет к срабатыванию защитного стопа. При этом сама система управления ордерами усложняется. Быстрый разворот позиции в обратном направлении лучше всего выполнить через встречный ордер с удвоенным количеством лотов и последующим закрытием встречной позиции. Этот маневр позволяет совершить все операции по развороту сразу же, как только будет получен сигнал от нейросети. Чтобы сократить количество ложных срабатываний от сигналов нейросети, их считывание и принятие решений будем производить только по сформировавшимся барам и по ценам открытия этих самых баров. Решение задачи Ниже приведен исходный код советника, реализующего данную торговую стратегию: //+------------------------------------------------------------------+ //| ArtificialIntelligence.mq4 | //| Copyright й 2006, Yury V. Reshetov | //| http://reshetov.xnet.uz/ | //+------------------------------------------------------------------+ #property copyright "Copyright й 2006, Yury V. Reshetov ICQ:282715499 http://reshetov.xnet.uz/" #property link "http://reshetov.xnet.uz/" //---- input parameters extern int x1 = 120; extern int x2 = 172; extern int x3 = 39; extern int x4 = 172; // StopLoss level extern double sl = 50; extern double lots = 0.1; extern int MagicNumber = 888; static int prevtime = 0; static int spread = 3; //+------------------------------------------------------------------+ //| expert initialization function | //+------------------------------------------------------------------+ int init() { //---- return(0); } //+------------------------------------------------------------------+ //| expert deinitialization function | //+------------------------------------------------------------------+ int deinit() { //---- return(0); } //+------------------------------------------------------------------+ //| expert start function | //+------------------------------------------------------------------+ int start() { if(Time[0] == prevtime) return(0); prevtime = Time[0]; //---- if(IsTradeAllowed()) { spread = MarketInfo(Symbol(), MODE_SPREAD); } else { prevtime = Time[1]; return(0); } int ticket = -1; // check for opened position int total = OrdersTotal(); for(int i = 0; i < total; i++) { OrderSelect(i, SELECT_BY_POS, MODE_TRADES); // check for symbol & magic number if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) { int prevticket = OrderTicket(); // long position is opened if(OrderType() == OP_BUY) { // check profit if(Bid > (OrderStopLoss() + (sl * 2 + spread) * Point)) { if(perceptron() < 0) { // reverse ticket = OrderSend(Symbol(), OP_SELL, lots * 2, Bid, 3, Ask + sl * Point, 0, "AI", MagicNumber, 0, Red); Sleep(30000); if(ticket < 0) { prevtime = Time[1]; } else { OrderCloseBy(ticket, prevticket, Blue); } } else { // trailing stop if(!OrderModify(OrderTicket(), OrderOpenPrice(), Bid - sl * Point, 0, 0, Blue)) { Sleep(30000); prevtime = Time[1]; } } } // short position is opened } else { // check profit if(Ask < (OrderStopLoss() - (sl * 2 + spread) * Point)) { if(perceptron() > 0) { // reverse ticket = OrderSend(Symbol(), OP_BUY, lots * 2, Ask, 3, Bid - sl * Point, 0, "AI", MagicNumber, 0, Blue); Sleep(30000); if(ticket < 0) { prevtime = Time[1]; } else { OrderCloseBy(ticket, prevticket, Blue); } } else { // trailing stop if(!OrderModify(OrderTicket(), OrderOpenPrice(), Ask + sl * Point, 0, 0, Blue)) { Sleep(30000); prevtime = Time[1]; } } } } // exit return(0); } } // check for long or short position possibility if(perceptron() > 0) { //long ticket = OrderSend(Symbol(), OP_BUY, lots, Ask, 3, Bid - sl * Point, 0, "AI", MagicNumber, 0, Blue); if(ticket < 0) { Sleep(30000); prevtime = Time[1]; } } else { // short ticket = OrderSend(Symbol(), OP_SELL, lots, Bid, 3, Ask + sl * Point, 0, "AI", MagicNumber, 0, Red); if(ticket < 0) { Sleep(30000); prevtime = Time[1]; } } //--- exit return(0); } //+------------------------------------------------------------------+ //| The PERCEPRRON - a perceiving and recognizing function | //+------------------------------------------------------------------+ double perceptron() { double w1 = x1 - 100.0; double w2 = x2 - 100.0; double w3 = x3 - 100.0; double w4 = x4 - 100.0; double a1 = iAC(Symbol(), 0, 0); double a2 = iAC(Symbol(), 0, 7); double a3 = iAC(Symbol(), 0, 14); double a4 = iAC(Symbol(), 0, 21); return (w1 * a1 + w2 * a2 + w3 * a3 + w4 * a4); } //+------------------------------------------------------------------+} Осталось только подобрать весовые коэффициенты линейного уравнения разделительной плоскости для нейросети. klot писал: Спасибо! Всё досупно и правильно написано. Я тут немного модернизировал Вашего советника, - попробовал сделать "многослойную сеть" из 4-х перцептронов.У каждого свой состав входов и каждый обучался отдельно на максимальную прибыль. Потом, 5-й обобщал результаты (обучался на минимизацию просадки) предыдущих 4-х. Получилось не плохо, много сделок и просадка не большая. А вообще, мне нравиться, эту тему я давно изучаю. Правда зашел через "парадный вход" начал с самых истоков. Если есть желание посотрудничать обсуждение идёт тут: http://www.fxexpert.ru/forum/index.php?showtopic=656 Yury V. Reshetov Я тоже попробовал 5-ти слойку. Первые 4 имеют по 5 входов, на каждый из которого поступают нормированные значения с отдельно взятого индикатора (на каждый слой свой индикатор). 5-й слой 4-х входовый и также обобщающий. Результаты весьма неплохие получаются. Самое главное, что вне репрезентативной выборки ведет себя очень стабильно по сравнению с однослойкой. Удобно тем, что каждый слой можно обучать по отдельности. Осталось только полностью автоматизировать весь процесс обучения на истории. Лучший вариант - это взять сразу 4 компьютера и распараллелить процессы обучения. Потом собрать результаты с 4 слоев воедино и обучить последний слой. |
![]() ![]() |
![]() |
Текстовая версия | Сейчас: 14.3.2025, 13:24 |