Последующие шаги сортировки методом пузырька
Повторяем вышеуказанные действия для части массива, начиная с 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 | |||||||
Под "шагами" здесь понимается "внешний" цикл 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().