http://www.ampfutures.com
Чтобы открыть демку и посмотреть, достаточно указать сервер AMPGlobalClearing-Live-CQG при открытии счета и выбрать «Новый реальный счет». Будет автоматически открыт предварительный счет, на котором будут доступны фьючерсы.
Американский брокер AMP Futures запустил MetaTrader 5
Новый MetaTrader 5 build 1485: доп режимы тестирования и графическая библиотека
Что нового:
- Terminal: Изменен порядок отображения записей в журналах терминала и MetaEditor. Ранее в начале журнала показывались самые свежие записи, теперь — самые старые. Обратный порядок сортировки сделает чтение журнала более удобным и привычным.
- Terminal: В торговой истории у ордеров и сделок закрытия позиций в режиме хеджинга теперь показывается тикет закрытой позиции. Это облегчит поиск парных операций открытия и закрытия.
- Terminal: Исправлена ошибка, приводившая к копированию уровней SL/TP из имеющейся позиции в новую позицию по тому же инструменту. Ошибка проявлялась при использовании функций торговли одним кликом (например, на графике, в окне «Обзор рынка») в режиме хеджинга.
- Terminal: Исправлено отображение объектов-стрелок на экранах сверхвысокого разрешения (4К).
- MQL5: Добавлена функция ArrayPrintдля вывода в журнал массивов простых типов и структур.
ArrayPrint выводит в журнал не все поля массива структур – поля-массивы и поля-указатели объектов пропускаются. Для вывода всех полей такой структуры понадобится собственная функция массового вывода с желаемым форматированием. - MQL5: Исправлена ошибка сложения строк вида S1=S2+S1
- MQL5: Изменено поведение функции ArrayResize. При передаче в качестве параметра reserve_size значения -1 функция освобождает неиспользованную (зарезервированную) память, если при этом не происходит увеличение размера массива. Изменение размера массива на 0 со значением reserve_size=-1 эквивалентно вызову ArrayFree. Новое поведение позволяет оптимизировать использование памяти в MQL5-программах.
- MQL5: В стандартную библиотеку добавлены функции для построения графиков. Для использования включите файл MQL5\Include\Graphics\Graphic.mqh в свой проект.
Построение графика из 3 серий данных при помощи GraphPlot:#include <Graphics/Graphic.mqh> double Func1(double x) { return MathPow(x,2); } double Func2(double x) { return MathPow(x,3); } double Func3(double x) { return MathPow(x,4); } void OnStart() { GraphPlot(Func1,Func2,Func3,-2,2,0.05,CURVE_LINES); }
Результат:
Построение графика на основе массива данных при помощи GraphPlot:#include <Math/Stat/Binomial.mqh> #include <Graphics/Graphic.mqh> void OnStart(void) { double vars[101]; double results[101]; const int N=2000; //--- MathSequence(0,N,20,vars); MathProbabilityDensityBinomial(vars,N,M_PI/10,true,results); ArrayPrint(results,4); GraphPlot(results); //--- }
Результат: - MQL5: Обновлены функции работы с математической статистикой в стандартной библиотеке. Проведена большая проверка качества и точности всех функций как в MQL5-версии, так и в исходном языке R. Для контроля точности и скорости работы вместе со статистической библиотекой распространяются юнит-тесты. Они находятся в каталоге \MQL5\Scripts\UnitTests\Stat.
- TestStat.mq5 — основной тестовый скрипт для проверки результатов вычислений
- TestPrecision.mq5 — тест точности вычислений
- TestBenchmark.mq5 — тест с замером производительности вычислений
- Tester: Расширены настройки задержки исполнения торговых запросов при тестировании. Теперь проверить торгового робота можно в еще большем количестве разнообразных торговых условий: от идеального случая без задержек до любой задержки, заданной пользователем.
Ранее был доступен только режим произвольных задержек. - Tester: Исправлена ошибка формирования тикового объема баров при тестировании в режиме OHLC на М1.
- Tester: Исправлено проставление времени открытия у ордеров и позиций с точностью до миллисекунд при торговле в режиме хеджинга.
- Tester: Исправлена ошибка «old tick» (тик устарел), появлявшаяся при мультивалютном либо мультитаймфреймовом тестировании в режиме реальных тиков.
- Tester: Ускорена работа функции CopyTicks в случае, когда запрошенные тики читались из базы на диске.
- MetaEditor: Команды работы с версионным хранилищем исходных кодов MQL5 Storage добавлены в контекстное меню файла в Навигаторе и на панель инструментов.
- MetaEditor: Исправлена ошибка, приводившая к нарушению целостности локальной базы MQL5 Storage при работе более чем с 1024 файлами в хранилище.
- MetaEditor: Исправлены ошибки отображения дерева файлов MQL5 Storage.
- MetaEditor: Исправлено отображение файла после массовой замены текста.
- Обновлена документация.
Обновление будет доступно через систему LiveUpdate.
Разработка спредовой стратегии на фьючерсах Московской биржи
MetaTrader 5 позволяет разрабатывать и тестировать роботов, торгующих одновременно на нескольких инструментах.
Встроенный в платформу тестер стратегий автоматически скачивает с торгового сервера брокера тиковую историю и учитывает спецификацию контрактов — разработчику ничего не нужно делать руками.
Это позволяет легко и максимально достоверно воспроизводить все условия торгового окружения — вплоть до миллисекундных интервалов между поступлениями тиков на разных символах.
Сейчас мы покажем, как провести разработку и тестирование спредовой стратегии на двух фьючерсах Московской биржи.
Обратная корреляция символов Si и RTS
На Московской бирже торгуются фьючерсы вида Si-M.Y и RTS-M.Y, которые достаточно тесно между собой связаны. Здесь M.Y обозначают дату истечения контракта:
- M — номер месяца
- Y — две последние цифры годв
Si — это фьючерсный контракт на курс доллар США/российский рубль, RTS — фьючерсный контракт на Индекс РТС, выраженный в долларах США. Так как в Индекс РТС входят акции российских компаний, цены на которые выражены в рублях, то колебания курса USD/RUR отражаются также и на колебаниях индекса, выраженного в долларах США.
На графиках этих инструментов видно, что при росте одного актива второй, как правило, падает.
Для лучшего представления мы наложили на оба графика канал стандартного отклонения.
Вычисляем линейную регрессию между Si и RTS
Мы можем выразить связь между двумя инструментами с помощью уравнения линейной регрессии вида Y(X)=A(X)+B. Для проверки напишем скрипт CalcShowRegression_script.mq5, который берет два массива цен закрытия, вычисляет коэффициенты и выводит диаграмму распределения с линией регрессии прямо на график.
Для вычисления коэффициентов регрессии используется функция из библиотеки ALGLIB, отрисовка делается графическими классамиСтандартной библиотеки.
Строим индикатор спреда между Si и синтетикой
Мы получили коэффициенты линейной регрессии, и теперь можем строить синтетический график вида Y(RTS) = A*RTS+B. Разницу между оригинальным активом и синтетическим рядом назовем спредом. Эта разница будет меняться на каждом баре, от положительных до отрицательных значений.
Для визуального представления спреда напишем индикатор TwoSymbolsSpread_Ind.mql5, который выводит в виде гистограммы спред на данных за последние 500 баров.
Положительные значения спреда рисуются голубым цветом, отрицательные — желтым:
Индикатор обновляет и пишет в журнал Экспертыкоэффициенты линейной регрессии при открытии каждого нового бара. При этом он дожидается того момента, когда новая свеча откроется на обоих инструментах — Si и RTS.
Таким образом индикатор позволяет контролировать правильность и точность расчетов.
Строим график линейной регрессии на графике спредов за последние 100 баров
Индикатор спреда показывает, что разница между фьючерсом Si и синтетическим инструментом периодически меняется. Чтобы оценить текущую тенденцию, напишем индикаторSpreadRegression_Ind.mq5 (спред и линейная регрессия на нём), который строит трендовую линию на графике спреда. Параметры линии вычисляем опять же методом линейной регрессии.
Наложим оба индикатора на график для отладки:
Красная линия тренда меняет свой наклон в зависимости от значения спреда на последних 100 барах. В принципе, теперь у нас есть минимум необходимых данных, чтобы попробовать построить торговую систему.
Стратегия №1 — изменение наклона линейной регрессии на графике спреда
Значения спреда в индикаторе TwoSymbolsSpread_Ind.mql5считаются как разность между Si и Y(RTS)=A*RTS + B.
Вы можете легко проверить это, запустив индикатор под отладкой (кнопкой F5):
Сделаем простого советника, который отслеживает изменение угла наклона линейной регрессии, наложенной на график спреда. Угол наклона линии — это не что иное, как коэффициент A в уравнении Y=A*X+B.
При положительном тренде на графике спреда A>0, при отрицательном A<0. Линейную регрессию мы считаем на последних 100 значениях графика спреда.
Вот часть кода из советника Strategy1_AngleChange_EA.mq5.
#include <Trade\Trade.mqh> //+------------------------------------------------------------------+ //| тип стратегии спреда | //+------------------------------------------------------------------+ enum SPREAD_STRATEGY { BUY_AND_SELL_ON_UP, // Buy 1-st, Sell 2-nd SELL_AND_BUY_ON_UP, // Sell 1-st, Buy 2-nd }; //--- input int LR_length=100; // кол-во баров для регрессии на спреде input int Spread_length=500; // кол-во баров для расчета спреда input ENUM_TIMEFRAMES period=PERIOD_M5; // таймфрейм input string symbol1="Si-12.16"; // первый символ пары input string symbol2="RTS-12.16"; // второй символ пары input double profit_percent=10; // сколько процентов прибыли фиксируем input SPREAD_STRATEGY strategy=SELL_AND_BUY_ON_UP; // тип спредовой стратегии //--- хендлы индикаторов int ind_spreadLR,ind,ind_2_symbols; //--- класс для торговых операций CTrade trade; //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- коэффициент A наклона линейной регрессии на графике спреда Y(X)=A*X+B static double Spread_A_prev=0; if(isNewBar()) PrintFormat("Новый бар %s открылся в %s",_Symbol,TimeToString(TimeCurrent(),TIME_DATE|TIME_SECONDS)); //--- дождемся, когда данные индикатора обновятся, так как он работает на двух символах if(BarsCalculated(ind_spreadLR)==Bars(_Symbol,_Period)) { //--- получим значения линейной регрессии на графике спреда для баров с индексами 1 и 2 ("вчера" и "позавчера") double LRvalues[]; double Spread_A_curr; int copied=CopyBuffer(ind_spreadLR,1,1,2,LRvalues); if(copied!=-1) { //--- коэффициент линейной регрессии на последнем завершенном ("вчерашнем") баре Spread_A_curr=LRvalues[1]-LRvalues[0]; //--- если наклон регрессии сменился, то произведение текущего и предыдущего меньше нуля if(Spread_A_curr*Spread_A_prev<0) { PrintFormat("Линия LR сменила наклон, Spread_A_curr=%.2f, Spread_A_prev=%.2f: %s", Spread_A_curr,Spread_A_prev,TimeToString(TimeCurrent(),TIME_SECONDS)); //--- если открытых позиций нет, то войдем в рынок по двум символам if(PositionsTotal()==0) DoTrades(Spread_A_curr-Spread_A_prev>0,strategy,symbol1,1,symbol2,1); //--- есть открытые позиции, делаем переворот else ReverseTrades(symbol1,symbol2); } //--- наклон регрессии не изменился, проверим плавающую прибыль - может пора закрывать? else { double profit=AccountInfoDouble(ACCOUNT_PROFIT); double balance=AccountInfoDouble(ACCOUNT_BALANCE); if(profit/balance*100>=profit_percent) { //--- достигнут нужный уровень плавающей прибыли - фиксируем trade.PositionClose(symbol1); trade.PositionClose(symbol2); } } //--- запомним направление тренда для сравнения на открытии нового бара Spread_A_prev=Spread_A_curr; } } }Чтобы не делать предположений, что нужно покупать, а что продавать при смене тренда, мы просто добавили в советника внешний параметр, который позволяет переворачивать торговые правила:
input SPREAD_STRATEGY strategy=SELL_AND_BUY_ON_UP; // тип спредовой стратегииТеперь мы можем запустить тестирование и отладку советника.
Тестирование торговой Стратегии №1
Для отладки новой стратегии лучше всего использовать режим визуального тестирования. Через меню Сервис-Настройки-Отладка задайте все необходимые данные:
- Символ
- Таймфрейм
- Интервал тестирования
- Режим торговли
- Размер депозита
- Режим генерации тиков
Для биржевых инструментов рекомендуем выбирать "Каждый тик на основе реальных тиков". В этом случае тестирование будет идти на записанных исторических данных, и вы получите результаты, максимально приближенные к реальным торговым условиям.
Торговый сервер MetaTrader 5 автоматически накапливает все пришедшие с биржи тики у себя и выдает в терминал всю тиковую историю по первому запросу:
В этом режиме отладки вы сможете визуально пройти через всё тестирование и проверить значения любых переменных в нужных местах кода с помощью точек прерывания.
Используемые в торговом роботе индикаторы автоматически будут загружены на графики, самому вручную ничего делать не придётся.
После того, как код советника отлажен, можем провести оптимизацию параметров.
Оптимизация торговой Стратегии №1
В советнике Strategy1_AngleChange_EA.mq5есть несколько внешних параметров, которые можно подбирать путем оптимизации (выделено желтым):
input int LR_length=100; // кол-во баров для регрессии на спреде input int Spread_length=500; // кол-во баров для расчета спреда input double profit_percent=10; // сколько процентов прибыли фиксируем input SPREAD_STRATEGY strategy=SELL_AND_BUY_ON_UP; // тип спредовой стратегииНо мы данном случае будем оптимизировать только параметр profit_percentдля двух вариантов стратегии, чтобы понять, есть ли между ними разница.
Иными словами, мы фиксируем значение параметра strategyи делаем оптимизацию по параметру profit_percentот 0.2 до 3.0%, чтобы увидеть общую картину для двух способов торговать на изменении наклона линии.
Для правила BUY_AND_SELL_ON_UP (покупаем первый актив, продаем второй), когда наклон линии меняется с отрицательного на положительный, оптимизация дает не очень хорошие результаты.
В целом такой способ входа в рынок не выглядит привлекательным, мы чаще получаем убыток при тестировании на интервале в 2 месяца.
При использовании правила SELL_AND_BUY_ON_UP (продаем первый актив, покупаем второй) результаты оптимизации лучше — 5 из 15 проходов оптимизации показывают какую-то прибыль.
Оптимизация проводилась на истории с 1 августа по 30 сентября 2016 (интервал в два месяца). В целом, оба варианта торговли не выглядят многообещающими.
Возможно, проблема в том, что для входов мы использовали достаточно запаздывающий показатель — наклон трендовой линии за последние 100 баров. Попробуем разработать второй вариант стратегии.
Стратегия №2 — смена знака спреда на завершенном баре
Во второй стратегии мы будем следить за изменениями знака спреда. Смотреть мы будем значения только на сформировавшихся барах, то есть на открытии нового «сегодняшнего» бара. Если спред на «позавчерашнем» баре был отрицательный, а на «вчерашнем» стал положительным, то мы считаем, что спред развернулся вверх (UP).
Опять-таки в коде оставлена возможность торговать смену спреда в любую сторону — мы можем разворачивать направления входа с помощью параметра strategy.
Вот блок кода советника Strategy2_SpreadSignChange_EA.mq5:
//+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- предыдущее значение спреда как разности Symbol1 и Y(Symbol2)=A*Symbol2+B static double Spread_prev=0; if(isNewBar()) PrintFormat("Новый бар %s открылся в %s",_Symbol,TimeToString(TimeCurrent(),TIME_DATE|TIME_SECONDS)); //--- дождемся, когда данные индикатора обновятся, так как он работает на двух символах if(BarsCalculated(ind_spreadLR)==Bars(_Symbol,_Period)) { //--- получим значения спреда для баров с индексами 1 и 2 ("вчера" и "позавчера") double SpreadValues[]; int copied=CopyBuffer(ind_spreadLR,0,1,2,SpreadValues); double Spread_curr=SpreadValues[1]; if(copied!=-1) { //--- если знак спреда изменился, то произведение текущего и предыдущего меньше нуля if(Spread_curr*Spread_prev<0) { PrintFormat("Спред изменил знак, Spread_curr=%.2f, Spread_prev=%.2f: %s", Spread_curr,Spread_prev,TimeToString(TimeCurrent(),TIME_SECONDS)); //--- если открытых позиций нет, то войдем в рынок по двум символам if(PositionsTotal()==0) DoTrades(Spread_curr>0,strategy,symbol1,1,symbol2,1); //--- есть открытые позиции, делаем переворот else ReverseTrades(symbol1,symbol2); } //--- знак спреда не изменился, проверим плавающую прибыль - может, пора закрывать? else { double profit=AccountInfoDouble(ACCOUNT_PROFIT); double balance=AccountInfoDouble(ACCOUNT_BALANCE); if(profit/balance*100>=profit_percent) { //--- достигнут нужный уровень плавающей прибыли - фиксируем trade.PositionClose(symbol1); trade.PositionClose(symbol2); } } //--- запомним значение спрреда для сравнения на открытии нового бара Spread_prev=Spread_curr; } } }
Сначала, как обычно, делаем отладку торгового робота в визуальном режиме тестирования, затем запускаем оптимизацию по параметру profit_percent, как и для первой стратегии.
Результаты:
Как видим, для второй стратегии правило «Продаем первый актив и покупаем второй» даёт такие же неутешительные результаты тестирования, как и для первой.
При этом правило «Покупаем первый актив и продаем второй» на всех проходах даёт больше убытков.
Попробуем сделать третий вариант стратегии.
Стратегия №3 — смена знака спреда на текущем баре с подтверждением на N тиках
Две предыдущие стратегии работали только на открытии бара, то есть анализировали изменения только на полностью завершенных барах. Попробуем теперь работать внутри текущего бара.
Проанализируем изменения спреда на каждом тике, и если знаки спреда на предыдущем завершенном и текущем развивающемся бара отличаются, то мы решаем, что направление спреда изменилось.
Потребуем также, чтобы изменение знака спреда было устойчивым на последних N тиках — таким образом мы пытаемся избавиться от ложных сигналов. Для этого добавим в советника внешний параметр ticks_for_trade=10.
Если на последних 10 тиках знак спреда отрицательный, а на предыдущем баре положительный, то мы входим в рынок.
Вот так выглядит функция OnTick() советника Strategy3_SpreadSignOnTick_EA.mq5:
//+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { if(isNewBar()) PrintFormat("Новый бар %s открылся в %s",_Symbol,TimeToString(TimeCurrent(),TIME_DATE|TIME_SECONDS)); //--- дождемся, когда данные индикатора обновятся, так как он работает на двух символах if(BarsCalculated(ind_spreadLR)==Bars(_Symbol,_Period)) { //--- получим значения спреда на текущем ("сегодня") и предыдущем ("вчера") барах double SpreadValues[]; int copied=CopyBuffer(ind_spreadLR,0,0,2,SpreadValues); double Spread_curr=SpreadValues[1]; // спред на текущем баре развивающемся который double Spread_prev=SpreadValues[0]; // спред на преыдущем завершенном баре if(copied!=-1) { //--- если изменение знака спреда сохраняется на последних ticks_for_trade тиках if(SpreadSignChanged(Spread_curr,Spread_prev,ticks_for_trade)) { PrintFormat("Спред изменил знак, Spread_curr=%.2f, Spread_prev=%.2f: %s", Spread_curr,Spread_prev,TimeToString(TimeCurrent(),TIME_SECONDS)); //--- покажем на графике значения последних ticks_for_trade тиков по обоим символам ShowLastTicksComment(ticks_for_trade); //--- если открытых позиций нет, то войдем в рынок по двум символам if(PositionsTotal()==0) DoTrades(Spread_curr>0,strategy,symbol1,1,symbol2,1); //--- есть открытые позиции, делаем переворот else ReverseTrades(Spread_curr>0,positionstype,symbol1,symbol2); } //--- знак спреда не изменился, проверим плавающую прибыль - может, пора закрывать? else { double profit=AccountInfoDouble(ACCOUNT_PROFIT); double balance=AccountInfoDouble(ACCOUNT_BALANCE); if(profit/balance*100>=profit_percent) { //--- достигнут нужный уровень плавающей прибыли - фиксируем trade.PositionClose(symbol1); trade.PositionClose(symbol2); positionstype=0; } } } } }
В этом советнике мы добавили функцию ShowLastTicksComment(), которая выводит на график в момент появления сигнала значения последних N тиков по обоим символам.
Так мы сможем визуально тестировать стратегию и видеть изменения тиков с точностью до миллисекунд:
Запускаем такие же варианты оптимизаций, как и в предыдущих стратегиях, и получаем следующие результаты:
«Покупаем 1-ый актив и продаем 2-ой»
«Продаем 1-ый актив и покупаем 2-ой»
Результаты при такой простой оптимизации не сильно улучшились.
Стратегия №4 — достижение спредом заданного значения в процентах
Создадим четвертую, последнюю, стратегию для торговли спредом. Она будет такой же простой как три предыдущие, а именно — торговый сигнал возникает в тот момент, когда спред составляет от цены первого актива заданное значение в процентах — spread_delta.
Обработчик поступающих тиков OnInit() изменился незначительно, вот его код из советника Strategy4_SpreadDeltaPercent_EA.mq5:
//+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { if(isNewBar()) PrintFormat("Новый бар %s открылся в %s",_Symbol,TimeToString(TimeCurrent(),TIME_DATE|TIME_SECONDS)); //--- дождемся, когда данные индикатора обновятся, так как он работает на двух символах if(BarsCalculated(ind_spreadLR)==Bars(_Symbol,_Period)) { //--- получим значение спреда на текущем ("сегодня")баре double SpreadValues[]; int copied=CopyBuffer(ind_spreadLR,0,0,1,SpreadValues); double Spread_curr=SpreadValues[0]; // спред на текущем развивающемся баре if(copied!=-1) { MqlTick tick; SymbolInfoTick(symbol1,tick); double last=tick.last; double spread_percent=Spread_curr/last*100; //--- если спред в % достиг заданной величины spread_delta if(MathAbs(spread_percent)>=spread_delta) { PrintFormat("Спред достиг %.1f%% (%G) %s", spread_percent,TimeToString(TimeCurrent(),TIME_SECONDS), Spread_curr); //--- если открытых позиций нет, то войдем в рынок по двум символам if(PositionsTotal()==0) DoTrades(Spread_curr,strategy,symbol1,1,symbol2,1); //--- есть открытые позиции, делаем переворот else ReverseTrades(Spread_curr,positionstype,symbol1,symbol2); } //--- спред в пределах допустимого, проверим плавающую прибыль - может, пора закрывать? else { double profit=AccountInfoDouble(ACCOUNT_PROFIT); double balance=AccountInfoDouble(ACCOUNT_BALANCE); if(profit/balance*100>=profit_percent) { //--- достигнут нужный уровень плавающей прибыли - фиксируем trade.PositionClose(symbol1); trade.PositionClose(symbol2); positionstype=0; } } } } }
Закрывать позиции мы будем также по достижению заданного процента прибыли profit_percent=2, на этот раз сделаем его фиксированным. Запускаем оптимизацию по параметру spread_deltaв диапазоне от 0.1 до 1%.
«Покупаем 1-ый актив и продаем 2-ой»
«Продаем 1-ый актив и покупаем 2-ой»
На этот раз первое правило «Покупаем 1-ый актив и продаем 2-ой» выглядит значительно лучше, чем второе. Оптимизацию по остальным параметрам вы можете сделать сами.
MetaTrader 5 — среда разработки торговых стратегий
В этой статье мы рассмотрели 4 простые стратегии для торговли на спреде. Показанные этими системами результаты тестирования и оптимизации нельзя принимать как руководство к действию, так как они были получены на ограниченном интервале и могут быть в какой-то степени случайными.
В этой статье мы показали, насколько удобно в MetaTrader 5 проверять и отлаживать торговые идеи.
Для разработчиков автоматических торговых систем тестер в MetaTrader 5 предлагает следующие удобные возможности:
- автоматическое скачивание тиковой истории по всем используемым в советника символам,
- визуальный режим отладки стратегий и индикаторов с показом сделок, торговой истории и журнала экспертов,
- автоматический запуск на графике используемых в советнике индикаторов в режиме визуального тестирования,
- тестирование стратегий на реальных записанных тиковых данных с воспроизведением реального торгового окружения,
- многопоточную оптимизацию параметров с заданием собственной целевой функции,
- использование тысяч агентов тестирования для ускорения оптимизации,
- визуализацию результатовоптимизации по своим правилам,
- тестирование стратегий, торгующих на нескольких инструментах с синхронизацией тиков до миллисекунд,
- отладку статегий прямо во время тестирования — можно расставить точки остановки, чтобы посмотреть значения нужных переменных и пошагово пройти по коду программы.
Тестер торговых стратегий в данной статье использовался как инструмент исследования и поиска правильного направления — это делалось в виде оптимизации по одному параметру, чтобы быстро получать качественные выводы.
Вы можете добавлять новые правила, модифицировать существующие и подвергнуть полученные советники тотальной оптимизации.
Для ускорения массовых тяжелых вычислений используйте глобальную вычислительную сеть MQL5 Cloud Network, которая создана специально для платформы MetaTrader 5
Необходимые замечания по стратегиям
Обычно при поиске символов для составления спреда используют не абсолютные значения цены, а приращения. То есть вместо ряда Close[i] вычисляют Delta[i]=Close[i]-Close[i-1].
Для сбалансированной торговли необходимо подбирать объем для каждого символа спреда. В статье же при тестировании использовались только объемы в 1 лот на каждом символе.
При тестировании используются текущие настройки в спецификации контрактов Si и RTS. Необходимо отметить, что:
- в основе фьючерса RTS-12.16 лежит доллар США,
- цена тика фьючерса RTS-12.16 каждый день задается Московской биржей
- и это значение равно 0.2 от индикативного курса доллара.
Методику расчета вы можете найти на сайте MOEX — http://fs.moex.com/files/3244. Поэтому нужно иметь в виду, что результаты оптимизации в тестере стратегий будут зависеть от курса доллара на момент проведения тестирования.
В статье использованы скриншоты с результатами оптимизации, проведенными 25 октября 2016 года.
Код написан для работы в условиях идеального исполнения — нет обработки результатов отправки торговых приказов, не обрабатываются ошибки, связанные с потерей связи, не учтены комиссии, нет проскальзываний.
Для фьючерсов ликвидность и заполненность графиков улучшаются ближе к моменту истечения контракта. В коде нет явной обработки ситуации, когда на одном символе котировки идут, а на второй пропущены целые бары (торговля в это время на бирже не велась по какой-либо причине).
Хотя сами индикаторы, использованные в советнике, гарантированно ждут синхронизации баров по обоим символам, чтобы рассчитать значение спреда, и пишут эти события в журнал.
Не затронут вопрос анализа статистики отклонений спреда от средних значений для создания более надежных торговых правил.
Не используется анализ стакана заявок, так как поток заявок в тестере MetaTrader 5 не эмулируется.
Индикаторы, используемые в данной статье, динамически пересчитывают коэффициенты линейной регрессии для создания графиков спреда и линии тренда. Поэтому по окончании тестирования вид графиков и значения индикаторов на текущий момент будут отличаться от тех, что были во время тестирования.
Запустите приложенные индикаторы или советники в режиме визуального тестирования, чтобы увидеть, как это происходит в режиме реального времени.
Статьи по теме:
- Тестирование торговых стратегий на реальных тиках
- Как в MetaTrader 5 быстро разработать и отладить торговую стратегию
- С чего начать при создании торгового робота для Московской биржи MOEX
- Как обезопасить себя и своего эксперта при торговле на Московской бирже
- Сравнение MQL5 и QLUA — почему торговые операции в MQL5 до 28 раз быстрее?
- Какие проверки должен пройти торговый робот перед публикацией в Маркете
Программы, используемые в статье:
Веб версия MetaTrader 5 с двухфакторной авторизацией
По многочисленным запросам клиентов в веб-версии MetaTrader 5усилена защита торговых счетов от несанкционированного доступа.
Она включает в себя двухфакторную авторизацию при помощи одноразовых паролей, а также возможность смены обычного и инвесторского паролей.
Чтобы включить двухфакторную авторизацию, воспользуйтесь мобильным приложением MetaTrader 5. Авторизуйтесь и в окне «Настройки» откройте генератор One-time password (OTP).
Привяжите к нему все свои торговые счета — и для каждого будет автоматически создаваться уникальный одноразовый пароль из шести цифр. Введите его при авторизации в веб-платформу — поздравляем, теперь ваш торговый счет под надежной защитой!
В обновленной веб-платформе MetaTrader 5 вы также можете сменить обычный и инвесторский пароли. Воспользуйтесь этой возможностью, чтобы создать удобный для запоминания персональный идентификатор.
И последнее важное новшество — автоматическая генерация демо-счетов. Теперь вы можете зайти в MetaTrader 5 Web из любого браузера и немедленно начать торговать на Форексе, фондовой бирже, фьючерсами или CFD.
Сделайте это прямо сейчас: https://www.mql5.com/ru/trading
MetaTrader 5 build 1525: Представление истории в виде позиций и улучшение тестера
Мы выпустили очередное обновление MetaTrader 5:
- Добавлено представление торговой истории в виде позиций. Терминал собирает данные по сделкам, относящимся к позиции и группирует эти данные в единую запись, где можно сразу посмотреть:
- Добавлена команда для визуализации истории сделок на графике по конкретному символу
- Добавлен показ международного имени торгового инструмента в спецификации контракта, а также возможность поиска по нему в диалоге управления инструментами.
- Добавлена возможность быстро установить разрешение для окна терминала. Функция будет удобна для тех, кто снимает видеоролики.
- Шаблоны и профили графиков перенесены из [каталога данных терминала\Profiles] в [каталог данных терминала\MQL5\Profiles]. Теперь можно легко добавлять шаблоны в хранилище MQL5 Storageи использовать их с любого вашего компьютера.
- Добавлена поддержка ресурсных переменных.
Использование таких переменных может существенно облегчить написание некоторых программ. Например, вы можете написать OpenCL код в отдельном CL-файле, а затем включить этот файл в виде строки в ресурсы вашей MQL5-программы.
Примеры использования:#resource "data.bin" as int ExtData[] // объявление массива числового типа, содержащего данные из файла data.bin #resource "data.bin" as MqlRates ExtData[] // объявление массива простых структур, содержащего данные из файла data.bin #resource "data.txt" as string ExtCode // объявление строки, содержащей данные файла data.txt #resource "data.txt" as string ExtCode[] // объявление строкового массива, содержащего строки файла data.txt #resource "image.bmp" as bitmap ExtBitmap[] // объявление одномерного массива, содержащего в себе растр из файла BMP, размер массива = height * width #resource "image.bmp" as bitmap ExtBitmap2[][] // объявление двумерного массива, содержащего в себе растр из файла BMP, размер массива [height][width]
- Добавлено свойство CHART_SHOW для отключения отображения графика. Для получения и установки свойства используются функции ChartGetIntegerи ChartSetInteger.
- Добавлено свойство CHART_KEYBOARD_CONTROL для включения/отключения управления графиком при помощи клавиатуры.
Установка CHART_KEYBOARD_CONTROL=false позволяет отключить скроллинг и масштабирование графика, но при этом сохраняется возможность получать события нажатия данных клавиш в OnChartEvent. - Добавлены новые функции и свойства для работы с OpenCL.
- Добавлена функция TranslateKey, которая возвращает Unicode-символ по виртуальному коду клавиши, учитывая текущий язык ввода и состояние управляющих клавиш.
- Добавлен код ответа TRADE_RETCODE_LIMIT_POSITIONS.
Количество открытых позиций, которое можно одновременно иметь на счете, может быть ограничено настройками сервера. При достижении лимита в ответ на выставление ордера сервер вернет ошибку TRADE_RETCODE_LIMIT_POSITIONS. - Исправлена ошибка, в некоторых случаях приводившая к пропуску тиков в тиковой истории.
- Исправлены ошибки косвенной типизации шаблонов.
- Обновлена библиотека работы с математической статистикой.
- Исправлено открытие страницы продукта при скачивании демо-версии.
- После завершения оптимизации результаты теперь автоматически сортируются по колонке «Результат».
- В контекстное меню вкладки результатов оптимизации и журнала добавлена опция автоматического переключения на результаты после завершения оптимизации.
- Тестер стратегий теперь остается в режиме оптимизации после запуска одиночного тестирования.
Ранее, если из вкладки результатов оптимизации запускалось одиночное тестирование, тестер стратегий полностью переходил в режим одиночного тестирования. Для проведения повторной оптимизации было необходимо включать ее вновь в настройках. - Теперь наборы входных параметров можно сохранять не только в виде set-файлов, но и в виде настроек локального тестера стратегий с удобным доступом к ним через контекстное меню.
- Добавлен перевод интерфейса на монгольский, венгерский, румынский языки и язык урду.
- Добавлена возможность менять порядок наблюдаемых выражений в окне отладки. Просто перетащите выражение в нужную позицию мышью.
- Исправлена ошибка определения кодировки исходных файлов.
- Исправлен поиск по файлам в кодировке UTF-8.
- Исправлена ошибка выделения текста мышью при наличии в нем знаков табуляции.
- Добавлен перевод интерфейса MetaEditor на венгерский и румынский языки.
- Обновлена документация.
Обновление уже доступно через систему LiveUpdate.
БКС Форекс, ИнстаФорекс, LiteForex и другие брокеры запустили MetaTrader 5
Кроме того, в 2017 году Binary.com, Benchmark Finance, MIB700 и другие брокеры также предложили это ПО своим трейдерам.
«Мы рады присоединиться к глобальному тренду и оказаться в числе первых российских брокеров, запустивших MetaTrader 5 с опцией хеджинга!» — говорит управляющий директор «БКС Форекс» Кирилл Агеев:
Наша компания предлагает более 420 торговых инструментов и выступает исключительно за высокотехнологичные решения, которые позволяют оптимизировать трейдинг по максимуму.
MetaTrader 5 же является, пожалуй, флагманской платформой и по востребованности среди трейдеров практически не имеет альтернатив на рынке. Продукт активно совершенствуется, что дает нашим трейдерам возможность постоянно совершенствовать свои торговые стратегии и использовать новые инструменты для заработка.
Совсем недавно мы выпустили новый релиз Личного кабинета, в который была добавлена опция хеджа (локирования) на счетах DIRECT.MT5 и NDD.MT5.
Это позволило трейдерам открывать разнонаправленные позиции по одному и тому же инструменту. При этом переключаться между разными режимами можно прямо в Личном кабинете в один клик. Неудивительно, что наши клиенты массово переходят на MetaTrader 5.
Запуск хеджинга по сути стер последние препятствия для перехода на платформу пятого поколения.
MetaTrader 5 iOS build 1509 и десктопный MetaTrader 5 build 1530

