Как работает AFL.

Введение

Одним из самых важных аспектов языка AFL является то, что он является языком обработки и вычислений массивов (array processing language). Он оперирует с массивами (векторами) данных. Этот способ вычислений очень похож на то, как работают популярные пакеты электронных таблиц (типа Microsoft Excel). Каждый, кто знаком с MS Excel, не должен испытать трудностей с пониманием AFL. Фактически все примеры в этой статье были подготовлены с использованием MS Excel.

Что такое массив (array)?

Массив это просто список (или строка) значений. В некоторых книжках он может называться вектором. Каждая пронумерованная строка в последующих примерах представляет собой отдельный массив. Для каждого символа Амиброкер сохраняет в своей базе данных 6 массивов. Один для цены открытия, один для цены лоу, один для цены хай, один для цены закрытия и один для объёма (см. строки с номерами 1-5 в таблицах далее по тексту) и один для открытого интереса. К ним можно обратиться в AFL по именам: open, low, high, close, volume, openint или O, L, H, C, V, OI.

Bar 1 2 3 4 5 6 7 8 9 10
1 Open 1.23 1.24 1.21 1.26 1.24 1.29 1.33 1.32 1.35 1.31
Массив цен открытия.

Любые другие массивы вычисляются из этих шести массивов с использованием встроенных функций AFL. Эти массивы не хранятся в базе данных, а вычисляются, когда они необходимы.

Каждое индивидуальное значение в массиве имеет ассоциированную с ним дату. Если у вас включена опция показывать подсказки (Preferences -> Miscellaneous Tab - > Price data tool tips), то когда вы перемещаете курсор над свечками дневного графика, появляется небольшой жёлтенький прямоугольник. AFL берёт значения open, low, high, close, volume из соответствующих массивов и показывает их в подсказке.

Обработка массивов – почему в AFL так быстро?

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

MyVariable = ( High + Low )/2;

Когда AFL вычисляет такой оператор как ( High + Low )/2 он не повторяет этот код для каждого бара. Вместо этого он берёт МАССИВ High и МАССИВ Low и суммирует соответственные элементы массивов за один этап. Другими словами оператор «+» (и другие операторы тоже) выполняется над целыми массивами сразу и производится на скорости исполнения полностью откомпилированного кода, затем результирующий массив (каждый его элемент) делится на 2 также за один раз.

Посмотрим всё это в деталях. Когда движок AFL разбирает выражение ( High + Low )/2 он сначала берёт массивы High (1) и Low (2) и производит (за один откомпилированный шаг) временный массив (3). Затем он создаёт финальный массив (4) деля значение каждого элемента временного массива (3) на два. Этот результат присваивается переменной myVariable

Bar 1 2 3 4 5 6 7 8 9 10
1 High (исходный массив) 1.24 1.27 1.25 1.29 1.25 1.29 1.35 1.35 1.37 1.29
2 Low (исходный массив) 1.20 1.21 1.19 1.20 1.21 1.24 1.30 1.28 1.31 1.27
3 High+Low (временный массив
создаваемый в процессе вычислений)
2.44 2.48 2.44 2.49 2.46 2.53 2.65 2.63 2.68 2.46
4 ( High+Low ) /2
(назначается в MyVariable)
1.22 1.24 1.22 1.245 1.23 1.265 1.325 1.315 1.34 1.23
Шаги AFL при вычислении ( High + Low ) /2.

Скользящие средние, условные выражения

Теперь рассмотрим следующий код:

Cond1 = Close > MA( Close, 3 );
Cond2 = Volume > Ref( Volume, -1 );
Buy = Cond1 AND Cond2;
Sell = High > 1.30;

Этот код генерирует сигнал на покупку когда сегодняшние закрытие происходит выше чем 3-х дневное скользящее среднее и сегодняшний объём превосходит вчерашний. Он также генерирует сигнал на продажу, когда цена хай дня пробьёт 1.30.

Когда в своём коде вам скажем нужно посмотреть не превзошла ли цена закрытия например 3-х дневную простую скользящую среднюю, AFL сначала пробегает по массиву close создавая новый массив который можно условно назвать как MA(close,3) для того символа который анализируется. Каждая ячейка нового массива затем может быть сравнена одна к одной с соответственной ячейкой массива close. В нашем примере таким образом создаётся массив называемый Cond1. Для каждой ячейки, где цена закрытия выше чем значение в соответствующей ячейке MA(close,3), значение элемента в новом массиве 'Cond1' устанавливается в '1'. В противном случае значение в 'Cond1' устанавливается в '0'.

AFL также может заглядывать на заданное число ячеек массива вперёд или назад используя функцию Ref (см. строчку 6 в таблице далее по тексту в которой показан созданный временный массив содержащий значения объёма за предыдущий день)

В строке 9 показан массив Cond2 созданный как результат сравнения значения каждого элемента массива volume с предыдущим ему элементом массива, которое устанавливает в ячейку массива Cond2 значение '1' (истина) или '0' (ложь).

