Сравнительный анализ 10 флэтовых стратегий
Содержание
- Введение
- Постановка задачи при создании флэтовой стратегии
- Флэтовые стратегии
- Стратегия №1. Индикатор Envelopes с фильтром в виде MFI
- Стратегия №2. Индикатор Bollinger Bands и две Moving Average
- Стратегия №3. WSO & WRO Channel с фильтром в виде Fractal Dimension Ehlers
- Стратегия №4. Индикатор Percentage Crossover Channel и TrendRange в качестве фильтра
- Стратегия №5. Индикатор Price Channel и RBVI в качестве фильтра
- Стратегия №6. Индикатор Williams Percent Range и ADX в качестве фильтра
- Стратегия №7. Модифицированный канал Келтнера и индикатор Magic Trend в качестве фильтра
- Стратегия №8. Канал Дончиана с подтверждением индикатором Trinity Impulse
- Стратегия №9. Индикатор ATR Channel и CCI Color Levels в качестве фильтра
- Стратегия №10. RSI в виде гистограммы и индикатор Flat в качестве фильтра
- Тестирование
- Выводы
- Заключение
Введение
Стратегии торговли по тренду — наиболее популярные и простые, особенно для начинающих трейдеров. Но в современных реалиях динамичность рынков выросла, а трендовые движения стали менее выраженными (и по величине, и по продолжительности). Поэтому не хотелось бы терять потенциальную прибыль, упуская возможность торговли во флэте. Правила торговли по тренду несложные: надо определить признаки тренда и попытаться извлечь выгоду из его развития. Трейдинг во флэте проходит совсем по-другому. Во время бокового движения цена находится в небольшом диапазоне и может вообще не меняться довольно долгое время. При этом направленного движения нет, а ликвидность низка.
Постановка задачи при создании флэтовой стратегии
В предыдущей статье я ставил перед собой три задачи, решение которых необходимо было для создания стратегии работы по тренду. Задачи для создания флэтовых стратегий очень похожи на них.
Рис. 1. Пример бокового движения (флэта).
Задача №1. Определение наличия флэта.
Общего и исчерпывающего понятия флэта не существует, (собственно, как и понятия тренда). Но есть определенные признаки того, что сейчас на рынке царит боковик (флэт). Собственно, такое движение и называется боковым, потому что нет ярко выраженного движения рынка по вертикали — ни вверх, ни вниз. При этом цена находится в определенном диапазоне, волнообразно подходя то к нижней его части, то к верхней. Другим признаком флэта может быть низкий объем сделок на рынке или низкий интерес участников рынка. Это заметно не только по слабому изменению цены, но и по небольшому тиковому объему.
Задача №2. Цели открытой позиции.
Очень часто при торговле во флэте используют такое понятие, как торговля в канале. Это и есть основной способ использования бокового движения для получения прибыли. Определяется канал флэта в неких виртуальных границах и далее, исходя из взаимоотношения цены и этих границ выстраивается стратегия торговли. Чаще всего она строится на покупке или продаже при отскоке цены от границы канала (рис.2).
Рис. 2. Торговля при отскоке цены от границ канала.
При продаже в верхней части канала мы предполагаем, что цена пойдет в направлении нижней границы. Там и будет стоять тейк-профит. Стоп-лосс можно поставить или определенным числовым значением в пунктах, или исходя из ширины канала. Для покупки всё наоборот: покупаем в нижней части канала, тейк-профит ставим вблизи верхней границы.
Флэтовые стратегии
При выборе флэтовых стратегий я решил руководствоваться принципами, описанными выше.
- Торговля будет происходить в канале. Поэтому выбираем такие инструменты, которые позволят нам его построить и определить виртуальные границы флэта.
- Кроме определения канала, нам понадобится еще хотя бы один инструмент для подтверждения того, что цена пойдет в нужную нам сторону, отскочив от границы канала. Такой фильтр нужно для отсеивания ложных сигналов на вход.
Стратегия №1: Индикатор Envelopes с фильтром в виде MFI
Для определения границ канала будет применяться Envelopes, а сигнал отфильтрует MFI.
Параметр | Описание |
---|---|
Используемый индикатор | Envelopes |
Используемый индикатор | MFI |
Таймфрейм | H1 |
Условия на покупку | Достижение ценой нижней границы канала и нахождение MFI в зоне перепроданности (ниже 20) |
Условия на продажу | Достижение ценой верхней границы канала и нахождение MFI в зоне перекупленности (выше 80) |
Условия выхода | Достижение противоположной границы канала |
На рис.3 показаны условия входа в рынок по стратегии №1.
Рис. 3. Условия входа по флэтовой стратегии №1.
Код торгового советника по этой стратегии выглядит так:
void OnTick() { //--- Проверка ранее открытых экcпертом ордеров if(!Trade.IsOpenedByMagic(Inp_MagicNum)) { //--- Получение данных для расчета if(!GetIndValue()) return; //--- Открытие ордера при наличии сигнала на покупку if(BuySignal()) Trade.BuyPositionOpen(Symbol(),Inp_Lot,close[0]-Inp_StopLoss*_Point,tp,Inp_MagicNum,Inp_EaComment); //--- Открытие ордера при наличии сигнала на продажу if(SellSignal()) Trade.SellPositionOpen(Symbol(),Inp_Lot,close[0]+Inp_StopLoss*_Point,tp,Inp_MagicNum,Inp_EaComment); } } //+------------------------------------------------------------------+ //| Условия на покупку | //+------------------------------------------------------------------+ bool BuySignal() { if(mfi[0]<20 && env_low[0]>close[0]) { tp=env_high[0]; return true; } else return false; } //+------------------------------------------------------------------+ //| Условия на продажу | //+------------------------------------------------------------------+ bool SellSignal() { if(mfi[0]>80 && env_high[0]<close[0]) { tp=env_low[0]; return true; } else return false; } //+------------------------------------------------------------------+ //| Получение текущих значений индикаторов | //+------------------------------------------------------------------+ bool GetIndValue() { return(CopyBuffer(InpInd_Handle1,0,0,2,mfi)<=0 || CopyBuffer(InpInd_Handle2,1,0,2,env_low)<=0 || CopyBuffer(InpInd_Handle2,0,0,2,env_high)<=0 || CopyClose(Symbol(),PERIOD_CURRENT,0,2,close)<=0 )?false:true; } //+------------------------------------------------------------------+
Тейк-профит устанавливается автоматически, исходя из заданных условий, а стоп-лосс — вручную, в зависимости от таймфрейма.
Стратегия №2: Индикатор Bollinger Bands и две Moving Average
Для определения границ канала используется индикатор Bollinger Bands, а в качестве фильтра — положение медленной и быстрой МА относительно друг друга.
Параметр | Описание |
---|---|
Используемый индикатор | Bollinger Bands |
Используемый индикатор | Moving Average |
Таймфрейм | H1 |
Условия на покупку | Достижение ценой нижней границы канала, быстрая МА выше медленной |
Условия на продажу | Достижение ценой верхней границы канала, быстрая МА ниже медленной |
Условия выхода | Достижение противоположной границы канала |
На рис.4 показаны условия входа в рынок. Период двух SMA по умолчанию небольшой: 4 и 8. В советнике можно настраивать периоды и методы сглаживания, изменяя таким образом чувствительность фильтрации сигнала от Bollinger Bands.
Рис. 4 Условия входа по флэтовой стратегии №2
За исключением условий входа в рынок, стратегия №2 очень похожа на стратегию №1.
void OnTick() { //--- Проверка ранее открытых экcпертом ордеров if(!Trade.IsOpenedByMagic(Inp_MagicNum)) { //--- Получение данных для расчета if(!GetIndValue()) return; //--- Открытие ордера при наличии сигнала на покупку if(BuySignal()) Trade.BuyPositionOpen(Symbol(),Inp_Lot,close[0]-Inp_StopLoss*_Point,tp,Inp_MagicNum,Inp_EaComment); //--- Открытие ордера при наличии сигнала на продажу if(SellSignal()) Trade.SellPositionOpen(Symbol(),Inp_Lot,close[0]+Inp_StopLoss*_Point,tp,Inp_MagicNum,Inp_EaComment); } } //+------------------------------------------------------------------+ //| Условия на покупку | //+------------------------------------------------------------------+ bool BuySignal() { if(ma_slow[0]>ma_fast[0] && bb_low[0]>close[0]) { tp=bb_up[0]; return true; } else return false; } //+------------------------------------------------------------------+ //| Условия на продажу | //+------------------------------------------------------------------+ bool SellSignal() { if(ma_slow[0]<ma_fast[0] && bb_up[0]<close[0]) { tp=bb_low[0]; return true; } else return false; } //+------------------------------------------------------------------+ //| Получение текущих значений индикаторов | //+------------------------------------------------------------------+ bool GetIndValue() { return(CopyBuffer(InpInd_Handle1,1,0,2,bb_up)<=0 || CopyBuffer(InpInd_Handle1,2,0,2,bb_low)<=0 || CopyBuffer(InpInd_Handle2,0,0,2,ma_slow)<=0 || CopyBuffer(InpInd_Handle3,0,0,2,ma_fast)<=0 || CopyClose(Symbol(),PERIOD_CURRENT,0,2,close)<=0 )?false:true; } //+------------------------------------------------------------------+
Стратегия №3. WSO & WRO Channel и Fractal Dimension Ehlers
Основным сигнальным индикатором станет WSO & WRO Channel — канал, построенный на основе значений двух осцилляторов: WSO (Widner Support Oscillator) и WRO (Widner Resistance Oscillator). Идея индикатора основана на статье Мэла Уиднера "Automated Support And Resistance". В качестве фильтра возьмем индикатор фрактальной размерности, описанный в статье Джона Эйлерса и Рика Уэйса "Fractal Dimension As A Market Mode Sensor".
Параметр | Описание |
---|---|
Используемый индикатор | WSO & WRO Channel |
Используемый индикатор | Fractal Dimension Ehlers |
Таймфрейм | Любой |
Условия на покупку | Достижение ценой нижней границы канала и значение Fractal Dimension ниже целевого порога |
Условия на продажу | Достижение ценой верхней границы канала и значение Fractal Dimension ниже целевого порога |
Условия выхода | Достижение противоположной границы канала |
На рис.5 показаны условия входа в рынок. Как и в предыдущих случаях, стратегия подразумевает торговлю на отскоке от границ канала, при этом с помощью фильтра пытаемся найти те точки входа, где рынок не находится в трендовом состоянии.
Рис. 5. Условия входа по флэтовой стратегии №3.
Код советника по этой стратегии выглядит вот так:
void OnTick() { //--- Проверка ранее открытых экcпертом ордеров if(!Trade.IsOpenedByMagic(Inp_MagicNum)) { //--- Получение данных для расчета if(!GetIndValue()) return; //--- Открытие ордера при наличии сигнала на покупку if(BuySignal()) Trade.BuyPositionOpen(Symbol(),Inp_Lot,close[0]-Inp_StopLoss*_Point,tp,Inp_MagicNum,Inp_EaComment); //--- Открытие ордера при наличии сигнала на продажу if(SellSignal()) Trade.SellPositionOpen(Symbol(),Inp_Lot,close[0]+Inp_StopLoss*_Point,tp,Inp_MagicNum,Inp_EaComment); } } //+------------------------------------------------------------------+ //| Условия на покупку | //+------------------------------------------------------------------+ bool BuySignal() { if(wwc_low[0]>close[0] && fdi[0]<Inp_FdiThreshold) { tp=wwc_up[0]; return true; } else return false; } //+------------------------------------------------------------------+ //| Условия на продажу | //+------------------------------------------------------------------+ bool SellSignal() { if(wwc_up[0]<close[0] && fdi[0]<Inp_FdiThreshold) { tp=wwc_low[0]; return true; } else return false; } //+------------------------------------------------------------------+ //| Получение текущих значений индикаторов | //+------------------------------------------------------------------+ bool GetIndValue() { return(CopyBuffer(InpInd_Handle1,3,0,2,wwc_up)<=0 || CopyBuffer(InpInd_Handle1,2,0,2,wwc_low)<=0 || CopyBuffer(InpInd_Handle2,0,0,2,fdi)<=0 || CopyClose(Symbol(),PERIOD_CURRENT,0,2,close)<=0 )?false:true; } //+------------------------------------------------------------------+
Стратегия №4. Индикатор Percentage Crossover Channel и TrendRange в качестве фильтра
Здесь попробуем использовать канал, строящийся по пробою уровней на определенный процент. Нам нужен индикатор, строящий канал, поиск точек отскока цены от его границ и фильтрация сигнала. Этим индикатором будет TrendRange, показывающий как трендовые состояния, так и флэтовые. Их мы и будем применять в качестве фильтра.
Параметр | Описание |
---|---|
Используемый индикатор | Percentage Crossover Channel |
Используемый индикатор | Trend Range |
Таймфрейм | Любой |
Условия на покупку | Достижение ценой нижней границы канала и цвет гистограммы Trend Range серого цвета |
Условия на продажу | Достижение ценой верхней границы канала и цвет гистограммы Trend Range серого цвета |
Условия выхода | Достижение противоположной границы канала |
Условия входа в рынок показаны на рис.6. Работа индикатора Percentage Crossover имеет некоторые особенности. Параметр Percent, отражающий предельную дистанцию, по пробою которой начинается построение нового уровня, зависит от таймфрейма. Чем он меньше, тем меньший процент нужно устанавливать. К примеру, на часовом таймфрейме рекомендуемое значение 20 — 30. Более высокие значения приведут к излишней избирательности индикатора.
Рис. 6. Условия входа по флэтовой стратегии №4.
Стратегия реализуется в коде так:
void OnTick() { //--- Проверка ранее открытых экcпертом ордеров if(!Trade.IsOpenedByMagic(Inp_MagicNum)) { //--- Получение данных для расчета if(!GetIndValue()) return; //--- Открытие ордера при наличии сигнала на покупку if(BuySignal()) Trade.BuyPositionOpen(Symbol(),Inp_Lot,close[0]-Inp_StopLoss*_Point,tp,Inp_MagicNum,Inp_EaComment); //--- Открытие ордера при наличии сигнала на продажу if(SellSignal()) Trade.SellPositionOpen(Symbol(),Inp_Lot,close[0]+Inp_StopLoss*_Point,tp,Inp_MagicNum,Inp_EaComment); } } //+------------------------------------------------------------------+ //| Условия на покупку | //+------------------------------------------------------------------+ bool BuySignal() { if(pcc_low[0]>close[0] && tr_flat[0]>tr_range[0]) { tp=pcc_up[0]; return true; } else return false; } //+------------------------------------------------------------------+ //| Условия на продажу | //+------------------------------------------------------------------+ bool SellSignal() { if(pcc_up[0]<close[0] && tr_flat[0]>tr_range[0]) { tp=pcc_low[0]; return true; } else return false; } //+------------------------------------------------------------------+ //| Получение текущих значений индикаторов | //+------------------------------------------------------------------+ bool GetIndValue() { return(CopyBuffer(InpInd_Handle1,0,0,2,pcc_up)<=0 || CopyBuffer(InpInd_Handle1,2,0,2,pcc_low)<=0 || CopyBuffer(InpInd_Handle2,1,0,2,tr_flat)<=0 || CopyBuffer(InpInd_Handle2,2,0,2,tr_range)<=0 || CopyClose(Symbol(),PERIOD_CURRENT,0,2,close)<=0 )?false:true; } //+------------------------------------------------------------------+
Стратегия №5. Индикатор Price Channel и RBVI в качестве фильтра
Индикатор Price Channel строит канал, верхние и нижние границы которого определяются максимумом и минимумом цены за период. Фильтровать ложные сигналы будет RBVI, определяющий флэт на рынке.
Параметр | Описание |
---|---|
Используемый индикатор | Price Channel |
Используемый индикатор | RBVI |
Таймфрейм | Любой |
Условия на покупку | Достижение ценой нижней границы канала и значение RBVI ниже порогового для флэта |
Условия на продажу | Достижение ценой верхней границы канала и значение RBVI ниже порогового для флэта |
Условия выхода | Достижение противоположной границы канала |
На рис.7 представлены условия входа. Пороговое значение индикатора RBVI — 40. Но в параметрах советника можно будет изменить это значение.
Рис. 7. Условия входа по флэтовой стратегии №5.
Реализация этой стратегии в коде выглядит так:
void OnTick() { //--- Проверка ранее открытых экcпертом ордеров if(!Trade.IsOpenedByMagic(Inp_MagicNum)) { //--- Получение данных для расчета if(!GetIndValue()) return; //--- Открытие ордера при наличии сигнала на покупку if(BuySignal()) Trade.BuyPositionOpen(Symbol(),Inp_Lot,close[0]-Inp_StopLoss*_Point,tp,Inp_MagicNum,Inp_EaComment); //--- Открытие ордера при наличии сигнала на продажу if(SellSignal()) Trade.SellPositionOpen(Symbol(),Inp_Lot,close[0]+Inp_StopLoss*_Point,tp,Inp_MagicNum,Inp_EaComment); } } //+------------------------------------------------------------------+ //| Условия на покупку | //+------------------------------------------------------------------+ bool BuySignal() { if(pc_low[0]>close[0] && rbvi[0]<=Inp_level) { tp=pc_up[0]; return true; } else return false; } //+------------------------------------------------------------------+ //| Условия на продажу | //+------------------------------------------------------------------+ bool SellSignal() { if(pc_up[0]<close[0] && rbvi[0]<=Inp_level) { tp=pc_low[0]; return true; } else return false; } //+------------------------------------------------------------------+ //| Получение текущих значений индикаторов | //+------------------------------------------------------------------+ bool GetIndValue() { return(CopyBuffer(InpInd_Handle1,0,0,2,pc_up)<=0 || CopyBuffer(InpInd_Handle1,1,0,2,pc_low)<=0 || CopyBuffer(InpInd_Handle2,0,0,2,rbvi)<=0 || CopyClose(Symbol(),PERIOD_CURRENT,0,2,close)<=0 )?false:true; } //+------------------------------------------------------------------+
Стратегия №6. Индикатор Williams Percent Range и ADX в качестве фильтра
Процентный диапазон Уильямса, определяющий состояние перекупленности/перепроданности, будет использоваться в качестве точек входа. Но поскольку у нас стоит задача торговли на флэте или подразумевается возвращение цены в некий диапазон, то трендовый индикатор ADX будет применяться для определения отсутствия направленного движения.
Параметр | Описание |
---|---|
Используемый индикатор | Williams Percent Range |
Используемый индикатор | ADX |
Таймфрейм | Любой |
Условия на покупку | Индикатор WPR находится в зоне перепроданности (ниже -80) и значение ADX ниже установленного порогового. |
Условия на продажу | Индикатор WPR находится в зоне перекупленности (выше -20) и значение ADX ниже установленного порогового. |
Условия выхода | Тейк-профит/Стоп-лосс |
Как видно на рис.8, зона флэта на индикаторе ADX по умолчанию установлена на значение 30. Но в коде советника предусмотрена возможность его пользовательской настройки.
Рис. 8. Условия входа по флэтовой стратегии №6.
На листинге ниже приведена реализации этой стратегии. Здесь переменная Inp_FlatLevel отвечает за пороговое значение ADX, о котором говорилось выше.
void OnTick() { //--- Проверка ранее открытых экcпертом ордеров if(!Trade.IsOpenedByMagic(Inp_MagicNum)) { //--- Получение данных для расчета if(!GetIndValue()) return; //--- Открытие ордера при наличии сигнала на покупку if(BuySignal()) Trade.BuyPositionOpen(Symbol(),Inp_Lot,Inp_StopLoss,Inp_TakeProfit,Inp_MagicNum,Inp_EaComment); //--- Открытие ордера при наличии сигнала на продажу if(SellSignal()) Trade.SellPositionOpen(Symbol(),Inp_Lot,Inp_StopLoss,Inp_TakeProfit,Inp_MagicNum,Inp_EaComment); } } //+------------------------------------------------------------------+ //| Условия на покупку | //+------------------------------------------------------------------+ bool BuySignal() { return(wpr[0]<-80 && adx[0]<Inp_FlatLevel)?true:false; } //+------------------------------------------------------------------+ //| Условия на продажу | //+------------------------------------------------------------------+ bool SellSignal() { return(wpr[0]>=-20 && adx[0]<Inp_FlatLevel)?true:false; } //+------------------------------------------------------------------+ //| Получение текущих значений индикаторов | //+------------------------------------------------------------------+ bool GetIndValue() { return(CopyBuffer(InpInd_Handle1,0,0,2,wpr)<=0 || CopyBuffer(InpInd_Handle2,0,0,2,adx)<=0)?false:true; } //+------------------------------------------------------------------+
Стратегия №7. Модифицированный канал Келтнера и индикатор Magic Trend в качестве фильтра
Здесь отскок цены от границ канала Келтнера будем проверять с помощью трендового индикатора Magic Trend в моменты, когда он будет идентифицировать флэт.
Параметр | Описание |
---|---|
Используемый индикатор | Модифицированный канал Келтнера |
Используемый индикатор | Magic Trend |
Таймфрейм | Любой |
Условия на покупку | Достижение ценой нижней границы канала и серый цвет линии Magic Trend |
Условия на продажу | Достижение ценой верхней границы канала и серый цвет линии Magic Trend |
Условия выхода | Достижение противоположной границы канала |
На рис.9 представлена визуальная демонстрация этой торговой стратегии. Видим, что при флэте значение индикатора Magic Trend не изменяется — он отображается серой горизонтальной линией. Значит, дополнительным условием, кроме достижения ценой границы канала, будет нахождение Magic Trend в состоянии флэта некоторое время. Эта проверка будет реализована сравнением значений на текущем и предыдущем баре — они должны быть одинаковыми.
Рис. 9. Условия входа по флэтовой стратегии №7.
В коде это учитывается в функциях, проверяющих условия на продажу/покупку:
void OnTick() { //--- Проверка ранее открытых экcпертом ордеров if(!Trade.IsOpenedByMagic(Inp_MagicNum)) { //--- Получение данных для расчета if(!GetIndValue()) return; //--- Открытие ордера при наличии сигнала на покупку if(BuySignal()) Trade.BuyPositionOpen(Symbol(),Inp_Lot,close[0]-Inp_StopLoss*_Point,tp,Inp_MagicNum,Inp_EaComment); //--- Открытие ордера при наличии сигнала на продажу if(SellSignal()) Trade.SellPositionOpen(Symbol(),Inp_Lot,close[0]+Inp_StopLoss*_Point,tp,Inp_MagicNum,Inp_EaComment); } } //+------------------------------------------------------------------+ //| Условия на покупку | //+------------------------------------------------------------------+ bool BuySignal() { if(kc_low[0]>close[0] && mt[0]==mt[1]) { tp=kc_up[0]; return true; } else return false; } //+------------------------------------------------------------------+ //| Условия на продажу | //+------------------------------------------------------------------+ bool SellSignal() { if(kc_up[0]<close[0] && mt[0]==mt[1]) { tp=kc_low[0]; return true; } else return false; } //+------------------------------------------------------------------+ //| Получение текущих значений индикаторов | //+------------------------------------------------------------------+ bool GetIndValue() { return(CopyBuffer(InpInd_Handle1,0,0,2,kc_up)<=0 || CopyBuffer(InpInd_Handle1,2,0,2,kc_low)<=0 || CopyBuffer(InpInd_Handle2,0,0,2,mt)<=0 || CopyClose(Symbol(),PERIOD_CURRENT,0,2,close)<=0 )?false:true; } //+------------------------------------------------------------------+
Стратегия №8. Канал Дончиана с подтверждением индикатором Trinity Impulse
В этой стратегии попробуем отловить моменты отскока от границ канала Дончиана, подтвердая его импульсным индикатором Trinity Impulse в состоянии бокового движения.
Параметр | Описание |
---|---|
Используемый индикатор | Канал Дончиана |
Используемый индикатор | Trinity Impulse |
Таймфрейм | Младшие таймфреймы |
Условия на покупку | Достижение ценой нижней границы канала и нулевое значение Trinity Impulse |
Условия на продажу | Достижение ценой верхней границы канала и нулевое значение Trinity Impulse |
Условия выхода | Достижение противоположной границы канала |
Входы в рынок представлены на рис.10. Стратегию нежелательно использовать на старших таймфреймах, потому что фильтр Trinity Impusle показывает пилообразное поведение, и зоны флэта отображаются с задержкой. При этом их ширина очень мала, а это делает стратегию слишком избирательной. Оптимально использовать 5 — 30-минутные таймфреймы.
Рис. 10. Условия входа по флэтовой стратегии №8.
Реализация торгового советника по стратегии:.
void OnTick() { //--- Проверка ранее открытых экcпертом ордеров if(!Trade.IsOpenedByMagic(Inp_MagicNum)) { //--- Получение данных для расчета if(!GetIndValue()) return; //--- Открытие ордера при наличии сигнала на покупку if(BuySignal()) Trade.BuyPositionOpen(Symbol(),Inp_Lot,close[0]-Inp_StopLoss*_Point,tp,Inp_MagicNum,Inp_EaComment); //--- Открытие ордера при наличии сигнала на продажу if(SellSignal()) Trade.SellPositionOpen(Symbol(),Inp_Lot,close[0]+Inp_StopLoss*_Point,tp,Inp_MagicNum,Inp_EaComment); } } //+------------------------------------------------------------------+ //| Условия на покупку | //+------------------------------------------------------------------+ bool BuySignal() { if(dc_low[0]>close[0] && ti[0]==0) { tp=dc_up[0]; return true; } else return false; } //+------------------------------------------------------------------+ //| Условия на продажу | //+------------------------------------------------------------------+ bool SellSignal() { if(dc_up[0]<close[0] && ti[0]==0) { tp=dc_low[0]; return true; } else return false; } //+------------------------------------------------------------------+ //| Получение текущих значений индикаторов | //+------------------------------------------------------------------+ bool GetIndValue() { return(CopyBuffer(InpInd_Handle1,0,0,2,dc_up)<=0 || CopyBuffer(InpInd_Handle1,1,0,2,dc_low)<=0 || CopyBuffer(InpInd_Handle2,0,0,2,ti)<=0 || CopyClose(Symbol(),PERIOD_CURRENT,0,2,close)<=0 )?false:true; } //+------------------------------------------------------------------+
Стратегия №9. Индикатор ATR Channel и CCI Color Levels в качестве фильтра
ATR Channel основан на отклонениях индикатора ATR от скользящей средней. CCI Color Levels — это CCI, отображающийся в виде гистограммы пороговых значений, которые являются признаками ценового движения. Мы же будем использовать его как фильтр канала во флэтовом состоянии (когда CCI находится в диапазоне между пороговыми значениями).
Параметр | Описание |
---|---|
Используемый индикатор | ATR Channel |
Используемый индикатор | CCI Color Levels |
Таймфрейм | Любой |
Условия на покупку | Достижение ценой нижней границы канала и значение CCI Color Levels находится в диапазоне между пороговыми значениями |
Условия на продажу | Достижение ценой верхней границы канала и значение CCI Color Levels находится в диапазоне между пороговыми значениями |
Условия выхода | Достижение противоположной границы канала |
На рис. 11 показано, как происходит вход в рынок. В некоторых случаях цена выходит за границы канала, однако фильтрация сигнала по нахождению значения CCI в заданном диапазоне позволяет предполагать, что она вернется в канал и достигнет установленного тейк-профита.
Рис. 11. Условия входа по флэтовой стратегии №9.
Код советника по этой стратегии:
void OnTick() { //--- Проверка ранее открытых экcпертом ордеров if(!Trade.IsOpenedByMagic(Inp_MagicNum)) { //--- Получение данных для расчета if(!GetIndValue()) return; //--- Открытие ордера при наличии сигнала на покупку if(BuySignal()) Trade.BuyPositionOpen(Symbol(),Inp_Lot,close[0]-Inp_StopLoss*_Point,tp,Inp_MagicNum,Inp_EaComment); //--- Открытие ордера при наличии сигнала на продажу if(SellSignal()) Trade.SellPositionOpen(Symbol(),Inp_Lot,close[0]+Inp_StopLoss*_Point,tp,Inp_MagicNum,Inp_EaComment); } } //+------------------------------------------------------------------+ //| Условия на покупку | //+------------------------------------------------------------------+ bool BuySignal() { if(atr_low[0]>close[0] && cci[0]<Inp_CCI_LevelUP && cci[0]>Inp_CCI_LevelDOWN) { tp=atr_up[0]; return true; } else return false; } //+------------------------------------------------------------------+ //| Условия на продажу | //+------------------------------------------------------------------+ bool SellSignal() { if(atr_up[0]<close[0] && cci[0]<Inp_CCI_LevelUP && cci[0]>Inp_CCI_LevelDOWN) { tp=atr_low[0]; return true; } else return false; } //+------------------------------------------------------------------+ //| Получение текущих значений индикаторов | //+------------------------------------------------------------------+ bool GetIndValue() { return(CopyBuffer(InpInd_Handle1,1,0,2,atr_up)<=0 || CopyBuffer(InpInd_Handle1,2,0,2,atr_low)<=0 || CopyBuffer(InpInd_Handle2,2,0,2,cci)<=0 || CopyClose(Symbol(),PERIOD_CURRENT,0,2,close)<=0 )?false:true; } //+------------------------------------------------------------------+
Стратегия №10. RSI в виде гистограммы и индикатор Flat в качестве фильтра
RSI в виде гистограммы выбран для большей наглядности, потому что основным сигналом для входа в рынок будут его зоны перекупленности/перепроданности. Flat, в свою очередь, отфильтрует ложные сигналы.
Параметр | Описание |
---|---|
Используемый индикатор | RSI_Histogram |
Используемый индикатор | Flat |
Таймфрейм | любой |
Условия на покупку | Нахождение RSI в зоне перепроданности(ниже порогового значения) и Flat находится в зоне флэта. |
Условия на продажу | Нахождение RSI в зоне перекупленности(выше порогового значения) и Flat находится в зоне флэта. |
Условия выхода | Тейк-профит/Стоп-лосс |
На рис.12 наглядно показаны точки входа. Отображение RSI в виде гистограммы делает более удобным отслеживание зон перекупленности/перепроданности, а также флэтовой зоны фильтра Flat.
Рис. 12. Условия входа по флэтовой стратегии №10.
Реализация торгового советника по стратегии представлена в листинге ниже.
void OnTick() { //--- Проверка ранее открытых экcпертом ордеров if(!Trade.IsOpenedByMagic(Inp_MagicNum)) { //--- Получение данных для расчета if(!GetIndValue()) return; //--- Открытие ордера при наличии сигнала на покупку if(BuySignal()) Trade.BuyPositionOpen(Symbol(),Inp_Lot,Inp_StopLoss,Inp_TakeProfit,Inp_MagicNum,Inp_EaComment); //--- Открытие ордера при наличии сигнала на продажу if(SellSignal()) Trade.SellPositionOpen(Symbol(),Inp_Lot,Inp_StopLoss,Inp_TakeProfit,Inp_MagicNum,Inp_EaComment); } } //+------------------------------------------------------------------+ //| Условия на покупку | //+------------------------------------------------------------------+ bool BuySignal() { return(rsi[0]<Inp_LowLevel && fl[0]<Inp_FLowLevel)?true:false; } //+------------------------------------------------------------------+ //| Условия на продажу | //+------------------------------------------------------------------+ bool SellSignal() { return(rsi[0]>Inp_HighLevel && fl[0]<Inp_FLowLevel)?true:false; } //+------------------------------------------------------------------+ //| Получение текущих значений индикаторов | //+------------------------------------------------------------------+ bool GetIndValue() { return(CopyBuffer(InpInd_Handle1,0,0,2,rsi)<=0 || CopyBuffer(InpInd_Handle2,0,0,2,fl)<=0)?false:true; } //+------------------------------------------------------------------+
Тестирование
Определившись с 10 флэтовыми стратегиями и реализовав их в коде, выберем максимально схожие условия тестирования.
- Интервал: Последний год.
- Валютная пара: EURUSD.
- Режим торговли: Без задержки (Представленные стратегии не относятся к высокочастотным, поэтому влияние задержек было бы очень мало).
- Тестирование: OHLC на М1 (Предварительное тестирование на реальных тиках оказалось почти неотличимо от этого режима).
- Начальный депозит: 1000 USD.
- Плечо: 1:500.
- Сервер: MetaQuotes-Demo.
- Котировки: 5-значные.
Тест Стратегии №1 (Индикатор Envelopes с фильтром в виде MFI)
Предустановка:
input int Inp_StopLoss=500; //Stop Loss(points) //--- Параметры индикатора MFI input ENUM_APPLIED_VOLUME Inp_applied_volume=VOLUME_TICK; // тип объема MFI input int Inp_MFI_period=10; // период MFI //--- Параметры индикатора Envelopes input int Inp_ma_period=10; // период скользящей Envelopes input ENUM_MA_METHOD Inp_ma_method=MODE_SMA; // тип сглаживания Envelopes input double Inp_deviation=0.1; // отклонение границ от скользящей Envelopes
Результат тестирования:
Рис. 13. Результаты тестирования флэтовой стратегии №1.
Тест Стратегии №2 (Индикатор Bollinger Bands и две Moving Average)
Предустановка:
input int Inp_StopLoss=450; //Stop Loss(points) //--- Параметры индикатора Bollinger Bands input int Inp_BBPeriod=14; //BB период input double Inp_deviation=2.0; //Отклонение //--- Параметры индикатора MA slow input int Inp_ma_period1=12; //Период MA slow input ENUM_MA_METHOD Inp_ma_method1=MODE_SMMA; //Метод сглаживания MA slow //--- Параметры индикатора MA fast input int Inp_ma_period2=2; //Период MA fast input ENUM_MA_METHOD Inp_ma_method2=MODE_LWMA; //Метод сглаживания MA fast
Результат тестирования:
Рис. 14. Результаты тестирования флэтовой стратегии №2.
Тест Стратегии №3 (WSO & WRO Channel с фильтром в виде Fractal Dimension Ehlers)
Предустановка:
input int Inp_StopLoss=500; //Stop Loss(points) //--- Параметры индикатора WSO & WRO Channel input int Inp_WsoWroPeriod=16; //Период Wso & Wro Channel //--- Параметры индикатора Fractal Dimension Ehlers input int Inp_FdiPeriod = 18; //Период Fractal dimension input double Inp_FdiThreshold = 1.4; //Порог Fractal dimension input ENUM_APPLIED_PRICE Inp_Price = PRICE_CLOSE; //Применяемая цена
Результат тестирования:
Рис. 15. Результаты тестирования флэтовой стратегии №3.
Тест Стратегии №4 (Индикатор Percentage Crossover Channel и TrendRange в качестве фильтра)
Предустановка:
input int Inp_StopLoss=500; //Stop Loss(points) //--- Параметры индикатора Percentage_Crossover_Channel input double Inp_Percent=26.0; //Процент предельной дистанции input ENUM_APPLIED_PRICE Inp_Price=PRICE_CLOSE; //Применяемая цена //--- Параметры индикатора Trend Range input uint Inp_PeriodTR = 14; //Период Trend Range input ENUM_MA_METHOD Inp_Method = MODE_EMA; //Метод сглаживания input double Inp_Deviation = 1.0; //Отклонение
Результат тестирования:
Рис.16. Результаты тестирования флэтовой стратегии №4.
Тест Стратегии №5 (Индикатор Price Channel и RBVI в качестве фильтра)
Предустановка:
input int Inp_StopLoss=450; //Stop Loss(points) //--- Параметры индикатора Price Channel input int Inp_ChannelPeriod=12; //Period //--- Параметры индикатора RBVI input int Inp_RBVIPeriod=5; //период RBVI input ENUM_APPLIED_VOLUME Inp_VolumeType=VOLUME_TICK; //объём input double Inp_level=40; //уровень флэта
Результат тестирования:
Рис. 17. Результаты тестирования флэтовой стратегии №5.
Тест Стратегии №6 (Индикатор Williams Percent Range и ADX в качестве фильтра)
Предустановка:
input int Inp_StopLoss=50; //Stop Loss(points) input int Inp_TakeProfit=50; //Take Profit(points) //--- Параметры индикатора WPR input int Inp_WPRPeriod=10; //Period WPR //--- Параметры индикатора ADX input int Inp_ADXPeriod=14; //Period ADX input int Inp_FlatLevel=40; //Flat Level ADX
Результат тестирования:
Рис. 18. Результаты тестирования флэтовой стратегии №6.
Тест Стратегии №7 (Модифицированный канал Келтнера и индикатор Magic Trend в качестве фильтра)
Предустановка:
input int Inp_SmoothCenter = 11; // Number of the periods to smooth the center line input int Inp_SmoothDeviation = 12; // Number of periods to smooth deviation input double Inp_F = 1.0; // Factor which is used to apply the deviation input ENUM_APPLIED_PRICE Inp_AppliedPrice = PRICE_CLOSE; // The center line applied price: input ENUM_MA_METHOD Inp_MethodSmoothing = MODE_SMA; // The center line smoothing method input ENUM_METHOD_VARIATION Inp_MethodVariation = METHOD_HL; // Variation Method //--- Параметры индикатора Magic Trend input uint Inp_PeriodCCI = 60; // CCI period input uint Inp_PeriodATR = 5; // ATR period
Результат тестирования:
Рис. 19. Результаты тестирования флэтовой стратегии №7.
Тест Стратегии №8 (Канал Дончиана с подтверждением индикатором Trinity Impulse)
Предустановка:
input int Inp_StopLoss=500; //Stop Loss(points) //--- Параметры индикатора канала Дончиана input int Inp_ChannelPeriod=12; //Doncian period //--- Параметры индикатора Trinity Impulse input int Inp_Period= 5; //Indicator period input int Inp_Level= 34; //Smoothing level input ENUM_MA_METHOD Inp_Type=MODE_LWMA; //Averaging type input ENUM_APPLIED_PRICE Inp_Price=PRICE_WEIGHTED; //Price input ENUM_APPLIED_VOLUME Inp_Volume=VOLUME_TICK; //Volume type
Результат тестирования:
Рис. 20. Результаты тестирования флэтовой стратегии №8.
Тест Стратегии №9 (Индикатор ATR Channel и CCI Color Levels в качестве фильтра)
Предустановка:
//--- Параметры индикатора ATR Channel input ENUM_MA_METHOD Inp_MA_Method=MODE_SMA; //MA smoothing method input uint Inp_MA_Period=10; //MA period input uint Inp_ATR_Period=12; //ATR period input double Inp_Factor=1.5; //Number of deviations input ENUM_APPLIED_PRICE Inp_IPC=PRICE_LOW; //Applied price input int Inp_Shift=0; //Horizontal shift of the indicator in bars //--- Параметры индикатора CCI Color Levels input int Inp_CCI_ma_period = 14; // Averaging period input double Inp_CCI_LevelUP = 90; // Level UP input double Inp_CCI_LevelDOWN =-90; // Level DOWN
Результат тестирования:
Рис. 21. Результаты тестирования флэтовой стратегии №9.
Тест Стратегии №10 (RSI в виде гистограммы и индикатор Flat в качестве фильтра)
Предустановка:
//--- Параметры индикатора RSI Histogram input uint Inp_RSIPeriod=12; // период индикатора input ENUM_APPLIED_PRICE Inp_RSIPrice=PRICE_CLOSE; // цена input uint Inp_HighLevel=60; // уровень перекупленности input uint Inp_LowLevel=40; // уровень перепроданности input int Inp_Shift=0; // сдвиг индикатора по горизонтали в барах //--- Параметры индикатора Flat input uint Inp_Smooth=10; // Smoothing period input ENUM_MA_METHOD Inp_ma_method=MODE_SMA; // Smoothing type input ENUM_APPLIED_PRICE Inp_applied_price=PRICE_CLOSE; // Price type input uint Inp_HLRef=100; input int Inp_FShift=0; // Horizontal shift of the indicator in bars input uint Inp_ExtraHighLevel=70; // Maximum trend level input uint Inp_FHighLevel=50; // Strong trend level input uint Inp_FLowLevel=30; // Weak trend level
Результат тестирования:
Рис. 22. Результаты тестирования флэтовой стратегии №10.
Выводы
По результатам тестирования и оптимизации представленных флэтовых стратегий были сделаны следующие наблюдения.
- Большинство стратегий построено по системе торговли в канале с фильтрацией сигналов, а значит, главный их недостаток — кратковременный пробой канала.
- Тестирование на слишком малых и на слишком больших таймфреймах приносило убытки в связи с частым срабатыванием условий входа в рынок, либо с большой избирательностью, соответственно.
- При оптимизации на одной и той же валютной паре и периоду времени не было выявлено особых отклонений в получении профита. Он оказался примерно одного порядка у всех стратегий.
В связи с этим можно сделать главный вывод: несмотря на то, что подбирались различные системы построения канала и его фильтрации, преимущества и недостатки всех стратегий оказались сопоставимыми.
Заключение
Ниже представлена сводная таблица названий экспертов, разработанных и используемых в статье, а также вспомогательные классы и перечень индикаторов, которые были использованы в текущих трендовых стратегиях. В конце статьи приложен архив со всеми перечисленными файлами, рассортированными по папкам. Поэтому для корректной работы достаточно положить папку MQL5 в корень терминала.
Программы, используемые в статье:
# |
Имя |
Тип |
Описание |
---|---|---|---|
1 |
Strategy_1.mq5 |
Эксперт |
Стратегия №1. Индикатор Envelopes с фильтром в виде MFI. |
2 |
Strategy_2.mql5 |
Эксперт |
Стратегия №2. Индикатор Bollinger Bands и две Moving Average. |
3 |
Strategy_3.mq5 |
Эксперт | Стратегия №3. WSO & WRO Channel с фильтром в виде Fractal Dimension Ehlers. |
4 |
Strategy_4.mq5 |
Эксперт |
Стратегия №4. Индикатор Percentage Crossover Channel и TrendRange в качестве фильтра. |
5 |
Strategy_5.mq5 | Эксперт | Стратегия №5. Индикатор Price Channel и RBVI в качестве фильтра. |
6 |
Strategy_6.mq5 |
Эксперт |
Стратегия №6. Индикатор Williams Percent Range и ADX в качестве фильтра. |
7 | Strategy_7.mq5 |
Эксперт |
Стратегия №7. Модифицированный канал Келтнера и индикатор Magic Trend в качестве фильтра. |
8 | Strategy_8.mq5 | Эксперт | Стратегия №8. Канал Дончиана с подтверждением индикатором Trinity Impulse. |
9 | Strategy_9.mq5 | Эксперт | Стратегия №9. Индикатор ATR Channel и CCI Color Levels в качестве фильтра. |
10 | Strategy_10.mq5 | Эксперт | Стратегия №10. RSI в виде гистограммы и индикатор Flat в качестве фильтра. |
11 | Trade.mqh | Библиотека | Класс торговых функций. |
13 | wwc.mq5 | Индикатор | Используется в Стратегии №3. |
14 | fdi.mq5 | Индикатор | Используется в Стратегии №3. |
15 | pcc.mq5 | Индикатор | Используется в Стратегии №4. |
16 | trend_range.mq5 | Индикатор | Используется в Стратегии №4. |
17 | price_channel.mq5 | Индикатор | Используется в Стратегии №5. |
18 | rbvi.mq5 | Индикатор | Используется в Стратегии №5. |
19 | customizable _keltner.mq5 | Индикатор | Используется в Стратегии №7. |
20 | magic_trend.mq5 | Индикатор | Используется в Стратегии №7. |
21 | donchian_channel.mq5 | Индикатор | Используется в Стратегии №8. |
22 | trinity_impulse.mq5 | Индикатор | Используется в Стратегии №8. |
23 | atr_channel.mq5 | Индикатор | Используется в Стратегии №9. |
24 | cci_color_levels.mq5 | Индикатор | Используется в Стратегии №9. |
25 | rsi_histogram.mq5 | Индикатор | Используется в Стратегии №10. |
26 | flat.mq5 | Индикатор | Используется в Стратегии №10. |
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Очень интересная статья (впрочем, как и всегда у Александра).
3. Результаты по всем стратегиям оказались сопоставимыми совсем неслучайно:
- везде используются традиционные индикаторы,
- а традиционные индикаторы (как и традиционный теханализ в целом) имеют глобальный недостаток:
частота движения цен любого финансового инструмента постоянно меняется, а такие индикаторы не имею механизма идентификации постоянно изменяющейся частоты.
Спасибо за отзыв. Да, вы правы, я не случайно использовал более узнаваемые или традиционные индикаторы(хотя некоторые из них, для фильтрации или определения сигнала были трендовыми и использовались в противоположном их применению). До этого была статья про трендовые стратегии и там я применял очень сложные тандемы или взаимодействия индикаторов со множеством параметров в них. Здесь было решено сделать всё более доступно для понимания с узнаваемыми индикаторами.
Маленький вопрос. Вы сказали: традиционные виды анализа. Это какие? ТА, ФА. А вероятностный, на Ваш взгляд, относится к традиционным? Спросил для поддержания разговора.
Безусловно, и ТА и ФА, и вероятностный подход (в имеющихся вариациях такого анализа, является традиционным.
Спасибо за отзыв. Да, вы правы, я не случайно использовал более узнаваемые или традиционные индикаторы(хотя некоторые из них, для фильтрации или определения сигнала были трендовыми и использовались в противоположном их применению). До этого была статья про трендовые стратегии и там я применял очень сложные тандемы или взаимодействия индикаторов со множеством параметров в них. Здесь было решено сделать всё более доступно для понимания с узнаваемыми индикаторами.
На мой взгляд, Ваши подходы совершенно верные. Ещё раз спасибо за интересную работу.
Честно говоря, статья-халтура. Ничего нового не подчерпнул. Извините.
Значит вы уже не новичок, и всё знаете.
Уважаемый Василий!
Процесс движения цен финансовых инструментов, в целом, является нестационарным. В рамках теории импульсного равновесия выявлена структура, которая постоянно повторяется (не просто периодически, а постоянно и непрерывно - изменятся лишь параметры этой структуры). Именно поэтому имеется возможность определить величину периода (или частоту ка обратную величину). А в рамках традиционных видов анализа это абсолютно невозможно (именно из-за того, что там нет механизма идентификации такой структуры).
Что касается вашего утверждения, что "фаза - отклонение от положения равновесия", а также предложение использовать демодулятор (да ещё амплитудно-фазовый) - так это довольно странные утверждения, особенно применительно к графикам цен финансовых инструментов (то есть к нестационарным процессам). И "в два действия", как Вы говорите, анализ такого сложного (нестационарного) процесса, не решается. Вот как-то так.
1. "выявлена структура", но "нет механизма идентификации такой структуры" - типа инопланетяне есть , но механизма, доказать это, нет.
2. при этом "имеется возможность определить величину периода" - как инопланетяне выглядят, мы знаем, но нарисовать не можем.
3. "в рамках традиционных видов анализа это абсолютно не возможно" - возможно, но Вы же занимаетесь синтезом, а не анализом.