Смотри, как бесплатно скачать роботов
Ищи нас в Twitter!
Ставь лайки и следи за новостями
Интересный скрипт?
Поставь на него ссылку - пусть другие тоже оценят
Понравился скрипт?
Оцени его работу в терминале MetaTrader 5
Советники

Советник по времени с динамическим трейлингстопом и трейлингпрофитом. - эксперт для MetaTrader 4

Просмотров:
6483
Рейтинг:
(12)
Опубликован:
2020.03.18 14:00
Нужен робот или индикатор на основе этого кода? Закажите его на бирже фрилансеров Перейти на биржу

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

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

Для рыночного ордера используется динамический трейлингстоп. Stoploss модифицируется на расстояние, не больше значения Трейлингстоп от текущей цены Bid, для ордеров Buy, и от цены Ask, для ордеров Sell и уменьшает Трейлингстоп при приближении к ТейкПрофит по формуле линейного уменьшения в первом варианте и убыстряющегося по обратной связи во втором варианте.

Для TakeProfit так же используется трейлинг на постоянную величину. При приближении текущей цены к уровню TakeProfit, Тейкпрофит модифицируется на расстояние TralingProfit.

 Ограничения выбора типов ордеров:

1.                       Можно выбрать только один тип рыночного ордера, либо Buy, либо Sell. И с выбранным рыночным ордером нельзя выбрать отложенные ордера.

2.                       Отложенные и лимитные ордера можно выбирать в любом сочетании.

 Во входных параметрах добавлены:

Tral_Profit=100;                        // Дист. отодвигания профита

Ksl = 0.2; // Коэффициент уменьшения StopLoss, по мере приближения к TakeProfit

                        // по формуле для Бай SL = Bid - (Tral_Stop - Ksl (Bid - OrderOpenPrice()))    в первом варианте

                       // и для Бай SL = Bid - (SL - Ksl (Bid - OrderOpenPrice()))  во втором варианте.

 

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

 Алгоритм работы.

 При инициализации.

Алгоритм не отличается от первого советника. Проверка на ошибки и ограничения по типам ордеров, подсчет ордеров с нашим магик на всякий случай.

 Начинаем работу на Тике. Функция OnTick

 Проверки на критическую ошибку, окончание работы не отличаются от первого советника.

 Здесь нет функции подсчета ордеров. Анализ перехода в рыночный ордер ведется по тикетам открытых ордеров и определению изменения их типа в рыночный  в функции CountMarketOrder(). Поэтому смотрим жив ли наш рыночный ордер без переменной Total. Далее, как и в первом советнике, если появился рыночный ордер смотрим время закрытия нашего ордера, если оно равно нулю, ордер не закрыт, значит нам надо проверить нужно ли модифицировать ордер, по условиям трейлингстопа в функции ModifyTral();