Строка 10 показывает массив 'Buy' создающийся как результат сравнения значений ячеек Cond1 с ячейками массива Cond2. Если элемент массива Cond1 равен '1' и соответствующий ему элемент из массива Cond2 также равен '1', то в ячейку массива 'Buy' устанавливается значение '1'.

Строка 11 показывает массив 'Sell' создаваемый во всех случаях когда значение в ячейке массива close превосходит $1.30.

День 1 2 3 4 5 6 7 8 9 10
1 Open 1.23 1.24 1.21 1.26 1.24 1.29 1.33 1.32 1.35 1.37
2 High 1.24 1.27 1.25 1.29 1.25 1.29 1.35 1.35 1.37 1.29
3 Low 2.44 2.48 2.44 2.49 2.46 2.53 2.65 2.63 2.68 2.46
4 Close 1.23 1.26 1.24 1.28 1.25 1.25 1.31 1.30 1.32 1.28
5 Volume 8310 3021 5325 2834 1432 5666 7847 555 6749 3456
6 Ref( Volume, -1 ) (временный массив
создаваемый в процессе вычислений)
Null 8310 3021 5325 2834 1432 5666 7847 555 6749
7 MA( Close, 3 ) (временный массив
создаваемый в процессе вычислений)
Null Null 1.243 1.260 1.357 1.260 1.270 1.287 1.310 1.300
8 Cond1 = Close < MA(close, 3) ( 1 (или True) если
выражение выполняется в противном случае ноль )
Null Null 1 0 1 1 0 0 0 1
9 Cond2 = Volume > Ref(volume, -1) Null 0 1 0 0 1 1 0 1 0
10 Buy = Cond1 AND Cond2 Null Null 1 0 0 1 0 0 0 0
11 Sell = High > 1.30 0 0 0 0 0 0 1 1 1 0

Buy и Sell являются специальными массивами чьи результирующие значения могут быть отображены в окне Analyser или в виде красных или зелёных отметок на экране при необходимости.

Чуть посложнее

Приведённые выше примеры очень простые. Здесь будет дано объяснение следующим трём вещам которые по-видимому порождают некоторую путаницу у пользователей:

Как описано в обучающем руководстве по базовым графическим средствам (Tutorial: Basic charting guide), вы можете выбрать и отметить любую котировку на графике и выделить временной интервал графика (From-To range). Бар, отмеченный вертикальной линией, называется “выбранным” баром ("selected" bar), также первый и последний бары интервала называются “начальным” и ”конечным” барами ("begin" and "end" bars). В AFL есть специальные функции, которые позволяют обращаться к значениям массива на выбранном, начальном и конечном баре соответственно. Это функции SelectedValue, BeginValue и EndValue. Также есть ещё одна функция – LastValue, которая позволяет получить значение массива на самом последнем баре графика. Эти четыре функции берут из массива элемент на заданном баре и возвращают ЕДИНСТВЕННОЕ ЧИСЛО представляющее собой значение массива в данной точке. Это позволяет вычислять различную статистику относительно выбранных точек графика. Например:

EndValue( Close ) - BeginValue( Close )
даст вам величину долларового изменения цены закрытия в выбранном временном промежутке.

Когда число, полученное с помощью одной из этих функций, сравнивается с массивом или выполняется какая-либо другая арифметическая операция, в которой участвует число и массив, она осуществляется так, как если бы число распространялось на все элементы массива. Это иллюстрируется в приведённой ниже таблице (строки 2, 6, 7). Зелёным цветом отмечен “начальный” бар, а красным цветом - “конечный” бар. “Выбранный” бар закрашен синим.

День 1 2 3 4 5 6 7 8 9 10
1 Open 1.23 1.24 1.21 1.26 1.24 1.29 1.33 1.32 1.35 1.37
2 BeginValue( Open ) 1.24 1.24 1.24 1.24 1.24 1.24 1.24 1.24 1.24 1.24
3 EndValue( Open ) 1.32 1.32 1.32 1.32 1.32 1.32 1.32 1.32 1.32 1.32
4 SelectedValue( Open ) 1.21 1.21 1.21 1.21 1.21 1.21 1.21 1.21 1.21 1.21
5 Volume 8310 3021 5325 2834 1432 5666 7847 555 6749 3456
6 Ref( Volume, -1 ) (временный массив
создаваемый в процессе вычислений)
Null 8310 3021 5325 2834 1432 5666 7847 555 6749
7 MA( Close, 3 ) (временный массив
создаваемый в процессе вычислений)
Null Null 1.243 1.260 1.357 1.260 1.270 1.287 1.310 1.300
8 Cond1 = Close < MA(close, 3) ( 1 (или True) если
выражение выполняется в противном случае ноль )
Null Null 1 0 1 1 0 0 0 1
9 Cond2 = Volume > Ref(volume, -1) Null 0 1 0 0 1 1 0 1 0
10 Buy = Cond1 AND Cond2 Null Null 1 0 0 1 0 0 0 0
11 Sell = High > 1.30 0 0 0 0 0 0 1 1 1 0


Удачи.