MetaQuotes Software
MetaQuotes Software Блог компании MetaQuotes Software
20 сентября 2016, 13:55

Как в MetaTrader 5 быстро разработать и отладить торговую стратегию: тиковый анализатор

Скальперские автоматические системы по праву считаются вершиной алгоритмического трейдинга, но при этом они же являются и самыми сложными для написания кода.

В этой статье мы покажем, как с помощью встроенных средств отладки и визуального тестирования строить стратегии, основанные на анализе поступающих тиков. Для выработки правил входа и выхода зачастую требуются годы ручной торговли. Но с помощью MetaTrader 5 вы можете быстро проверить любую подобную стратегию на реальной истории.

Торговая идея на тиках

Прежде всего, нам необходимо создать индикатор, который будет строить тиковые графики — то есть графики,  на которых можно увидеть каждое изменение цены.

Один из первых таких индикаторов вы можете найти в Библиотеке — https://www.mql5.com/ru/code/89. В отличие от обычных, на тиковых графиках при поступлении нового тика необходимо весь график смещать назад.

Как в MetaTrader 5 быстро разработать и отладить торговую стратегию: тиковый анализатор

За основу проверяемой идеи возьмем ряд изменений цены между двумя последовательными тиками, это будет примерно такая последовательность в пунктах:

+1, 0, +2, -1, 0, +1, -2, -1, +1, -5, -1, +1, 0, -1, +1, 0, +2, -1, +1, +6, -1, +1,...

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

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

 

Создаем тиковый индикатор

В MetaEditor запускаем Мастер MQL, задаем имя  и два входных параметра:

  • ticks — сколько тиков будет использоваться для расчета среднеквадратичного отклонения
  • gap — коэффициент для получения интервала в сигмах.

Далее отмечаем «Индикатор в отдельном окне» и указываем 2 графических построения, которые будут отображать информацию в подокне: линия для тиков и цветные стрелки для сигналов о появлении резких изменений цены.

Как в MetaTrader 5 быстро разработать и отладить торговую стратегию: тиковый анализатор

Внесем в полученную заготовку изменения, которые отмечены желтым

//+------------------------------------------------------------------+
//|                                              TickSpikeHunter.mq5 |
//|                        Copyright 2016, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 3
#property indicator_plots   2
//--- plot TickPrice
#property indicator_label1  "TickPrice"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrGreen
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- plot Signal
#property indicator_label2  "Signal"
#property indicator_type2   DRAW_COLOR_ARROW
#property indicator_color2  clrRed,clrBlue,C'0,0,0',C'0,0,0',C'0,0,0',C'0,0,0',C'0,0,0',C'0,0,0'
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1
//--- input parameters
input int      ticks=50;         // количество тиков в расчетах
input double   gap=3.0;          // ширина канала в сигмах
//--- indicator buffers
double         TickPriceBuffer[];
double         SignalBuffer[];
double         SignalColors[];
//--- счетчик изменений цены
int ticks_counter;
//--- первый вызов индикатора
bool first;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,TickPriceBuffer,INDICATOR_DATA);
   SetIndexBuffer(1,SignalBuffer,INDICATOR_DATA);
   SetIndexBuffer(2,SignalColors,INDICATOR_COLOR_INDEX);
//--- укажем пустые значения, которые нужно игнорировать при отрисовке  
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0);
   PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,0);
//--- сигналы будем выводить в виде этого значка
   PlotIndexSetInteger(1,PLOT_ARROW,159);
//--- инициализация глобальных переменных
   ticks_counter=0;
   first=true;
//--- успешная инициализация программы
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+

Теперь осталось добавить код в предопределенный обработчик поступающих тиков OnCalculate(). При первом вызове функции явно обнулим значения в индикаторных буферах, а также для удобства установим для них признак таймсерии — таким образом индексация у них будет справа налево.

Это позволит обращаться к самому свежему значению индикаторного буфера по индексу ноль, то есть в TickPriceBuffer[0] будет храниться значение последнего  тика.