Теперь любой пользователь этой социальной сети в несколько кликов может получить доступ к чатам и всему набору сервисов для MetaTrader 5. Среди огромной аудитории Facebook найдется немало мобильных трейдеров, которые оценят новый способ авторизации.
Хотя это главная видимая тема обновления мобильной платформы, за бортом остались еще пару десятков исправлений и улучшений.
Очень просим обновиться до последний мобильных версий или просто попробовать наши решения. Например, на сервере MetaQuotes-Demo доступны инструменты MOEX с 15 минутной задержкой. Достаточно потратить минуту, чтобы все получить:
Еще одно хорошее обновление — это бета-версия дестопного MetaTrader 5 build 1530. В нем тоже очень много внутренних улучшений, но из видимых преимуществ — это кратное снижение нагрузки на процессор при наличии множества окон и массе графических объектов.
Обновиться до последней версии можно подключившись к серверу MetaQuotes-Demo.
Ликвидность для MetaTrader 5 от Just2Trade: 9 000+ инструментов на NYSE, NASDAQ, LSE и других биржах
Продолжает расширяться пул поставщиков ликвидности для MetaTrader 5.
На волне интереса брокеров к этой платформе группа компаний Just2Trade (генеральный партнер инвестиционного холдинга «ФИНАМ») предложила интеграционное решениена базе шлюза MetaTrader 5 Gateway to MetaTrader 5.
По словам операционного директора Just2Trade Евгения Жилина это простой и удобный способ обеспечить трейдерам прямой выход на ведущие мировые биржи, включая фондовый и срочный рынки США.
Всего компания предоставляет доступ к 9 000 финансовых инструментов: 6 000+ акций и ETF на фондовом рынке США, 700+ акций российских компаний, фьючерсы на индекс РТС, ММВБ, акции и валюту, а также прямой доступ к биржам GLOBEX, EUREX, SGX и другим.
Кроме того, по запросу доступны акции и срочные контракты на всех основных биржах Европы и Азии.
«Ликвидность от Just2Trade расширяет возможности компаний, которые предоставляют своим клиентам услуги через MetaTrader 5» — говорит Евгений Жилин:
Пожалуй, это наиболее эффективный способ решить задачу подключения интересующих рынков.
Учитывая непрерывную миграцию мировых брокеров на MetaTrader 5, мы рассчитываем на активный спрос со стороны институциональных клиентов. Открывая счет в нашей компании, брокер получает возможность торговать всеми доступными инструментами — при этом брокерская комиссия списывается только при совершении торговых операций.
Отмечу, что подключиться к нашему шлюзу штатными средствами MetaTrader 5 можно за 10 минут».
Релиз MetaTrader 5 build 1545: быстрое переключение между окнами и изменение цен мышью
Сегодня выходит новая версия MetaTrader 5 билд 1545:
- Terminal: Добавлено быстрое переключение между окнами «Инструменты» и «Тестер стратегий».
- Terminal: Добавлена возможность изменения цен и объемов ордеров при помощи колеса мыши:
- Terminal: Теперь при переходе к скачиванию мобильных терминалов запоминается список ваших торговых серверов. При последующей установке MetaTrader 5 для iPhone или Android на мобильном устройстве вам сразу будет показан готовый список серверов. Вы сможете быстро подключить существующие торговые счета. Сервер текущего подключенного счета будет показан в мобильном терминале первым.
- Terminal: Значительно снижена нагрузка на терминал, создаваемая невидимыми (свернутыми) графиками и объектами.
- Terminal: Исправлена ошибка, в некоторых случаях приводившая к некорректному срабатыванию трейлинг-стопов.
- Terminal: Исправлена ошибка фильтрации сделок по символу в торговой истории счета.
- Terminal: Исправлена ошибка отображения поля «Тип» в истории позиций.
- Terminal: Исправлена ошибка в формировании и представлении торговой истории в виде позиций.
- MQL5: Исправлено отображение пользовательских индикаторов с типом построения DRAW_COLOR_LINE, DRAW_COLOR_ZIGZAG и DRAW_COLOR_SECTION при использовании цвета CLR_NONE.
- MQL5: Исправлена ошибка в шаблонах при типизации константным указателем.
- MQL5: Исправлен контроль доступа к private и protected членам класса.
- Tester: Исправлено срабатывание лимитных ордеров на биржевых инструментах при выставлении ордеров хуже текущего рынка (цена покупки выше рыночной, или цена продажи ниже рыночной).
- Tester: Снято ограничение на тестирование пользовательских индикаторов с более чем 64 входными параметрами.
- Tester: Добавлен перевод пользовательского интерфейса на хинди.
- Обновлена документация.
Обновление начнет распространяться через торговые серверы брокеров в воскресенья или с нашего MetaQuotes-Demo сегодня ночью.
Инсталлировать и открыть за 10 секунд бесплатно демо-счета можно, скачав дистрибутив по ссылке https://download.mql5.com/cdn/web/metaquotes.software.corp/mt5/mt5setup.exe
Вышли десктопный MetaTrader 5 build 1571 и MetaTrader 5 iOS build 1547
- Terminal: Обновлена витрина магазина приложений MetaTrader Market. Выбирать торговых роботов и технические индикаторы стало удобнее. Мы обновили дизайн, а также добавили подборки продуктов:
- На главной странице теперь показываются популярные эксперты, индикаторы, новинки Маркета, а также топ бесплатных приложений.
- В разделах экспертов, индикаторов и утилит появились подкатегории: сеточные и хеджирующие роботы, трендовые и мультивалютные индикаторы, а также многое другое.
- Terminal: Исправлено обновление клиентского терминала и работа встроенных покупок в Маркете, Сигналах и Виртуальном хостинге при использовании учетной записи Windows с ограниченными правами.
- Terminal: Исправлена ошибка, в некоторых случаях приводившая к нарушению сортировки истории позиций.
- Terminal: Оптимизировано и исправлено отображение вкладки «Активы».
- MQL5: Добавлена поддержка перегрузки шаблонных функцийпо параметрам.
- MQL5: Добавлена возможность явной специализации шаблонных функций.
- MQL5: Оптимизировано отображение пользовательских индикаторов с типом рисования DRAW_ZIGZAG.
- MQL5: В перечисление типов сделок ENUM_DEAL_TYPEдобавлены новые значения:
- DEAL_DIVIDEND — сделка начисления дивиденда.
- DEAL_DIVIDEND_FRANKED — сделка начисления франкированного дивиденда (не облагается налогом, налог за клиента оплачивает компания).
- DEAL_TAX — сделка удержания налога.
- MQL5: Исправлено отображение пользовательских индикаторов с типом рисования DRAW_FILLING. При совпадении координат верхней и нижней линии теперь рисуется тонкая линия.
- MQL5: Исправлено вычисление координат объекта «Графическая метка» (Bitmap Label) при выставлении параметра CHART_SHOW в состояние false. Этот параметр устанавливается функцией ChartSetIntegerи позволяет скрыть все элементы ценового графика для создания собственного интерфейса программы.
- MQL5: Исправлена ошибка перекодировки 24-битных изображений при помещении их в ресурсы MQL5-приложения.
- MQL5: Исправлена ошибка вывода на печать структур функцией ArrayPrint.
- MQL5: Обновлены стандартные библиотеки MQL5.
- MetaEditor: Добавлен перевод пользовательского интерфейса на малайский язык.
- Signals: Исправлено открытие страницы сигнала в терминале при переходе с сайта MQL5.community в случае отсутствия подключения торговым счетом.
- Tester: Исправлены ошибки при работе функции CopyTicksв тестере стратегий.
- Tester: Исправлена сортировка сделок типа «Снятие» (Withdrawal) при формировании отчета тестирования.
- Tester: Исправлена модификация отложенных ордеров.
- Hosting: Исправлено отображение мастера виртуального хостинга на экранах сверхвысокого разрешения (4К).
- Обновлена документация.
Главное новшество мобильной версии для iPhone и iPad — представление торговой истории в виде позиций.
Ранее во вкладке «История» отражались только сделки и ордера из истории, теперь в ней представлены и позиции. Торговая платформа собирает данные по сделкам, относящимся к позиции, и группирует эти данные в единую запись.
В ней можно увидеть:
- Время открытия и закрытия позиции, определяемое по первой и последней сделке
- Объем позиции; если позиция закрыта частично, показывается закрытый объем и исходный объем
- Средневзвешенную цену открытия и цену закрытия позиции
- Суммарный финансовый результат по сделкам, относящимся к позиции
Apple Multi-Asset DMCC запускает торговлю DGCX Shanghai Gold Futures через MetaTrader 5
Дубайская биржа золота и сырьевых товаров DGCX запустила новый финансовый продукт — шанхайские фьючерсные контракты на золото (Shanghai Gold Futures, DSGC).
Китайский фьючерс стал впервые доступен за пределами Китая, торговля и расчеты по контрактам производятся в юанях. Первой компанией, запустившей торговлю новым финансовым инструментом в платформе MetaTrader 5, стала Apple Multi-Asset DMCC (AMA).
Дубай исторически является центром торговли золотом для стран Ближнего Востока и Северной Африки. Большая часть мирового торгового сообщества заинтересована в участии в китайских рынках реальных товаров и производных инструментов.
Этот интерес сочетается со стремлением китайского правительства увеличить степень глобального признания китайского юаня и эталонных цен на золото, устанавливаемых Китаем.
Запуск на бирже DGCX шанхайских фьючерсных контрактов на золото предоставляет всем сторонам, включая правительство Китая, ОАЭ и Дубая, участников рынка, Шанхайскую биржу золота SGE и Дубайскую биржу DGCX, возможность вместе развиваться, участвуя в инициативе «Один пояс и один путь».
Вот тут https://www.metaquotes.net/ru/company/newsеще больше новостей про MetaTrader 5.
Лента сделок в MetaTrader 5: новый инструмент для анализа фондового рынка
На днях был выпущен релиз торговой платформы MetaTrader 5 build 1375 с лентой сделок (Time & Sales) в стакане цен.
Лента сделок позволяет видеть список всех биржевых торговых операций в режиме реального времени. По каждой сделке показывается ее время, направление, цена и объем. Каждое направление выделяется отдельным цветом, а объемы даны в виде гистограммы:
Из ленты можно экспортировать данные в формате CSV и анализировать в сторонних редакторах электронных таблиц.
Если у вас не произошло автоматическое обновление через вашего брокера, попробуйте обновиться через демо счет на сервере MetaQuotes-Demo. Для этого просто добавьте MetaQuotes-Demo в список серверов и откройте там демо-счет:
Полный список изменений 1375 билда: http://www.metatrader5.com/ru/releasenotes
Новый шлюз к Interactive Brokers для MetaTrader 5 от MetaQuotes и oneZero — это торговля на 130 фондовых биржах мира, включая NASDAQ и NYSE
Мы вместе с oneZero Financial Systemsвыпустили шлюз интеграции с Interactive Brokers Group, Inc. С его помощью в MetaTrader 5 можно торговать акциями, фьючерсами и другими биржевыми инструментами на крупнейших фондовых биржах мира: Нью-Йоркской (NYSE), Лондонской (LSE), Гонконгской (HKEX), Токийской (TSE), NASDAQ и пр.
Помимо ценных бумаг и фьючерсов, шлюз позволяет торговать валютными парами, контрактами на разницу и драгоценными металлами с поддержкой стакана цен для соответствующих инструментов. Кроме того, с помощью шлюза брокеры могут автоматически производить корпоративные действия по определенной ценной бумаге (например, начислять дивиденды) сразу по всем трейдерам, имеющим открытые позиции по данному инструменту. На сайте американского брокера можно ознакомиться с полным списком символови бирж, доступ к которым обеспечивает новый продукт (в MetaTrader 5 можно торговать всем, кроме опционов).
Отметим важное преимущество шлюза Interactive Brokers для брокеров: компании, использующие этот продукт, получают доступ к различным биржам по единому соединению без необходимости напрямую подключаться к этим биржам или биржевым клиринг-агентам. Для приобретения шлюза oneZero Hub для MetaTrader 5 необходимо обратиться в компанию oneZero Financial Systems. Для работы также потребуется активный счет от компании Interactive Brokers.
“Мы в oneZero были рады работать над этой важной и долгожданной интеграцией напрямую с компанией MetaQuotes Software, — комментирует партнерство генеральный директор oneZero Эндрю Ралич. — В результате тесного взаимодействия с компаниями MetaQuotes Software и Interactive Brokers мы выпустили действительно востребованный шлюз для MetaTrader 5 на основе нашего продукта Hub и существующей технологической платформы. Интеграция с Interactive Brokers предоставляет дополнительные институциональные возможности к уже имеющимся в платформе MetaTrader 5, например, к использованию стакана цен”.
«Выпуск шлюза oneZero для интеграции с Interactive Brokers — это важный прогрессивный шаг для MetaTrader 5, — убежден генеральный директор MetaQuotes Software Corp. Ренат Фатхуллин. — Теперь у миллионов пользователей нашей платформы появилась уникальная возможность торговать ценными бумагами и фьючерсами международных корпораций на пятнадцати из двадцати крупнейших фондовых бирж мира!»
Выпущен новый шлюз MetaTrader 5 Gateway to CQG от Forexware
Мы расширяем торговые возможности мультирыночной платформы MetaTrader 5: вслед за релизом шлюза к Interactive Brokers выпущен шлюз к платформе CQG.
Приложение разработано компанией Forexware и предоставляет прямой доступ на международные биржи CME, CBOT, NYMEX, ICE, EUREX и десятки других.
Спектр торгуемых на этих площадках инструментов максимально широк — от фьючерсов и опционов до индексов и биржевых спредов (counter spread). Причем для всех этих инструментов шлюз поддерживает стакан цен (market depth).
CQG, Inc.более 15 лет поставляет котировки мировым банкам, инвестиционным компаниям, брокерам и другим крупнейшим участникам финансового мира. Обладая собственной инфраструктурой, компания получает котировки от бирж напрямую, без посредников.
Таким образом, шлюз к CQG для MetaTrader 5 способен успешно прописаться в рабочем арсенале биржевых трейдеров, предпочитающих прозрачные котировки и молниеносное исполнение ордеров.
http://www.metatrader5.com/ru/news
Cравниваем MQL5 и QLUA - почему роботы на MQL5 до 28 раз быстрее?
- Условия испытаний
- Результаты сравнения скорости операций: MetaTrader 5 vs QUIK
- Видео сравнения скорости торговых операций
- MetaTrader 5 быстрее QUIK в торговых операциях до 28 раз
- Детальные отчеты по сравнению терминалов
- Почему такая разница?
Многие трейдеры зачастую не задумываются над тем, как быстро доходит их заявка до биржи, как долго она там исполняется и когда торговый терминал трейдера узнает о результате.
В результате они не знают, что легко могут улучшить качество исполнения своих сделок за счет более быстрой реакции и скорости проведения транзакций.
12 сентября 2016 года были проведены три замера скорости на реальном счете БД «Открытие» на MetaTrader 5 build 1415 и Quik 7.2.23 в одно и то же время.Каждый тест был призван измерить конкретную скоростную характеристику, важную с точки зрения алгоритмического трейдинга:
- Тестирование синхронных операций — серия из 10 синхронныхпоследовательных торговых операций Buyс подтверждением успешности выполнения каждой транзакции на бирже. Последующая операция не производится, пока не будет получено подтверждение от торгового сервера, что операция прошла/не прошла на бирже. Скорость выполнения зависит от всей цепочки терминал — торговый сервер — биржа — торговый сервер — терминал. Чем меньше будет среднее время торговой синхронной операции, тем лучше.
- Тестирование асинхронных операций— серия из 10 асинхронныхторговых операций Buyбез подтверждения успешности выполнения транзакции. Это чистый тест на скорострельность, измеряющий скорость отправки заявок на биржу. Тут также лучшим будет тот терминал, у которого время выполнения 10-ти асинхронных покупок будет меньше.
- Тестирование обновления стакана заявок— замер скорости изменений заявок в Стакане. Это простой подсчет количества тиков (обновлений) Стакана в единицу времени. Чем чаще приходят котировки с биржи в торговый терминал, тем быстрее будет обновляться Стакан. Следовательно, чем больше тиков за секунду поступает в программу автоматической торговли, тем быстрее она может среагировать на изменения в структуре спроса/предложения на рынке. Лучшим будет тот терминал, в котором скорость обновления Стакана выше.
Условия испытаний
Оба терминала установлены на арендованном сервере VPS в Москве, как и сами торговые серверы БД «Открытие». Торговля велась на одном и том же реальном счете в срочной секции Московской биржи инструментом Si-9.6.
Мы записали на видео все три теста одним роликом, чтобы было видно:
- торговые операции проводились на одном и том же реальном счете;
- и на одном и том же инструменте Si-9.16;
- на одном и том же компьютере;
- торговые операции проводились в одно и то же время;
- в одних и тех же рыночных условиях;
- скорости обновления стаканов замерялись на одном и том же инструменте и в одно и то же время;
- сетевая задержка до серверов Открытия была 2 мс.
Результаты сравнения скорости операций: MetaTrader 5 vs QUIK
Результаты всех трех тестов собраны в сводной таблице, детальные результаты по каждому тесту представлены ниже отдельными разделами этой статьи.
Тест MetaTrader 5 QUIK Выигрыш MT5 Синхронные операции 9.59 ms 277.80 ms 28.96 раз Асинхронная 0.09 ms 0.30 ms 3.33 раза Обновлений стакана 42.7 в сек 8.40 5.08 раза
Как видно из таблицы, MetaTrader 5 опережает по всем трем тестам со значительным отрывом. Желающие могут самостоятельно провести подобные испытания с помощью приложенных исходных кодов. Само тестирование представлено на видео выше.
Видео сравнения скорости торговых операций
MetaTrader 5 быстрее QUIK в торговых операциях до 28 раз
Проведенные замеры показали, что язык MQL5 значительно опережает QLUA как в проведении торговых операций на Московской бирже, так и просто в сканировании стакана заявок. Торговые роботы, написанные на языке MQL5, не только считают в 50-100 раз быстрее, но и торгуют до 28 раз быстрее. И при этом вам не нужно изобретать свои велосипеды — приводы, коннекторы и т.д. К вашим услугам готовые торговые классыстандартной библиотеки и масса статейпо автоматизации трейдинга.
Надежный торговый робот просто обязан проверять результаты отправки торговых операций — то есть, дожидаться ответа от торгового сервера. Тесты доказали, что MetaTrader 5 значительно быстрее в синхронных операциях. Если же вам нужны асинхронные операции — то и здесь скорость в 3 раза выше. Требуется анализировать поток заявок — и тут MetaTrader 5 даст вам преимущество по сравнению с QUIK за счет в 5 раз более быстрого потока котировок без снапшотов.
Проведенные испытания показали, что для создания быстрых автоматических торговых систем язык MQL5 подходит как нельзя лучше. Никакие коннекторы и библиотеки, подключаемые к терминалу QUIK для ускорения расчетов, не спасут: узким местом будет являться само время проведения торговых операций.
Теперь рассмотрим скучные, но обязательные детали тестирования.
Детальные отчеты по сравнению терминалов
Программа на QLUA при замере времени обращается к системному таймеру операционной системы, который по умолчанию имеет погрешность измеренияв пределах в 10…15.6 миллисекунда (чаще всего — 15.6 мс). Поэтому мы повысили точность замеров времени в QLUA простым повышением точности системного таймера до 1 ms.
Сделано это с помощью скрипта на SpeedupSystemTimer.mq5, который вызывает функцию timeBeginPeriodсистемной библиотеки Winmm.dll
#import "winmm.dll" int timeBeginPeriod(uint per); #import void OnInit() { timeBeginPeriod(1); } void OnTick() { }
Этот скрипт мы запустили перед началом тестов в терминале MetaTrader 5 и разрешив вызов DLL, в результате чего обеспечили погрешность измерений операций в терминале QUIK не более 1 миллисекунды.
В языке MQL5 есть готовая функция GetMicrosecondCount(), поэтому замеры в терминале MetaTrader 5 делались с точностью 1 микросекунда (1 миллисекунда=1000 микросекунд).
#1 Тестирование скорости синхронных торговых операций
Тестирование заключалось в измерении скорости синхронных торговых операций — это значит, что каждая последующая торговая операция совершалась только после получения от торгового сервера подтверждения, что предыдущая транзакция была успешно проведена с полным подтверждением от биржи.
Сначала была проведена серия торговых операций через терминал MetaTrader 5 build 1415, затем такая же серия была произведена через терминал QUIK версии 7.2.23.
Суть испытания заключается в измерении среднего времени 10 синхронных операций покупки по рынку 1 лотом:
- SyncTradeTest.mq5
- SyncTradeTest.lua
Измерение времени, затраченного на синхронную транзакцию, проводилось следующим образом:
- В языке MQL5 есть синхронная функция OrderSend, а время легко замерить в начале и конце серии сделок.
- В языке QLUA нет синхронной торговой функции и поэтому статус сделки приходится отлавливать отдельно. Время старта торговой операции замерялось непосредственно перед вызовом sendTransaction () с помощью функции os.closck().
Успешное выполнение транзакции отслеживалось во встроенном обработчике OnOrder() на первом вызове в момент, когда приходило событие о совершении сделки на бирже. Разница между этими событиями и есть время, потраченное на выполнение торговой операции.
#2 Тестирование скорости асинхронных торговых операций
В этом тесте все значительно проще. Десять раз подряд на биржу отправляется приказ на покупкуодного контракта фьючерса Si-9.16. Это позволило нам измерить среднее время асинхронной передачи в QLUA с точностью 1 ms / 10 = 0.10 ms. В MetaTrader 5 погрешности нет, так как в нем используется микросекундный таймер.
Мы не ждем никакого результата наших операций, за каждой отправкой заявки торговому серверу сразу же делается отправка новой заявки:
- AsyncTradeTest.mq5
- AsyncTradeTest.lua
#3Тестирование обновления стакана заявок
Ряд торговых стратегий строится на анализе потока заявок в стакане. В языке MQL5 событие изменения стакана можно отлавливать в обработчике OnBookEvent(), а в QLUA через OnQuote().
Тесты скорости обновления стаканов проводились с помощью следующих программ, которые доступны в приложенном ZIP-архиве:
- MarketUpdateTest.mq5
- MarketUpdateTest.lua
В результате последовательного запуска этих программ на двух разных терминалах было зафиксировано, что стакан в MetaTrader 5 обновляется примерно в 5 раза чаще, чем в QUIK. Скорее всего QUIK просто лимитирует частоту обновлений стакана и не показывает все изменения.
Так как все исходные коды приложены тут же, любой желающий может самостоятельно воспроизвести эти тесты и убедиться лично в представленных результатах.
Почему такая разница?
Мы фанатично относимся к производительности и боремся за каждый десяток микросекунд, годами оптимизируя торговую платформу.
Именно поэтому мы показываем потрясающую производительность встроенного алгоритмического языка MQL5 и скорость торговых транзакций.Ведущая MTF-площадка для торговли валютами LMAX Exchange стала поставщиком ликвидности для MetaTrader 5
Мы рады сообщить об интеграции с LMAX Exchange— многосторонней площадкой (Multilateral Trading Facility, MTF) для торговли валютами, драгоценными металлами и индексами.
Шлюз MetaTrader 5 к LMAX Exchangeпредлагает брокерам, фондам и профессиональным трейдерам доступ к потоковой ликвидности с использованием лимитных ордеров, прозрачное ценообразование и качественное исполнение при отсутствии «last look».
Используемая LMAX Exchange схема «no last look» обеспечивает отсутствие реквотов и гарантированное исполнение по заявленной поставщиком ликвидности цене.
При постоянно повышающемся спросе брокеров и институциональных трейдеров на нейтральное, бесконфликтное и прозрачное исполнение шлюз к LMAX Exchange обеспечивает пользователей MetaTrader 5 качественной рыночной инфраструктурой, ликвидностью, исполнением и потоковыми рыночными данными.
На данный момент на LMAX доступны более 70 валютных пар и самые популярные CFD на индексы и сырьевые фьючерсы.
Скотт Моффат, LMAX Exchange
«Я очень рад нашему продолжающемуся сотрудничеству с компанией MetaQuotes и тому позитивному влиянию, которое оно оказывает на клиентов розничных брокеров, предоставляя передовые технологии и доступ к мировому рынку, — отмечает исполнительный директор LMAX Exchange Скотт Моффат. — Выпуск шлюза MetaTrader 5 к LMAX Exchange свидетельствует о нашем совместном стремлении к инновациям и наилучшему исполнению».
Как в MetaTrader 5 быстро разработать и отладить торговую стратегию: тиковый анализатор
Скальперские автоматические системы по праву считаются вершиной алгоритмического трейдинга, но при этом они же являются и самыми сложными для написания кода.
В этой статье мы покажем, как с помощью встроенных средств отладки и визуального тестирования строить стратегии, основанные на анализе поступающих тиков. Для выработки правил входа и выхода зачастую требуются годы ручной торговли. Но с помощью MetaTrader 5 вы можете быстро проверить любую подобную стратегию на реальной истории.
Торговая идея на тиках
Прежде всего, нам необходимо создать индикатор, который будет строить тиковые графики — то есть графики, на которых можно увидеть каждое изменение цены.
Один из первых таких индикаторов вы можете найти в Библиотеке — https://www.mql5.com/ru/code/89. В отличие от обычных, на тиковых графиках при поступлении нового тика необходимо весь график смещать назад.
За основу проверяемой идеи возьмем ряд изменений цены между двумя последовательными тиками, это будет примерно такая последовательность в пунктах:
+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 графических построения, которые будут отображать информацию в подокне: линия для тиков и цветные стрелки для сигналов о появлении резких изменений цены.
Внесем в полученную заготовку изменения, которые отмечены желтым
//+------------------------------------------------------------------+ //| 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] последний тик. Запускаем индикатор под отладкой и наблюдаем некоторое время.
Видим, что цена Bid, по которой строится Close текущей свечи, очень часто остается неизменной, и поэтому график рисуется кусками «плато». Немного подправим код, чтобы получать только «пилу» — так глазу более понятно.
//--- вычисляем только если цена изменилась if(lastprice!=TickPriceBuffer[0]) { ticks_counter++; // считаем тики ApplyTick(lastprice); // проведем вычисления и сдвиг в буферах }
Итак, первую версию индикатора мы создали, теперь у нас не бывает нулевых приращений цены.
Добавляем вспомогательный буфер и расчет среднеквадратичного отклонения
Для вычисления отклонения нам необходим дополнительный массив, который будет хранить приращения цены на каждом тике. В качестве такого массива добавим еще один индикаторный буфер и добавим соответствующий код в нужных местах:
#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, как работает наш индикатор.
Теперь пришло время заняться отладкойкода, которая позволит выявить ошибки и ускорить работу программы.
Профилировка кода для ускорения работы
Для программ, работающих в режиме реального времени, критически важна скорость выполнения. Среда разработки MetaEditor позволяет удобно и быстро оценивать затраты времени на выполнение тех или иных участков программы.
Для этого необходимо запустить профилирование кода и дать поработать программе некоторое время. Для профилировки индикатора будет достаточно минуты.
Как видите, большая часть времени (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(), которая отвечает за вычисление среднеквадратичного отклонения.
Таким образом, мы ускорили работу функции ApplyTick() на несколько порядков, что даст нам существенную экономию при оптимизации стратегии и при работе программы в режиме реального времени. Ведь вычислительных ресурсов никогда не бывает слишком много.
Аналитическая оптимизация кода
Иногда даже оптимально написанный код можно заставить работать еще быстрее. В данном случае вычисление среднеквадратичного отклонения можно ускорить, если немного переписать формулу.
Таким образом, мы можем просто вычислять квадрат суммы и сумму квадратов приращений цены — это позволит нам выполнять меньше математических операций на каждом тике. На каждом тике мы просто отнимаем выпадающий элемент массива и добавляем входящий элемент массива в переменные, содержащие суммы.
Создадим новую функцию 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);
Результат выполнения:
Видно, что новая функция getStdDevOptimized() требует в два раза меньше времени — 4.56%, чем лобовой обсчет в getStdDev() — 9.54%. Она выполняется даже быстрее, чем встроенная функция PrintFormat(), которая использовала 4.74% времени работы программы.
Таким образом, использование оптимального способа вычисления дает еще больший выигрыш по скорости работы программы. Рекомендуем также посмотреть статью 3 метода ускорения индикаторов на примере линейной регрессии.
Кстати, о вызове стандартных функций — в данном индикаторе мы получаем цену из таймсерии close[], которая строится по ценам Bid. Есть еще два способа получить эту цену — с помощью функций SymbolInfoDouble()и SymbolInfoTick(). Добавим эти вызовы в код и снова сделаем профилировку.
Как видите, здесь тоже есть разница по скорости работы. И это понятно, так как чтение готовой цены из close[] не требует затрат по сравнению с вызовом универсальных функций.
Отладка на реальных тиках в тестере
При написании индикаторов и торговых роботов нельзя предусмотреть все возможные ситуации, которые могут случиться при онлайн-работе. К счастью, MetaEditor позволяет проводить отладку и на исторических данных.
Просто запустите отладку в режиме визуального тестирования, и вы сможете проверить вашу программу на заданном интервале истории. Вы сможете ускорять, останавливать и прокручивать тестирование до нужной даты.
Важно:в окне Отладкаукажите режим моделирования "Каждый тик на основе реальных тиков". Это позволит использовать для отладки реальные записанные котировки, которые хранит у себя торговый сервер. При первом запуске тестирования они автоматически загрузятся на ваш компьютер.
Если эти параметры не заданы в MetaEditor, то при в виузальном режиме тестирования будут использоваться текущие настройки тестера.Укажите в них режим «Каждый тик на основе реальных тиков».
Мы видим, что на тиковом графике появляются странные разрывы. Значит, в алгоритме допущена какая-то ошибка. Неизвестно, сколько времени ушло бы на её проявление при тестировании в реальном времени. В данном случае по выводам в Журнал визуального тестирования видно, что странные разрывы возникают в момент появления нового бара.
Точно! — мы забыли, что при переходе на новый бар размер индикаторных буферов автоматически увеличивается на 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 — это самый первый тик нового бара.
Ну вот, мы провели оптимизацию кода, исправили ошибки, замерили время выполнения различных функций, теперь индикатор готов к работе. Можно запускать визуальное тестированиеи наблюдать, что происходит после появления сигналов на тиковом графике. Можно что-то еще улучшить в коде индикатора?
Перфекционист от кодинга скажет — да! Мы еще не попробовали использовать кольцевой буфердля ускорения работы. Желающие могут проверить сами — дает ли это прирост производительности?
MetaEditor — это готовая лаборатория для разработки торговых стратегий
Для написания автоматической торговой системы важно иметь не только удобную среду разработки и мощный язык программирования, но и дополнительные инструменты для отладки и калибровки программы. В этой статье мы показали как:
- создавать за пару минут тиковый график в первом приближении;
- пользоваться отладкой в режиме реального времени на графике по кнопке F5;
- запускать профилировку для выявления неэффективных мест в коде;
- проводить быструю отладку на исторических данных в режиме визуального тестирования;
- просматривать значения нужных переменных в процессе отладки.
Разработка индикатора, показывающего торговые сигналы, зачастую является первым необходимым шагом для написания торгового робота. Визуализация помогает выработать торговые правила либо отвергнуть идею еще до начала работы над проектом.
Пользуйтесь всеми возможностями среды разработки MetaEditor для создания эффективных торговых роботов!
Статьи по теме:
- Как написать индикатор в MQL5
- Создание тиковых индикаторов
- Принципы экономного пересчета индикаторов
- Усреднение ценовых рядов без дополнительных буферов для промежуточных расчетов
- Отладка программ на MQL5
Готовый файл можно скачать по ссылке: https://www.mql5.com/ru/articles/download/2661/tickspikehunter.mq5
Вышел MetaTrader 5 build 1455 с библиотеками математических функций в MQL5 - на пути к R
Ниже представлен список изменений:
1) Terminal: Добавлены всплывающие подсказки для кнопок Buy, Sell и Close в диалогах торговли.
Подсказки поясняют, какие именно активы будут куплены и проданы при выполнении той или иной операции, помогая начинающим трейдерам понять суть торгового процесса.

