Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Книга по написанию робота под MT4.docx
Скачиваний:
1
Добавлен:
01.07.2025
Размер:
484 Кб
Скачать
☆

Реализация трейлинг стопа в эксперте

Вначале мы перебираем открытые позиции и выставленные ордера и ищем позицию, открытую по данному инструменту и чье магическое число равно MyMagicNumber:

// управление трейлинг стопом

for (i=0; i<OrdersTotal(); i++)

{

if (!OrderSelect(i, SELECT_BY_POS))

{

Print("Error ", GetLastError(), ": Start()->OrderSelect(", i, ") [OrderTotal()=", OrdersTotal(),"]");

continue;

}

if (OrderSymbol()!=Symbol()) continue;

if (OrderMagicNumber()!=MyMagicNumber) continue;

double diff;

if (OrderType() == OP_BUY)

{

...

}

if (OrderType() == OP_SELL)

{

...

}

}

Далее мы рассчитываем для найденных позиций расстояние между текущей ценой и ценой Stop Loss ордера для этой позиции. Если это расстояние превышает TrailingStop пипсов, то эксперт посылает команду на изменение уровня Stop Loss ордера.

Для открытой позиции на покупку:

if (OrderType() == OP_BUY)

{

diff = Bid-Point*TrailingStop-OrderStopLoss();

if (diff>0)

{

if (!OrderModify(OrderTicket(), OrderOpenPrice(), Bid-Point*TrailingStop, 0,0))

Print("Error ", GetLastError(), ": Start()->OrderModify() [trailing stop]");

else

Print("Trailing stop on #", OrderTicket()," [place stop loss at ",

Bid-Point*TrailingStop, "]");

}

return(0);

}

Для позиции на продажу:

if (OrderType() == OP_SELL)

{

diff = OrderStopLoss()-Ask-Point*TrailingStop;

if (diff>0)

{

if (!OrderModify(OrderTicket(), OrderOpenPrice(), Ask+Point*TrailingStop,0,0))

Print("Error ", GetLastError(), ": Start()->OrderModify() [trailing stop]");

else

Print("Trailing stop on #", OrderTicket()," [place stop loss at ",

Ask+Point*TrailingStop, "]");

}

return(0);

}

}

В следующем выпуске я расскажу о сортировке методом пузырька.

Сортировка методом пузырька

В прошлых выпусках я начал рассмотрение способа реализации глобальных массивов и рассказал о функциях Count(), AddItem(), SearchItem(), GetItem() и DeleteItem().

В этом выпуске я расскажу о том, как можно отсортировать глобальный массив по возрастанию или убыванию. Один из наиболее простых в реализации, но медленных по скорости методов сортировки - метод пузырька.

Основная идея сортировки (например, по возрастанию) методом пузырька очень простая. Предположим, что у нас N элементов в массиве и индекс каждого элемента лежит в промежутке от 1 до N.

Первый шаг сортировки методом пузырька

  1. Сравниваем первый и второй элементы массива. Если первый элемент больше, чем второй, то меняем их местами.

  2. Сравниваем второй и третий элементы массива. Если второй элемент больше, чем третий, то меняем их местами.

  3. ...

  4. Cравниваем предпоследний (N-1) и последний (N) элементы массива. Если предпоследний элемент больше, чем последний, то меняем их местами.

В результате самым последним элементом в массиве у нас окажется самый большой элемент.

Повторяем вышеуказанные действия для части массива, начиная с 1 позиции до N-1 (шаг 2).

Второй шаг сортировки методом пузырька

  1. Сравниваем первый и второй элементы массива. Если первый элемент больше, чем второй, то меняем их местами.

  2. Сравниваем второй и третий элементы массива. Если второй элемент больше, чем третий, то меняем их местами.

  3. ...

  4. Cравниваем элемент N-2 и элемент N-1 массива. Если (N-2)-й элемент больше, чем элемент N-1, то меняем их местами.

В результате предпоследний элемент в массиве у нас тоже будет на своем, "отсортированном" месте.

Последующие шаги сортировки методом пузырька

Повторяем вышеуказанные действия для части массива, начиная с 1 позиции до N-2 (шаг 3), а потом для диапазона 1..N-3 и так далее до диапазона 1..2.

После завершения последнего шага наш массив будет отсортирован по возрастанию.

