Оператор цикла FOR

 При программировании индикаторов и советников часто приходится решать такую задачу: подсчитать среднее арифметическое нескольих цен. Возьмём к примеру скользящую среднюю по ценам открытия с периодом 5.

Как получить цены открытия мы уже знаем (используем предопределённую переменную Open[]). Дальше вроде бы всё просто, пишем примерно следующее:

(Open[0]+Open[1]+Open[2]+Open[3]+Open[4])/5

и получаем требуемое значение. Но если период будет не 5 как в этом примере, а 50? или 100?? (или 300.....это вполне реально, скользящие средние с большими периодами используются достаточно часто)
В таком случае сложить кучу цен не так просто.

Для решения подобных задач мы можем использовать операторы цикла. Для начала напишем несложный код. Количество данных для расчёта будем задавать во внешней переменной ma_period.

extern int ma_period=100; // количество цен для расчёта
double prices; // переменная для сохранения результата
int start()
{
for ( int i=0; i<=ma_period; i++ ) //оператор цикла
{ //тело цикла (начало)
prices += Open[i]; //суммирование цен
} //завершение цикла
prices /= ma_period; //считаем среднее, т.е делим полученную сумму на количество данных
comment (prices); //вывод результата на экран
return (0);
}

Теперь подробнее, сначала об операторах. Тут мы видим несколько непонятные операторы

( i++ , prices += Open[i] , prices /= ma_period )

Ничего сверхестественного в них нет, это просто сокращённая запись. Язык си ( и соответственно mql )допускает такие сокращения.
i++ оператор инкремента, то есть увеличения на единицу, эквивалентно i=i+1

(догадайтесь что означает i--)))))))))))))))
(для тех кто не догадался))))))) i-- это оператор декремента, то есть уменьшения на единицу, то же самое что i=i-1 )


запись вида prices += Open [i] то же самое что prices = prices + Open [i]
соответственно prices /= ma_period то же самое что prices = prices / ma_period
Можно использовать тот вид записи который вам более удобен и понятен.

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

for ( int i=0; i<=ma_period; i++ ),

состоит как бы из трёх частей, разделённых точкой с запятой.
первая часть (int i=0) это инициализация цикла. переменная i в данном случае является счётчиком цикла, а инициализация-это просто задание начального значения счётчика.
вторая часть (i<=ma_period)- выражение, по сути представляет собой условие выхода из цикла.
ну и третья часть (i++) изменение значения счётчика.... (на то он и счётчик чтоб считать))))))))
алгоритм работы цикла такой:

задаем начальное значение счётчика
проверяем выражение (условие выхода)
если выражение истинно, выполняем операторы в теле цикла,
если ложно-выходим из цикла
изменяем счётчик цикла
возвращаемся к п 2
Посмотрим как будет работать наш пример по этому алгоритму. Переменная ma_period уже задана в настройках и равна 100.

инициализируем цикл, то есть задаём начальное значение счётчика int i=0;
проверяем выражение..ноль меньше чем 100 ? (вопрос конечно сложный, но решаемый)))))))))))))))))
выражение истинно, 0 действительно меньше чем 100))))) значит выполняем операторы цикла
prices изначально =0, значит получается: priices=0+Open[0];
изменяем счётчик цикла... i=i+1,то есть i=0+1, теперь i=1
возвращаемся к п2
Пройдём ещё раз, с учётом изменений, теперь начиная от п2, как сказано в п5)))))))))
проверяем вражение, счётчик i теперь равен 1 и всё ещё меньше 100 (хм...странно...)))))))
выражение истинно , выполняем операторы, prices равно Open[0] после выполнения первой итерации (то есть прохода по циклу);
значит теперь действие будет таким prices=Open[0]+Open[1]
изменяем счётчик цикла i=1+1 то есть теперь i=2
таким образом с каждым проходом мы увеличиваем счётчик цикла на 1 пока он не станет больше 100, при этом каждый раз прибавляем к результирующему значению цену открытия следующего бара. В конце концов мы подсчитаем все 100 значений, то есть наши вычисления будут выглядеть так Open[0]+Open[1]+.....+Open[i]+....+Open[100], при этом счётчик при последующем увеличении станет равен 101 и выражение станет ложным так как 101 не меньше 100 и в соответствии с алгоритмом цикл прекращается (выходим из цикла)

Дальше остаётся только поделить полученную величину на 100 и мы получим требуемое среднее арифметическое цен открытия за 100 баров
В этом примере мы подсчитывали цены начиная от текущего бара (самого свежего, без червей)))))))) к самому дальнему (возможно уже протухшему))))))))). Но можно сделать и наоборот, начать подсчёт от самого дальнего бара и уменьшать счётчик , пока он не станет меньше нуля
For ( i=100; i>0 ; i-- ) { операторы цикла }
то есть мы можем задавать направление цикла. В нашем примере это непринципиально, какая разница откуда начинать подсчёт баров, но иногда это может иметь значение При этом нужно обращать внимание на следующее:

если мы неправильно зададим направление цикла, например так: For ( i=100; i<0; i-- ) {......} то есть выражение изначально ложно, 100 ну никак не меньше нуля)))) цикл просто не будет выполняться и в последующих вычислениях мы можем получить результат весьма далёкий от ожидаемого))))))

А если неправильно задать изменение счётчика, например:

For ( i=100; i>0 ; i++ ) {.......} мы просто наглухо подвесим наш советник. Ведь что получается в таком случае, выражение истинно, 100 действительно больше 0 и операторы цикла будут выполняться. Но счётчик с каждым проходом будет увеличиваться, 101,102, и т.д то есть он никогда не будет меньше нуля Соответственно выражение никогда не станет ложным и мы никогда не выйдем из такого цикла ( ныне и присно и во веки веков....аминь))))))))) Наша программа просто зависнет.

Пожалуй с циклом for мы разобрались, можно переходить к следующему оператору. ( не забываем читать учебник MQL))))))

 

 

 Назад

 

 

TEXT.RU - 100.00%

 

 

Комментарии (0)

Нет комментариев. Ваш будет первым!

Яндекс.Метрика