Смотри, как бесплатно скачать роботов
Ищи нас в Facebook!
Ставь лайки и следи за новостями
Интересный скрипт?
Поставь на него ссылку - пусть другие тоже оценят
Понравился скрипт?
Оцени его работу в терминале MetaTrader 5
Просмотров:
469
Рейтинг:
(7)
Опубликован:
MQL5 Фриланс Нужен робот или индикатор на основе этого кода? Закажите его на бирже фрилансеров Перейти на биржу

Настройка

Нам понадобится :

  • 1 зигзагообразный график
  • 2 буфера данных для максимумов и минимумов
  • входные параметры
  • постоянный набор системных переменных, которые обнуляются при каждом пересчете индикатора

#property indicator_buffers 2
#property indicator_plots 1
input double retracement=23.6;// сумма отката
input double minSizeInAtrUnits=0.0;//min Размер волн в единицах атр
input int rollingAtrPeriod=14;// период качения
input color Color=clrDodgerBlue;//цвет волны
input int Width=3;// ширина волны
input ENUM_LINE_STYLE Style=STYLE_SOLID;//волновой стиль
//+------------------------------------------------------------------+




//| Пользовательская функция инициализации индикатора |
//+------------------------------------------------------------------+
//--- восходящие волны и нисходящие волны
  double upWaves[],dwWaves[];

Массив upWaves будет хранить максимумы, а массив dwWaves - минимумы.

Системные переменные :

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

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

//--- слежение за зигзагом
  //--- тип волны [0] нет [1] вверх [2] вниз
    int wave_type=0;
  //--- цена с начала волны (начальная цена) 
    double wave_start_price=0.0;
  //--- цена до конца волны (цена окончания)
    double wave_end_price=0.0;
  //--- расстояние в барах от начальной цены
    int wave_start_distance=0;
  //--- расстояние в барах от конечной цены
    int wave_end_distance=0;
  //--- отслеживание высоких цен
    double high_mem=0.0;
    int distance_from_high=0;
  //--- низкая цена отслеживания
    double low_mem=0.0;
    int distance_from_low=0;
  //--- rolling atr
    double rollingAtr=0.0;
       int rollingAtrs=0;

И, наконец, единица измерения скользящего атр и их количество.

Затем мы создадим функцию сброса системы:

void resetSystem(){
ArrayFill(upWaves,0,ArraySize(upWaves),0.0);
ArrayFill(dwWaves,0,ArraySize(dwWaves),0.0);
wave_type=0;
wave_start_price=0.0;
wave_end_price=0.0;
wave_start_distance=0;
wave_end_distance=0;
high_mem=0.0;
low_mem=0.0;
distance_from_high=0;
distance_from_low=0;
rollingAtr=0.0;
rollingAtrs=0;
}

Стандартные вещи, заполняем массивы нулями и сбрасываем системные переменные.

В Oninit мы настраиваем буферы, график и вызываем reset в первый раз:

  SetIndexBuffer(0,upWaves,INDICATOR_DATA);
  SetIndexBuffer(1,dwWaves,INDICATOR_DATA);
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
   PlotIndexSetInteger(0,PLOT_DRAW_TYPE,DRAW_ZIGZAG);
   PlotIndexSetInteger(0,PLOT_LINE_COLOR,0,Color);
   PlotIndexSetInteger(0,PLOT_LINE_WIDTH,Width);
   PlotIndexSetInteger(0,PLOT_LINE_STYLE,Style);
  resetSystem();

Так что давайте сразу перейдем к вычислениям.

Первое, о чем нам нужно позаботиться, - это скользящий атр.

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

Часть, которая управляет скользящим atr, выглядит следующим образом:

  • если мы не собрали больше периода, продолжаем складывать диапазон найденных баров в сумму
  • как только мы достигли периода, мы выполняем первое деление (среднее)
  • после этого мы отрезаем одну часть скользящего atr, которая является atr/period, а затем добавляем новую часть, которая является диапазоном баров / периодом
