Основы языка MQL4. Технические индикаторы и встроенные функции
Часть 1
Введение
Это третья статья из цикла "Основы языка MQL4". В первых двух статьях мы познакомились с основами языка MQL4, фундаментом дальнейшего развития. Сейчас мы будем разбираться, как использовать встроенные функции и функции для работы с техническими индикаторами. Последние будут жизненно необходимы при разработке в дальнейшем ваших советников и индикаторов. Кроме того, мы на простом примере посмотрим, как можно отслеживать торговые сигналы для входа в рынок, что бы вы поняли, как правильно использовать индикаторы. А в конце статьи вы узнаете кое-что новенькое и интересное про сам язык.
Математические функции
Начнем с наиболее простых, но все же используемых и полезных математических функций.
MathAbs
Прототип функции:
double MathAbs(double value)
Очень простая функция, которая возвращает абсолютное значение (модуль числа). Это значит, что, если вы, например, примените ее к отрицательному числу, то в результате получите положительное число.
Примеры использования:
int a=-10;
double b=-20.0;
double c=7.0;
a=MathAbs(a); // теперь a равно 10
b=MathAbs(b); // теперь b равно 20.0
c=MathAbs(c); // значение c не изменится, так как, оно и так было положительно
MathCeil, MathFloor и MathRound
Прототипы функций:
double MathCeil(double x)
double MathFloor(double x)
double MathRound(double value)
Эти три функции очень похожи между собой: все они округляют число до целого. Но у каждой своя маленькая особенность:
MathCeil округляет таким образом, что, если имеется даже одна тысячная целого (например, 1.001), то это уже считается целым числом. То есть округление происходит в сторону, где получим большее значение. Например:
double a;
a=MathCeil(1.001); // a=2.0, даже одна тысячная округляется до целого
a=MathCeil(1.999); // a=2.0
a=MathCeil(-1.001); // a=-1.0, все правильно, так как, -1.0 больше чем -1.001
a=MathCeil(-1.999); // a=-1.0, правильно, -1.0 больше чем -1.999
MathFloor делает тоже, что и MathCeil, с точностью до наоборот. То есть, если нужно округлить положительное число, то оно просто лишиться дробной части:
double a;
a=MathFloor(1.999); // a=1.0, какой бы большой не была дробная часть, она убирается
a=MathFloor(1.001); // a=1.0
a=MathFloor(-1.001); // a=-2.0, верно, так как, -2.0 меньше чем -1.001
a=MathFloor(-1.999); // a=-2.0, все верно, -2.0 меньше -1.999
MathRound позволяет округлить число в привычном для нас с вами смысле. То есть, если дробная часть достаточно большая (0.5 и более), то она будет округлена до 1. Если дробная часть мала (меньше 0.5), то она будет округлена до 0, то есть она просто исчезнет. Примеры:
double a;
a=MathRound(1.1); // a=1.0, дробная часть слишком мала (0.1)
a=MathRound(1.57); // a=2.0, дробная часть достаточна, что бы быть округленной до 1
a=MathRound(-3.1); // a=-3.0 недостаточно
a=MathRound(-6.99); // a=-7.0 достаточно
MathMax
MathMin
Прототипы функций:
double MathMax(double value1, double value2)
double MathMin(double value1, double value2)
Это 2 очень похожие функции, которые принимают 2 аргумента, а возвращают соответственно наибольший и наименьший. Примеры:
double a;
a=MathMax(50.0,1.0); // a=50.0
a=MathMin(10.0,12.0); // a=10.0
MathPow
Прототип функции:
double MathPow(double base, double exponent)
Эта функция позволяет возвести число base в степень exponent. Примеры:
double a;
a=MathPow(5.0,2.0); // a=25.0, 5 во 2-ой степени
a=MathPow(2.0,8.0); // a=256.0, 2 в 8-ой степени
a=MathPow(25.0,0.5); // a=5.0, вы же знали, что число в степи 0.5 это его квадратный корень?
MathSqrt
Прототип функции:
double MathSqrt(double x)
Но квадратные корни лучше извлекать с помощью этой функции, так как это ее прямое назначение. Но не вздумайте узнавать корень отрицательного числа, так как вам будет возвращен нуль. Примеры:
double a;
a=MathSqrt(9.0); // a=3.0
a=MathSqrt(25.0); // a=5.0
a=MathSqrt(-256.0); // a=0.0, я предупреждал
MathLog
Прототип функции:
double MathLog(double x)
Еще кто-то помнит, что такое логарифм? Логарифм числа a по основанию b равен показателю степени, в которую нужно возвести число b, чтобы получить число a. Широкое применение нашли логарифмы по основаниям e (число Эйлера) — натуральные логарифмы (lna) и по основанию 10 — десятичные логарифмы (lg a). Что бы вспомнить больше, а возможно и узнать что-то новенькое, воспользуйтесь этой ссылкой:
http://ru.wikipedia.org/wiki/Логарифм
Так вот, функция MathLog предназначена для извлечения натурального логарифма из числа х. Не нужно узнавать натуральный логарифм отрицательных чисел или нуля. В таком случае вы получите -1. Примеры использования:
double a;
a=MathLog(10.0); // a=2.30258509
a=MathLog(0.0); // a=-1.0, неправильно
a=MathLog(-10.0); // a=-1.0, неверно
MathExp
Прототип функции:
double MathExp(double d)
Эта функция возвращает число e, возведенное в степень d. Многие наверняка не помнят про это число.
e — математическая константа, основание натурального логарифма, иррациональное и трансцендентное число. e = 2,718281828459045… Иногда число e называют числом Эйлера или неперовым числом. Играет важную роль в дифференциальном и интегральном исчислении. Узнать больше про число Эйлера можно по этой ссылке:
http://ru.wikipedia.org/wiki/Число_Эйлера
Если вы укажите слишком большую степень, то произойдет переполнение и будет возвращен нуль. Насколько большой должна быть степень, что бы произошла ошибка? Давайте узнаем это и проделаем небольшой эксперимент:
double exponent=1.0; // тут будем хранить показатель степени
double result=1.0; // возвращаемый функцией результат
int i=0; // количество итераций цикла
while(result!=0.0) // пока результат не равен нулю(пока не произошло переполнение)
{
result=MathExp(exponent); // запоминаем очередной результат
exponent*=10.0; // увеличиваем показатель степени
i++; // очередная итерация пройдена
}
MessageBox("i="+i); // результат эксперимента
А происходит следующее: каждый раз мы пытаемся вызвать функцию MathExp и с каждой итерацией степень увеличивается в 10 раз, пока, в конце концов, не произойдет переполнение и не будет возвращен нуль. В результате я получил i=310, что означает: в качестве степени вы можете использовать числа 1*10 в 309 степени (только представьте себе число длиной в 309 цифр!!). Поэтому, я думаю, что про переполнение вы можете не беспокоится.
MathMod
Прототип функции:
double MathMod(double value,double value2)
Эта функция позволяет узнать остаток от деления двух чисел. Например, 5 поделить на 2 равно 2 и остаток равен 1. Первый аргумент value – что делим, второй value2 – на что. И возвращается остаток. Примеры:
double a;
a=MathExp(5,2); // a=1.0
a=MathExp(10,3); // a=1.0, все правильно
a=MathExp(50,10); // a=0.0, делится без остатка
MathRand и MathSrand
Прототипы функций:
int MathRand()
void MathSrand(int seed)
MathRand возвращает одно за другим псевдослучайные целые числа в диапазоне от 0 до 32767. Тут у вас возникает куча вопросов: что значит приставка «псевдо»? Что за странный диапазон, а если мне надо от 5 до 10? Почему именно 32767? Отвечаю по порядку:
«Псевдо» означает, что числа не совсем случайные и все же зависят от чего-то. Допустим, вы написали скрипт, который выдает 5 псевдослучайных чисел, например, так:
int a=0;
while(a<5)
{
MessageBox(“random=”+MathRand());
a++;
}
Так вот, числа действительно будут случайными, но запустив скрипт еще раз, вы заметите, что последовательность будет постоянно повторяться. Это все потому, что существует число, от которого отталкивается функция MathRand. Будем называть его начальным числом. Что бы его изменить, нужно воспользоваться другой функцией – MathSrand. Эта функция принимает единственный аргумент – начальное число, от которого будут зависеть все псевдослучайные числа. Представьте себе, что начальное число – это плод, из которого вырастет дерево (случайные числа). По умолчанию начальное число равно единице. Таким образом, что бы получить действительно случайную последовательность нам нужно сначала присвоить начальному числу уникальное значение. Как это сделать? Есть еще одна функция TimeLocal, которая не имеет аргументов и возвращает количество секунд, прошедших после 00:00 1 января 1970 года. Эта функция идеально подходит, так как в большинстве случаев получим уникальное число. Ну как, еще не запутались? Вот как это выглядит:
int a=0;
MathSrand(TimeLocal()); // присваиваем начальному числу уникальное значение
while(a<5)
{
MessageBox(“random=”+MathRand());
a++;
}
Теперь каждый раз будем получать новую последовательность. Поехали дальше.
От 0 до 32767. Почему 32767? Смотрите: максимальное значение, которое может принимать int равно 2 в степени 16 (потому что значение переменной типа int занимает 16 бит в памяти компьютера, без учета знака) равно 32768, но так как мы считаем с нуля, то нужно отнять единицу. Вот и получили 32767.
Что бы получить любой нужный вам диапазон, нужно воспользоваться оператором % - остаток от деления. Например, если нужно получить случайные числа в диапазоне от 0 до 5:
int a=0;
MathSrand(TimeLocal());
while(a<5)
{
MessageBox(“random=”+MathRand()%6);
a++;
}
Обратите внимание, что мы написали MathRand()%6, а не MathRand()%5, это потому, что наш диапазон начинается с нуля, то есть нужно добавить еще единицу. Теперь, допустим, вам нужны случайные числа в диапазоне от 5 до 10:
MessageBox(“random=”+MathRand()%6+5); // просто добавляем нужное нам смещение
Аналогично можно получить и диапазон с отрицательными числами, например, от -5 до 5:
MessageBox(“random=”+MathRand()%11-5);
Если вам нужны только отрицательные числа, то умножьте результат на -1. Например, нужен диапазон от -10 до -20:
MessageBox(“random=”+(MathRand()%11+10)*(-1));
Если вам нужно получить случайное дробное число, например, в диапазоне от 0.0 до 1.0 с точностью до тысячной, то воспользуйтесь таким кодом:
MessageBox(“random=”+MathRand()%1001/1000.0);
Сначала мы создаем случайное число в диапазоне от 0 до 1000, а потом делим его на 1000.0. Обратите внимание, что делить нужно именно на 1000.0 (с плавающей запятой), а не на 1000(целое). В противном случае получим нуль, так как будет произведено округление.
|