В следующем выпуске я приведу исходный код функции Sort(), которая сортирует глобальный массив, переданный ей в качестве параметра.

Исходный код функции сортировки методом пузырька

В прошлом выпуске я рассказал о сортировке методом пузырька. В этом выпуске я приведу исходный код функции, которая сортирует массив таким методом.

//+---------------------------------------------------------------------------------------------------+

//| Функция Sort() - сортирует массив методом пузырька |

//| |

//| Возвращает true, если не было ошибки, и false, если ошибка была |

//| |

//| Параметры: |

//| array - имя массива |

//| is_asc_order - если true, то сортируется по возрастанию; если |

//| false, то по убыванию |

//+--------------------------------------------------------------------------------------------------+

bool Sort(string array, bool is_asc_order)

{

// Залокируем критическую секцию

string critical_section = array+"Lock";

if (Lock(critical_section)!=0) return(false);

// Количество элементов массива хранится в переменной с именем,

// равным имя массива + "Count"

string gv_count;

gv_count = array+"Count";

int count, err;

// Если глобальная переменная не существует, то элементов нет

if (!GlobalVariableCheck(gv_count))

{

err = GetLastError();

if (err!=0)

{

// Разлокировать критическую секцию

Unlock(critical_section);

// Вывести сообщение об ошибке и выйти

Print("Sort()->GlobalVariableCheck(): ошибка ", err);

return(false);

}

else

count = 0;

}

else

// переменная существует, получим количество элементов

count = GlobalVariableGet(gv_count);

int i, up_idx;

for (up_idx=count; up_idx>1; up_idx--)

{

// обработаем участок массива 1..up_idx

for (i=1; i<up_idx; i++)

{

// m1 - элемент i

// m2 - элемент i+1

double m1 = GlobalVariableGet(array+DoubleToStr(i, 0));

double m2 = GlobalVariableGet(array+DoubleToStr(i+1, 0));

bool is_sorted; // если true, то не надо переставлять элементы

is_sorted = true;

if (is_asc_order)

{

// сортируем по возрастанию

if (m1>m2) is_sorted = false;

}

else

{

// сортируем по убыванию

if (m1<m2) is_sorted = false;

}

// переставим элементы местами

if (is_sorted) continue;

if (GlobalVariableSet(array+DoubleToStr(i, 0),m2)==0)

{

// произошла ошибка при изменении элемента

// Разлокировать критическую секцию

Unlock(critical_section);

// Вывести сообщение об ошибке и выйти

Print("Sort()->GlobalVariableSet(): ошибка ", GetLastError());

return(false);

}

if (GlobalVariableSet(array+DoubleToStr(i+1, 0),m1)==0)

{

// произошла ошибка при изменении элемента

// Разлокировать критическую секцию

Unlock(critical_section);

// Вывести сообщение об ошибке и выйти

Print("Sort()->GlobalVariableSet(): ошибка ", GetLastError());

return(false);

}

}

}

// Разлокировать критическую секцию

Unlock(critical_section);

return(true);

}

В следующем выпуске я покажу на примере, как работает эта функция.

Пример работы функции Sort() - сортировки методом пузырька

В прошлом выпуске я привел исходный код функции Sort() глобального массива, которая осуществляет сортировку методом пузырька.

На мой взгляд, подробно разбирать ее не имеет смысла, т.к. она содержит много комментариев. Проблема с пониманием может возникнуть только на этом участке кода:

int i, up_idx;

for (up_idx=count; up_idx>1; up_idx--)

{

// обработаем участок массива 1..up_idx

for (i=1; i<up_idx; i++)

{

// m1 - элемент i

// m2 - элемент i+1

double m1 = GlobalVariableGet(array+DoubleToStr(i, 0));

double m2 = GlobalVariableGet(array+DoubleToStr(i+1, 0));

bool is_sorted; // если true, то не надо переставлять элементы

is_sorted = true;

if (is_asc_order)

{

// сортируем по возрастанию

if (m1>m2) is_sorted = false;

}

else

{

// сортируем по убыванию

if (m1<m2) is_sorted = false;

}

// переставим элементы местами

if (is_sorted) continue;

if (GlobalVariableSet(array+DoubleToStr(i, 0),m2)==0)

{

// произошла ошибка при изменении элемента

...

return(false);

}

if (GlobalVariableSet(array+DoubleToStr(i+1, 0),m1)==0)

{

// произошла ошибка при изменении элемента

...

return(false);

}

}

}

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