Мы помещаем последнюю часть первой, потому что она будет происходить чаще, и нам не нужно будет обращаться к 2 операторам if.

     //--- управляйте атр
       rollingAtrs++;
       if(rollingAtrs>rollingAtrPeriod){
       double new_portion=((high[i]-low[i])/_Point)/((double)rollingAtrPeriod);
       //--- мы удаляем старую порцию и добавляем новую
       rollingAtr=(rollingAtr)-(rollingAtr/((double)rollingAtrPeriod))+new_portion;
       }
       else if(rollingAtrs<=rollingAtrPeriod){
         rollingAtr+=(high[i]-low[i])/_Point;
         if(rollingAtrs==rollingAtrPeriod){
           rollingAtr/=((double)rollingAtrs);
           //--- запустите память для максимумов и минимумов и систему
             high_mem=high[i];
             low_mem=low[i];
             distance_from_high=0;
             distance_from_low=0;
           }
         }

Потрясающе, теперь возникает другая проблема.

Основой этого зиг-зага является откат.

Но чтобы произошел откат, должна быть хотя бы одна волна.

Но какой будет первая волна? xD

По этой причине мы сделаем следующее:

  • как только atr заполнится (atr собран = период), мы захватим максимум и минимум в нашей системе переменных
  • какая сторона сумеет сформировать волну, имеющую действительный размер в единицах atr, и сформирует новый максимум (восходящая волна) или новый минимум (нисходящая волна), та и победит

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

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

Именно так мы и поступаем, пока у нас нет волны:

   //--- если у нас еще нет типа волны
     else{
       //--- если мы пробили максимум, а не минимум
         if(high[i]>high_mem&&low[i]>=low_mem){
         double new_wave_size_in_atr_units=((high[i]-low_mem)/_Point)/rollingAtr;
         //--- если новый размер волны действителен
         if(new_wave_size_in_atr_units>=minSizeInAtrUnits){
           //--- начните новую волну 
             wave_type=1;
           //--- Стартовая цена - это низкий мем 
             wave_start_price=low_mem;
             wave_start_distance=distance_from_low;
           //--- конечная цена - новый максимум
             wave_end_price=high[i];
             wave_end_distance=0;
           //--- нарисуйте волну 
             dwWaves[i-wave_start_distance]=low_mem;
             upWaves[i]=high[i];
           //--- изменить высокий
             high_mem=high[i];
             distance_from_high=0;
           //--- измените низкий уровень 
             low_mem=low[i];
             distance_from_low=0;
           }
           } 
       //--- если мы пробили минимум, а не максимум
         else if(low[i]<low_mem&&high[i]<=high_mem){
         double new_wave_size_in_atr_units=((high_mem-low[i])/_Point)/rollingAtr;
         //--- если новый размер волны действителен
         if(new_wave_size_in_atr_units>=minSizeInAtrUnits){         
           //--- начало новой волны снижения 
             wave_type=-1;
           //--- Стартовая цена - это старшая память 
             wave_start_price=high_mem;
             wave_start_distance=distance_from_high;
           //--- конечная цена - новый минимум
             wave_end_price=low[i];
             wave_end_distance=0;
           //--- нарисуйте волну 
             upWaves[i-wave_start_distance]=high_mem;
             dwWaves[i]=low[i];
           //--- изменить высокий
             high_mem=high[i];
             distance_from_high=0;
           //--- измените низкий уровень 
             low_mem=low[i];
             distance_from_low=0;
           }
           }
       //--- если мы сломали оба
         else if(low[i]<low_mem&&high[i]>high_mem){
           //--- измените их
             high_mem=high[i];
             low_mem=low[i];
             distance_from_high=0;
             distance_from_low=0;
           }
       }

Отлично Теперь последняя часть.

  • Если у нас есть восходящая волна:
  1. если достигнут новый максимум, перемещаем зигзаг с предыдущей позиции максимума на новую позицию максимума, что мы можем сделать, так как сохраняем расстояния между барами. Также обновляем минимум и расстояние от минимума. Мы делаем это, чтобы поймать самый низкий минимум с момента пика и проверить, достаточно ли он отступил, чтобы начать новый минимум.
  2. Если новый минимум достигнут, или установлен новый минимум, мы вычисляем расстояние от пика до минимума и делим его на размер волны. Таким образом, если размер волны составляет 100 пунктов, а откат 24 пункта, мы получаем 24/100 0.24, затем x 100 24%. Если размер новой волны, которая отступает от предыдущей, также соответствует единицам atr, мы начинаем новую волну вниз, устанавливаем новые локальные максимумы и минимумы, задаем расстояния между барами.