if(Or==0 || Or==1)  // если рыночный ордер был выставлен и жив

     {

     if(OrderSelect(Ticket, SELECT_BY_TICKET)==true)

        {

         if(OrderCloseTime()==0)              // Если наш рыночный ордер не закрыт

           {             ModifyTral();

            return;

           }

Проверка на закрытие нашего ордера, выставление ордеров по времени такое же как и в первом советнике. После выставления ордеров флаг OpnOr=true;

 Далее, если флаг открытия ордеров положительный, OpnOr=true;, в функции CountMarketOrder() проверяем наши ордера, не стали ли они рыночными и если появился рыночный ордер, вызываем функцию SelectOrder(int Tickets) в которой присваиваем нашим переменным значения рыночного ордера, и удаляем оставшиеся отложенные ордера в функции DeleteOrder();

if(OpnOr==true)

     {

      CountMarketOrder();// функция отслеживания рыночного ордера с нашими тикет

     }

  И уходим на ожидание нового тика.

   return;

На этом работа функции OnTick заканчивается.

 Алгоритм работы функций.

 Функция подсчета ордеров с нашим Магик Countinit()

 Алгоритм не отличается от первого советника. Подсчет рыночных и отложенных ордеров по нашему инструменту и с нашим Магик.

 Функция подсчета рыночных ордеров Count()

 Нет такой функции здесь.

 Функция модификации рыночного ордера по условиям Трейлингстоп ModifyTral()

 Модификацию ордера проводим в цикле while по условию (true) как и в первом советнике.

Присваиваем переменным значения

      double TSt=New_Stop(Tral_Stop) ;          // Неизменяемое значение трейлингстопа

      double TS=New_Stop(Tral_Stop);            // Изменяемое значение трейлингстопа

      double TT=New_Stop(Tral_Profit) ;         // Неизменяемое значение трейлингпрофита.

Значения присваиваем через функцию New_Stop(), которая присваивает минимально допустимое значение, если вдруг значение параметра станет меньше допустимого.

Присваиваем флагу модификации Modify=false; значение Ложь перед подсчетом и сравнением уровней цены плюс или минус трейлингстоп и стоплосс.

 В операторе switch(Tip)

Для Типа ордера 0, case 0 : т.е. Buy действия следующие:

Считаем уровень Трейлингстопа в зависимости от уровня цены по формуле

TS = round((TSt-Ksl*(Bid-Price)*point));

           TS=New_Stop(TS) ;     // и проверяем на минимально допустимые значения.

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

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

             TS = round((TS-Ksl*(Bid-Price)*point));

           TS=New_Stop(TS) ;     // и проверяем на минимально допустимые значения.

Так называемая обратная связь. Дает убыстрение уменьшения трейлингстопа. Т.е. трейлингстоп уменьшается не линейно, по прямой, а по кривой, убыстряясь.

Далее все как в первом советнике.

Если уровень СтопЛосс меньше (ниже) значения текущей цены Bid минус новое значение Трейлингстоп в пунктах умноженный на значение Point, т.е. цена поднялась выше цены открытия ордера, то уровень СтопЛосс делаем на уровне цены Bid минус Трейлингстоп умноженный на значение Point то модифицируем ордер, т.е. присваиваем переменной SL новое значение, а флагу модификации Modify=true; значение Истина и проверяем уровень трейлингпрофита.

Если цена приблизилась к уровню Тейкпрофита ближе чем значение Трейлингпрофита, отодвигаем его.

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

Далее выходим из оператора switch по команде break;, но не из цикла  while. Так же переменной Text ="Buy "; присваиваем соответствующее значение, для сообщения. 

             if(NormalizeDouble(SL,Digits)<  // Если ниже желаем.

               NormalizeDouble(Bid-TS*Point,Digits))

              {

               SL=Bid-TS*Point;           // то модифицируем его

               Text="Buy ";        // Текст для Buy

               Modify=true;               // Назначен к модифи.

             TP    =OrderTakeProfit();

            if(TP<Bid+TT*Point)

            TP=Bid+TT*Point;

              }

            break;                        // Выход из switch

Для Типа ордера 1, case 1 : т.е. Sell действия симметричные.

Далее, если флаг модификации не изменился, т.е. Ложь, выходим из цикла while, и за циклом возвращаем значение флага модификации return(Modify); 

if(Modify==false)                   // Если его не модифи

         break;                           // Выход из while

Иначе флаг модификации Истина, и мы приступаем к модификации ордера.

Делаем это как и в первом советнике и после модификации возвращаем значение флага модификации.

return(Modify); 

Функция обработки ошибок. 

Алгоритм одинаков с первым советником, по кодам ошибок определяем, исправляемые они или нет и далее исправляем или флаг работы делаем Ложь. 

Функция проверки минимальной дистанции.  

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

Функция открытия ордеров.

Функция открытия ордеров начинает свою работу после наступления времени открытия ордеров.

Алгоритм одинаков с первым советником. Функция открывает выбранные типы ордеров. 

Функция удаления ордеров 

Функция удаления ордеров вызывается сразу после появления рыночного ордера в функции отслеживания появления рыночного ордера по тикету CountMarketOrder().

Алгоритм одинаков с первым советником. Удаляем отложенные ордера по условию, что тикет рыночного ордера не равен тикету отложенного ордера и тикет отложенного ордера не равен нулю. 

Функция отслеживания рыночного ордера CountMarketOrder() 

Мы точно знаем, что переменные тикетов по типам открытых ордеров не равны нулю, переменные тикетов неоткрытых типов ордеров равны нулю. Этим и воспользуемся.

Для рыночных типов просто смотрим, не равен ли он нулю, и если не равен, присваиваем переменной Ticket значение нашего тикета Ticket0 или Ticket1. Далее в функции SelectOrder(Ticket); присваиваем нашим переменным значения выбранного ордера и на всякий случай удаляем оставшиеся. Здесь это не нужно, т.к. мы не можем выставить рыночный ордер с отложенным вместе, но мне так спокойней.

if(Ticket0!=0)

     {

      Ticket=Ticket0;

      SelectOrder(Ticket);

      DeleteOrder();

      return(Ticket);

Для отложенных ордеров, если тикет открытого отложенного ордера не равен нулю, выбираем ордер по тикету и смотрим его тип. Если для Ticket2 и Ticket4, ордеров BuyStop и BuyLimit тип стал равен нулю, , а для Ticket3 и Ticket5 ордеров SellStop и SellLimit стал равен 1, т.е. стал рыночным, присваиваем переменной Ticket значение тикета открытого отложенного ордера, далее в функции SelectOrder(Ticket); присваиваем нашим переменным значения выбранного ордера и удаляем оставшиеся в функции DeleteOrder(). Возвращаем значение тикет.

if(Ticket2!=0)

     {

      sel=OrderSelect(Ticket2, SELECT_BY_TICKET);

      if(OrderType()==0)

        {

         Ticket=Ticket2;

         SelectOrder(Ticket);

         DeleteOrder();

         return(Ticket);

        } 

Функция присваивания значений ордера. 

Еще раз выбираем наш рыночный ордер, присваиваем значения, выводим Алерт что наш ордер стал рыночным, и в зависимости от типа присваиваем значение переменной Or.

Так же выводим сообщение, какой отложенный ордер стал рыночным. 

   sel=OrderSelect(Tickets, SELECT_BY_TICKET);

   Tip   =OrderType();                    // Тип выбранного орд.

   Symb= Symbol();                        //Инструмент выбранного ордера;

   Price =OrderOpenPrice();               // Цена открытия выбранн. орд.

//   ClosePrice = OrderClosePrice();

   SL    =OrderStopLoss();                // SL выбранного орд.

   TP    =OrderTakeProfit();              // TP выбранного орд.

   Lot   =OrderLots();                    // Количество лотов

   Alert("Наш Ордер Тикет = ", Ticket,"Тип = ", Tip,OrderType(),"Ask",Ask,"Цена открытия",OrderOpenPrice()); 

   if(Tip==OP_BUY)

      Or=0; 

   if(Tip==OP_SELL)

      Or=1; 

   if(Ticket == Ticket2)

     {  Alert("Рыночным Ордером стал ордер BuyLimit, Тралим его");}

   if(Ticket == Ticket3)

     { Alert("Рыночным Ордером стал ордер SellLimit, Тралим его");}

   if(Ticket == Ticket4)

     { Alert("Рыночным Ордером стал ордер BuyStop, Тралим его");}

   if(Ticket == Ticket5)

     { Alert("Рыночным Ордером стал ордер SellStop, Тралим его");}

   Work=true;

   return(Or);                             // Выход из функции

Библиотека для работы с COM-объектами. Библиотека для работы с COM-объектами.

Эта библиотека даёт возможность работать с COM-объектами, предоставленными некоторыми приложениями. Например: Excel, Word, Mathcad, Matlab. А также объект ADODB для работы с базами данных через драйвер ODBC. Библиотека работает и в MT4 и в MT5.

Average Day Range Average Day Range

Индикатор рисует два квадрата: один от минимума вверх, а второй от максимума вниз. Высота квадрата равна ADR (5 дней).

AccEq - индикатор Equity счёта AccEq - индикатор Equity счёта

Индикатор отслеживает изменения Equity, сохраняет историю М1, отображает в произвольных стандартных таймфреймах изменения Эквити и баланса.

MCP MCP

Любопытная индикаторная система на основе MCPI (Multi Currency Pair Indicator). Основное его предназначение - экономия времени для проверки состояния других валютных пар.