rss

Профиль компании

Финансовые компании

Блог компании MetaQuotes Software | Как в 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
★27
41 комментарий
Профилирование кода — это очень сильно. Не ожидал =)
avatar
Андрей К, а вы думаете, почему у нас такая производительность как в чистом MQL5 языке, так и в торговых транзакциях?

Мы написали 4 поколения своих собственных компиляторов к тому же.
avatar
Андрей К, сейчас все трейдеры научаться и программировать, и профилировать. И наступит всеобщая эра айти.

Парни с другой планеты. Клепают то, что никому не нужно. А вместо критики начинают обвинять, что я на кого-то работаю. Видимо я из компании Арка, создаю Quik :)))
avatar
 Клепают то, что никому не нужно.
насчет профилирования не согласен =)
еще и дебаггер прикрутили. Тоже хорошо
avatar
Андрей К, особенно хорош отладчик, когда тестируешь мультисимвольную стратегию и можешь опуститься на уровень миллисекунд, чтобы понять взаимную конфигурацию цен именно в нужный момент времени.

Тестер умеет отлично строить модель рынка на реальных тиках с точностью до миллисекунд по любому набору параллельных символов.

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

Единственно, что моделирования стакана нет, только best bid/ask.
avatar
С помощью своих алгоритмических платформ мы стараемся поднять технический уровень трейдеров.

И это получается:
  — для программистов полный набор функционала и документация
  — библиотеки открытого кода с тысячами программ
  — встроенный маркет с тысячами программ (платными и бесплатными)
  — фриланс сервис, где можно заказать все что угодно
  — еще много всего вкусного и бесплатного

Спрос огромный, как бы это не нравилось некоторым.
avatar
MetaQuotes Software, это ты сейчас с кем говорил?!
avatar
MZS, некому Евгению, который невпопад пытается критиковать каждую нашу запись в блоге.
avatar
А как сделать секундные графики в мт5? 5сек, 10сек, 15сек и т.д.? Есть ли такая возможность?
avatar
Kraftus, к сожалению, нет

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

Исходные тики на любую глубину можно получить через CopyTicks функцию.
avatar
MetaQuotes Software, Тики за предыдущие сессии можно получить, например получить тики за 10 дней назад?
Одним словом какова тиковая история?
avatar
Александр, выше указано «на любую глубину».

Простой код скрипта:
MqlTick ticks[];

void OnStart(void)
  {
   PrintFormat(«Ticks: %d»,CopyTicks(_Symbol,ticks,COPY_TICKS_ALL,0,100000000));
  }

выдает даже на истекшем Si-9.16: Ticks: 56 192 184

Да, 56 миллионов тиков одним ударом. Описание функции тут: https://www.mql5.com/ru/docs/series/copyticks
avatar
MetaQuotes Software, Типа вы стали бесплатным хранилищем тиков :) Надо будет потестить. А что вы тогда не сделаете не стандартные таймфреймы из коробки? Полезная ведь вещь :)
avatar
MetaQuotes Software, Здравствуйте)) появилась большая нужда в секундных таймфреймах в Mt5… прям головная  боль теперь как написать индикатор… кароче как-то нужно получить массив их этих секундных баров… помогите пожалуйста, ранее Вы писали 

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

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

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

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

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



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

Сделайте как в квике на якорь нажимаешь и якорь на окне графика, чтобы они подхватывались, а то когда инструмент подгружен сразу на 10 графиках, то не получается быстро все графики перевести на другой инструмент… только это держит покупать подписку у трейдинг вью за 155 долларов… Вы сделайте я бы Вам платил по 150 баксов в год за терминал. за один якорь!!!
avatar
Спасибо за ответ. Очень жаль, именно этого очень не хватает в мт. Приходится пользовать сторонние приводы. Скрипт это понятно, но на планшет его не поставишь.
avatar
Здравствуйте. Как известно, биржевые рынки немного отличаются от форекса. Есть некоторые вещи, которые очень неудобны в языке при работе конкретно на ФОРТС. Например, свойства позиции. Вот у вас есть ENTRY_PRICE, но ведь на ФОРТС данное свойство совсем не отражает того, что под ним должно подразумеваться. Это очень неудобно. В конце концов мы тестируем без учета всяких клирингов. Получается на тесте это свойство адекватно, а в реальности нет. 
То же самое по прибыли позиции. Хотелось бы иметь истинную прибыль позиции без учета переоткрытий при клиринге. Ведь нет же никаких клирингов при тестировании. А для масштабирования стратегий удобнее было бы иметь прибыль в пунктах или в пунктах на контракт. Что за прибыль в деньгах, детский сад ей богу. Даже не вычислить ее ретроспективно, т.к. может меняться цена тика. Короче призываю вас сделать язык, а также библиотеку более биржеориентированными.
avatar
Миха, вы можете смотреть или нет на ENTRY_PRICE.

Подразумевать не надо — вы торгуете на ФОРТС и используете его схему постоянных переоткрытий позиций. Истинную прибыль позиции можно легко посчитать по истории и связанным идентификаторам. Для этого достаточно написать свою функцию.

