PDA

View Full Version : Метод новичка



Scriptong
20-03-2011, 18:13
Большинству читателей, наверняка, известна поговорка: "Новичкам везет". В справедливости этой поговорки мне пришлось (а может, посчастливилось?) убедиться на личном опыте. Речь идет о первом знакомстве с рынком Форекс, который в те далекие времена казался воплощением американской мечты.
Подход к изучению нового для меня дела, как я тогда считал, был выполнен основательно: удостоились прочтению теория волн Эллиотта, которая не поддалась усвоению, и не менее противоречивая тактика Адверса. После этого произошел переход к практике, а именно: к торговле на демо-счете. Нетрудно догадаться, каков был результат. Обладая лишь смутными догадками о технике торговли, в течение месяца мне удалось увеличить депозит в два раза. Подобный итог привел к абсолютно логичному (но скоропалительному) выводу: с таким же успехом я могу "тренироваться" на реальном счете, зарабатывая при этом солидные деньги. Сказано - сделано: в скором времени был открыт реальный счет, размер которого в точности соответствовал стартовому депозиту демо-счета. Первый месяц торговли, хоть и не привел к повторению былого успеха, все же получился достаточно удачным - 40% прибыли. Удвоение депозита пришлось на конец третьего месяца ведения реальной торговли.
Такой успех не мог остаться незамеченным среди ближайших знакомых трейдеров, которые не преминули поинтересоваться основами используемой мною стратегии. Узнав, что никакой стратегии у меня нет, они, все как один, стали уверять меня в том, что "так торговать нельзя". В течение следующих трех месяцев я усиленно занимался своим "образованием" в сфере фундаментального и технического анализа по книгам, которые любезно предоставили многочисленные доброжелатели. К концу упомянутого срока содержимое серого вещества моей верхней конечности иначе, как кашей, назвать было трудно, хотя самооценка была диаметрально противоположной - "ух, сколько всего я теперь знаю!". Полученные знания были тут же использованы по назначению на разбухшем реальном счете. Результат вышел не менее потрясающим - все имеющиеся средства (вложенные и заработанные) растаяли в течение одного месяца...
С тех пор я неоднократно возвращаюсь к анализу своего первого опыта рыночной торговли. С одной стороны я, конечно же, понимаю, что рецепт успеха в те времена был обусловлен именно озвученной в начале поговоркой. Когда мы учимся ездить на велосипеде, то успешный проезд первых двадцати метров лишь вселяет в нас уверенность в своих силах, но речь о полном понимании процесса езды еще не идет. Для этого требуются дальнейшие тренировки с падениями и ушибами, дающими неоценимый опыт. И только в момент, когда количество опыта достигает какого-то критического уровня, к нам приходит понимание сути того, чему мы учились.
С другой стороны, если подходить к анализу причин первого успеха чисто с формальной точки зрения, т.е. рассматривая только технику совершения сделок, то можно все-таки сложить некоторую стратегию, которой я придерживался совершенно неосознанно. В чем же заключалась эта стратегия? Основанием для совершения сделки всегда становился один и тот же признак - цена в течение продолжительного времени возвращалась к некоторому уровню. От этого уровня производилось открытие сделки в любую сторону с таким расчетом, что в случае ошибки цена все равно вернется сюда же и я смогу закрыть сделку с наименьшим убытком или даже в ноль. Никаких планов действий на те случаи, когда цена не сможет вернуться к уровню входа, у меня не было. Более того - ни у одной сделки не было уровня стоп-приказа, только профит, который раз за разом достигался, что не позволяло трезво оценивать ситуацию. Описывая этот метод с позиций технического анализа, можно сказать, что для торговли выбирался момент формирования горизонтального канала, и сделка совершалась от середины канала в любом направлении с целью, находящейся около границы канала. Вариант выхода цены из канала попросту не рассматривался, а серия успешных сделок объясняется тем фактом, что в течение трех месяцев, на которые выпало начало моей торговой деятельности, рынок находился в узком ценовом диапазоне, не нарушая его границ. Отсюда и отсутствие больших просадок за время существования каждой сделки, и обязательное достижение прибыли.
Несмотря на кажущуюся абсурдность описанной стратегии, в ней есть рациональное зерно, которое можно взять за основу для разработки полноценной стратегии, которая будет ограничивать риски при помощи установки уровня стоп-приказа. Еще одним важным качеством стратегии будет ее способность приносить прибыль после выхода цены из флэта. Основной сигнал стратегии оставляем - совершение сделки при формировании горизонтального канала. Критерием формирования канала будет следующая ситуация (см. рис. 1)