Вот соответствующий код для всего вышесказанного:

       //--- если у нас есть восходящая волна 
         if(wave_type==1){
           //--- если волна расширяется вверх 
             if(high[i]>wave_end_price){
               //--- удалите предыдущую конечную цену из своей позиции в массиве (0.0=пусто)
                upWaves[i-wave_end_distance]=0.0;
               //--- поместите его на новую позицию
                upWaves[i]=high[i];
                wave_end_price=high[i];
                wave_end_distance=0;
               //--- изменить высокий
                high_mem=high[i];
                distance_from_high=0;
               //--- измените низкий уровень 
                low_mem=low[i];
                distance_from_low=0;
               }
           //--- проверяем на откат
             if(low[i]<low_mem||distance_from_low==0){
               low_mem=low[i];
               distance_from_low=0;
               double size_of_wave=(wave_end_price-wave_start_price)/_Point;
               double size_of_retracement=(wave_end_price-low_mem)/_Point;
               if(size_of_wave>0.0){
                 double retraced=(size_of_retracement/size_of_wave)*100.0;
                 double new_wave_size_in_atr_units=((wave_end_price-low_mem)/_Point)/rollingAtr;
               //--- если новый размер волны действителен
               if(new_wave_size_in_atr_units>=minSizeInAtrUnits){
                 //--- если откат будет значительным, начните волну вниз
                   if(retraced>=retracement){
                    //--- начало новой волны снижения 
                      wave_type=-1;
                    //--- Стартовая цена - это старшая память 
                      wave_start_price=high[i-distance_from_high];
                      wave_start_distance=distance_from_high;
                    //--- конечная цена - новый минимум
                      wave_end_price=low[i];
                      wave_end_distance=0;
                    //--- нарисуйте волну 
                      upWaves[i-wave_start_distance]=high_mem;
                      dwWaves[i]=low[i];
                    //--- изменить высокий
                      high_mem=high[i];
                      distance_from_high=0;
                    //--- измените низкий уровень 
                      low_mem=low[i];
                      distance_from_low=0;                     
                     }
                   }
                 }
               }
           }

Мы делаем обратное, когда у нас есть волна вниз.

И все, наш зигзаг коррекции готов.

Вот зигзаг с 23,6% коррекцией и 0,0 мин размером волн в единицах atr


И вот тот же зигзаг с размером волн 3 мин в единицах atr






Перевод с английского произведен MetaQuotes Ltd.
Оригинальная публикация: https://www.mql5.com/en/code/56619

Swaps Monitor for a Single Symbol Swaps Monitor for a Single Symbol

Простая утилита для мониторинга длинных и коротких свопов по одному символу. Если свопы вашего брокера-дилера указаны в пунктах, а не в валюте счета, эта утилита автоматически конвертирует пункты в валюту счета. В среду свопы утраиваются. Горизонтальное и вертикальное выравнивание можно настроить во входных данных.

AutoCloseOnProfitLoss Expert - Automatically Close All Positions on Profit/Loss AutoCloseOnProfitLoss Expert - Automatically Close All Positions on Profit/Loss

Советник AutoCloseOnProfitLoss - это мощный инструмент автоматизации для MetaTrader 5, предназначенный для закрытия всех открытых позиций при достижении заданных целей по прибыли или убытку.

Autoscaling Zigzag Autoscaling Zigzag

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

Telegram integration made easy. Telegram integration made easy.

Цель - сделать функцию легкодоступной для любой задачи по интеграции Telegram при разработке на MQL5. Добавив этот файл в CodeBase, вы можете просто включить его в свои эксперты и вызывать функцию непосредственно из включенного модуля. Это избавляет от необходимости многократно переделывать код с нуля, обеспечивая возможность повторного использования в различных проектах.