Допустим, что у нас есть неотсортированный массив и мы хотим его отсортировать по убыванию.

№ элемента

Исходное состояние

После шага 1

После шага 2

После шага 3

После шага 4

После шага 5

6

89

2

2

2

2

2

5

2

89

7

7

7

7

4

45

7

89

8

8

8

3

7

45

8

89

24

24

2

8

8

45

24

89

45

1

24

24

24

45

45

89

Под "шагами" здесь понимается "внешний" цикл for (up_idx=count; up_idx>1; up_idx--).

Во внутреннем же цикле, например, на первом шаге мы осуществляем следующие действия:

  1. Сравниваем первый элемент (24) и второй (8). Т.к. они расположены по убыванию, то ничего с ними не делаем.

  2. Сравниваем второй элемент (8) и третий (7). Т.к. они расположены по убыванию, то ничего с ними не делаем.

  3. Сравниваем третий элемент (7) и четвертый (45). Т.к. они не расположены по убыванию, то поменяем их местами.

  4. Сравниваем новый четвертый элемент (7) и пятый (2). Т.к. они расположены по убыванию, то ничего с ними не делаем.

  5. Сравниваем пятый элемент (2) и шестой (89). Т.к. они расположены по убыванию, то ничего с ними не делаем.

  6. Сравниваем первый элемент (24) и второй (8). Т.к. они не расположены по убыванию, то поменяем их местами.

Результат первого шага изображен в таблице.

По аналогии мы проходим наш массив еще 4 раза (четыре шага) и получае массив, отсортированный по убыванию.

Стандартные индикаторы технического анализа в MQL4

Этим постом я начинаю рассматривать стандартные индикаторы технического анализа, которые можно использовать в экспертах.

MetaTrader 4 - один из лучших клиентских терминалов, с очень большим списком встроенных индикаторов технического анализа.

В своих предыдущих выпусках, посвященных техническому анализу, теории хаоса Б.Вильямса, индикатору Ишимоку и теории Демарка, я рассказал почти о каждом из них.

Вот полный список функций языка MQL4, с помощью которых Вы можете использовать встроенные индикаторы технического анализа в своих экспертах:

  • iAC - Индикатор Ускорения/Замедления (Acceleration/Deceleration, AC)

  • iAD - Индикатор накопления/распределения (Accumulation Distribution, A/D)

  • iAlligator - Аллигатор Билла Вильямса (Alligator)

  • iADX - Индекс Среднего Направления Движения (Average Directional Movement Index, ADX)

  • iATR - Средний Истинный Диапазон (Average True Range, ATR)

  • iAO - Волшебный Осциллятор Билла Вильямса (Awesome Oscillator - AO)

  • iBearsPower - индекс силы медведей

  • iBands - Полосы Боллинджера (Bollinger Bands)

  • iBandsOnArray - Полосы Боллинджера (Bollinger Bands), построенные по данным, хранящимся в массиве

  • iBullsPower - индекс силы быков

  • iCCI - Индекс торгового канала (Commodity Channel Index, CCI)

  • iCCIOnArray - индикатор CCI, построенный по данным, хранящимся в массиве

  • iCustom - вызов самописного индикатора (о том, как создать свой индикатор на языке MQL4, я расскажу в следующих выпусках)

  • iDeMarker - Индикатор Демарка (Demarker)

  • iEnvelopes - Каналы изменения цен (Envelopes)

  • iEnvelopesOnArray - Каналы изменения цен (Envelopes), построенные по данным, хранящимся в массиве

  • iForce - Индекс Силы (Force Index)

  • iFractals - Фракталы (Fractals) Б.Вильямса

  • iGator - Gator Oscillator

  • iIchimoku - Ишимоку Кинко Хайо (Ichimoku Kinko Hyo)

  • iBWMFI - Индекс Облегчения Рынка (Market Facilitation Index, BW MFI)

  • iMomentum - Индикатор Momentum

  • iMomentumOnArray - Индикатор Momentum, построенный по данным, хранящимся в массиве

  • iMFI - Индекс денежного потока (Money Flow Index - MFI)

  • iMA - скользящая средния

  • iMAOnArray - скользящая средния, построенная по данным, хранящимся в массиве

  • iOsMA - Индикатор Скользящая Средняя Осциллятора (Moving Average of Oscillator, OsMA)

  • iMACD - MACD-гистограмма (метод конвергенции-дивергенции)

  • iOBV - Индикатор равновесного объема (On Balance Volume - OBV)

  • iSAR - Индикатор Параболик

  • iRSI - Индекс относительной силы (Relative Strength Index, RSI)

  • iRSIOnArray - Индекс относительной силы (Relative Strength Index, RSI), построенный по данным, хранящимся в массиве

  • iRVI - Индекс Относительной Бодрости (Relative Vigor Index, RVI)

  • iStdDev - индикатор Standard Deviation

  • iStdDevOnArray - индикатор Standard Deviation, построенный по данным, хранящимся в массиве

  • iStochastic - Стохастик (Stochastic Oscillator)

  • iWPR - Индикатор Процентный Диапазон Вильямса (Williams’ Percent Range, %R)