Кроме того,  основную обработку тиков мы вынесем в отдельную функцию ApplyTick():

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//--- при первом вызове обнулим индикаторные буферы и установим признак серии
   if(first)
     {
      ZeroMemory(TickPriceBuffer);
      ZeroMemory(SignalBuffer);
      ZeroMemory(SignalColors);
      //--- массивы серии идут задом наперед, так удобнее в данном случае
      ArraySetAsSeries(SignalBuffer,true);
      ArraySetAsSeries(TickPriceBuffer,true);
      ArraySetAsSeries(SignalColors,true);
      first=false;
     }
//--- возьмем в качестве цены текущее значение Close
   double lastprice=close[rates_total-1];
//--- считаем тики
   ticks_counter++;
   ApplyTick(lastprice); // проведем вычисления и сдвиг в буферах   
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| применяет тик для вычислений                                     |
//+------------------------------------------------------------------+
void ApplyTick(double price)
  {
   int size=ArraySize(TickPriceBuffer);
   ArrayCopy(TickPriceBuffer,TickPriceBuffer,1,0,size-1);
   ArrayCopy(SignalBuffer,SignalBuffer,1,0,size-1);
   ArrayCopy(SignalColors,SignalColors,1,0,size-1);
//--- запишем последнее значение цены
   TickPriceBuffer[0]=price;
//---
  }

Функция ApplyTick() пока производит самые простые действия — сдвигает все значения буфера на одну позицию вглубь истории и пишет в TickPriceBuffer[0] последний тик. Запускаем индикатор под отладкой и наблюдаем некоторое время.

Как в MetaTrader 5 быстро разработать и отладить торговую стратегию: тиковый анализатор

Видим, что цена Bid, по которой строится Close текущей свечи, очень часто остается неизменной, и поэтому график рисуется кусками «плато». Немного подправим код, чтобы получать только «пилу» — так глазу более понятно.

//--- вычисляем только если цена изменилась
   if(lastprice!=TickPriceBuffer[0])
     {
      ticks_counter++;      // считаем тики
      ApplyTick(lastprice); // проведем вычисления и сдвиг в буферах
     }

Итак, первую версию индикатора мы создали, теперь у нас не бывает нулевых приращений цены.

Как в MetaTrader 5 быстро разработать и отладить торговую стратегию: тиковый анализатор

 

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

Для вычисления отклонения нам необходим дополнительный массив, который будет хранить приращения цены на каждом тике. В качестве такого массива добавим еще один индикаторный буфер и добавим соответствующий код  в нужных местах:

#property indicator_separate_window
#property indicator_buffers 4
#property indicator_plots   2
...
//--- indicator buffers
double         TickPriceBuffer[];
double         SignalBuffer[];
double         DeltaTickBuffer[];
double         ColorsBuffers[];
...
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,TickPriceBuffer,INDICATOR_DATA);
   SetIndexBuffer(1,SignalBuffer,INDICATOR_DATA);
   SetIndexBuffer(2,SignalColors,INDICATOR_COLOR_INDEX);
   SetIndexBuffer(3,DeltaTickBuffer,INDICATOR_CALCULATIONS);
...
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const ...)

//--- при первом вызове обнулим индикаторные буфера и установим признак серии
   if(first)
     {
      ZeroMemory(TickPriceBuffer);
      ZeroMemory(SignalBuffer);
      ZeroMemory(SignalColors);
      ZeroMemory(DeltaTickBuffer);
      //--- массивы серии идут задом наперед, так удобнее в данном случае
      ArraySetAsSeries(TickPriceBuffer,true);
      ArraySetAsSeries(SignalBuffer,true);
      ArraySetAsSeries(SignalColors,true);
      ArraySetAsSeries(DeltaTickBuffer,true);
      first=false;
     }