Прибыль в пунктах тоже элементарно вычислить — это дело одной функции.

Это же программирование, где берешь и пишешь что тебе нужно.

В стандартную библиотеку мы обязательно добавим функции полного связанного пересчета профитов и цен. Это не сложно.
avatar
MetaQuotes Software, хорошая новость, что добавите. Было сложно однако ранее, когда вы при перевороте позы не меняли идентификатор. Сейчас кажется изменили это?
avatar
Миха, должны были поменять. 
avatar
MetaQuotes Software, хотел бы добавить что ситуация с определением «истинной» цены открытия позиции осложняется также тем что коррекционные сделки там имеют обычный тип (DEAL_TYPE_BUY или DEAL_TYPE_SELL). Чтобы их отфильтровать (чтобы не учитывать в определении цены открытия позиции) приходится смотреть комментарий который содержит подстроку «variation margin...». А это согласитесь совсем уже не комильфо, если вдруг этот комментарий изменится на стороне торгового сервера/биржи, придется менять алгоритм.
avatar
На таком уровне уже нужно по FIX работать и свои тестеры гонять исходя из процента заполнения лимитных ордеров и(или) проскальзывания маркет ордеров. А так… ну не более чем фича
avatar
ELab, в прошлом бенчмарке было показано, что и fix при использовании МТ5 не нужен.

FIX на Фортсе работает поверх инфраструктуры Плазы и никак не быстрее ее. Соответственно и не быстрее МТ5, плюс минус погрешность конечно.
avatar
MetaQuotes Software, я про свои тестеры говорил — убогая эмуляция по минуткам до уровня решения, когда трейдер сохраняет тики и эмулирует исполнение исходя их текущих значений отклика биржа, никогда не будет корректной. А МТ5, который работает через сервера брокера и MetaQuotes до уровня доступа прямого по Plaza даже в теории дорасти не сможет никогда.
avatar
ELab, спорно.

Если выкинем тормозуху в виде закрытой Плазы, то запросто. MOEX все никак полного и открытого единого протокола не дает к себе. Вместо этого какие-то половинчатые протоколы как на зло.
avatar
Всё круто, кроме одного — брокеров с мт5 для фонды всего 2. Не все работают через них.
avatar
DedBoroded, просите своих брокеров поставить параллельно МТ5 и увидите, как качество анализа и исполнения кратно повысятся.

Это не говоря еще о наших мобильных платформах.
avatar
MetaQuotes Software, Нет смысла пока вы не сделаете наконец то единый счёт и опционы. Как сделаете так да, буду первым, а пока мт5, несмотря на все прелести использую только для тестов, а не для торговли.
avatar
MetaQuotes Software, Добрый день! Скажите, пожалуйста, почему Открытие брокер в графиках акций отображает в mt5 очень обрезанную историю по инструментам, это проблема на стороне брокера? Не знаете как у других брокеров отображается история по акциям? Это большая проблема, например, в квике я вижу историю по дневному графику лукойла с 2004 года, а в mt5 Открытия с 2013 года… Или это проблема mt5?
avatar
HareOFF, все очень просто.

Дело не в платформе, а том, закачали историю на конкретный символ или нет.

В МТ5 хоть миллиарды тиков закачай — отдаст и не поперхнется.
avatar
А роботы DiverProfit MOEX и DiverProfit FOREX для Metatrader5 можно у нас взять в аренду. 
avatar
OilтрейдиOil, и здесь реклама :( Может хватит считать вокруг всех идиотами?
avatar
DedBoroded, А идиотами в чём извините? 
Наберите на этой страничке http://ninjatraderecosystem.com/Partners/Add-Ons-Search.php#78 в поиске DiverProfit они нас не считают идиотами и еще порядка 50 компаний со всего мира тоже не считают идиотами.
Более того у нас уже более 150 постоянных клиентов из разных стран.

avatar
Я не вижу здесь никаких тиковых данных.
avatar
MyKey, «ТАМ ИХ НЕТ» — это эмулятор по минуткам
avatar
ELab, давно уже в тестере можно тестировать по реальным тикам.

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

Просто попробуйте.
avatar
MetaQuotes Software, я просто пробовал и не просто. форекс рынок не для hft. соответсвенно и смысла в таких расчетах нет. то реджект, то слип, то вообще бан
avatar
MyKey, не совсем понятно про «здесь».

Но если речь об МТ5, то там тики абсолютно неотключаемая вещь и всегда доступна любом трейдеру.

Вы можете открыть МТ5 демо-счет на сервере MetaQuotes-Demo, выбрать в броузере символов любые символы MOEX, открыть их и использовать тики в тестере или своих роботах.

Дам десятки миллионов тиков по каждому инструменту есть. И все они доступны бесплатно.

Данные MOEX транслируются с 15 минутной задержкой.
avatar
MetaQuotes Молодцы!
Андрей Иванушкин, спасибо!
avatar

теги блога MetaQuotes Software

....все тэги



UPDONW
Новый дизайн