2) Terminal: Добавлены новые пиктограммы ордеров, сделок и позиций на вкладках «Торговля» и «История».
3) Terminal: Оптимизировано и значительно ускорено (до 4-5 раз) отображение и обновление стакана цен, тикового графика стакана цен и ленты сделок.
4) Terminal: Исправлена ошибка синхронизации тиковой истории в неторговое время. В некоторых случаях ошибка приводила к чрезмерному потреблению сетевого трафика.
5) MQL5: В стандартную библиотеку включена MQL5-версия библиотеки численного анализа ALGLIB.
Возможности библиотеки:
- Линейная алгебра
- Решение систем уравнений — линейных и нелинейных
- Интерполяция
- Оптимизация
- Быстрое преобразование Фурье
- Численное интегрирование
- Линейная и нелинейная аппроксимация по методу наименьших квадратов
- Решение обыкновенных дифференциальных уравнений
- Вычисление специальных функций
- Описательная статистика и проверка гипотез
- Анализ данных — классификация, регрессия
- Реализация алгоритмов линейной алгебры, интерполяции и т.д. в арифметике высокой точности (с использованием MPFR)
Файлы библиотеки ALGLIB расположены в каталоге \MQL5\Include\Math\Alglib. Для использования функций, включите основной файл библиотеки в свою программу: #include <Math\Alglib\alglib.mqh>
6) MQL5: В стандартную библиотеку включены функции работы с математической статистикой.
Теперь в MQL5 доступны возможности языка R — одного из лучших инструментов статистической обработки и анализа данных.
Статистическая библиотека содержит функции для расчета статистических характеристик данных, а также функции для работы со статистическими распределениями:
- Функции для расчета статистических характеристик элементов массива
- Функции для работы со статистическими распределениями: нормальное распределение, логнормальное распределение, бета-распределение и т.д.
Файлы расположены в каталоге \MQL5\Include\Math\Stat. Для использования включите файл с нужными функциями в свою программу, например: #include <Math\Stat\Binomal.mqh>
Подробное описание функций библиотеки читайте в статье "Статистические распределения в MQL5 — берем лучшее из R".
7) MQL5: В стандартную библиотеку включена MQL5-версия библиотеки Fuzzy, в которой реализованы системы нечеткого логического вывода Мамдани и Сугено.
Возможности библиотеки:
- 13 функций принадлежностей
- Гибкая форма написания правил для нечетких систем
- Система нечеткого логического вывода Мамдани
- Система нечеткого логического вывода Сугено
- 5 методов дефаззификации для систем типа Мамдани
- Неограниченное количество входных и выходных переменных
Файлы расположены в каталоге \MQL5\Include\Math\Fuzzy. Для использования включите файл с нужными функциями в свою программу, например: #include <Math\Fuzzy\mamdanifuzzysystem.mqh>
8) MQL5: Добавлено свойство CHART_QUICK_NAVIGATION для включения/отключения строки быстрой навигации на графике.
Для изменения и получения состояния свойства используйте функции ChartSetInteger и ChartGetInteger. Строка вызывается нажатием клавиши Enter или Space. При помощи нее можно быстро переместиться к заданной дате на графике, переключить символ и таймфрейм.
Если ваша MQL5-программа обрабатывает нажатия клавиш Enter или Space, отключите свойство CHART_QUICK_NAVIGATION, чтобы терминал не перехватывал эти события. При этом останется возможность вызова строки навигации двойным кликом мыши.
9) MQL5: Добавлены функции FileLoad и FileSave для легкого чтения и сохранения массивов в файлы.
В отличие от FileRead* и FileWrite*, этим функциям не требуется хэндл файла. FileLoad и FileSave работают с массивами числовых типов, а также с простыми структурами, не имеющими строк, динамических массивов или объектов класса.
10) MQL5: Модифицировано отображение пользовательского индикатора с режимом рисования DRAW_CANDLES. Теперь для этого стиля можно задавать от одного до трех цветов, в зависимости от этого меняется внешний вид свечей.
11) MQL5: Исправлен ряд ошибок и ускорена работа с тиковой историей при помощи функции CopyTicks.
12) MQL5: Разрешено использование операторов в интерфейсах.
13) Market: Исправлена ошибка, в некоторых случаях приводившая к повторному запросу авторизации на MQL5.community при покупке в Маркете.
14) Tester: Добавлен перевод пользовательского интерфейса на греческий язык, малайский язык и иврит.
15) Обновлена документация.
Обновление доступно через систему LiveUpdate. Если с торгового сервера вашего брокера не приходит обновление, то подключитесь к серверу MetaQuotes-Demo и перезапустите программу. Обновление придет на старте.
Если у вас еще нет MetaTrader 5, то скачайте его бесплатно по ссылке https://download.mql5.com/cdn/web/metaquotes.software.corp/mt5/mt5setup.exe, пожалуйста.
Откройте демо-счет на сервере MetaQuotes-Demo и получите доступ к задержанным на 15 минут котировкам MOEX:
На демо-счете вы можете проводить анализ и тестировать торговые стратегии на реальных тиках.
MQL4 и MQL5 – на 41-м месте рейтинга языков программирования TIOBE
Язык программирования торговых стратегий MQL4/MQL5 скакнул на 77 позиций в мировом индексе TIOBE.
В декабре 2014 года MQL4/MQL5 дебютировал в нем на 118-м месте, а в ноябре 2016 года добрался уже до 41-й строчки. Отметим, что для организаторов рейтинга оба языка MQL4 и MQL5 объединены из-за одинаковости.
TIOBE считается самым авторитетным рейтингом языков программирования и показывает не только текущую позицию языка, но и ее динамику.
Cтатистика TIOBE ежемесячно отражает, какие языки становятся популярнее, а какие – теряют своих сторонников. Методика подсчета рейтинга подробно описана здесь.
Главный критерий оценки – количество поисковых запросов, содержащих название языка. Чем выше интерес к языкам MQL4/MQL5 в поисковых системах Google, Bing, Yahoo, Википедии и YouTube, тем выше их место в рейтинге.
77 позиций вверх за 2 года – это впечатляющий рывок, говорящий о серьезном росте интереса к самостоятельному написанию роботов для платформ MetaTrader и увеличении количества алготрейдеров.
Благодарим всех пользователей, проявивших интерес к алготрейдингу и языкам MQL4/MQL5!
У MetaTrader 5 победа в номинации "Лучшая мультирыночная платформа"!
Торговые платформы MetaTrader завоевали награды в двух номинациях на конкурсе Finance Magnates Awards 2016.
Победителем в категории «Лучшая мультирыночная платформа» стала MetaTrader 5, а лучшей форекс-платформой была признана MetaTrader 4.
Награждение победителей состоялось 15 ноября на вечерней церемонии закрытия Finance Magnates Awards.
В этом году мероприятие собрало более 2 000 профессионалов финансовой индустрии и 90 компаний-участников – это рекордное количество посетителей в истории конкурса.
В результате независимого голосования MetaTrader 4 и MetaTrader 5 обошли своих конкурентов и набрали большинство голосов. Поэтому полученные награды по праву можно считать объективной оценкой ситуации на рынке.
Напомним, что это не первый успех наших продуктов на Finance Magnates Awards: в прошлом годуплатформы MetaTrader победили в ключевых номинациях «Лучшая платформа» и «Лучший мобильный продукт».
Таким образом, из года в год крупнейшие игроки финансовой отрасли выбирают MetaTrader.