Scriptong
15-12-2009, 21:55
Просматривая темы статей за последние полгода, с удивлением обнаружил, что до сих пор не была затронута такая обширная тема как торговля на дивергенциях. Восполнить такой досадный пробел было решено немедленно. Ко всему прочему, помогло удачное стечение обстоятельств - во время работы над статьей меня попросили создать советника по очень схожему алгоритму. Отличия от разрабатываемого мной алгоритма было два - другой индикатор, при помощи которого определяется дивергенция, и другая тактика входа (вместо открытия рыночного ордера применяется вход отложенным лимитным ордером).
Для начала, специально для тех, кто еще не сталкивался с самим понятием дивергенции, дадим определение. Дивергенция (от англ. "divergence" - несоответствие, отклонение, расхождение) - разнонаправленное движение цены и показаний индикатора. Полезным можно назвать всего два типа дивергенции:
Показания индикатора уменьшаются, а цена при этом продолжает восходящее движение. В таких случаях стоит готовиться к осуществлению продаж.
Показания индикатора растут, а цена продолжает нисходящее движение. В таких случаях необходимо рассматривать возможность покупок.
Оставшиеся два варианта дивергенции (рост индикатора при падении цены и падение индикатора при росте цены) практического применения не имеют, так как в данном случае мы наблюдаем самый большой недостаток абсолютно всех индикаторов - запаздывание. Запаздывание происходит по той простой причине, что первичной все же является цена, в то время как любой индикатив всего лишь производная от цены.
Предложенный алгоритм рассмотрим на двух примерах - для покупки (см. рис. 1) и продажи (см. рис. 2):
http://www.forextrade.ru/media/Image/MQLabs/45_ag/figure_1.gif
Рис. 1. - Показания индикатора растут, а цена падает.
Вертикальными черными линиями показаны две точки, по которым была определена дивергенция. Эти точки были найдены после того, как показания MACD пересекли нулевую линию снизу вверх. Как только MACD стал положительным, на всем участке от текущего пересечения нулевой линии до предыдущего ищется самое минимальное значение гистограммы. На рис. 1 это первая вертикальная линия. Как известно, для построения прямой требуется две точки. В качестве второй точки берется локальный минимум гистограммы, который является последним перед пересечением нулевой линии. Соединяя найденные точки, получаем восходящую прямую, то есть показания индикатора растут.
Далее проводим вертикальные линии через найденные экстремумы MACD так, чтобы они отобразились на графике цен. Таким образом, мы находим две свечи, которые соответствуют минимальным показаниям MACD. Через минимумы этих свечей проводим наклонную линию, которая оказывается нисходящей. В результате получаем две разнонаправленные прямые, что говорит о наличии дивергенции.
После идентификации дивергенции необходимо определить минимальное значение цены на всем промежутке, где гистограмма MACD находилась ниже нуля. Это ориентировочный уровень стопа для будущей длинной позиции и нулевой уровень для сетки Фибоначчи. Уровень 100% сетки Фибоначчи находится как максимальное значение цены, которое было достигнуто на участке после фиксации минимума гистограммы MACD. Построение линий Фибоначчи дает возможность определить середину сложившегося канала, куда и откладывается ордер Buy Limit. На рис. 1 цена открытия длинной позиции (сработал отложенный ордер) расположена несколько выше 50%, что объясняется учетом спрэда - BUY открывается по цене Ask, в то время как цены в терминале отображаются по Bid.
Не стоит уровень стоп-приказа для длинной позиции располагать непосредственно на найденном минимуме цены. Необходимо делать хоть какой-то запас для случаев ложного пробития. На рис. 1. это запас минимальный - 1 пункт.
Цель сделки очень удобно указывать в числах Фибоначчи, тем более, сетка у нас уже посчитана и отображена. Наиболее интересными оказались уровни 161.8, 361.8 461.8 и 561.8. Хотя во входных параметрах советника, который будет описан чуть ниже, по умолчанию установлен уровень 300%. В результате получаем солидное превосходство уровня профита над стопом.
Подобным образом определяется дивергенция для коротких сделок (см. рис. 2):
http://www.forextrade.ru/media/Image/MQLabs/45_ag/figure_2.gif
Рис. 2. - Показания индикатора уменьшаются, а цена растет.
Когда гистограмма MACD пересекает нулевую линию сверху вниз, находим максимальное положительное значение индикатора на отрезке между соседними пересечениями нулевой линии. Максимум отмечен вертикальной линией, находящейся левее. Справа от найденного максимума фиксируется локальный максимум, который является ближайшим к пересечению нуля. Через эти два максимума проводится нисходящая линия.
На графике цен отмечаются свечи, которые соответствуют двум найденным экстремумам индикатора. Через максимумы этих свечей проводится восходящая линия. Таким образом, получаем расхождение линий - дивергенцию.
Далее нужно найти максимальное значение цены за то время, пока гистограмма MACD находилась выше нуля. Это будет нулевой уровень линий Фибоначчи. Для нахождения уровня 100% потребуется найти минимальное значение цены, начиная от свечи, которая соответствует максимуму индикатора MACD. После формирования сетки Фибоначчи, на уровень 50% откладывается ордер Sell Limit. Уровень стопа ставится чуть выше нулевого уровня Фибо с учетом спрэда, а уровень профита на один из уровней Фибоначчи. По умолчанию это 300%, но наиболее вероятными, как было указано выше, оказались уровни 161.8, 361.8, 461.8 и 561.8.
Перейдем к написанию торгового робота DivergenceOnMACDFibo_Expert, который основывается на описанной стратегии. Первым делом займемся сигнальной частью, которая сегодня на порядок сложнее обычного:
//+-------------------------------------------------------------------------------------+
//| Расчет значений MACD с формированием сигналов для открытия позиций |
//+-------------------------------------------------------------------------------------+
void GetSignal()
{
Signal = 0;
// - 1 - == Получение значений индикатора ===============================================
double MACD1 = iMACD(Symbol(), 0, FastM, SlowM, SignalM, MACDPrice, MODE_MAIN, 1);
double MACD2 = iMACD(Symbol(), 0, FastM, SlowM, SignalM, MACDPrice, MODE_MAIN, 2);
// - 1 - == Окончание блока =============================================================
// - 2 - == Генерация сигнала SELL ======================================================
if (MACD1 < 0 && MACD2 > 0) // Пересечение нулевой линии MACD
if (ExtremumsFind(1)) // найти положительные значения
if (VMax > VFirst && NMax > NFirst) // последняя вершина ниже максимума
if (High[NMax] < High[NFirst]) // Там, где MACD падает, цена еще растет
{
Signal = -1; // сигнал SELL
ShowDivergence(-1); // Рисуем линии дивергенции в отрицательной зоне MACD
ShowFibo(Time[LowBar], CurLow, Time[HighBar], CurHigh); // Рисуем сетку Фибо
return;
}
// - 2 - == Окончание блока =============================================================
// - 3 - == Генерация сигнала BUY =======================================================
if (MACD1 > 0 && MACD2 < 0) // Пересечение нулевой линии MACD
if (ExtremumsFind(-1)) // найти отрицательные значения
if (VMax<VFirst && NMax > NFirst)//последняя впадина выше минимального значения MACD
if (Low[NMax] > Low[NFirst]) // Там, где MACD растет, цена падает
{
Signal = 1; // сигнал Buy
ShowDivergence(1); // Рисуем линии дивергенции в положительной зоне MACD
ShowFibo(Time[HighBar], CurHigh, Time[LowBar], CurLow); // Рисуем сетку Фибо
return;
}
// - 3 - == Окончание блока =============================================================
}
Блок 1 рассчитывает ближайшие значения гистограммы MACD для того, чтобы впоследствии можно было определить момент пересечения нулевой линии. Если пересечения линии не было, то на этом выполнение функции GetSignal заканчивается.
Во втором блоке происходит проверка пересечения нуля сверху вниз. При фиксации пересечения управление передается функции ExtremumsFind с параметром 1, что означает обработку положительной зоны гистограммы MACD. ExtremumsFind возвращает результат True, если удалось найти максимальное значение MACD и следующий за ним локальный максимум. При этом заполняются значения переменных VMax (максимальное значение MACD), NMax (номер бара, где зафиксировано максимальное значение), VFirst (значение локального максимума), NFirst (номер бара, где найден локальный максимум), CurLow (минимальное значение цены после максимума MACD), CurHigh (максимальное значение цены за время нахождения гистограммы выше нуля). После успешного выполнения ExtremumsFind сравниваются значения VMax и VFirst. При этом локальный максимум должен быть ниже максимума MACD, а максимум свечи, соответствующей локальному максимуму, выше максимума свечи, соответствующей VMax. При выполнении всех этих условий переменная Signal принимает значение -1, подавая сигнал к продаже. При помощи функции ShowDivergence отображаются линии дивергенции, а при помощи функции ShowFibo отображаются линии Фибоначчи.
Третий блок аналогичен второму. Только здесь отслеживается пересечение нуля снизу вверх, а затем вызывается функция ExtremumsFind с параметром -1, что указывает на обработку отрицательной зоны MACD. При успешном выполнении ExtremumsFind требуется, чтобы найденный минимум MACD, который содержится в VMax, был ниже локального минимума, содержащегося в VFirst. При этом минимум свечи, соответствующей VMax должен быть выше минимума свечи, соответствующей VFirst. Вновь, если все условия соблюдены, то флаг Signal принимает значение 1, подавая сигнал к покупке, а функции ShowDivergence и ShowFibo отображают линии дивергенции и Фибоначчи.
Код функции ExtremumsFind выглядит грозно:
//+-------------------------------------------------------------------------------------+
//| Поиск последних двух вершин или впадин индикатора |
//+-------------------------------------------------------------------------------------+
bool ExtremumsFind(int Type)
{
// - 1 - ====================== Принятие начальных условий поиска =======================
VFirst = 0; NFirst = 0; // Первая вершина/впадина
VMax = 0; NMax = 0; // максимальное/минимальное значение индикатора
int i = 2;
double IndPred = iMACD(Symbol(), 0, FastM, SlowM, SignalM, MACDPrice, MODE_MAIN, 1);
double IndCur = iMACD(Symbol(), 0, FastM, SlowM, SignalM, MACDPrice, MODE_MAIN, 2);
double IndPrev = iMACD(Symbol(), 0, FastM, SlowM, SignalM, MACDPrice, MODE_MAIN, 3);
// - 1 - ====================== Окончание блока =========================================
// - 2 - ==== Поиск вершины/впадины и максимального (по модулю) значения индикатора =====
while (((IndCur > 0 && Type > 0) || (IndCur < 0 && Type < 0)) && i < Bars)
{
if ((IndPred < IndCur && IndPrev < IndCur && Type > 0) || // определена вершина
(IndPred > IndCur && IndPrev > IndCur && Type < 0)) // или впадина
{
if (VFirst == 0) // найдена первая вершина/впадина
{
VFirst = IndCur; // запоминаем значение
NFirst = i; // и номер бара
VMax = IndCur; // Это же значение пока будет максимальным/минимальным
NMax = i;
}
else
if ((IndCur > VMax && Type > 0) || (IndCur < VMax && Type < 0))//найдена следую-
{ // щая вершина/впадина, не будет ли она максимумом в абсолютном значении?
VMax = IndCur;
NMax = i;
}
}
i++;
// готовим данные для следующего цикла
IndPred = IndCur;
IndCur = IndPrev;
IndPrev = iMACD(Symbol(), 0, FastM, SlowM, SignalM, MACDPrice, MODE_MAIN, i+1);
}
// - 2 - ====================== Окончание блока =========================================
if (i == Bars) return(False); // если достигнут конец истории, то выдаем ошибку
// - 3 - ==== Нахождение максимального/минимального значения после экстремума MACD ======
if (Type > 0)
{
HighBar = iHighest(Symbol(), 0, MODE_HIGH, i);
CurHigh = High[HighBar];
LowBar = iLowest(Symbol(), 0, MODE_LOW, HighBar);
CurLow = Low[LowBar];
}
if (Type < 0)
{
LowBar = iLowest(Symbol(), 0, MODE_LOW, i);
CurLow = Low[LowBar];
HighBar = iHighest(Symbol(), 0, MODE_HIGH, LowBar);
CurHigh = High[HighBar];
}
// - 3 - ====================== Окончание блока =========================================
return(True);
}
В первом блоке рассчитывается значение последних трех значений MACD, из которых IndCur считается потенциальной вершиной или впадиной.
Второй блок в цикле проходит все свечи, пока не находит обратное пересечение нулевой линии. При этом каждый локальный максимум или минимум (максимум, когда IndCur больше значений IndPrev и IndPred, а минимум, когда IndCur меньше IndPrev и IndPred) сравнивается с предыдущим найденным экстремумом. Наибольший в абсолютном значении экстремум, в конце концов, остается в VMax, а первый найденный - в VFirst.
Еще одним условием прерывания цикла второго блока является достижение конца истории. В этом случае функция возвращает результат False.
Задачей третьего блока является нахождение минимального и максимального значения цены в соответствии со стратегией. По окончанию работы блока формируются данные в CurHigh (нулевой уровень сетки Фибо или 100%, в зависимости от направления) и в CurLow (противоположный CurHigh уровень Фибо).
Отображением линий дивергенции занимается функция ShowDivergence:
//+-------------------------------------------------------------------------------------+
//| Отображение линий дивергенции |
//+-------------------------------------------------------------------------------------+
void ShowDivergence(int Type)
{
// - 1 - ========= Подготовка значений в зависимости от типа отоюражения ================
datetime Time1 = Time[NMax];
datetime Time2 = Time[NFirst];
double IndPrice1 = VMax;
double IndPrice2 = VFirst;
if (Type == 1)
{
double Price1 = Low[NMax];
double Price2 = Low[NFirst];
}
else
{
Price1 = High[NMax];
Price2 = High[NFirst];
}
// - 1 - ========= Окончание блока ======================================================
// - 2 - ========= Линия дивергенции на графике =========================================
if (ObjectFind(Name1) < 0)
{
ObjectCreate(Name1, OBJ_TREND, 0, Time1, Price1, Time2, Price2);
ObjectSet(Name1, OBJPROP_COLOR, DiverColor);
ObjectSet(Name1, OBJPROP_RAY, True);
}
else
{
ObjectMove(Name1, 0, Time1, Price1);
ObjectMove(Name1, 1, Time2, Price2);
}
// - 2 - ========= Окончание блока ======================================================
// - 3 - ========= Линия дивергенции на индикаторе ======================================
if (WindowFind(IndicatorName) > 0) // если индикатор существует
if (ObjectFind(Name2) < 0) // если объект еще не создан
{
ObjectCreate(Name2, OBJ_TREND, WindowFind(IndicatorName), Time1, IndPrice1, Time2,
IndPrice2);
ObjectSet(Name2, OBJPROP_COLOR, DiverColor);
ObjectSet(Name2, OBJPROP_RAY, True);
}
else // объект создан - передвигаем
{
ObjectMove(Name2, 0, Time1, IndPrice1);
ObjectMove(Name2, 1, Time2, IndPrice2);
}
// - 3 - ========= Окончание блока ======================================================
}
Первый блок формирует значения Time1, Price1 (первая точка прямой на графике цен), Time2, Price2 (вторая точка на графике цен), IndPrice1 (значение индикатора для первой точки на гистограмме MACD) и IndPrice2 (значение индикатора для второй точки на MACD). Значение времени для обеих прямых будет совпадать.
Второй блок в особых комментариях не нуждается. Он просто рисует на графике наклонную линию, которая впоследствии передвигается.
В третьем блоке производится отображение линии дивергенции в окне индикатора MACD. Для этого сначала необходимо узнать номер окна. Номер окна можно найти, зная короткое название индикатора. Чаще всего это "MACD(12,26,9)" - стандартные настройки MACD. Но если пользователь решит использовать другие параметры MACD, то и здесь можно подстроиться, используя входные параметры эксперта. В них пользователь должен внести соответствующие настройки параметров индикатора (FastM, SlowM и SignalM). При использовании этих настроек в функции init формируется значение строковой переменной IndicatorName, которая содержит короткое имя индикатора. Поэтому попытка отображения линии дивергенции в окне индикатора осуществляется только при нахождении нужного окна MACD. Если индикатор не присоединен или у него установлены несоответствующие значения, то линия не отображается.
Подобным образом работает функция ShowFibo:
//+-------------------------------------------------------------------------------------+
//| Отображение линий Фибоначчи |
//+-------------------------------------------------------------------------------------+
void ShowFibo(datetime Time1, double Price1, datetime Time2, double Price2)
{
// - 1 - ========= Если сетка еще не отображалась, то создаем новый объект ==============
if (ObjectFind(FiboName) < 0)
{
ObjectCreate(FiboName, OBJ_FIBO, 0, Time1, Price1, Time2, Price2);
ObjectSet(FiboName, OBJPROP_FIBOLEVELS, 4); // Всего будет четыре Фибо-уровня
ObjectSet(FiboName, OBJPROP_FIRSTLEVEL, 0); // Первый уровень - ноль
ObjectSet(FiboName, OBJPROP_FIRSTLEVEL+1, FiboPercent/100); // Второй - уровень входа
ObjectSet(FiboName, OBJPROP_FIRSTLEVEL+2, 1.0); // Третий - уровень 100%
ObjectSet(FiboName, OBJPROP_FIRSTLEVEL+3, FiboTarget/100);// Четвертый - уровень цели
// Подписываем уровни
ObjectSetFiboDescription(FiboName, 0, "0.0 (%$)");
ObjectSetFiboDescription(FiboName, 1, DoubleToStr(FiboPercent, 1) + " (%$)");
ObjectSetFiboDescription(FiboName, 2, "100.0 (%$)");
ObjectSetFiboDescription(FiboName, 3, DoubleToStr(FiboTarget, 1) + " (%$)");
ObjectSet(FiboName, OBJPROP_BACK, True); // Сетка на заднем плане
ObjectSet(FiboName, OBJPROP_COLOR, CLR_NONE);// Не показывать техническую линию сетки
ObjectSet(FiboName, OBJPROP_LEVELCOLOR, Gray); // Цвет сетки
ObjectSet(FiboName, OBJPROP_LEVELSTYLE, STYLE_DOT); // Стиль сетки
}
// - 1 - ========= Окончание блока ======================================================
// - 2 - ========= Иначе просто передвигаем имеющуюся сетку =============================
else
{
ObjectMove(FiboName, 0, Time1, Price1);
ObjectMove(FiboName, 1, Time2, Price2);
}
// - 2 - ========= Окончание блока ======================================================
}
Первый блок создает объект "линии Фибоначчи" с четырьмя уровнями, два из которых пользователь может изменить по собственному желанию (FiboPercent - уровень для цены открытия отложенного ордера и FiboTarget - уровень цели позиции). Во втором блоке происходит обычное перемещение объекта при смене данных по дивергенции.
Связывание всех приведенных функций производится в функции start. Ее вид настолько стандартный, что рассматривать его сегодня не будем, а перейдем непосредственно к тестированию стратегии. Разработанный эксперт имеет такие входные параметры:
TakeProfit = True - включение/выключение установки уровня профита. Если отключен, то выход из сделки произойдет по уровню стопа или при получении обратного сигнала StopLoss = True - включение/выключение установки уровня стоп-приказа. Если отключен, то выход из сделки произойдет по уровню профита или при получении обратного сигнала Lots = 0.1 - фиксированный объем сделки FastM = 12 - период быстрой средней MACD SlowM = 26 - период медленной средней MACD SignalM = 9 - период сигнальной средней MACD. Используется только для идентификации советником присоединения MACD. MACDPrice = 0 - цена, по которой рассчитывается MACD. 0 - Close, 1 - Open, 2 - High, 3 - Low, 4 - Median Price, 5 - Typical Price, 6 - Weigthed Close DiverColor = Blue - цвет линий дивергенции DeltaStopLoss = 1 - отступ от экстремума в пунктах для установки уровня стоп-приказа FiboPercent = 50.0 - уровень Фибоначчи в процентах, на котором будет установлен отложенный лимитный ордер FiboTarget = 300.0 - уровень Фибоначчи в процентах, на котором будет установлен профит сделки
Для получения достаточного для анализа количества сделок, тестирование произведем на истории 01.01.2008 - 06.12.2009 и таймфрейме М15. Значения эксперта приняты по умолчанию (см. рис. 3 - 6):
http://www.forextrade.ru/media/Image/MQLabs/45_ag/EURUSD%20Begin.gif
Рис. 3. - Результаты тестирования эксперта DivergenceOnMACDFibo_Expert на валютной паре EURUSD.
http://www.forextrade.ru/media/Image/MQLabs/45_ag/USDCHF%20Begin.gif
Рис. 4. - Результаты тестирования эксперта DivergenceOnMACDFibo_Expert на валютной паре USDCHF.
http://www.forextrade.ru/media/Image/MQLabs/45_ag/GBPUSD%20Begin.gif
Рис. 5 - Результаты тестирования эксперта DivergenceOnMACDFibo_Expert на валютной паре GBPUSD.
http://www.forextrade.ru/media/Image/MQLabs/45_ag/USDJPY%20Begin.gif
Рис. 6. - Результаты тестирования эксперта DivergenceOnMACDFibo_Expert на валютной паре USDJPY.
Даже такие невыразительные результаты можно считать успешными, так как мы еще не подключали грозное оружие - оптимизацию параметров для каждой валютной пары в отдельности. Наиболее неудачные показатели у EURUSD - 177 долларов чистой прибыли против 2535 долларов максимальной просадки. Самые лучшие показатели у USDJPY - чистая прибыль 1333 долларов и максимальная просадка 640 долларов (фактор восстановления больше двух).
Если же произвести оптимизацию советника по каждой валютной паре, то результаты выйдут более оптимистичные. О том, как производится оптимизация, было написано в предыдущих двух статьях. Поэтому сейчас рассмотрим только конечные результаты.
Для валютной пары EURUSD были подобраны такие параметры: FastM = 3, SlowM = 49, FiboTarget = 161.8. Остальные параметры - по умолчанию (рис. 7):
http://www.forextrade.ru/media/Image/MQLabs/45_ag/EURUSD%20End.gif
Рис. 7. - Результаты тестирования эксперта после оптимизации на валютной паре EURUSD.
Кривая баланса выглядит очень стабильной. Правда, число сделок немного недотягивает до достаточного - 162. Чистая прибыль 1605 долларов, а максимальная просадка 562 доллара, что дает фактор восстановления 2.85. Итог - вполне прилично.
Для валютной пары USDCHF параметры взяты следующие: FastM = 4, SlowM = 42, FiboTarget = 461.8 (рис. 8):
http://www.forextrade.ru/media/Image/MQLabs/45_ag/USDCHF%20End.gif
Рис. 8. - Результаты тестирования эксперта после оптимизации на валютной паре USDCHF.
Вид кривой баланса немного хуже, чем у евро, но здесь более высокий фактор стабильности системы, так как максимальная просадка показана меньше (585 долларов) при большем количестве сделок (172). За то чистая прибыль составила 2279 долларов. И в результате фактор восстановления выходит 3.9. Итог - можно брать на вооружение.
Валютная пара GBPUSD остановилась на таких параметрах: FastM = 8, SlowM = 24, FiboTarget = 561.8 (рис. 9):
http://www.forextrade.ru/media/Image/MQLabs/45_ag/GBPUSD%20End.gif
Рис. 9. - Результаты тестирования эксперта после оптимизации на валютной паре GBPUSD.
Вновь имеем довольно стабильный вид кривой баланса. К тому же, количество сделок приличное - 292. Чистая прибыль наибольшая из всех результатов - 3530 долларов при максимальной просадке 991 доллар. Фактор восстановления 3.56. Прибыль достигнута тотальным превосходством потенциальной прибыли над потенциальным убытком. Средняя прибыль - 188 долларов, а средний убыток всего лишь 39 долларов. При этом даже максимальное значение убытка не дотягивает до средней прибыли (111 долларов). Итог - стоит взять на вооружение.
Последняя валютная пара - USDJPY. На ней уже получены удобоваримые результаты. Поэтому с нетерпением ждем их улучшения. Параметры такие: FastM = 7, SlowM = 51, FiboTarget = 161.8 (рис. 10).
http://www.forextrade.ru/media/Image/MQLabs/45_ag/USDJPY%20End.gif
Рис. 10. - Результаты тестирования эксперта после оптимизации на валютной паре USDJPY.
Самый лучший вид кривой баланса - это одно из заметных достижений йены. Вторым достижением является минимальное значение просадки - 329 долларов. А чистая прибыль даже превысила значение при начальном тесте - 2091 доллар. Фактор восстановления получается неприлично большим - 6.36. Поэтому итог вполне логичен - использовать всегда и везде.
Общий итог по стратегии можно подвести как никогда оптимистичный. Все валютные пары очень хорошо вписываются в концепцию, при этом не страдают от чрезмерных просадок. Поэтому советую как можно лучше приглядеться к полученному эксперту.
Доработка эксперта для работы в среде AutoGraf 4.0.
Входных параметров у эксперта довольно много. Поэтому впервые придется задействовать входные параметры AutoGraf: AT_1, AT_2, AT_3, AT_4 и AT_5. В них нужно указать те значения, которые заносились бы соответственно в FastM, SlowM, SignalM, FiboPercent и FiboTarget. Параметру DeltaStopLoss будет соответствовать значение дистанции Ds. Параметры TakeProfit и StopLoss будут все время включены. Поэтому для их отключения нужно будет указать большие значения AT_5 и Ds.
Для запуска стратегии необходимо проделать такие шаги:
Воспользоваться ссылкой Файлы стратегий для Autograf 4.0 (http://www.forextrade.ru/media/Image/MQLabs/45_ag/AG_DivergenceOnMACD.zip) и полученный архив распаковать в папку MT4\experts\libraries. Запустить AutoGraf и во входных параметрах AT_1 - AT_5 указать необходимые значения. Например, для пары EURUSD: AT_1 = 3, AT_2 = 49, AT_3 = 9, AT_4 = 50, AT_5 = 161.8. Для получения похожих результатов работы выставить объем открываемой позиции (Lots) 0.1, настроить значение Ds (DeltaStopLoss) = 1. Выбрать стратегию №3. Для этого передвинуть вверх значок So и среди названий стратегий найти S3 Запустить функцию автоматической торговли, передвинув значок AT в верхнее положение.
Советник DivergenceOnMACDFibo_Expert (http://www.forextrade.ru/media/Image/MQLabs/45_ag/DivergenceOnMACDFibo_Expert.mq4)
Файлы стратегий для Autograf 4.0 (http://www.forextrade.ru/media/Image/MQLabs/45_ag/AG_DivergenceOnMACD.zip)
Развернутые отчеты тестирования и оптимизации эксперта (http://www.forextrade.ru/media/Image/MQLabs/45_ag/Test.zip)
Использование полученного советника рекомендуется только в полуавтоматическом режиме под присмотром трейдера и после всестороннего изучения слабых и сильных сторон стратегии.
Для начала, специально для тех, кто еще не сталкивался с самим понятием дивергенции, дадим определение. Дивергенция (от англ. "divergence" - несоответствие, отклонение, расхождение) - разнонаправленное движение цены и показаний индикатора. Полезным можно назвать всего два типа дивергенции:
Показания индикатора уменьшаются, а цена при этом продолжает восходящее движение. В таких случаях стоит готовиться к осуществлению продаж.
Показания индикатора растут, а цена продолжает нисходящее движение. В таких случаях необходимо рассматривать возможность покупок.
Оставшиеся два варианта дивергенции (рост индикатора при падении цены и падение индикатора при росте цены) практического применения не имеют, так как в данном случае мы наблюдаем самый большой недостаток абсолютно всех индикаторов - запаздывание. Запаздывание происходит по той простой причине, что первичной все же является цена, в то время как любой индикатив всего лишь производная от цены.
Предложенный алгоритм рассмотрим на двух примерах - для покупки (см. рис. 1) и продажи (см. рис. 2):
http://www.forextrade.ru/media/Image/MQLabs/45_ag/figure_1.gif
Рис. 1. - Показания индикатора растут, а цена падает.
Вертикальными черными линиями показаны две точки, по которым была определена дивергенция. Эти точки были найдены после того, как показания MACD пересекли нулевую линию снизу вверх. Как только MACD стал положительным, на всем участке от текущего пересечения нулевой линии до предыдущего ищется самое минимальное значение гистограммы. На рис. 1 это первая вертикальная линия. Как известно, для построения прямой требуется две точки. В качестве второй точки берется локальный минимум гистограммы, который является последним перед пересечением нулевой линии. Соединяя найденные точки, получаем восходящую прямую, то есть показания индикатора растут.
Далее проводим вертикальные линии через найденные экстремумы MACD так, чтобы они отобразились на графике цен. Таким образом, мы находим две свечи, которые соответствуют минимальным показаниям MACD. Через минимумы этих свечей проводим наклонную линию, которая оказывается нисходящей. В результате получаем две разнонаправленные прямые, что говорит о наличии дивергенции.
После идентификации дивергенции необходимо определить минимальное значение цены на всем промежутке, где гистограмма MACD находилась ниже нуля. Это ориентировочный уровень стопа для будущей длинной позиции и нулевой уровень для сетки Фибоначчи. Уровень 100% сетки Фибоначчи находится как максимальное значение цены, которое было достигнуто на участке после фиксации минимума гистограммы MACD. Построение линий Фибоначчи дает возможность определить середину сложившегося канала, куда и откладывается ордер Buy Limit. На рис. 1 цена открытия длинной позиции (сработал отложенный ордер) расположена несколько выше 50%, что объясняется учетом спрэда - BUY открывается по цене Ask, в то время как цены в терминале отображаются по Bid.
Не стоит уровень стоп-приказа для длинной позиции располагать непосредственно на найденном минимуме цены. Необходимо делать хоть какой-то запас для случаев ложного пробития. На рис. 1. это запас минимальный - 1 пункт.
Цель сделки очень удобно указывать в числах Фибоначчи, тем более, сетка у нас уже посчитана и отображена. Наиболее интересными оказались уровни 161.8, 361.8 461.8 и 561.8. Хотя во входных параметрах советника, который будет описан чуть ниже, по умолчанию установлен уровень 300%. В результате получаем солидное превосходство уровня профита над стопом.
Подобным образом определяется дивергенция для коротких сделок (см. рис. 2):
http://www.forextrade.ru/media/Image/MQLabs/45_ag/figure_2.gif
Рис. 2. - Показания индикатора уменьшаются, а цена растет.
Когда гистограмма MACD пересекает нулевую линию сверху вниз, находим максимальное положительное значение индикатора на отрезке между соседними пересечениями нулевой линии. Максимум отмечен вертикальной линией, находящейся левее. Справа от найденного максимума фиксируется локальный максимум, который является ближайшим к пересечению нуля. Через эти два максимума проводится нисходящая линия.
На графике цен отмечаются свечи, которые соответствуют двум найденным экстремумам индикатора. Через максимумы этих свечей проводится восходящая линия. Таким образом, получаем расхождение линий - дивергенцию.
Далее нужно найти максимальное значение цены за то время, пока гистограмма MACD находилась выше нуля. Это будет нулевой уровень линий Фибоначчи. Для нахождения уровня 100% потребуется найти минимальное значение цены, начиная от свечи, которая соответствует максимуму индикатора MACD. После формирования сетки Фибоначчи, на уровень 50% откладывается ордер Sell Limit. Уровень стопа ставится чуть выше нулевого уровня Фибо с учетом спрэда, а уровень профита на один из уровней Фибоначчи. По умолчанию это 300%, но наиболее вероятными, как было указано выше, оказались уровни 161.8, 361.8, 461.8 и 561.8.
Перейдем к написанию торгового робота DivergenceOnMACDFibo_Expert, который основывается на описанной стратегии. Первым делом займемся сигнальной частью, которая сегодня на порядок сложнее обычного:
//+-------------------------------------------------------------------------------------+
//| Расчет значений MACD с формированием сигналов для открытия позиций |
//+-------------------------------------------------------------------------------------+
void GetSignal()
{
Signal = 0;
// - 1 - == Получение значений индикатора ===============================================
double MACD1 = iMACD(Symbol(), 0, FastM, SlowM, SignalM, MACDPrice, MODE_MAIN, 1);
double MACD2 = iMACD(Symbol(), 0, FastM, SlowM, SignalM, MACDPrice, MODE_MAIN, 2);
// - 1 - == Окончание блока =============================================================
// - 2 - == Генерация сигнала SELL ======================================================
if (MACD1 < 0 && MACD2 > 0) // Пересечение нулевой линии MACD
if (ExtremumsFind(1)) // найти положительные значения
if (VMax > VFirst && NMax > NFirst) // последняя вершина ниже максимума
if (High[NMax] < High[NFirst]) // Там, где MACD падает, цена еще растет
{
Signal = -1; // сигнал SELL
ShowDivergence(-1); // Рисуем линии дивергенции в отрицательной зоне MACD
ShowFibo(Time[LowBar], CurLow, Time[HighBar], CurHigh); // Рисуем сетку Фибо
return;
}
// - 2 - == Окончание блока =============================================================
// - 3 - == Генерация сигнала BUY =======================================================
if (MACD1 > 0 && MACD2 < 0) // Пересечение нулевой линии MACD
if (ExtremumsFind(-1)) // найти отрицательные значения
if (VMax<VFirst && NMax > NFirst)//последняя впадина выше минимального значения MACD
if (Low[NMax] > Low[NFirst]) // Там, где MACD растет, цена падает
{
Signal = 1; // сигнал Buy
ShowDivergence(1); // Рисуем линии дивергенции в положительной зоне MACD
ShowFibo(Time[HighBar], CurHigh, Time[LowBar], CurLow); // Рисуем сетку Фибо
return;
}
// - 3 - == Окончание блока =============================================================
}
Блок 1 рассчитывает ближайшие значения гистограммы MACD для того, чтобы впоследствии можно было определить момент пересечения нулевой линии. Если пересечения линии не было, то на этом выполнение функции GetSignal заканчивается.
Во втором блоке происходит проверка пересечения нуля сверху вниз. При фиксации пересечения управление передается функции ExtremumsFind с параметром 1, что означает обработку положительной зоны гистограммы MACD. ExtremumsFind возвращает результат True, если удалось найти максимальное значение MACD и следующий за ним локальный максимум. При этом заполняются значения переменных VMax (максимальное значение MACD), NMax (номер бара, где зафиксировано максимальное значение), VFirst (значение локального максимума), NFirst (номер бара, где найден локальный максимум), CurLow (минимальное значение цены после максимума MACD), CurHigh (максимальное значение цены за время нахождения гистограммы выше нуля). После успешного выполнения ExtremumsFind сравниваются значения VMax и VFirst. При этом локальный максимум должен быть ниже максимума MACD, а максимум свечи, соответствующей локальному максимуму, выше максимума свечи, соответствующей VMax. При выполнении всех этих условий переменная Signal принимает значение -1, подавая сигнал к продаже. При помощи функции ShowDivergence отображаются линии дивергенции, а при помощи функции ShowFibo отображаются линии Фибоначчи.
Третий блок аналогичен второму. Только здесь отслеживается пересечение нуля снизу вверх, а затем вызывается функция ExtremumsFind с параметром -1, что указывает на обработку отрицательной зоны MACD. При успешном выполнении ExtremumsFind требуется, чтобы найденный минимум MACD, который содержится в VMax, был ниже локального минимума, содержащегося в VFirst. При этом минимум свечи, соответствующей VMax должен быть выше минимума свечи, соответствующей VFirst. Вновь, если все условия соблюдены, то флаг Signal принимает значение 1, подавая сигнал к покупке, а функции ShowDivergence и ShowFibo отображают линии дивергенции и Фибоначчи.
Код функции ExtremumsFind выглядит грозно:
//+-------------------------------------------------------------------------------------+
//| Поиск последних двух вершин или впадин индикатора |
//+-------------------------------------------------------------------------------------+
bool ExtremumsFind(int Type)
{
// - 1 - ====================== Принятие начальных условий поиска =======================
VFirst = 0; NFirst = 0; // Первая вершина/впадина
VMax = 0; NMax = 0; // максимальное/минимальное значение индикатора
int i = 2;
double IndPred = iMACD(Symbol(), 0, FastM, SlowM, SignalM, MACDPrice, MODE_MAIN, 1);
double IndCur = iMACD(Symbol(), 0, FastM, SlowM, SignalM, MACDPrice, MODE_MAIN, 2);
double IndPrev = iMACD(Symbol(), 0, FastM, SlowM, SignalM, MACDPrice, MODE_MAIN, 3);
// - 1 - ====================== Окончание блока =========================================
// - 2 - ==== Поиск вершины/впадины и максимального (по модулю) значения индикатора =====
while (((IndCur > 0 && Type > 0) || (IndCur < 0 && Type < 0)) && i < Bars)
{
if ((IndPred < IndCur && IndPrev < IndCur && Type > 0) || // определена вершина
(IndPred > IndCur && IndPrev > IndCur && Type < 0)) // или впадина
{
if (VFirst == 0) // найдена первая вершина/впадина
{
VFirst = IndCur; // запоминаем значение
NFirst = i; // и номер бара
VMax = IndCur; // Это же значение пока будет максимальным/минимальным
NMax = i;
}
else
if ((IndCur > VMax && Type > 0) || (IndCur < VMax && Type < 0))//найдена следую-
{ // щая вершина/впадина, не будет ли она максимумом в абсолютном значении?
VMax = IndCur;
NMax = i;
}
}
i++;
// готовим данные для следующего цикла
IndPred = IndCur;
IndCur = IndPrev;
IndPrev = iMACD(Symbol(), 0, FastM, SlowM, SignalM, MACDPrice, MODE_MAIN, i+1);
}
// - 2 - ====================== Окончание блока =========================================
if (i == Bars) return(False); // если достигнут конец истории, то выдаем ошибку
// - 3 - ==== Нахождение максимального/минимального значения после экстремума MACD ======
if (Type > 0)
{
HighBar = iHighest(Symbol(), 0, MODE_HIGH, i);
CurHigh = High[HighBar];
LowBar = iLowest(Symbol(), 0, MODE_LOW, HighBar);
CurLow = Low[LowBar];
}
if (Type < 0)
{
LowBar = iLowest(Symbol(), 0, MODE_LOW, i);
CurLow = Low[LowBar];
HighBar = iHighest(Symbol(), 0, MODE_HIGH, LowBar);
CurHigh = High[HighBar];
}
// - 3 - ====================== Окончание блока =========================================
return(True);
}
В первом блоке рассчитывается значение последних трех значений MACD, из которых IndCur считается потенциальной вершиной или впадиной.
Второй блок в цикле проходит все свечи, пока не находит обратное пересечение нулевой линии. При этом каждый локальный максимум или минимум (максимум, когда IndCur больше значений IndPrev и IndPred, а минимум, когда IndCur меньше IndPrev и IndPred) сравнивается с предыдущим найденным экстремумом. Наибольший в абсолютном значении экстремум, в конце концов, остается в VMax, а первый найденный - в VFirst.
Еще одним условием прерывания цикла второго блока является достижение конца истории. В этом случае функция возвращает результат False.
Задачей третьего блока является нахождение минимального и максимального значения цены в соответствии со стратегией. По окончанию работы блока формируются данные в CurHigh (нулевой уровень сетки Фибо или 100%, в зависимости от направления) и в CurLow (противоположный CurHigh уровень Фибо).
Отображением линий дивергенции занимается функция ShowDivergence:
//+-------------------------------------------------------------------------------------+
//| Отображение линий дивергенции |
//+-------------------------------------------------------------------------------------+
void ShowDivergence(int Type)
{
// - 1 - ========= Подготовка значений в зависимости от типа отоюражения ================
datetime Time1 = Time[NMax];
datetime Time2 = Time[NFirst];
double IndPrice1 = VMax;
double IndPrice2 = VFirst;
if (Type == 1)
{
double Price1 = Low[NMax];
double Price2 = Low[NFirst];
}
else
{
Price1 = High[NMax];
Price2 = High[NFirst];
}
// - 1 - ========= Окончание блока ======================================================
// - 2 - ========= Линия дивергенции на графике =========================================
if (ObjectFind(Name1) < 0)
{
ObjectCreate(Name1, OBJ_TREND, 0, Time1, Price1, Time2, Price2);
ObjectSet(Name1, OBJPROP_COLOR, DiverColor);
ObjectSet(Name1, OBJPROP_RAY, True);
}
else
{
ObjectMove(Name1, 0, Time1, Price1);
ObjectMove(Name1, 1, Time2, Price2);
}
// - 2 - ========= Окончание блока ======================================================
// - 3 - ========= Линия дивергенции на индикаторе ======================================
if (WindowFind(IndicatorName) > 0) // если индикатор существует
if (ObjectFind(Name2) < 0) // если объект еще не создан
{
ObjectCreate(Name2, OBJ_TREND, WindowFind(IndicatorName), Time1, IndPrice1, Time2,
IndPrice2);
ObjectSet(Name2, OBJPROP_COLOR, DiverColor);
ObjectSet(Name2, OBJPROP_RAY, True);
}
else // объект создан - передвигаем
{
ObjectMove(Name2, 0, Time1, IndPrice1);
ObjectMove(Name2, 1, Time2, IndPrice2);
}
// - 3 - ========= Окончание блока ======================================================
}
Первый блок формирует значения Time1, Price1 (первая точка прямой на графике цен), Time2, Price2 (вторая точка на графике цен), IndPrice1 (значение индикатора для первой точки на гистограмме MACD) и IndPrice2 (значение индикатора для второй точки на MACD). Значение времени для обеих прямых будет совпадать.
Второй блок в особых комментариях не нуждается. Он просто рисует на графике наклонную линию, которая впоследствии передвигается.
В третьем блоке производится отображение линии дивергенции в окне индикатора MACD. Для этого сначала необходимо узнать номер окна. Номер окна можно найти, зная короткое название индикатора. Чаще всего это "MACD(12,26,9)" - стандартные настройки MACD. Но если пользователь решит использовать другие параметры MACD, то и здесь можно подстроиться, используя входные параметры эксперта. В них пользователь должен внести соответствующие настройки параметров индикатора (FastM, SlowM и SignalM). При использовании этих настроек в функции init формируется значение строковой переменной IndicatorName, которая содержит короткое имя индикатора. Поэтому попытка отображения линии дивергенции в окне индикатора осуществляется только при нахождении нужного окна MACD. Если индикатор не присоединен или у него установлены несоответствующие значения, то линия не отображается.
Подобным образом работает функция ShowFibo:
//+-------------------------------------------------------------------------------------+
//| Отображение линий Фибоначчи |
//+-------------------------------------------------------------------------------------+
void ShowFibo(datetime Time1, double Price1, datetime Time2, double Price2)
{
// - 1 - ========= Если сетка еще не отображалась, то создаем новый объект ==============
if (ObjectFind(FiboName) < 0)
{
ObjectCreate(FiboName, OBJ_FIBO, 0, Time1, Price1, Time2, Price2);
ObjectSet(FiboName, OBJPROP_FIBOLEVELS, 4); // Всего будет четыре Фибо-уровня
ObjectSet(FiboName, OBJPROP_FIRSTLEVEL, 0); // Первый уровень - ноль
ObjectSet(FiboName, OBJPROP_FIRSTLEVEL+1, FiboPercent/100); // Второй - уровень входа
ObjectSet(FiboName, OBJPROP_FIRSTLEVEL+2, 1.0); // Третий - уровень 100%
ObjectSet(FiboName, OBJPROP_FIRSTLEVEL+3, FiboTarget/100);// Четвертый - уровень цели
// Подписываем уровни
ObjectSetFiboDescription(FiboName, 0, "0.0 (%$)");
ObjectSetFiboDescription(FiboName, 1, DoubleToStr(FiboPercent, 1) + " (%$)");
ObjectSetFiboDescription(FiboName, 2, "100.0 (%$)");
ObjectSetFiboDescription(FiboName, 3, DoubleToStr(FiboTarget, 1) + " (%$)");
ObjectSet(FiboName, OBJPROP_BACK, True); // Сетка на заднем плане
ObjectSet(FiboName, OBJPROP_COLOR, CLR_NONE);// Не показывать техническую линию сетки
ObjectSet(FiboName, OBJPROP_LEVELCOLOR, Gray); // Цвет сетки
ObjectSet(FiboName, OBJPROP_LEVELSTYLE, STYLE_DOT); // Стиль сетки
}
// - 1 - ========= Окончание блока ======================================================
// - 2 - ========= Иначе просто передвигаем имеющуюся сетку =============================
else
{
ObjectMove(FiboName, 0, Time1, Price1);
ObjectMove(FiboName, 1, Time2, Price2);
}
// - 2 - ========= Окончание блока ======================================================
}
Первый блок создает объект "линии Фибоначчи" с четырьмя уровнями, два из которых пользователь может изменить по собственному желанию (FiboPercent - уровень для цены открытия отложенного ордера и FiboTarget - уровень цели позиции). Во втором блоке происходит обычное перемещение объекта при смене данных по дивергенции.
Связывание всех приведенных функций производится в функции start. Ее вид настолько стандартный, что рассматривать его сегодня не будем, а перейдем непосредственно к тестированию стратегии. Разработанный эксперт имеет такие входные параметры:
TakeProfit = True - включение/выключение установки уровня профита. Если отключен, то выход из сделки произойдет по уровню стопа или при получении обратного сигнала StopLoss = True - включение/выключение установки уровня стоп-приказа. Если отключен, то выход из сделки произойдет по уровню профита или при получении обратного сигнала Lots = 0.1 - фиксированный объем сделки FastM = 12 - период быстрой средней MACD SlowM = 26 - период медленной средней MACD SignalM = 9 - период сигнальной средней MACD. Используется только для идентификации советником присоединения MACD. MACDPrice = 0 - цена, по которой рассчитывается MACD. 0 - Close, 1 - Open, 2 - High, 3 - Low, 4 - Median Price, 5 - Typical Price, 6 - Weigthed Close DiverColor = Blue - цвет линий дивергенции DeltaStopLoss = 1 - отступ от экстремума в пунктах для установки уровня стоп-приказа FiboPercent = 50.0 - уровень Фибоначчи в процентах, на котором будет установлен отложенный лимитный ордер FiboTarget = 300.0 - уровень Фибоначчи в процентах, на котором будет установлен профит сделки
Для получения достаточного для анализа количества сделок, тестирование произведем на истории 01.01.2008 - 06.12.2009 и таймфрейме М15. Значения эксперта приняты по умолчанию (см. рис. 3 - 6):
http://www.forextrade.ru/media/Image/MQLabs/45_ag/EURUSD%20Begin.gif
Рис. 3. - Результаты тестирования эксперта DivergenceOnMACDFibo_Expert на валютной паре EURUSD.
http://www.forextrade.ru/media/Image/MQLabs/45_ag/USDCHF%20Begin.gif
Рис. 4. - Результаты тестирования эксперта DivergenceOnMACDFibo_Expert на валютной паре USDCHF.
http://www.forextrade.ru/media/Image/MQLabs/45_ag/GBPUSD%20Begin.gif
Рис. 5 - Результаты тестирования эксперта DivergenceOnMACDFibo_Expert на валютной паре GBPUSD.
http://www.forextrade.ru/media/Image/MQLabs/45_ag/USDJPY%20Begin.gif
Рис. 6. - Результаты тестирования эксперта DivergenceOnMACDFibo_Expert на валютной паре USDJPY.
Даже такие невыразительные результаты можно считать успешными, так как мы еще не подключали грозное оружие - оптимизацию параметров для каждой валютной пары в отдельности. Наиболее неудачные показатели у EURUSD - 177 долларов чистой прибыли против 2535 долларов максимальной просадки. Самые лучшие показатели у USDJPY - чистая прибыль 1333 долларов и максимальная просадка 640 долларов (фактор восстановления больше двух).
Если же произвести оптимизацию советника по каждой валютной паре, то результаты выйдут более оптимистичные. О том, как производится оптимизация, было написано в предыдущих двух статьях. Поэтому сейчас рассмотрим только конечные результаты.
Для валютной пары EURUSD были подобраны такие параметры: FastM = 3, SlowM = 49, FiboTarget = 161.8. Остальные параметры - по умолчанию (рис. 7):
http://www.forextrade.ru/media/Image/MQLabs/45_ag/EURUSD%20End.gif
Рис. 7. - Результаты тестирования эксперта после оптимизации на валютной паре EURUSD.
Кривая баланса выглядит очень стабильной. Правда, число сделок немного недотягивает до достаточного - 162. Чистая прибыль 1605 долларов, а максимальная просадка 562 доллара, что дает фактор восстановления 2.85. Итог - вполне прилично.
Для валютной пары USDCHF параметры взяты следующие: FastM = 4, SlowM = 42, FiboTarget = 461.8 (рис. 8):
http://www.forextrade.ru/media/Image/MQLabs/45_ag/USDCHF%20End.gif
Рис. 8. - Результаты тестирования эксперта после оптимизации на валютной паре USDCHF.
Вид кривой баланса немного хуже, чем у евро, но здесь более высокий фактор стабильности системы, так как максимальная просадка показана меньше (585 долларов) при большем количестве сделок (172). За то чистая прибыль составила 2279 долларов. И в результате фактор восстановления выходит 3.9. Итог - можно брать на вооружение.
Валютная пара GBPUSD остановилась на таких параметрах: FastM = 8, SlowM = 24, FiboTarget = 561.8 (рис. 9):
http://www.forextrade.ru/media/Image/MQLabs/45_ag/GBPUSD%20End.gif
Рис. 9. - Результаты тестирования эксперта после оптимизации на валютной паре GBPUSD.
Вновь имеем довольно стабильный вид кривой баланса. К тому же, количество сделок приличное - 292. Чистая прибыль наибольшая из всех результатов - 3530 долларов при максимальной просадке 991 доллар. Фактор восстановления 3.56. Прибыль достигнута тотальным превосходством потенциальной прибыли над потенциальным убытком. Средняя прибыль - 188 долларов, а средний убыток всего лишь 39 долларов. При этом даже максимальное значение убытка не дотягивает до средней прибыли (111 долларов). Итог - стоит взять на вооружение.
Последняя валютная пара - USDJPY. На ней уже получены удобоваримые результаты. Поэтому с нетерпением ждем их улучшения. Параметры такие: FastM = 7, SlowM = 51, FiboTarget = 161.8 (рис. 10).
http://www.forextrade.ru/media/Image/MQLabs/45_ag/USDJPY%20End.gif
Рис. 10. - Результаты тестирования эксперта после оптимизации на валютной паре USDJPY.
Самый лучший вид кривой баланса - это одно из заметных достижений йены. Вторым достижением является минимальное значение просадки - 329 долларов. А чистая прибыль даже превысила значение при начальном тесте - 2091 доллар. Фактор восстановления получается неприлично большим - 6.36. Поэтому итог вполне логичен - использовать всегда и везде.
Общий итог по стратегии можно подвести как никогда оптимистичный. Все валютные пары очень хорошо вписываются в концепцию, при этом не страдают от чрезмерных просадок. Поэтому советую как можно лучше приглядеться к полученному эксперту.
Доработка эксперта для работы в среде AutoGraf 4.0.
Входных параметров у эксперта довольно много. Поэтому впервые придется задействовать входные параметры AutoGraf: AT_1, AT_2, AT_3, AT_4 и AT_5. В них нужно указать те значения, которые заносились бы соответственно в FastM, SlowM, SignalM, FiboPercent и FiboTarget. Параметру DeltaStopLoss будет соответствовать значение дистанции Ds. Параметры TakeProfit и StopLoss будут все время включены. Поэтому для их отключения нужно будет указать большие значения AT_5 и Ds.
Для запуска стратегии необходимо проделать такие шаги:
Воспользоваться ссылкой Файлы стратегий для Autograf 4.0 (http://www.forextrade.ru/media/Image/MQLabs/45_ag/AG_DivergenceOnMACD.zip) и полученный архив распаковать в папку MT4\experts\libraries. Запустить AutoGraf и во входных параметрах AT_1 - AT_5 указать необходимые значения. Например, для пары EURUSD: AT_1 = 3, AT_2 = 49, AT_3 = 9, AT_4 = 50, AT_5 = 161.8. Для получения похожих результатов работы выставить объем открываемой позиции (Lots) 0.1, настроить значение Ds (DeltaStopLoss) = 1. Выбрать стратегию №3. Для этого передвинуть вверх значок So и среди названий стратегий найти S3 Запустить функцию автоматической торговли, передвинув значок AT в верхнее положение.
Советник DivergenceOnMACDFibo_Expert (http://www.forextrade.ru/media/Image/MQLabs/45_ag/DivergenceOnMACDFibo_Expert.mq4)
Файлы стратегий для Autograf 4.0 (http://www.forextrade.ru/media/Image/MQLabs/45_ag/AG_DivergenceOnMACD.zip)
Развернутые отчеты тестирования и оптимизации эксперта (http://www.forextrade.ru/media/Image/MQLabs/45_ag/Test.zip)
Использование полученного советника рекомендуется только в полуавтоматическом режиме под присмотром трейдера и после всестороннего изучения слабых и сильных сторон стратегии.