http://www.forextrade.ru/media/Image/MQLabs/106_ag/figure1.png
Рис. 1. Формирование горизонтального канала.

Канал считается сформированным в том случае, если в наборе из пяти (это значение можно изменять) последних баров каждый последующий бар не выходил за границы предыдущего бара более чем на 3/4 его высоты. В результате формируется канал, который наиболее часто является воплощением всех возможных представлений о флэте. Иногда, конечно, бывают и "промашки", но в условиях жесткой формализации от этого никуда не деться. Еще одним непременным условием идентификации канала является его высота. Она должна быть, как минимум, в два раза больше, чем сумма текущих минимального уровня стопов и спрэда. Поэтому существование канала зависит также от текущих торговых условий брокера. Для сведения их влияния к минимуму необходимо избегать установки малых значений стопа и профита. В данном случае они будут представлены коэффициентами умножения.
В процессе принятия решения о направлении сделки используется два условия. Первое условие - направление последней свечи канала. Если последняя свеча бычья, то сделка - длинная, если свеча медвежья, то сделка - короткая. Второе условие - профит сделки, определенной по типу последней свечи канала, должен располагаться внутри канала. Если это условие не выполняется, то производится попытка открытия противоположной сделки, но при этом цена открытия текущей свечи должна находиться в соответствующей половине канала. Чтобы открыть длинную сделку, необходимо, чтобы цена открытия располагалась в нижней части канала. Если цена открытия свечи находится в верхней части канала, то возможно совершение только короткой сделки.
Расчет уровней профита и стоп-приказа производится на основании значения средней волатильности, определяемой по индикатору ATR. Профит откладывается от цены открытия сделки, а уровень стоп-приказа - от соответствующей границы канала. В итоге стоп-приказ всегда находится за пределами канала, а не на самой его границе, что дает возможность цене выйти за пределы канала, но не сбить стоп. Вероятность достижения профита раньше, чем будет достигнут стоп, в этом случае значительно увеличивается.
Кроме торговли в канале, стратегия должна предусматривать выход цены из него. Ведь вполне возможно, что сделки будут приходиться на момент окончания канала, за которым последует тренд. В этом случае сделка получится убыточной, а стратегия будет ожидать формирования нового канала. Выходом из ситуации является размещение страхующего ордера на уровне стоп-приказа основной сделки. Профит страхующего ордера будет рассчитываться на основании размера возможного убытка, полученного от первичной сделки, а уровень стоп-приказа будет установлен на уровень профита канальной сделки (см. рис. 2).

http://www.forextrade.ru/media/Image/MQLabs/106_ag/figure2.png
Рис. 2. Размещение страхующих ордеров.

