Как построить и протестировать стратегию бинарных опционов в Тестере Стратегий MetaTrader 4
Martin Amiri | 30 декабря, 2016
Оглавление
1. Введение
2. Установка
3. Образец стратегии бинарных опционов
3.1. Определение стратегии бинарных опционов
3.2. Создание стратегии бинарных опционов
3.2.1. Входные параметры
3.2.2. Включение библиотеки Binary-Options-Strategy-Library
3.2.3. Добавление CallStrategy()
3.2.4. Имплементация CheckMyRules() и вспомогательной функции
3.2.5. Отладочная печать
3.2.6. Использование внешних индикаторов (ex4-файлов)
3.3. Окончательный код
4. Запуск бэк-тестов (видео)
5. Запуск форвард-теста
6. FAQ
7. Разное
1. Введение
В Тестере Стратегий MetaTrader 4 можно тестировать советники и индикаторы на исторических данных, но он не может обрабатывать бинарные опционы с временем истечения. Поэтому, когда мне потребовалось протестировать стратегию бинарных опционов в MetaTrader 4, я создал для этих целей утилиту Binary-Options-Strategy-Tester.
Чтобы последовать этому примеру и протестировать стратегию бинарных опционов, вам понадобится эта утилита, которая сейчас доступна для аренды в Маркете. Чтобы пользователь мог оценить, насколько она соответствует его требованиям, и понять ее концепцию, вполне достаточно демо-версии.
Идея состоит из следующих частей:
Это пошаговый пример того, как можно выстроить стратегию работы с бинарными опционами: индикатор (отмечен красным цветом на рисунке выше) через библиотеку Binary-Options-Strategy-Library связывается с Binary-Options-Strategy-Tester, далее стратегия размещает виртуальные ордера и обсчитывает результаты их работы с помощью бэк- и форвард-тестов.
Качество бэк-тестов будет зависеть от исторических данных. Поэтому настоятельно рекомендуется использовать набор данных высокого качества!
2. Установка
Загрузите Binary-Options-Strategy-Tester из Маркета. Доступна и пробная конфигурация для тестирования стратегий бинарных опционов в Тестере Стратегий Metatrader 4. Стратегия будет вызывать функцию Binary-Options-Strategy-Tester (через библиотеку Binary-Options-Strategy-Library) для размещения виртуальных сделок. В связи с концепцией лицензионного соглашения MQL4, это будет работать только если продукт имеет рабочую лицензию. Поэтому вы должны будете либо приобрести платную версию продукта, либо демо-версию.
Загрузите Binary-Options-Strategy-Library и разместите ее в вашу папку \Include ([ваш путь к MetaTrader 4] \ MQL4 \ Include). Бесплатная библиотека предоставляет несколько функций для построения стратегии бинарных опционов и для простой связи ее с продуктом Binary-Options-Strategy-Tester.
Загрузите бесплатный индикатор KVO и поместите его в папку Индикаторы \ Downloads ([ваш путь к MetaTrader 4] \ MQL4 \ Индикаторы \ Downloads. Этот индикатор используется в качестве примера доступа стратегии к внешним индикаторам и их ex4-файлам. Более подробная информация по этому индикатору находится здесь.
Теперь вы можете перейти в раздел 3 и построить пример кода самостоятельно или же загрузить пример, представленный ниже: поместите его (и его скомпилированный файл ex4) в папку \Indicators ([путь к вашему MetaTrader 4]\MQL4\Indicators).
3. Пример построения стратегии бинарных опционов
Теперь шаг за шагом будет описано, как построить пример стратегии бинарных опционов в составе индикатора, чтобы он мог взаимодействовать с утилитой Binary-Options-Strategy-Tester.
3.1 Определение стратегии
В первую очередь, мы должны определить стратегию и изменяемые значения (входные параметры). Документация MQL4 описывает все технические индикаторы, к которым можно обращаться через интерфейс iCustom: https://docs.mql4.com/indicators
Допустим, мы хотим создать простую стратегию на основе пересечения одной "быстрой" и одной "медленной" скользящей средней, которая будет торговать на следующей после пересечения свече. Документация описывает, как мы можем получить значения простой МА: https://docs.mql4.com/indicators/ima.
Мы хотим иметь возможность выбирать значения для периода усреднения МА (быстрой и медленной), цену, по которой рассчитывается МА, а также метод усреднения. Другие значения (такие, как символ, таймфрейм и сдвиг) зависят от тестируемой ситуации (к примеру, от символа, на котором запущен Тестер) и должны устанавливаться автоматически. Поэтому нам в сущности потребуются следующие переменные для МА:
int ma_method
int applied_price
Поскольку нам необходимы две МА (чтобы отмечать их пересечения), понадобятся следующие входные параметры со значениями по умолчанию:
int period_slow = 10;
int method_both = 0;
int applied_price_both = 0;
3.2 Создание стратегии бинарных опционов
Построим индикатор, в котором будет заключена стратегия бинарных опционов и который можно будет перетаскивать на график, где будет запускаться также и утилита Binary-Options-Strategy-Tester.
Откройте редактор MQL (в Metatrader 4 кликните на "Сервис" -> "Редактор MetaQuotes Language" или просто нажмите F4) и кликните на "Создать":
Появится Мастер MQL. Выберите "Пользовательский Индикатор", чтобы создать пустой индикатор, и кликните на "Далее":
Введите название, копирайт и ссылку на стратегию, а также входные параметры с их типами и значениями по умолчанию (начальными значениями), нажав кнопку "Добавить" и затем "Далее":
Во вкладке обработчиков событий установите флажок "OnCalculate", поскольку нам нужно это событие для проверки стратегии на каждом тике. Нажмите "Далее":
Во вкладке свойств отрисовки выберите флажок "Индикатор в отдельном окне", поскольку нам нужно будет отдельное окно для отладочной печати. Нажмите "Закончить":
Появится заготовка кода вашего индикатора:
//| BinaryOptionsStrategyExample.mq4 |
//| Copyright 2016, __martin__ |
//| https://www.mql5.com/ru/users/__martin__ |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, __martin__"
#property link "https://www.mql5.com/ru/users/__martin__"
#property version "1.00"
#property strict
#property indicator_separate_window
//--- input parameters
input int period_fast=5;
input int period_slow=10;
input int method_both=0;
input int applied_price_both=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- Отображение индикаторных буферов
//---
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[])
{
//---
//--- Возвращает значение prev_calculated для следующего вызова
return(rates_total);
}
//+------------------------------------------------------------------+
3.2.1 Входные параметры
Начальные входные параметры создаются Мастером MQL (см. 3.2, Создании стратегии бинарных опционов), а мы их усовершенствуем с помощью следующих шагов.
Чтобы избежать установки значения int для применяемой цены и метода усреднения для МА во входных параметрах, тип параметров method_both и applied_price_both изменяем с int на перечисление со значениями по умолчанию.
ENUM_MA_METHOD: https://docs.mql4.com/constants/indicatorconstants/enum_ma_method
ENUM_APPLIED_PRICE: https://docs.mql4.com/constants/indicatorconstants/prices#enum_applied_price_enum
Кроме того, добавлены комментарии для входных параметров, чтобы показать комментарии как метки вместо имен переменных:
//--- Входные параметры
input int period_fast = 5; // Значения быстрой MA
input int period_slow = 10; // Значения медленной MA
input ENUM_MA_METHOD method_both = MODE_SMA; // Метод для расчета МА
input ENUM_APPLIED_PRICE applied_price_both = PRICE_CLOSE; // Цена для расчета МА
...
Эта модификация делает для входных параметров доступным выпадающее меню с позициями для выбора, а также включение меток :
3.2.2 Включение библиотеки Binary-Options-Strategy-Library
Если вы скачали библиотеку (см 2. Установка) и установили ее в папку \Include ([путь к Metatrader 4]\MQL4\Include), можете подключить ее следующим образом:
//| BinaryOptionsStrategyExample.mq4 |
//| Copyright 2016, __martin__ |
//| https://www.mql5.com/ru/users/__martin__ |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, __martin__"
#property link "https://www.mql5.com/ru/users/__martin__"
#property version "1.00"
#property strict
#property indicator_separate_window
#include <BinaryOptionsStrategyLibrary.mqh>
//--- Входные параметры
...
Изменять содержимое библиотеки не требуется!
С помощью библиотеки мы дополним входные параметры еще двумя новыми:
- На одну свечу размещается только одна сделка SELL или BUY
- Проверка в рамках стратегии осуществляется только в начале новой свечи
3.2.3 Добавление CallStrategy()
Добавим вызов функции CallStrategy() в OnCalculate() вашего индикатора, чтобы обращаться к стратегии на каждом новом тике. CallStrategy() предоставляется библиотекой Binary-Options-Strategy-Library, которую вы уже подключили, как описано выше:
//+------------------------------------------------------------------+
//| 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[])
{
//---
CallStrategy(); // Вызов стратегии, функция находится в BinaryOptionsStrategyLibrary.mqh (подключенной выше)
//--- Возвращает значение prev_calculated для следующего вызова
return(rates_total);
}
//+------------------------------------------------------------------+
Поэтому в стратегии необходимо реализовать функцию CheckMyRules().
3.2.4 Имплементация СheckMyRules() и вспомогательной функции
В функции CheckMyRules(), которая вызывается с помощью библиотеки Binary-Options-Strategy-Library, реализованы условия стратегии и происходит размещение сделок посредством функции PlaceTrade() из этой же библиотеки. Значения обеих МА берутся из вспомогательной функции GetValuesForMA() и временно хранятся в переменных для того, чтобы сравнивать их с помощью условия if.
...
//--- Входные параметры
input int period_fast = 5; // Значения для быстрой MA
input int period_slow = 10; // Значения для медленной MA
input ENUM_MA_METHOD method_both = MODE_SMA; // Метод для расчета MA
input ENUM_APPLIED_PRICE applied_price_both = PRICE_CLOSE; // Цена для расчета MA
...
//+------------------------------------------------------------------+
//| Разместите здесь ваши торговые условия — см. пример ниже. |
//| Тестер Стратегий вызывает эту функцию, чтобы разместить сделки. |
//| НЕ СЛЕДУЕТ: |
//| - Переименовывать функцию |
//| - Добавлять параметры функции, например, CheckMyRules(int a) |
//| - Изменять тип возвращаемого значения функции |
//+------------------------------------------------------------------+
void CheckMyRules()
{
// Сохранить значения MA с shift=0 (текущая свеча) -> текущая свеча,
// Вызов вспомогательной функции GetValueForMA() для получения значений — см. вспомогательные функции ниже
double emaSlow_Current = GetValueForMA(period_slow, 0);
double emaFast_Current = GetValueForMA(period_fast, 0);
// Сохранить значения MA с shift=1 (прошедшая свеча) -> последняя свеча,
// Вызов вспомогательной функции GetValueForMA() для получения значений — см. вспомогательные функции ниже
double emaSlow_Past = GetValueForMA(period_slow, 1);
double emaFast_Past = GetValueForMA(period_fast, 1);
if(emaFast_Past > emaSlow_Past
&& emaFast_Current < emaSlow_Past) // Проверить, пересекаются ли медленная МА и быстрая МА
{
PlaceTrade(OP_SELL); // Разместить сделку SELL для Тестера Стратегий, функция находится в BinaryOptionsStrategyFunctions.mqh
}
if(emaFast_Past < emaSlow_Past
&& emaFast_Current > emaSlow_Past) // Проверить, пересекаются ли медленная МА и быстрая МА
{
PlaceTrade(OP_SELL); // Разместить сделку BUY для Тестера Стратегий, функция находится в BinaryOptionsStrategyFunctions.mqh
}
}
//+------------------------------------------------------------------+
//| Разместите вашу вспомогательную функцию здесь, см. пример ниже |
//+------------------------------------------------------------------+
//----
//+---------------------------------------------------------------------+
//| Получить значения периода, метод, цену для расчета и сдвиг для МА |
//| Для подробностей по iMA() см. https://docs.mql4.com/indicators/ima |
//+---------------------------------------------------------------------+
double GetValueForMA(int _period,int _shift)
{
return iMA(NULL,0,_period,0,method_both,applied_price_both,_shift);
}
3.2.5 Отладочная печать
Функция PrintDebugValue() обеспечивает отладочную печать во время работы тестера. В примере ниже значения МА выводятся с их именами переменных в виде меток:
...
//--- входные параметры
input int period_fast = 5; // Значения для быстрой MA
input int period_slow = 10; // Значения для медленной MA
input ENUM_MA_METHOD method_both = MODE_SMA; // Метод для расчета MA
input ENUM_APPLIED_PRICE applied_price_both = PRICE_CLOSE; // Цена для расчета MA
...
//+-----------------------------------------------------------------------------+
//| Разместить здесь ваши торговые условия — смотрите пример ниже. |
//| Тестер Стратегий вызывает эту функцию, чтобы разместить сделки. |
//| НЕ СЛЕДУЕТ: |
//| - Переименовать функцию |
//| - Добавить параметры функции, например, CheckMyRules(int a) |
//| - Изменить тип возвращаемого значения функции, например, int CheckMyRules() |
//+-----------------------------------------------------------------------------+
void CheckMyRules()
{
// Сохранить значения MA с помощью shift=0 (текущая свеча) -> текущая свеча,
//вызов вспомогательной функции GetValueForMA() для получения значений — см. вспомогательные функции ниже <br50/> double emaSlow_Current = GetValueForMA(period_slow, 0);
double emaFast_Current = GetValueForMA(period_fast, 0);
//Сохранить значения MA с помощью shift=1 (прошедшая свеча) -> последняя свеча,<br61/> <s62>//вызов вспомогательной функции GetValueForMA() для получения значений — см. вспомогательные функции ниже </s62><br63/> double emaSlow_Past = GetValueForMA(period_slow, 1);
double emaFast_Past = GetValueForMA(period_fast, 1);
PrintDebugValue("emaSlow_Current: ",(string)emaSlow_Current,0); // Метка и значение на линии 0
PrintDebugValue("emaFast_Current: ",(string)emaFast_Current,1); // Метка и значение на линии 1
PrintDebugValue("emaSlow_Past: ",(string)emaSlow_Past,2); // Метка и значение на линии 2
PrintDebugValue("emaFast_Past: ",(string)emaFast_Past,3); // Метка и значение на линии 3
if(emaFast_Past > emaSlow_Past
&& emaFast_Current < emaSlow_Past) // проверить, пересекаются ли медленная МА и быстрая МА
{
PlaceTrade(OP_SELL); // Разместить сделку SELL для Тестера Стратегий, функция находится в BinaryOptionsStrategyFunctions.mqh
}
if(emaFast_Past < emaSlow_Past
&& emaFast_Current < emaSlow_Past) // Проверить, пересекаются ли медленная МА и быстрая МА
{
PlaceTrade(OP_SELL); // Разместить сделку BUY для Тестера Стратегий, функция находится в BinaryOptionsStrategyFunctions.mqh
}
}
//+------------------------------------------------------------------+
//| Разместите вашу вспомогательную функцию здесь, см. пример ниже |
//+------------------------------------------------------------------+
//----
//+--------------------------------------------------------------------+
//| Получить значения МА для периода, метод, цену для расчета и сдвиг. |
//| For details of iMA() see https://docs.mql4.com/indicators/ima |
//+--------------------------------------------------------------------+
double GetValueForMA(int _period,int _shift)
{
return iMA(NULL,0,_period,0,method_both,applied_price_both,_shift);
}
3.2.6 Использование внешних индикаторов (ex4-файлов)
Для стратегии бинарных опционов могут быть доступны дополнительно и внешние индикаторы, которые сохраняют свои значения в буферах, даже если в вашем распоряжении есть только скомпилированные ex4-файлы.
Скажем, мы хотели бы подключить сигнальную линию индикатора KVO https://www.mql5.com/ru/code/8677 и размещать сделки BUY, если она выше 0, и SELL — если она ниже 0. Загрузим индикатор и поместим компилированный файл (ex4) в папку \Indicators\Downloads ([путь к MetaTrader 4]\MQL4\Indicators\Downloads).
Сначала мы должны определить соответствующие буферы для доступа, в которых будут храниться значения. Чтобы показать все доступные буферы используемых индикаторов, нажмем кнопку "Окно данных" терминала и перетащим индикатор KVO на график. При наведении перекрестия на график (нажмите колесо мышки, чтобы оно появилось), значения буфера индикатора на выделенном периоде будут показаны в окне данных.
Метки окна данных сообщат нам значение буфера индикатора с индексом. В этом буфере хранятся данные по сигнальной линии Если буферы индикаторов не снабжены метками, мы можем найти нужный путем сравнения значений буфера с отображаемым значением под наведенным перекрестием на графике индикатора. Индексы буферов индикатора начинаются с 0. Таким образом, значение буфера 1 соответствует значению буфера с индексом 0, и так далее. Мы должны иметь доступ к буферу 1, чтобы получить значение сигнала.
Затем мы должны узнать все входные параметры внешнего индикатора, к которому мы бы хотели получить доступ. При перетаскивании индикатора на график мы сможем открыть поле "Входные параметры":
Допустим, мы бы хотели получить доступ к индикатору с начальными значениями 34, 55 и 13. Используем вспомогательную функцию (на основе iCustom), которая позволит нам получать значения индикатора с параметрами для буфера и сдвига, в то время как сдвиг 0 будет значением текущей свечи, сдвиг 1 — значением предыдущей свечи, сдвиг 2 — значением позапрошлой свечи, и т.д. В дополнение мы временно сохраним значения индикаторных буферов и доработаем if-условия стратегии:
...
//--- Входные параметры
input int period_fast = 5; // Значения быстрой МА
input int period_slow = 10; // Значения медленной МА
input ENUM_MA_METHOD method_both = MODE_SMA; // Метод расчета MA
input ENUM_APPLIED_PRICE applied_price_both = PRICE_CLOSE; // Цена для расчета MA
...
//+-------------------------------------------------------------------------------+
//| Разместите свои торговые правила здесь - см. пример ниже |
//| Тестер стратегий вызовет эту функцию для размещения сделок |
//| НЕ СЛЕДУЕТ: |
//| - Переименовывать функцию |
//| - Добавлять параметры функции (например, CheckMyRules(int a) |
//| - Изменять тип возвращаемого значения функции (например, int CheckMyRules()) |
//+-------------------------------------------------------------------------------+
void CheckMyRules()
{
// Сохранение значений МА с помощью shift=0 (текущая свеча) -> current candle,
// Вызов вспомогательной функции GetValueForMA() для получения значения - см. описание вспомогательной функции ниже
double emaSlow_Current = GetValueForMA(period_slow, 0);
double emaFast_Current = GetValueForMA(period_fast, 0);
// Сохранение значений МА с помощью shift=1 (прошлая свеча) -> last candle,
// // Вызов вспомогательной функции GetValueForMA() для получения значения - см. описание вспомогательной функции ниже
double emaSlow_Past = GetValueForMA(period_slow, 1);
double emaFast_Past = GetValueForMA(period_fast, 1);
// Сохранение сигнального значения (буфер 1) индикатора KVO с текущей свечи (shift 0)
double kvoSignal = GetValuesFromIndicator__KVO__(1,0);
PrintDebugValue("emaSlow_Current: ",(string)emaSlow_Current,0); // Метка и значение на линии 0
PrintDebugValue("emaFast_Current: ",(string)emaFast_Current,1); // Метка и значение на линии 1
PrintDebugValue("emaSlow_Past: ",(string)emaSlow_Past,2); // Метка и значение на линии 2
PrintDebugValue("emaFast_Past: ",(string)emaFast_Past,3); // Метка и значение на линии 3
if(emaFast_Past > emaSlow_Past
&& emaFast_Current < emaSlow_Past // Проверка, пересекаются ли медленная МА и быстрая МА
&& kvoSignal < 0) // Проверка, находится ли сигнальное значение KVO ниже нулевой линии
{
PlaceTrade(OP_SELL); // Разместите сделку SELL для Тестера Стратегий, функция расположена в BinaryOptionsStrategyFunctions.mqh}
if(emaFast_Past < emaSlow_Past
&& emaFast_Current > emaSlow_Past // Проверка, пересекаются ли медленная МА и быстрая МА
&& kvoSignal > 0) // Проверка, находится ли сигнальное значение KVO выше нулевой линии
{
PlaceTrade(OP_BUY); // Разместите сделку BUY для Тестера Стратегий, функция расположена в BinaryOptionsStrategyFunctions.mqh
}
}
//+------------------------------------------------------------------+
//| Разместите здесь вашу вспомогательную функцию (см. пример ниже) |
//+------------------------------------------------------------------+
//----
//+------------------------------------------------------------------------+
//| Получить значений МА для периода, метод, цену для расчета и сдвиг |
//| Для более подробно об iMA() см. https://docs.mql4.com/indicators/ima |
//+------------------------------------------------------------------------+
double GetValueForMA(int _period,int _shift)
{
return iMA(NULL,0,_period,0,method_both,applied_price_both,_shift);
}
//+------------------------------------------------------------------+
//| Пример получения значений от внешнего индикатора |
//| см. https://docs.mql4.com/indicators/icustom |
//| Параметры : |
//| int _buffer - индикаторный буфер (от 0) |
//| int _shift - значение сдвига; 0 = текущая свеча, 1 = предыдущая |
//+------------------------------------------------------------------+
double GetValuesFromIndicator__KVO__(int _buffer, int _shift=0) // Изменить "__KVO__" на имя индикатора
{
return (
iCustom (
NULL, // NULL для текущего таймфрейма, выбранного в тестере - НЕ ТРЕБУЕТСЯ ИЗМЕНЕНИЙ
0, // 0 для текущего символа в тестере - НЕ ТРЕБУЕТСЯ ИЗМЕНЕНИЙ
//BEGIN EDIT
"\\Downloads\\KVO.ex4", // Путь к файлам и имена файлов индикатора(*.ex4)
//BEGIN INDICATORS INPUTS
34,
55,
13,
//END FOR INPUTS
//END EDIT
_buffer, // Индекс буфера (начинаются с 0), _buffer передается через параметры функции - НЕ ТРЕБУЕТСЯ ИЗМЕНЕНИЙ
_shift // Сдвиг(0 для текущей свечи), _shift передается через параметры функции - НЕ ТРЕБУЕТСЯ ИЗМЕНЕНИЙ
)
);
}
Есть и другой путь доработки входных параметров в нашем индикаторе стратегии. К примеру, можно использовать значения используемого нами индикатора KVO и установить их в качестве переменных вспомогательной функции. Однако поскольку в этой статье показывается всего лишь пример, да еще и наиболее простой из возможных, то этот вариант я подробно рассматривать не буду.
3.3 Полный код
Ниже вы найдете полный код образца стратегии бинарных опционов, со всеми вышеописанными шагами, уже готовый к перетаскиванию в Тестер Стратегий бинарных опционов для полноценного тестирования и вывода результатов на график:
//| BinaryOptionsStrategyExample.mq4 |
//| Copyright 2016, __martin__ |
//| https://www.mql5.com/en/users/__martin__ |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, __martin__"
#property link "https://www.mql5.com/en/users/__martin__"
#property version "1.00"
#property strict
#property indicator_separate_window
#include <BinaryOptionsStrategyLibrary.mqh>
//+------------------------------------------------------------------+
//| Разместите здесь ваши входные параметры - см. пример ниже |
//+------------------------------------------------------------------+
//--- Входные параметры
input int period_fast = 5; // Период быстрой МА
input int period_slow = 10; // Период медленной МА
input ENUM_MA_METHOD method_both = MODE_SMA; // Метод для расчета МА
input ENUM_APPLIED_PRICE applied_price_both = PRICE_CLOSE; // Цена для расчета MA
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- Расположение индикаторных буферов
//---
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[])
{
//---
CallStrategy(); // Вызов стратегии, функция расположена в библиотеке BinaryOptionsStrategyLibrary.mqh (она подключена выше)
//--- возвращение значения prev_calculated для следующего вызова
return(rates_total);
}
//+-------------------------------------------------------------------------------+
//| Разместите свои торговые правила здесь - см. пример ниже |
//| Тестер стратегий вызовет эту функцию для размещения сделок |
//| НЕ СЛЕДУЕТ: |
//| - Переименовывать функцию |
//| - Добавлять параметры функции (например, CheckMyRules(int a) |
//| - Изменять тип возвращаемого значения функции (например, int CheckMyRules()) |
//+-------------------------------------------------------------------------------+
void CheckMyRules()
{
// Сохранение значений МА с помощью shift=0 (текущая свеча) -> current candle,
// Вызов вспомогательной функции GetValueForMA() для получения значения - см. вспомогательные функции ниже
double emaSlow_Current = GetValueForMA(period_slow, 0);
double emaFast_Current = GetValueForMA(period_fast, 0);
// Сохранение значений MA с помощью shift=1 (прошедшая свеча) -> last candle,
// Вызов вспомогательной функции GetValueForMA() для получения значения - см. вспомогательные функции ниже
double emaSlow_Past = GetValueForMA(period_slow, 1);
double emaFast_Past = GetValueForMA(period_fast, 1);
// Сохранение сигнального значения (буфер 1) индикатора KVO с текущей свечи (shift 0)
double kvoSignal = GetValuesFromIndicator__KVO__(1,0);
PrintDebugValue("emaSlow_Current: ",(string)emaSlow_Current,0); // Метка и значение на линии 0
PrintDebugValue("emaFast_Current: ",(string)emaFast_Current,1); // Метка и значение на линии 1
PrintDebugValue("emaSlow_Past: ",(string)emaSlow_Past,2); // Метка и значение на линии 2
PrintDebugValue("emaFast_Past: ",(string)emaFast_Past,3); // Метка и значение на линии 3
if(emaFast_Past > emaSlow_Past
&& emaFast_Current < emaSlow_Past // Проверка, пересекаются ли медленная и быстрая МА
&& kvoSignal < 0) // Проверка, находится ли сигнальное значение KVO ниже нулевой линии
{
PlaceTrade(OP_SELL); // Разместить сделку SELL для Тестера Стратегий, функция расположена в BinaryOptionsStrategyLibrary.mqh
}
if(emaFast_Past < emaSlow_Past
&& emaFast_Current > emaSlow_Past // Проверка, пересекаются ли медленная и быстрая МА
&& kvoSignal > 0) // Проверка, находится ли сигнальное значение KVO выше нулевой линии
{
PlaceTrade(OP_BUY); // Разместить сделку BUY для Тестера Стратегий, функция расположена в BinaryOptionsStrategyLibrary.mqh
}
}
//+------------------------------------------------------------------+
//| Разместите здесь вспомогательную функцию, см. пример ниже |
//+------------------------------------------------------------------+
//----
//+--------------------------------------------------------------------+
//| Получить значения МА для периода, метод, примененную цену и сдвиг |
//| Подробнее об iMA() см. https://docs.mql4.com/indicators/ima |
//+--------------------------------------------------------------------+
double GetValueForMA(int _period,int _shift)
{
return iMA(NULL,0,_period,0,method_both,applied_price_both,_shift);
}
//+--------------------------------------------------------------------------+
//| Пример получения значений от внешних индикаторов, |
//| см. https://docs.mql4.com/indicators/icustom |
//| Параметры: |
//| int _buffer - индикаторный буфер (начинается с 0) |
//| int _shift - значения сдвига; 0 = текущая свеча, 1 = предыдущая свеча |
//+--------------------------------------------------------------------------+
double GetValuesFromIndicator__KVO__(int _buffer, int _shift=0) // Изменить "__KVO__" на имя индикатора
{
return (
iCustom (
NULL, // NULL для текущего таймфрейма, выбранного в Тестере - ИЗМЕНЕНИЙ НЕ ТРЕБУЕТСЯ
0, // 0 для текущего символа, выбранного в Тестере - ИЗМЕНЕНИЙ НЕ ТРЕБУЕТСЯ
//BEGIN EDIT
"\\Downloads\\KVO.ex4", // Имя индикатора (*.ex4 file) и путь к нему
//BEGIN INDCATORS INPUTS
34,
55,
13,
//END FOR INPUTS
//END EDIT
_buffer, // Буферный индекс (начинается с 0), _buffer передается через параметры функции - ИЗМЕНЕНИЙ НЕ ТРЕБУЕТСЯ
_shift // Сдвиг (0 для текущей свечи), _shift передается через параметры функции - ИЗМЕНЕНИЙ НЕ ТРЕБУЕТСЯ
)
);
}
//+-----------------------------------------------------------------+
4. Запуск бэк-теста (видео)
Нижеследующее видео показывает, как запустить бэк-тест в вашей стратегии бинарных опционов в Тестере Стратегий MetaTrader 4:
- Запустите Binary-Options-Strategy-Tester в Тестере Стратегий MetaTrader 4 и установите входные параметры
- Перетащите ваш индикатор стратегии на график, выставьте входные параметры и проверьте, выставлено ли "Разрешить импорт из внешних экспертов во вкладке "Общие"".
- Перетащите ваш используемый индикатор с его входными параметрами на график, чтобы увидеть, как меняются его значения, пока запущен тестер (это опциональный пункт программы).
- Сохраните все настройки в шаблоне, чтобы запустить тест со всеми этими настройками опять - используйте кнопку паузы в Тестере Стратегий (это тоже необязательно).
- Теперь вы можете посмотреть результаты работы вашей стратегии бинарных опционов на графике Тестера Стратегий.
5. Запустите форвард-тест
Чтобы запустить форвард-тестирование, просто перетащите утилиту Binary-Options-Strategy-Tester и ваш индикатор стратегии на ваш демо-график или на график реального счета вашего брокера, вместо того, чтобы использовать Тестер Стратегий.
- Перетащите утилиту Binary-Options-Strategy-Tester на демо-графмк или на живой счет и установите входные параметры.
- Перетащите ваш индикатор стратегии на график, выставьте входные параметры и проверьте, выставлено ли разрешение использовать параметры внешних экспертов в таблице условий.
- Перетащите используемый вами индикатор с его параметрами на график, чтобы посмотреть, как изменяются его условия, пока идет форвард-тест.
- Сохраните все настройки в шаблоне, чтобы потом запустить тест снова.
- Теперь вы можете посмотреть результат работы вашей стратегии бинарных опционов на графике демонстрационного или реального счета.
6. Часто задаваемые вопросы
Вопрос: Почему вы показываете пример неприбыльной стратегии бинарных опционов?
Ответ: Это всего лишь пример того, как выстроить стратегию, связав ее индикатор с утилитой Binary-Options-Strategy-Tester, чтобы протестировать ее на рыночных условиях и доработать.
Вопрос: Утилита Binary-Options-Strategy-Tester прекращает работу с сообщением об ошибке "Array out of range" после того, как достигается определенное количество потерь. Почему?
Ответ: После некоего количества потерь — скажем, x, в работе Binary-Options-Strategy-Tester может выдать ошибку, чтобы остановить Тестер и проанализировать ситуацию на графике. Если вам этого не нужно — просто отключите эту опцию в настройках.
Вопрос: Некоторые стрелки-указатели, казалось бы, не обрабатываются утилитой Binary-Options-Strategy-Tester. Почему?
Ответ: Чтобы оставить некоторые различия между демо-версией и версией для продажи. В демонстрационном варианте не все ордера обрабатываются тестером. Необрабатываемые ордера обозначаются зелеными стрелками.
Вопрос: На графике не появляется стрелка после того, как я перетащил мой индикатор с работающей стратегией. Что случилось?
Ответ: Вы должны включить галочку "Разрешить импорт из внешних экспертов" перед перетаскиванием вашего индикатора стратегии на график (сообщение в логе будет показывать вам в этом случае ошибку).
Вопрос: Я не вижу результатов во вкладках Тестера Стратегий "Результаты", "График", "Отчет". Где я могу увидеть результаты тестирования?
Ответ: Тестер Стратегий MetaЕrader 4 не может обрабатывать бинарные опционы, поэтому эти вкладки не могут быть использованы. Поэтому наша утилита вычисляет все выигрыши и проигрыши и распечатывает результаты прямо на графике.
7. Разное
Эта утилита была разработана, поскольку мне нужна была возможность тестировать стратегии бинарных опционов в автоматическом режиме в MetaTrader 4 для долгосрочных периодов и делать форвард-тесты на брокерских чартах. Я провел много времени над разработкой концепции и над имплементацией утилиты Binary-Options-Strategy-Tester, а также над изучением ее документации. Может быть, есть и более удобный путь, чтобы сделать это, и может быть, некоторые улучшения сделают утилиту более подходящей для вас. Поэтому пожалуйста, не стесняйтесь связаться со мной, если у вас есть идеи по улучшению этой работы.