Двухэтапный вариант модификации открытых позиций
Введение
В статье "Подход Т. Демарка к техническому анализу" есть рекомендованные коэффициенты длины коррекции, в частности 0,382 и 0,618. Применяя эти коэффициенты при отслеживании открытых позиций, можно избежать ненужных ситуаций закрытия и переоткрытия позиций в ситуациях близких к трендовым. Функция хорошо работает особенно в ситуациях возникновения дивергенций.
Этот подход с учетом переустановки величины профита помогает уловить и возникновение "хорошего" тренда. Например, как показано на рис1 по сравнению с рис2.
Алгоритм функции
1-ая модификация ордера по заданному значению TrailingStop, последующие - устанавливают StopLoss на 1 или 2 пункта ниже возможного уровня коррекции (в данном случае коэффициент коррекции = 0.382 "Coeff_ "). Значение TakeProfit при каждом шаге увеличиваем, например на половину величины TrailingStop-а (можно выбрать и другую величину!). Можно так же и не менять величину TakeProfit. Для этого в начале программы в операторе extern double March = 0; установить значение ноль.
Для тех трейдеров, которые предпочитают адресный анализ-поддержку выполнения конкретных действий программы непосредственно в ходе торгов, целесообразнее будет переменную MagicNumber перенести в код самого советника в то место, где происходит открытие позиции. Более подробно о конкретной адресной поддержке можно прочитать в Учебнике, опубликованного на сайте MQL4.com (автор С.Ковалев).
Рассмотрим поподробнее предлагаемый код и комментарии к нему будущей функции в советнике:
//+------------------------------------------------------------------+ //| Двухэтапный вариант TrailingStop Modify_2step v5.mq4 | //| Модификация ордеров: переустановка StopLoss и TakeProfit | //+------------------------------------------------------------------+ #property copyright "Copyright © 2008, GenKov" #property link Genkov@bk.ru //+------------------------------------------------------------------+ /* Magic=N
Magic=N - такой оператор надо вставлять при открытии позиции сразу же после операторов контроля выполнения условий в самой программе (советнике), и в функцию! Наверное, в связи с непредсказуемостью рынка, как мне кажется, универсального модификатора мне создать не удалось, а поэтому для каждого вида условий открытия позиций (по Magic=N) надо писать функцию отслеживания (передвижения S/L и T/P) и условия закрытия позиции.
extern double March = 1; // шаг увеличения TakeProfit-а // "0" шаг не увеличивает T/P.
S/L должен быть на 1 пункт меньше TrailingStop-а, чтобы при первом же срабатывании S/L оказался на безубыточном уровне. Таким образом мы страхуем себя от возможных потерь (управление капиталом).
extern double StopLoss = 15; extern double TrailingStop = 16; extern double TakeProfit = 60; // подбор по тестеру //+------------------------------------------------------------------+ //void TrailingStop() int start() { //----------------------------------------------------------------+ int point = MarketInfo(Symbol(),MODE_POINT); // Размер пункта int StopLev= MarketInfo(Symbol(),MODE_STOPLEVEL); double half_Trail = MathRound(TrailingStop/2);//половина TrailingStop-а double Step = March*half_Trail; //величина увеличения TakeProfit-а if (TrailingStop<0) return; { for (int i=0; i<OrdersTotal(); i++) { if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break; if (OrderSymbol()!=Symbol() || OrderMagicNumber()!=Magic) continue; if (OrderType()==OP_BUY) {
Первый этап модификации позиций BUY
if(OrderStopLoss()<OrderOpenPrice())//если S/L ниже цены открытия ордера { // и если разность между текущей ценой и ценой открытия поз больше T/S if(Bid-OrderOpenPrice()>TrailingStop*Point) // && { // и если OrderStopLoss() меньше разницы текущей цены и T/S if(OrderStopLoss()<Bid-TrailingStop*Point) { // расчитаем новое значение T/P double Now_T_P=(OrderTakeProfit()+Step*Point); { OrderModify(OrderTicket(),OrderOpenPrice(), OrderStopLoss()+TrailingStop*Point, OrderTakeProfit()+Step*Point,0,Aqua); // повышаем значение T/P return; } } } }
Однако, может возникнуть ситуация, когда передвигаемый TakeProfit станет на 2-3 пункта выше ранее запланированного уровня прибыли, остановится и
начнет медленно снижаться.
Чтобы избежать упущенной прибыли, введем оператор контроля над этой ситуацией, который и закроет ордер на запланированном уровне прибыли. Если же цена продолжит рост, то будет продолжено продвижение стоп-лоса и тейк-профита.
if(Bid-OrderOpenPrice()>=TakeProfit*Point && (Pr_Op_1-Pr_Op_0)>2*Point) { // Print(" Bid= ",Bid," >= ",OrderTakeProfit()," Magic= ",Magic); OrderClose(OrderTicket(),Lots,Bid,2,Red); }
// второй этап модификации поз.BUY
if(OrderStopLoss()>=OrderOpenPrice()) // Стор лос на безубыточном уровне { // посчитаем коэффициент коррекции double Coeff_up = NormalizeDouble((Bid-OrderOpenPrice())*0.382,Digits); // и если разность между текущей ценой и ценой открытия поз больше коэфф. коррекции if(Bid-OrderOpenPrice()>Coeff_up) { // посчитаем значение нового StopLoss с запасом в 2-а пункта double New_S_Loss = Bid-Coeff_up-2*Point; // и если значение нового StopLoss-a выше текущего значения if(New_S_Loss-OrderStopLoss()>3*Point) { // передвинем S/L и T/P OrderModify(OrderTicket(),OrderOpenPrice(), New_S_Loss,OrderTakeProfit()+Step*Point,0,Yellow); } // Print(" Bid-OrderOpenPrice()= ",Bid-OrderOpenPrice()); // Print(" 2 Coeff_up= ",Coeff_up," Order_S_Los= ",New_S_Loss," Bid= ",Bid); return; } } }
Подход к короткой позиции аналогичен предыдущим рассуждениям и поэтому комментариев поменьше.
// ---------------------------- 1 этап модификации -----SELL-------------& else if(OrderType()==OP_SELL) { if(OrderStopLoss()>OrderOpenPrice())//если S/L выше цены открытия ордера { if(OrderOpenPrice()-Ask>TrailingStop*Point && OrderStopLoss()>Ask+TrailingStop*Point) { OrderModify(OrderTicket(),OrderOpenPrice(), Ask+TrailingStop*Point,OrderTakeProfit()-Step*Point,0,SkyBlue); return; } } if(OrderOpenPrice()-Ask>=TakeProfit*Point && (Pr_Op_0-Pr_Op_1)>2*Point) { OrderClose(OrderTicket(),Lots,Bid,2,Red); } // ---------------------------- 2 этап модификации -----SELL-------------& if(OrderStopLoss()<=OrderOpenPrice()) // Стор лос на безубыточном уровне { // посчитаем коэффициент коррекции double Coeff_down = NormalizeDouble((OrderOpenPrice()-Ask)*0.382,Digits); // и если разность между ценой открытия поз и текущей ценой больше коэфф. коррекции if(OrderOpenPrice()-Ask>Coeff_down) { // посчитаем значение нового StopLoss с запасом в 2-а пункта New_S_Loss = Ask+Coeff_down+2*Point; // и если значение нового StopLoss-a ниже текущего значения if(New_S_Loss-OrderStopLoss()>3*Point) { // передвинем S/L и T/P OrderModify(OrderTicket(),OrderOpenPrice(), New_S_Loss,OrderTakeProfit()-Step*Point,0,Khaki); return; } } } } } // -----------------------------------------------------------------------------------
Для превращения этого советника в функцию надо закомментировать специальную функцию int start(), стоящую в начале программы, заменив ее на раскомментированное определение функции TrailingStop() в начале программы, закомментированный вызов функции в конце программы
//TrailingStop();
раскомментировать.
Если добавить нижеприведенный блок, то с его помощью можно провести проверку работоспособности функции, используя ее в качестве советника на тестере истории .
// -------------------------------------------------------------------------------- double Macd_m15_0= iMACD(NULL,PERIOD_M15,12,26,9,PRICE_CLOSE,MODE_MAIN,0); double Macd_m15_1= iMACD(NULL,PERIOD_M15,12,26,9,PRICE_CLOSE,MODE_MAIN,1); if(OrdersTotal()<2) { if(Macd_m15_0<Macd_m15_1) { OrderSend(Symbol(),OP_SELL,0.1,Bid,3,Ask+StopLoss*Point,Bid-TakeProfit*Point,"",Magic,0,Red); } if(Macd_m15_0>Macd_m15_1) { OrderSend(Symbol(),OP_BUY,0.1,Ask,3,Bid-StopLoss*Point,Ask+TakeProfit*Point,"",Magic,0,Blue); } return(0); } // -------------------------------------------------------------------------------- // TrailingStop(); } return(0); } // --- end --- &
Теперь убираем из вышеприведенного текста кода подробные комментарии, и оформляем код в виде исполнительной функции: получим следующий фай, который рекомендуется хранить в директории каталог_терминал\experts\include с расширением .mqh или каталог_терминал\libraries с расширением mq4.
//+------------------------------------------------------------------+ //| Modify_2_Step v5.mq4 | //| Copyright © 2008, GenKov | //| Genkov@bk.ru | //+------------------------------------------------------------------+ #property copyright "Copyright © 2008, GenKov" #property link "Genkov@bk.ru" extern double March = 1; // шаг увеличения TakeProfit-а // "0" шаг не увеличивает T/P. // S/L должен быть на 1 пункт меньше TrailingStop-а, чтобы при // первом же срабатывании S/L оказался на безубыточном уровне extern double StopLoss = 15; extern double TrailingStop = 16; extern double Lots = 0.1; extern double TakeProfit = 60; // подобрать по тестеру void TrailingStop() { int Magic=3090; // номер условия открывшего позицию int point = MarketInfo(Symbol(),MODE_POINT); // Размер пункта int StopLev= MarketInfo(Symbol(),MODE_STOPLEVEL); double half_Trail = MathRound(TrailingStop/2);//половина TrailingStop-а double Step = March*half_Trail; //величина увеличения TakeProfit-а if (TrailingStop<0) return; { for (int i=0; i<OrdersTotal(); i++) {//1 +цикл по перебору ордеров if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break; if (OrderSymbol()!=Symbol() || OrderMagicNumber()!=Magic) continue; if (OrderType()==OP_BUY) { // --------------------------- 1 этап модификации -----BUY-------------& if(OrderStopLoss()<OrderOpenPrice())//если S/L ниже цены открытия ордера { // и если разность между текущей ценой и ценой открытия поз больше T/S if(Bid-OrderOpenPrice()>TrailingStop*Point) // && { // и если OrderStopLoss() меньше разницы текущей цены и T/S if(OrderStopLoss()<Bid-TrailingStop*Point) { // расчитаем новое значение T/P double Now_T_P=(OrderTakeProfit()+Step*Point); { OrderModify(OrderTicket(),OrderOpenPrice(), OrderStopLoss()+TrailingStop*Point, OrderTakeProfit()+Step*Point,0,Aqua); // повышаем значение T/P return; } } } } if(Bid-OrderOpenPrice()>=TakeProfit*Point) { OrderClose(OrderTicket(),Lots,Bid,2,Red); } //------------------------- 2-ой этап модификации -----BUY---------------& if(OrderStopLoss()>=OrderOpenPrice()) // Стор лос на безубыточном уровне { // посчитаем коэффициент коррекции double Coeff_up = NormalizeDouble((Bid-OrderOpenPrice())*0.382,Digits); // и если разность между текущей ценой и ценой поз. больше коэфф. коррекции if(Bid-OrderOpenPrice()>Coeff_up) { // посчитаем значение нового StopLoss с запасом в 6-и пункта double New_S_Loss = Bid-Coeff_up-6*Point-StopLev*Point; // и если значение нового StopLoss-a выше текущего значения if((New_S_Loss-OrderStopLoss())<2*Point) { // передвинем S/L и T/P OrderModify(OrderTicket(),OrderOpenPrice(), OrderStopLoss(),OrderTakeProfit()+Step*Point/2,0,Yellow); } else { OrderModify(OrderTicket(),OrderOpenPrice(), New_S_Loss+1*Point,OrderTakeProfit()+Step*Point,0,Yellow); } return; } } } // ---------------------------- 1 этап модификации -----SELL-------------& else if(OrderType()==OP_SELL) { if(OrderStopLoss()>OrderOpenPrice())//если S/L выше цены открытия ордера { if(OrderOpenPrice()-Ask>TrailingStop*Point && OrderStopLoss()>Ask+TrailingStop*Point) { OrderModify(OrderTicket(),OrderOpenPrice(), Ask+TrailingStop*Point,OrderTakeProfit()-Step*Point,0,SkyBlue); return; } } if(OrderOpenPrice()-Ask>=TakeProfit*Point) { OrderClose(OrderTicket(),Lots,Bid,2,Red); } // ---------------------------- 2 этап модификации -----SELL-------------& if(OrderStopLoss()<=OrderOpenPrice()) // Стор лос на безубыточном уровне if(OrderOpenPrice()-Ask>=OrderTakeProfit()) OrderClose(OrderTicket(),Lots,Ask,2,Red); { // посчитаем коэффициент коррекции double Coeff_down = NormalizeDouble((OrderOpenPrice()-Ask)*0.382,Digits); // и если разность между ценой открытия поз и текущей ценой больше коэффициента коррекции if(OrderOpenPrice()-Ask>Coeff_down) { // посчитаем значение нового StopLoss с запасом в 6-и пункта New_S_Loss = Ask+Coeff_down+6*Point; // и если значение нового StopLoss-a ниже текущего значения if((OrderStopLoss()-New_S_Loss-StopLev*Point)>=10*Point) { // передвинем S/L и T/P OrderModify(OrderTicket(),OrderOpenPrice(), New_S_Loss-5*Point,OrderTakeProfit()-Step*Point,0,Khaki); return; } } } } } return(0); } } // ---end----- void TrailingStop()--------------------------------& // этот блок только для контроля ошибок в коде функции // int start() // { // if(25>26) TrailingStop(); // } // --------------------------------
В заключении нужно сказать, что в отличие от "образцова трейлинг-стопа", описанного 21.04.2008 Сергеем Кравчуком в статье "Образцовый трейлинг-стоп и выход с рынка", предлагаемый вариант попроще в понимании, и в моем советнике срабатывал, правда на демо-счете, и, по моему, подходит для агрессивного и умеренного трейлинга.
Прикреплены варианты версий:
v4 - с закрытием по S/L; v5 - с упреждающим закрытием по T/P; v6 - с учетом упреждения и адресной поддержке по Magic померу.
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Заметил, что в программе вычисляется значение переменной point (с маленькой буквы), а фактически все равно используется стандартная переменная Point (с большой буквы).
Относительно большой и маленькой буквы в переменной Point - дело в том, что в моем компе при тестировании (не на Демо) на некоторых модификациях MQL4 переменная с маленькой буквы не определяется, а с большой - сбоев не наблюдал.
Относительно метода модификации "....., но особенно лучше не стало." - спасибо за приятное для меня сообщение, т.к. можно понять, что небольшое усовершествование дает такую-то пользу, по принципу "лучше 40 раз по разу, чем ниразу 40 раз".
Как прикрутить его к советнику?
А где исходники можно скачать?
Перейдите в первый пост - там ссылка на статью. В конце статьи будут коды,