Если установить коэффициент компенсации убытка два и более (как на рис. 2), то совершение любой пары сделок будет приводить к росту капитала, кроме случаев наиболее неблагоприятного развития событий. Описать такие события просто: выход цены за пределы канала ровно настолько, сколько нужно для срабатывания уровня стоп-приказа первичной сделки и открытия страхующего ордера. Затем цена производит возврат к уровню профита канальной сделки. К счастью, как показывает тестирование стратегии (см. ниже), в таком русле события развиваются нечасто. Чтобы осуществить тестирование стратегии, необходимо иметь ее программный аналог. Иначе, при ручной проверке, тестирование рискует значительно затянуться во времени.
Отличие нового советника NoviceMethod от советника, рассмотренного в прошлый раз (http://www.forextrade.ru/mqlabs/12.03.2011-mqlabs-otklonenie-ot-sostoyaniya-pokoya-chast-2), заключается в содержимом трех функций: GetSignal, FindOrders и Trade. Также добавлена функция DeleteOrder, которая была описана в статье http://www.forextrade.ru/mqlabs/01.07.2010-mqlabs-volatilnost-fleta-i-trenda. Описание начнем с функции генерации сигнала:

//+-------------------------------------------------------------------------------------+
//| Генерация сигналов открытия сделки |
//+-------------------------------------------------------------------------------------+
void GetSignal()
{
Signal = 0;
// - 1 - == Формирование канала с расчетом его границ и середины ========================
for (int i = 1; i < Bars-1; i++) // Пройдемся по всем доступным барам
{
double PrevVol = OutPercent*(High[i+1] - Low[i+1])/100;// Величина максимального..
// ..выхода границ одной свечи за..
// ..границы другой
if (High[i] > High[i+1] + PrevVol || // Если максимум или минимум текущей..
Low[i] < Low[i+1] - PrevVol) // ..свечи выходит за пределы..
break; // ..экстремумов предыдущей свечи с..
//..учетом допуска, то прекрываем цикл
}
if (i <= MinBarsCount) return; // Если канал состоит из меньшего, чем
// ..указано, количества баров, то..
// ..сигнал не генерируется
double HighV = High[iHighest(NULL, 0, MODE_HIGH, i-1, 1)];// Верхняя граница канала
double LowV = Low[iLowest(NULL, 0, MODE_LOW, i-1, 1)];// Нижняя граница канала
if (HighV - LowV <= 2*(StopLevel+Spread)) // Если ширина канала не дает..
return; // ..возможности открытия сделки с..
// ..минимальным размером профита, то
// ..сигнал не генерируется
double Middle = (HighV + LowV)/2; // Средняя линия канала
double TPVol = ProfitKoef*iATR(NULL, 0, 24, 1); // Размер профита
double SLVol = LossKoef*iATR(NULL, 0, 24, 1); // Размер стопа от границы канала
// - 1 - == Окончание блока =============================================================

// - 2 - == Генерация сигнала покупки ===================================================
if (((Open[1] > Close[1] && // Если последняя свеча медвежья,
Open[0] - TPVol - Spread < LowV && // ..но для открытия короткой не..
Open[0] < Middle) || // ..хватает ширины канала, а цена..
// ..открытия находится в нижней части
// ..канала или..
Open[1] < Close[1]) && // ..если последняя свеча бычья и..
Open[0] + TPVol + Spread < HighV) // ..хватает ширины канала для профита
{
Signal = 1; // Генерируем бычий сигнал
BuyTP = Open[0] + TPVol + Spread; // Рассчитываем уровень профита
BuySL = LowV - SLVol + Spread; // Рассчитываем уровень стопа
}
// - 2 - == Окончание блока =============================================================

// - 3 - == Генерация сигнала продажи ===================================================
if (((Open[1] < Close[1] && // Если последняя свеча бычья,
Open[0] + TPVol + Spread > HighV && // ..но для открытия длинной не..
Open[0] > Middle) || // ..хватает ширины канала, а цена..
//..открытия находится в верхней части
// ..канала или..
Open[1] > Close[1]) && // ..если последняя свеча медвежья и..
Open[0] - TPVol - Spread > LowV) // ..хватает ширины канала для профита
{
Signal = -1; // Генерируем медвежий сигнал
SellTP = Open[0] - TPVol; // Рассчитываем уровень профита
SellSL = HighV + SLVol; // Рассчитываем уровень стопа
}
// - 3 - == Окончание блока =============================================================
}
Алгоритмически функция разделена на три блока. Задачей первого блока является идентификация горизонтального канала, а второго и третьего блоков - генерация соответствующих сигналов.
Поиск горизонтального канала производится методом простого перебора свечей от ближайшей сформированной до последней имеющейся в истории. Для каждой свечи проверяется выполнение условия: экстремумы свечи не должны выходить за пределы экстремумов предыдущей свечи более чем на OutPercent процентов от высоты предыдущей свечи. Переменная OutPercent - настроечный параметр эксперта. С его помощью пользователь может задать пределы флэта, коим выступает горизонтальный канал. Уменьшая значение OutPercent, можно дать указание программе реагировать на более "жесткий" флэт, а при увеличении значения OutPercent требования к флэту становятся мягче.
При нахождении первой же свечи, для которой не выполняется условие допустимого отклонения экстремумов от экстремумов предыдущей свечи, цикл перебора прерывается. Количество принадлежащих каналу свечей сравнивается с минимально допустимым значением ширины канала - MinBarsCount. Это также один из настроечных параметров эксперта. С его помощью задается минимальная продолжительность флэта (в свечах). Если продолжительность флэта приемлемая, то выполнение функции GetSignal продолжается. В противном случае происходит немедленный выход, и переменная Signal, при помощи которой эксперт сигнализирует о направлении сделки, остается равной нулю.
Если канал удовлетворяет требованиям "жесткости" и продолжительности флэта, то далее следует расчет высоты канала и сравнение ее с минимально допустимой высотой канала. Если высота недостаточна, то функция GetSignal прерывается. В противном случае производится расчет средней линии канала, а также размеров профита и стоп-приказа, зависящих от текущей волатильности. Переменные ProfitKoef и LossKoef - настроечные параметры эксперта.
Второй и третий блоки используют полученные в первом блоке значения для определения направления будущей сделки. В случае генерации сигнала также рассчитываются уровни профита и стоп-приказа для каждого типа сделки.
Использование значений переменных Signal, BuyTP, BuySL, SellTP и SellSL производится в торговой функции Trade. Но для ее правильной работы требуется располагать сведениями об имеющихся ордерах. В данном случае эксперт оперирует сразу двумя ордерами: основной сделкой и страхующим ордером. Поэтому использование обычного вида функции FindOrders явно недостаточно. Требуется ее изменение:

//+-------------------------------------------------------------------------------------+
//| Функция поиска своих ордеров |
//+-------------------------------------------------------------------------------------+
void FindOrders()
{
// - 1 - == Инициализация переменных перед поиском ======================================
int total = OrdersTotal() - 1;
Ticket = -1;
Type = -1;
PenTicket = -1;
PenType = -1;
// - 1 - == Окончание блока =============================================================

// - 2 - == Поиск ордера ================================================================
for (int i = total; i >= 0; i--) // Используется весь список ордеров
if (OrderSelect(i, SELECT_BY_POS)) // Убедимся, что ордер выбран
if (OrderMagicNumber() == MagicNumber && // Ордер открыт экспертом,
OrderSymbol() == Symbol()) // ..который прикреплен к текущей..
{ // Сохраним его признак в..
// ..соответствующих переменных
if (OrderType() < 2)
{
Ticket = OrderTicket();
Type = OrderType();
}
else
{
PenTicket = OrderTicket();
PenType = OrderType();
}
}
// - 2 - == Окончание блока =============================================================
}
Стандартный вид функции FindOrders включает в себя определение наличия или отсутствия одного ордера, который, чаще всего, является рыночным. В этом отношении изменений нет - один из ордеров советника всегда будет рыночным. Если обнаруживается два ордера, то второй всегда будет отложенным. По этому признаку можно произвести сортировку ордеров. Для рыночного ордера используются имеющиеся переменные Ticket (номер ордера) и Type (тип ордера), а для отложенного ордера необходимо объявить две новые переменные - PenTicket (номер ордера) и PenType (тип ордера). Как и в случае с переменными Ticket и Type, отрицательное значение новых переменных свидетельствует об отсутствии ордера (в данном случае отложенного ордера).
Функция Trade подверглась незначительным изменениям:

//+-------------------------------------------------------------------------------------+
//| Открытие позиций |
//+-------------------------------------------------------------------------------------+
bool Trade()
{
// - 1 - == Сигнал открытия длинной сделки ==============================================
if (Signal > 0 && Type != OP_BUY) // Необходимо открыть длинную
{
// - 1.1 - == Закрытие сделки и удаление ордера ===================================
if (Type == OP_SELL) // Если имеется короткая сделка, то..
if (!CloseDeal(Ticket)) // ..закроем ее. При неудаче вернем..
return(false); // ..ошибку
if (PenType > 0) // При наличии отложенного ордера,..
if (!DeleteOrder(PenTicket)) // ..удалим его
return(false);
// - 1.1 - == Окончание блока =====================================================

// - 1.2 - == Открытие сделки и установка страхующего ордера ======================
RefreshRates(); // Обновление значений Bid и Ask
if (OpenOrderCorrect(OP_SELLSTOP, Lots, NP(BuySL), // Установка страхующего ордера
NP(BuyTP), NP(BuySL - Compensation*(Ask - BuySL))) != 0)
return(false);
RefreshRates(); // Обновление значений Bid и Ask
if (OpenOrderCorrect(OP_BUY, Lots, NP(Ask), // Открытие позиции Buy
NP(BuySL), NP(BuyTP)) != 0)
return(false);
// - 1.2 - == Окончание блока =====================================================
}
// - 1 - == Окончание блока =============================================================

// - 2 - == Сигнал открытия короткой сделки =============================================
if (Signal < 0 && Type != OP_SELL) // Необходимо открыть короткую
{
// - 2.1 - == Закрытие сделки и удаление ордера ===================================
if (Type == OP_BUY) // Если имеется длинная сделка, то..
if (!CloseDeal(Ticket)) // ..закроем ее. При неудаче вернем..
return(false); // ..ошибку
if (PenType > 0)
if (!DeleteOrder(PenTicket))
return(false);
// - 2.1 - == Окончание блока =====================================================

// - 2.2 - == Открытие сделки и установка страхующего ордера ======================
RefreshRates(); // Обновление значений Bid и Ask
if (OpenOrderCorrect(OP_BUYSTOP, Lots, NP(SellSL), // Установка страхующего ордера
NP(SellTP), NP(SellSL + Compensation*(SellSL - Bid))) != 0)
return(false);
RefreshRates(); // Обновление значений Bid и Ask
if (OpenOrderCorrect(OP_SELL, Lots, NP(Bid), // Открытие позиции Sell
NP(SellSL), NP(SellTP)) != 0)
return(false);
// - 2.2 - == Окончание блока =====================================================
}
// - 2 - == Окончание блока =============================================================

return(True); // Все операции завершены успешно
}
Как и раньше, каждый из блоков функции отвечает за открытие соответствующей сделки: первый блок - длинной, а второй - короткой.
В новой интерпретации функции, описывающей текущую стратегию, в каждом блоке добавлен анализ существования отложенного ордера. Если существует сигнал открытия сделки, а из ордеров присутствует только отложенный ордер, то он, вне зависимости от типа, удаляется. Далее добавлены строки кода, приводящие к установке отложенного ордера. Первым устанавливается именно отложенный ордер, а не рыночный. Это позволяет выполнить каждый из блоков повторно в случае ошибки установки страхующего ордера (в условии блоков имеется выражение Type != ).
Переменная Compensation, используемая для расчета профита страхующих ордеров, является настроечным параметром эксперта. С ее помощью пользователь может указать размер компенсации после получения убытка. Компенсация будет кратна размеру убытка.
При возникновении любой ошибки в процессе установки, закрытия или удаления ордера функция Trade возвращает значение false. Успешное выполнение всех действий знаменуется результатом true.


Тестирование советника
Тестирование стратегии проводилось на историческом периоде 08.01.2009 - 11.03.2011 и таймфрейме Н1. Минимальное количество баров, необходимое для идентификации канала, было установлено равным 5 (MinBarsCount = 5), у пары USDCHF - 6. Для всех валютных пар, кроме GBPUSD, максимальное "забегание" за экстремум предыдущего бара 75% (OutPercent = 75), для GBPUSD - 60%. Индивидуальными для каждой валютной пары стали коэффициенты для расчета уровней профита и стоп-приказа - ProfitKoef и LossKoef, а также размер компенсации - Compensation. Результаты тестирования приведены на рис. 3-6.
EURUSD. Значения изменяемых параметров: ProfitKoef = 1.5, LossKoef = 3.5, Compensation = 6. Кривая баланса на протяжении всего участка тестирования стабильно растет. Нестабильность проявляется только со знаком "плюс", т.е. вверх. На такое грех жаловаться. Чистая прибыль 4 372 доллара, максимальная просадка 601 доллар. Фактор восстановления 7.27. Блестящий результат!

http://www.forextrade.ru/media/Image/MQLabs/106_ag/EURUSD.gif
Рис. 3. Результаты тестирования эксперта NoviceMethod на валютной паре EURUSD.

USDCHF. Значения изменяемых параметров: ProfitKoef = 1.8, LossKoef = 2.8, Compensation = 2. Кривая баланса, несмотря на общий рост, выглядит вяло и неуверенно. Чистая прибыль 1 454 доллара, максимальная просадка 476 долларов. Фактор восстановления 3.05. Учитывая вид кривой баланса, это посредственный результат.

http://www.forextrade.ru/media/Image/MQLabs/106_ag/USDCHF.gif
Рис. 4. Результаты тестирования эксперта NoviceMethod на валютной паре USDCHF.

GBPUSD. Значения изменяемых параметров: ProfitKoef = 1.3, LossKoef = 1.1, Compensation = 5. Удивительно наблюдать у валютной пары с наивысшей, среди рассматриваемых валютных пар, волатильностью такие низкие значения коэффициентов. Вид кривой баланса чем-то напоминает вид предыдущей кривой, но все же со знаком "минус" - наличие значительного спада в конце. Чистая прибыль 2 186 долларов, максимальная просадка 959 долларов. Фактор восстановления 2.28. Очень низкий показатель.

http://www.forextrade.ru/media/Image/MQLabs/106_ag/GBPUSD.gif
Рис. 5. Результаты тестирования эксперта NoviceMethod на валютной паре GBPUSD.

USDJPY. Значения изменяемых параметров: ProfitKoef = 1.5, LossKoef = 2.8, Compensation = 2. Такому хорошему и стабильному виду кривой баланса не хватает уверенности в росте. После отличного начала рост был приторможен. Хотя, неплохо смотрится концовка, которая обещает продолжение тенденции в будущем. Чистая прибыль 2 415 долларов, максимальная просадка 474 доллара. Фактор восстановления 5.09. Неплохой результат.

http://www.forextrade.ru/media/Image/MQLabs/106_ag/USDJPY.gif
Рис. 6. Результаты тестирования эксперта NoviceMethod на валютной паре USDJPY.

Как подтвердили результаты тестирования, тактика новичка действительно может принести прибыль. Главное, не совершать наиболее грубых ошибок, присущих новичкам: следить за рисками, ставить стоп-приказы и не расслабляться после достижения локальных успехов.


Доработка стратегии для использования в AutoGraf 4.0
Использование стратегии "Метод новичка" в среде AutoGraf 4 требует занесения пяти настроечных параметров в список входных параметров приложения, использующихся для управления автоматической торговлей. Соответствие параметров эксперта и параметров стратегии следующее: MinBarsCount - AT_1, OutPercent - AT_2, ProfitKoef - AT_3, LossKoef - AT_4, Compensation - AT_5.
Параметр Lots, как обычно, можно настраивать во время исполнения стратегии при помощи панели настроек (нижняя часть графика, параметр Lot). Параметры OpenOrderSound и MagicNumber в стратегии, работающей в среде AutoGraf, недоступны пользователю для изменения. Их можно менять только путем редактирования исходного кода программы.
Запуск стратегии "Метод новичка" в среде AutoGraf 4.0 состоит из следующих шагов:

Получить файл по ссылке Файлы стратегий для AutoGraf 4.0 (http://www.forextrade.ru/media/Image/MQLabs/106_ag/AG_NoviceMethod.zip) и распаковать полученный архив в папку MT4\experts\libraries (с перезаписью файлов AG_AT.ex4 и AG_AT.mq4).
Запустить AutoGraf (прикрепить индикатор AG_ind, а затем эксперт AG_exp).
Для работы стратегии в ключе приведенных результатов в окне настроек AutoGraf (закладка "Входные параметры") установить нужные значения параметров AT_1 - AT_5. Полное повторение результатов при этом не гарантируется.
Выбрать стратегию №5. Для этого необходимо передвинуть вверх значок So и среди названий стратегий найти значок S5, который также потянуть вверх.
Запустить функцию автоматической торговли, передвинув значок AT в верхнее положение.


Советник NoviceMethod (http://www.forextrade.ru/media/Image/MQLabs/106_ag/NoviceMethod_Expert.mq4)
Файлы стратегий для AutoGraf 4.0 (http://www.forextrade.ru/media/Image/MQLabs/106_ag/AG_NoviceMethod.zip)
Развернутые результаты тестирования эксперта (http://www.forextrade.ru/media/Image/MQLabs/106_ag/test.zip)

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