iAlligator() - Аллигатор Билла Вильямса (Alligator)

Рассмотрение функций языка MQL4, с помощью которых Вы можете использовать встроенные индикаторы технического анализа в своих экспертах, я начну с функции iAlligator().

С помощью этой функции можно получить значения Аллигатора Билла Вильямса (Alligator).

Думаю, будет нелишним сначала рассказать о самом идикаторе.

Аллигатор Билла Вильямса (Alligator) – это комбинация трех линий баланса (рис. 1):

  • Челюсть Аллигатора (синяя линия) – это 13-периодная скользящая средняя по центральной цене (High+Low)/2, смещенная на 8 баров в будущее;

  • Зубы Аллигатора (красная линия) – это 8-периодная скользящая средняя по центральной цене (High+Low)/2, смещенная на 5 баров в будущее;

  • Губы Аллигатора (зеленая линия) - это 5-периодная скользящая средняя по центральной цене (High+Low)/2, смещенная на 2 бара в будущее.

Для добавления Аллигатора (Alligator) на график платформы MetaTrader 4 выберите пункт меню "Вставка -> Индикаторы -> Билла Вильямса - Alligator".

Рис. 1. Аллигатор Билла Вильямса (Alligator)

С помощью Аллигатора можно определить направление существующего тренда или его отсутствие.

Если все три линии переплетены, то Аллигатор "спит". В это время рынок торгуется в небольшом ценовом диапазоне (во флэте), отбирая у трейдера заработанное на прошлом движении цены. Чем дольше спит Аллигатор, тем более голодным он становится, и тем более сильным будет последующее движение цены. Пока Аллигатор спит, оставайтесь квадратными. Проснувшись, Аллигатор раскрывает пасть (Линии Баланса расходятся) и начинает охотиться за добычей. Наевшись, Аллигатор снова засыпает (Линии Баланса сходятся).

Если Аллигатор не спит, на рынке существует повышательный или понижательный тренд (добыча убегает от Аллигатора):

  • если цена находится выше пасти Аллигатора, то тренд повышательный;

  • если цена ниже пасти Аллигатора, то тренд понижательный.

Еще одна полезная функция Аллигатора – помощь в определении разметки волн Эллиотта. Если цена находится за пределами пасти Аллигатора, на рынке формируется импульсная волна, а если внутри пасти, то корректирующая.

Формула расчета Аллигатора:

MEDIAN PRICE = (HIGH + LOW) / 2 ALLIGATORS JAW = SMMA (MEDIAN PRICE, 13, 8) ALLIGATORS TEETH = SMMA (MEDIAN PRICE, 8, 5) ALLIGATORS LIPS = SMMA (MEDIAN PRICE, 5, 3)

Где: MEDIAN PRICE - центральная цена; HIGH - максимальная цена бара; LOW - минимальная цена бара; SMMA (A, B, C) — сглаженное скользящее среднее (А — сглаживаемые данные, В — период сглаживания, С — сдвиг в будущее). ALLIGATORS JAW — Челюсти Аллигатора (синяя линия); ALLIGATORS TEETH — Зубы Аллигатора (красная линия); ALLIGATORS LIPS — Губы Аллигатора (зеленая линия).

Для того, чтобы получить значения Аллигатора в эксперте, мы можем использовать функцию iAlligator().