...
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| применяет тик для вычислений                                     |
//+------------------------------------------------------------------+
void ApplyTick(double price)
  {
   int size=ArraySize(TickPriceBuffer);
   ArrayCopy(TickPriceBuffer,TickPriceBuffer,1,0,size-1);
   ArrayCopy(SignalBuffer,SignalBuffer,1,0,size-1);
   ArrayCopy(SignalColors,SignalColors,1,0,size-1);  
   ArrayCopy(DeltaTickBuffer,DeltaTickBuffer,1,0,size-1);
//--- запишем последнее значение цены
   TickPriceBuffer[0]=price;
//--- вычислим разницу с предыдущим значением
   DeltaTickBuffer[0]=TickPriceBuffer[0]-TickPriceBuffer[1];
//--- получим ср.кв. отклонение
   double stddev=getStdDev(ticks);  

Теперь мы готовы вычислить среднеквадратичное отклонение. Сначала напишем функцию getStdDev(), которая делает все вычисления«в лоб», пробегая по всем элементам массива столько циклов, сколько нужно.

//+------------------------------------------------------------------+
//| вычисляет стандартное отклонение "в лоб"                            |
//+------------------------------------------------------------------+
double getStdDev(int number)
  {
   double summ=0,sum2=0,average,stddev;
//--- считаем сумму изменений и вычисляем матожидание
   for(int i=0;i<ticks;i++)
      summ+=DeltaTickBuffer[i];
   average=summ/ticks;
//--- теперь считаем среднеквадратичное отклонение
   sum2=0;
   for(int i=0;i<ticks;i++)
      sum2+=(DeltaTickBuffer[i]-average)*(DeltaTickBuffer[i]-average);
   stddev=MathSqrt(sum2/(number-1));
   return (stddev);
  }

Затем там же допишем блок, который отвечает за выставление сигналов на тиковом графике — установку кружков красного и синего цвета

//+------------------------------------------------------------------+
//| применяет тик для вычислений                                     |
//+------------------------------------------------------------------+
void ApplyTick(double price)
  {
   int size=ArraySize(TickPriceBuffer);
   ArrayCopy(TickPriceBuffer,TickPriceBuffer,1,0,size-1);
   ArrayCopy(SignalBuffer,SignalBuffer,1,0,size-1);
   ArrayCopy(SignalColors,SignalColors,1,0,size-1);
   ArrayCopy(DeltaTickBuffer,DeltaTickBuffer,1,0,size-1);   
//--- запишем последнее значение цены
   TickPriceBuffer[0]=price;
//--- вычислим разницу с предыдущим значением
   DeltaTickBuffer[0]=TickPriceBuffer[0]-TickPriceBuffer[1];   
//--- получим ср.кв. отклонение
   double stddev=getStdDev(ticks);   
//--- если изменение цены превысило заданный порог
   if(MathAbs(DeltaTickBuffer[0])>gap*stddev) // при первом тике будет показан сигнал, оставим как фичу
     {
      SignalBuffer[0]=price;     // поставим точку
      string col="Red";          // по умолчанию, точка красного цвета
      if(DeltaTickBuffer[0]>0)   // цена резко выросла
        {
         SignalColors[0]=1;      // тогда точка синего цвета
         col="Blue";             // запомним для вывода в лог
        }
      else                       // цена резко упала
      SignalColors[0]=0;         // точка красного цвета
      //--- выведем запись в журнал Экспертов
      PrintFormat("tick=%G change=%.1f pts, trigger=%.3f pts,  stddev=%.3f pts %s",
                  TickPriceBuffer[0],DeltaTickBuffer[0]/_Point,gap*stddev/_Point,stddev/_Point,col);
     }
   else SignalBuffer[0]=0;       // нет сигнала      
//---
  }

Нажимаем кнопку F5 (Начало отладки/продолжение выполнения) и наблюдаем в терминале MetaTrader 5, как работает наш индикатор.

Как в MetaTrader 5 быстро разработать и отладить торговую стратегию: тиковый анализатор

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

 

Профилировка кода для ускорения работы

Для программ, работающих в режиме реального времени, критически важна скорость выполнения. Среда разработки MetaEditor позволяет удобно и быстро оценивать затраты времени на выполнение тех или иных участков программы.

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

Как в MetaTrader 5 быстро разработать и отладить торговую стратегию: тиковый анализатор

Как видите, большая часть времени (95.21%) ушла на отработку функции ApplyTick(), которая была вызвана 41 раз из функции OnCalculate(). Сама же OnCalculate() вызывалась 143 раза, но только в 41 случае цена в пришедшем тике отличалась от цены предыдущего.

При этом в самой функции ApplyTick() большую часть времени заняли вызовы функции ArrayCopy(), которые выполняют только вспомогательные действия и не производят вычислений, ради которых и был задуман данный индикатор. Вычисление среднеквадратичного отклонения на 111 строке кода заняло только 0.57% общего времени выполнения программы. 

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

Просматривать их все нет необходимости. Поэтому введем входной параметр shift=200, который задает  количество сдвигаемых значений. Добавьте в код строки, выделенные желтым:

//--- input parameters
input int      ticks=50;         // кол-во тиков в расчетах
input int      shift=200;        // кол-во сдвигаемых значений
input double   gap=3.0;          // ширина канала в сигмах
...
void ApplyTick(double price)
  {
//--- сколько элементов сдвигаем в индикаторных буферах на каждом тике
   int move=ArraySize(TickPriceBuffer)-1;
   if(shift!=0) move=shift;
   ArrayCopy(TickPriceBuffer,TickPriceBuffer,1,0,move);
   ArrayCopy(SignalBuffer,SignalBuffer,1,0,move);
   ArrayCopy(SignalColors,SignalColors,1,0,move);
   ArrayCopy(DeltaTickBuffer,DeltaTickBuffer,1,0,move);

Запускаем заново профилировку и видим новый результат — время на копирование массивов упало в в сотни или тысячи раз, теперь основное время занимает вызов StdDev(), которая отвечает за вычисление среднеквадратичного отклонения.

Как в MetaTrader 5 быстро разработать и отладить торговую стратегию: тиковый анализатор

Таким образом, мы ускорили работу функции ApplyTick() на несколько порядков, что даст нам существенную экономию при оптимизации стратегии и при работе программы в режиме реального времени.  Ведь вычислительных ресурсов никогда не бывает слишком много.

 

Аналитическая оптимизация кода

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

Как в MetaTrader 5 быстро разработать и отладить торговую стратегию: тиковый анализатор

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

Создадим новую функцию getStdDevOptimized(), в которой применим уже знакомый метод сдвига значений массива внутри себя.

//+------------------------------------------------------------------+
//| вычисляет стандартное отклонение по формулам                     |
//+------------------------------------------------------------------+
double getStdDevOptimized(int number)
  {
//---
   static double X2[],X[],X2sum=0,Xsum=0;
   static bool firstcall=true;
//--- первый вызов
   if(firstcall)
     {
      //--- зададим размер динамических массивов на 1 больше количества тиков
      ArrayResize(X2,ticks+1);
      ArrayResize(X,ticks+1);
      //--- гарантируем себе нулевые значения в начале вычислений
      ZeroMemory(X2);
      ZeroMemory(X);

      firstcall=false;
     }
//--- сдвигаем массивы
   ArrayCopy(X,X,1,0,ticks);
   ArrayCopy(X2,X2,1,0,ticks);
//--- вычислим новые входящие значения сумм
   X[0]=DeltaTickBuffer[0];
   X2[0]=DeltaTickBuffer[0]*DeltaTickBuffer[0];
//--- вычислим новые суммы
   Xsum=Xsum+X[0]-X[ticks];
   X2sum=X2sum+X2[0]-X2[ticks];
//--- квадрат стандартного отклонения
   double S2=(1.0/(ticks-1))*(X2sum-Xsum*Xsum/ticks);
//--- считаем сумму тиков и вычисляем матожидание
   double stddev=MathSqrt(S2);
//---
   return (stddev);
  } 

Добавим в функцию ApplyTick() вычисление среднеквадратичного отклонения вторым способом через функцию getStdDevOptimized() и вновь запустим профилировку.

//--- вычислим разницу с предыдущим значением
   DeltaTickBuffer[0]=TickPriceBuffer[0]-TickPriceBuffer[1];
//--- получим ср.кв. отклонение
   double stddev=getStdDev(ticks);
   double std_opt=getStdDevOptimized(ticks);

Результат выполнения:

Как в MetaTrader 5 быстро разработать и отладить торговую стратегию: тиковый анализатор

Видно, что новая функция getStdDevOptimized() требует в два раза меньше времени — 4.56%, чем лобовой обсчет в getStdDev() — 9.54%. Она выполняется даже быстрее, чем встроенная функция PrintFormat(), которая использовала 4.74% времени работы программы.

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

Кстати, о вызове стандартных функций — в данном индикаторе мы получаем цену из таймсерии close[], которая строится по ценам Bid. Есть еще два способа получить эту цену — с помощью функций SymbolInfoDouble() и SymbolInfoTick(). Добавим эти вызовы в код и снова сделаем профилировку.

Как в MetaTrader 5 быстро разработать и отладить торговую стратегию: тиковый анализатор

Как видите, здесь тоже есть разница по скорости работы. И это понятно, так как чтение готовой цены из close[] не требует затрат по сравнению с вызовом универсальных функций.

Отладка на реальных тиках в тестере

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

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

Важно: в окне Отладка укажите режим моделирования "Каждый тик на основе реальных тиков". Это позволит использовать для отладки реальные записанные котировки, которые хранит у себя торговый сервер. При первом запуске тестирования они автоматически загрузятся на ваш компьютер.

Как в MetaTrader 5 быстро разработать и отладить торговую стратегию: тиковый анализатор

Если эти параметры не заданы в MetaEditor, то при в виузальном режиме тестирования будут использоваться текущие настройки тестера. Укажите в них режим «Каждый тик на основе реальных тиков».

Как в MetaTrader 5 быстро разработать и отладить торговую стратегию: тиковый анализатор


Мы видим, что на тиковом графике появляются странные разрывы. Значит, в алгоритме допущена какая-то ошибка. Неизвестно, сколько времени ушло бы на её проявление при тестировании в реальном времени. В данном случае по выводам в Журнал визуального тестирования видно, что странные разрывы возникают в момент появления нового бара.

Точно! — мы забыли, что при переходе на новый бар размер индикаторных буферов автоматически увеличивается на 1. Внесём исправление в код:

void ApplyTick(double price)
  {
//--- будем запоминать размер массива TickPriceBuffer - он равен кол-ву баров на графике
   static int prev_size=0;
   int size=ArraySize(TickPriceBuffer);
//--- если размер индикаторных буферов не изменился, то сдвинем все элементы на 1 позицию назад
   if(size==prev_size)
     {
      //--- сколько элементов сдвигаем в индикаторных буферах на каждом тике
      int move=ArraySize(TickPriceBuffer)-1;
      if(shift!=0) move=shift;
      ArrayCopy(TickPriceBuffer,TickPriceBuffer,1,0,move);
      ArrayCopy(SignalBuffer,SignalBuffer,1,0,move);
      ArrayCopy(SignalColors,SignalColors,1,0,move);
      ArrayCopy(DeltaTickBuffer,DeltaTickBuffer,1,0,move);
     }
   prev_size=size;
//--- запишем последнее значение цены
   TickPriceBuffer[0]=price;
//--- вычислим разницу с предыдущим значением

Запустим визуальное тестирование и поставим точку остановки, чтобы поймать момент открытия нового бара. Добавим наблюдаемые значения и убедимся, что всё сделали правильно: количество баров на графике увеличилось на единицу, тиковый объем текущего бара равен 1 — это самый первый тик нового бара.

Как в MetaTrader 5 быстро разработать и отладить торговую стратегию: тиковый анализатор

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

Перфекционист от кодинга скажет — да! Мы еще не попробовали использовать кольцевой буфер для ускорения работы.  Желающие могут проверить сами — дает ли это прирост производительности?

 

MetaEditor — это готовая лаборатория для разработки торговых стратегий

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

  1. создавать за пару минут тиковый график в первом приближении;
  2. пользоваться отладкой в режиме реального времени на графике по кнопке F5;
  3. запускать профилировку для выявления неэффективных мест в коде;
  4. проводить быструю отладку на исторических данных в режиме визуального тестирования;
  5. просматривать значения нужных переменных в процессе отладки.

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

Пользуйтесь всеми возможностями среды разработки MetaEditor для создания эффективных торговых роботов!

Статьи по теме:

  1. Как написать индикатор в MQL5
  2. Создание тиковых индикаторов
  3. Принципы экономного пересчета индикаторов
  4. Усреднение ценовых рядов без дополнительных буферов для промежуточных расчетов
  5. Отладка программ на MQL5

Готовый файл можно скачать по ссылке: https://www.mql5.com/ru/articles/download/2661/tickspikehunter.mq5
41 Комментарий
  • Андрей К
    20 сентября 2016, 14:04
    Профилирование кода — это очень сильно. Не ожидал =)
    • Евгений
      20 сентября 2016, 14:12
      Андрей К, сейчас все трейдеры научаться и программировать, и профилировать. И наступит всеобщая эра айти.

      Парни с другой планеты. Клепают то, что никому не нужно. А вместо критики начинают обвинять, что я на кого-то работаю. Видимо я из компании Арка, создаю Quik :)))
  • Андрей К
    20 сентября 2016, 14:19
     Клепают то, что никому не нужно.
    насчет профилирования не согласен =)
    еще и дебаггер прикрутили. Тоже хорошо
    • MZS
      20 сентября 2016, 17:49
      MetaQuotes Software, это ты сейчас с кем говорил?!
  • Kraftus
    20 сентября 2016, 16:22
    А как сделать секундные графики в мт5? 5сек, 10сек, 15сек и т.д.? Есть ли такая возможность?
      • Александр
        20 сентября 2016, 17:17
        MetaQuotes Software, Тики за предыдущие сессии можно получить, например получить тики за 10 дней назад?
        Одним словом какова тиковая история?
          • Александр
            20 сентября 2016, 18:25
            MetaQuotes Software, Типа вы стали бесплатным хранилищем тиков :) Надо будет потестить. А что вы тогда не сделаете не стандартные таймфреймы из коробки? Полезная ведь вещь :)
      • HareOFF
        25 августа 2020, 16:52
        MetaQuotes Software, Здравствуйте)) появилась большая нужда в секундных таймфреймах в Mt5… прям головная  боль теперь как написать индикатор… кароче как-то нужно получить массив их этих секундных баров… помогите пожалуйста, ранее Вы писали 

        Kraftus, к сожалению, нет

        Хотя можно самостоятельно нарезать (или найти готовый скрипт) нужные таймфреймы и отобразить их.

        Исходные тики на любую глубину можно получить через CopyTicks функцию.

        --------------
        где найти готовый скрипт...???

        ПЫСЫ цены Вам не будет, если Вы добавите с терминал, например, хотя бы один секундный таймфрейм — 5 сек… заранее спасибо… лучше, конечно меньше, например 3 сек… а там потом можно будет параметрами индюка забрать то, что нужно…



        и еще забыл совсем!!!!!!

        Сделайте как в квике на якорь нажимаешь и якорь на окне графика, чтобы они подхватывались, а то когда инструмент подгружен сразу на 10 графиках, то не получается быстро все графики перевести на другой инструмент… только это держит покупать подписку у трейдинг вью за 155 долларов… Вы сделайте я бы Вам платил по 150 баксов в год за терминал. за один якорь!!!
  • Kraftus
    20 сентября 2016, 17:02
    Спасибо за ответ. Очень жаль, именно этого очень не хватает в мт. Приходится пользовать сторонние приводы. Скрипт это понятно, но на планшет его не поставишь.
  • Миха
    20 сентября 2016, 17:31
    Здравствуйте. Как известно, биржевые рынки немного отличаются от форекса. Есть некоторые вещи, которые очень неудобны в языке при работе конкретно на ФОРТС. Например, свойства позиции. Вот у вас есть ENTRY_PRICE, но ведь на ФОРТС данное свойство совсем не отражает того, что под ним должно подразумеваться. Это очень неудобно. В конце концов мы тестируем без учета всяких клирингов. Получается на тесте это свойство адекватно, а в реальности нет. 
    То же самое по прибыли позиции. Хотелось бы иметь истинную прибыль позиции без учета переоткрытий при клиринге. Ведь нет же никаких клирингов при тестировании. А для масштабирования стратегий удобнее было бы иметь прибыль в пунктах или в пунктах на контракт. Что за прибыль в деньгах, детский сад ей богу. Даже не вычислить ее ретроспективно, т.к. может меняться цена тика. Короче призываю вас сделать язык, а также библиотеку более биржеориентированными.
      • Миха
        20 сентября 2016, 18:17
        MetaQuotes Software, хорошая новость, что добавите. Было сложно однако ранее, когда вы при перевороте позы не меняли идентификатор. Сейчас кажется изменили это?
          • Миха
            26 сентября 2016, 20:01
            MetaQuotes Software, хотел бы добавить что ситуация с определением «истинной» цены открытия позиции осложняется также тем что коррекционные сделки там имеют обычный тип (DEAL_TYPE_BUY или DEAL_TYPE_SELL). Чтобы их отфильтровать (чтобы не учитывать в определении цены открытия позиции) приходится смотреть комментарий который содержит подстроку «variation margin...». А это согласитесь совсем уже не комильфо, если вдруг этот комментарий изменится на стороне торгового сервера/биржи, придется менять алгоритм.
  • ELab
    20 сентября 2016, 18:12
    На таком уровне уже нужно по FIX работать и свои тестеры гонять исходя из процента заполнения лимитных ордеров и(или) проскальзывания маркет ордеров. А так… ну не более чем фича
      • ELab
        21 сентября 2016, 15:49
        MetaQuotes Software, я про свои тестеры говорил — убогая эмуляция по минуткам до уровня решения, когда трейдер сохраняет тики и эмулирует исполнение исходя их текущих значений отклика биржа, никогда не будет корректной. А МТ5, который работает через сервера брокера и MetaQuotes до уровня доступа прямого по Plaza даже в теории дорасти не сможет никогда.
  • oreshkinalexey
    20 сентября 2016, 19:20
    Всё круто, кроме одного — брокеров с мт5 для фонды всего 2. Не все работают через них.
      • oreshkinalexey
        20 сентября 2016, 20:30
        MetaQuotes Software, Нет смысла пока вы не сделаете наконец то единый счёт и опционы. Как сделаете так да, буду первым, а пока мт5, несмотря на все прелести использую только для тестов, а не для торговли.
      • HareOFF
        04 октября 2016, 16:30
        MetaQuotes Software, Добрый день! Скажите, пожалуйста, почему Открытие брокер в графиках акций отображает в mt5 очень обрезанную историю по инструментам, это проблема на стороне брокера? Не знаете как у других брокеров отображается история по акциям? Это большая проблема, например, в квике я вижу историю по дневному графику лукойла с 2004 года, а в mt5 Открытия с 2013 года… Или это проблема mt5?
  • DIVER PROFIT
    20 сентября 2016, 19:36
    А роботы DiverProfit MOEX и DiverProfit FOREX для Metatrader5 можно у нас взять в аренду. 
    • oreshkinalexey
      20 сентября 2016, 20:30
      OilтрейдиOil, и здесь реклама :( Может хватит считать вокруг всех идиотами?
      • DIVER PROFIT
        20 сентября 2016, 20:44
        DedBoroded, А идиотами в чём извините? 
        Наберите на этой страничке http://ninjatraderecosystem.com/Partners/Add-Ons-Search.php#78 в поиске DiverProfit они нас не считают идиотами и еще порядка 50 компаний со всего мира тоже не считают идиотами.
        Более того у нас уже более 150 постоянных клиентов из разных стран.

  • Чарльз Маккей
    20 сентября 2016, 21:51
    Я не вижу здесь никаких тиковых данных.
    • ELab
      21 сентября 2016, 15:50
      MyKey, «ТАМ ИХ НЕТ» — это эмулятор по минуткам
        • ELab
          04 ноября 2016, 16:41
          MetaQuotes Software, я просто пробовал и не просто. форекс рынок не для hft. соответсвенно и смысла в таких расчетах нет. то реджект, то слип, то вообще бан
  • Андрей Иванушкин
    21 сентября 2016, 11:06
    MetaQuotes Молодцы!

Активные форумы
Что сейчас обсуждают

Старый дизайн
Старый
дизайн